自分の音声のクローンをつくってみた。

## はじめに
昨年2023年7月にChatGPTのAPIを使って、自分のデジタルクローンをつくりました。

https://qiita.com/Namy/items/391685909823de3312d5

そのときは、OpenJTalkをつかって、自分の音声モデルをつくったのですが、昨今の生成AIの進化の速いことを考えると、もっと自分の声に似ているようにできるのではないか、と考えて、いろいろ調べて実装してみました。

完成形のデモ動画はこちら。うん、かなりリアル。

https://youtu.be/gUT90AKGJzU

ブラウザで対話することもできます。

https://namikawasusumu.jp

PC/スマホ　最新のSafari/Chromeで動作します。

## 音声クローンのやりかたあれこれ

音声クローンをつくるにあたり、まず考えたのはオープンソースです。OpenJTalkもオープンソース（利用規約はあります。商用利用には制限があります）ですが、他には、barkが良さそうでした。

https://zenn.dev/kun432/scraps/10187ffc065499

でも自前は結構大変なので、今回はサービス系を探ってみることにしました。

- 自分の音声を学習させられる
- 費用がそこまで高くない
- 日本語対応
- APIで利用可能
- レイテンシー（遅延）が短い
- 仕事じゃないので、手続きが面倒でない

というあたりを条件に探してみました。

## 候補 ##

特に、自分の音声を学習させられる、手続きが面倒でない、というところで条件がぐっと絞り込まれていきました。

国内系
CoeFont

海外系
Descript
Resemble.ai
ElevenLabs

あたりを候補に調べていきました。（2024年4月）

その中でも、
**Resemble.ai**
https://www.resemble.ai/
**ElevenLabs**
https://elevenlabs.io/
が最終候補になりました。

どちらも、上の条件にはまりそうです。

ただ、
Resemble.aiは、
多言語対応がProfessionalの　$99.00 / month　プランから。
結構高い！

ElevenLabsは、
Starter $5/ month　プランから
- 自分の音声を学習させられる
- 日本語対応
- APIで利用可能
でした。

いま（2024年4月）時点で音声クローンを考えている人は、ElevenLabsはかなり良い選択肢だと思います。

## ElevenLabsの使い方 ##

**ステップ1: ElevenLabsに登録する**
ElevenLabsのウェブサイトにアクセスし、アカウントを作成します。

**ステップ2: 音声サンプルの録音とアップロード**
音声サンプルを録音します。なんと１分間！文章はなんでも大丈夫です。日本語でOK。あっという間です。

**ステップ3: 自分の声のクローンを作成**
アップロードした音声サンプルを使用して声のクローンを作成します。

**ステップ4: テキストから声を生成する**
クローンが完成したら、テキストを入力して声に変換してみます。
異なるテキストで試してみて、声の自然さや発音を確認します。

**ステップ5: APIとVOICE_IDを取得する**
ElevenLabsのダッシュボードからAPIキーを取得します。
VOICE IDだけ、ちょっとわかりにくいので補足。
つくったVOICEのリストの右肩部分をおすと、VOICE IDが取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/ea8c6533-61a5-554d-3cd9-96cf1f1ac259.png)

ということで、かなり簡単に、ここまでたどり着きました。
ちょっと怖くなるほど、自分に似ている声ができます。

## プログラミング ##

今回は、前回つくった並河進Bオンラインを改造して、声の生成部分を、ElevenLabsに変更します。

```
import requests
from flask import Flask, request, Response
from flask_cors import CORS
import base64

app = Flask(__name__)
CORS(app)

XI_API_KEY = "API_KEY"
VOICE_ID = "VOICE_ID"

def text_to_reading(text):
    reading = ""
    for word in tagger(text):
        if word.feature.kana:
            reading += word.feature.kana
        else:
            reading += word.surface
    return reading

def synthesize_voice(text):
    tts_url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}/stream"
    headers = {
        "Accept": "application/json",
        "xi-api-key": XI_API_KEY
    }
    data = {
        "text": text,
        "model_id": "eleven_multilingual_v2",
        "voice_settings": {
            "stability": 0.5,
            "similarity_boost": 1.0,
            "style": 0.2,
            "use_speaker_boost": True,
            "speed": 1.0,
            "pitch": 1.0
        }
    }
    response = requests.post(tts_url, headers=headers, json=data, stream=True)
    if response.ok:
        return response.content
    else:
        return None

@app.route('/synthesize_base64', methods=['POST'])
def synthesize_base64():
    text = request.form['text']
    text = text.replace("並河進", "なみかわすすむ").replace("並河", "なみかわ").replace("進", "すすむ").replace("湯葉", "ゆば").replace("会い", "あい")
    voice_data = synthesize_voice(text)
    if voice_data:
        enc = base64.b64encode(voice_data)
        return Response(enc, mimetype="audio/mp3")
    else:
        return "Failed to synthesize voice", 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=3000)
```

ちょっとプログラムの一部を抜粋しちゃったので、よくわからないかもしれませんが、こんな感じです。

```
    data = {
        "text": text,
        "model_id": "eleven_multilingual_v2",
        "voice_settings": {
            "stability": 0.5,
            "similarity_boost": 1.0,
            "style": 0.2,
            "use_speaker_boost": True,
            "speed": 1.0,
            "pitch": 1.0
```
ここで、いろいろなパラメータを設定しています。

多言語対応は、「eleven_multilingual_v2」を選んでください。

パラメータは、こんな感じです。
- "stability": 安定性。低くしすぎるとイントネーションがおかしくなります。0.5ぐらいがいいと思います。
- "similarity_boost": 自分の声に似ている具合。低くするときれいな感じになりますが、自分の声と離れていきます。0〜1.0
-  "style": この数字を大きくすると演技がかり、感情の抑揚が大きくなります。僕は0.2にしましたが、お好みで。
- "use_speaker_boost": Trueにしておくのが良さそうです。
- "speed": 1.0を中心に速くしたり、遅くしたり。でも、あんまり変化がないです。
- "pitch": ピッチです。1.0が通常の高さ。これは結構変化あります。

## 完成！ ##
ということで、かなり簡単に、自分の声に近いクローンをつくることができました。技術の進化はすごい・・・。

OpenAIが、数秒の自分の声からクローンボイスがつくれる技術「Voice Engine」を開発したけれど、公開に慎重だったり、声や顔の複製についてはさまざまな危険性や議論があります。

一方、もうひとりの自分がいる、というのはとても面白かったりもするので、引き続き、「自分B」の開発はいろいろ研究してみようと思います。