0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UnityでGeminiのText-to-Speechを試す

Posted at

動機

先日書いた記事ではGemini Live APIを取り扱った。

また、以前、OpenAI APIのText-to-Speechを試したこともある。その結果をYouTubeへも投稿:

Gemini APIの Text-to-Speechも試したくなってきた。こういうとき、私は、WebアプリかUnityやGodotでアプリつくって試す。今回はUnityで試すことにした。

まずはGemini APIのC#コードを作成

ベースは、以前、Godot向けに書いたGemini APIのGDScriptコード。Gemini CLIで、これをC#のコードへ変換した。

更に、このコードをVS Codeで開き、Gemini Code Assistによるアシストで細かな部分の修正を行った後、以下のサイトの情報をGemini Code Assistへテキストで与え、Text-to-Speechにも対応させた:

いや、すごい時代が来たものだ。。。最近、コードを書くときは、何をつくるにしても、Geminiが2~5割、私が5~8割という作業分担。今後、生成AIが書く割合は増えていく。。。

作成したC#コードは以下:
https://github.com/araobp/unity-robotics/blob/main/robotics/Assets/Scripts/Gemini.cs

これを動かしてみる

Gemini APIからどんな形式の音声データが返されるのか?試しに、このコードのText-to-Speechの部分を動かしてみた。WAVかMP3形式で返されたデータだろうと勝手に想像し、とりあえずWAVの拡張子でファイルへ保存し、Audacityという音声データ解析ツールでこれを開いてみたところ、これはRAWデータだと文句を言われた。

Gemini APIのドキュメントを見ると24000という数値が。これはPCMオーディオのサンプリングレートに違いないと思い、以下のようにサンプリングレート指定し、再度読み込ませた。

Screenshot 2025-11-30 at 11.08.26.png

そうすると音声データの波形が表示され、これを再生出来た。

Screenshot 2025-11-30 at 11.09.03.png

さて、ここからはお遊びだが、Gemini APIが生成した音声データのスペクトログラムを表示してみる。人の声の場合、これは声紋に相当する。これを見ると、Geminiが人間の真似をしている様子を実感出来る。Gemini API "Leda"さんの声。

Screenshot 2025-11-30 at 11.14.38.png

余談になるが、今年、私はG検定を受験し、G検定の教科書にも、PCM、サンプリング定理、ナイキスト周波数、スペクトログラム、更にはメルケプストラムまで解説されていた。。。そんなマニアックなところまで出題するのか???私のように、電話の開発や音のAI開発をやったことあれば、こういうのは楽勝かもしれないが、そうでないと、結構ハードル高いのでは。。。いや、これからフィジカルAIの時代に入るし、音のAIも重要になってきたのかもしれない。

試験用アプリの制作:まずは枠から

UIの制作から始める。声を選択するためのDropDownメニュー、テキストを入力するためのInputFieldとText-to-Speechを実行するボタンをUIへ配備した。
更に、GameControllerという空のオブジェクトを追加し、これに、メインのスクリプトとAudioSourceコンポーネントをアタッチ。

Screenshot 2025-11-30 at 12.06.38.png

残りは、Gemini APIが生成したPCMデータをAudioSourceコンポーネントへ渡す処理を書くだけ。

PCMデータをUnityのAudioSourceコンポーネントへ入力

このコードもVS Code上のGemini Code Assistantへ書かせた。以下のようなコードが生成された。私は組み込みシステム開発をやったことあるので、これを見て、懐かしくなった。符号付き16bit整数を浮動小数点の配列データへ変換し、この、サンプリングレート24000Hzのモノラル音声データをAudioSourceコンポーネントへ入力。

    void PlayAudio(byte[] pcmData)
    {
        // The synthesized audio is 16-bit PCM, so 2 bytes per sample.
        int samplesCount = pcmData.Length / 2;
        float[] floatData = new float[samplesCount];

        for (int i = 0; i < samplesCount; i++)
        {
            // Convert two bytes to a 16-bit signed integer (short)
            short sample = (short)((pcmData[i * 2 + 1] << 8) | pcmData[i * 2]);
            // Convert to float in the range -1.0 to 1.0
            floatData[i] = sample / 32768.0f;
        }

        const int sampleRate = 24000;
        const int channels = 1; // Mono

        AudioClip audioClip = AudioClip.Create("SynthesizedSpeech", samplesCount, channels, sampleRate, false);
        audioClip.SetData(floatData, 0);

        audioSource.clip = audioClip;
        audioSource.Play();
        Debug.Log("Playing synthesized speech.");
    }

このコードを通し、見事、音声を再生出来ることが出来た。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?