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?

More than 1 year has passed since last update.

プラ子ちゃんとおしゃべりができるようにしてみた!

Posted at

この記事の続きの内容になります。
今回はタイトルにもある通りプラ子ちゃんとおしゃべりできるようにするべくOpenAIとAzureを用いて機能を追加していきます!

OpenAIで返答を生成!!

まずやることは返答を生成することになります。
前回までで話しかけられた言葉を文字に起こすところまでは完成しているので、今回は文字起こしされた文章をOpenAIになげて返答を生成をしていこうと思います!
下記のサイトのソースを元に一部変更して実装していきます!
ChatGPT APIをUnityから動かす。
//ChatGPT APIとやり取りをするクラス

- public async UniTask<ChatGPTResponseModel> RequestAsync(string userMessage)
+ public async UniTask<string> RequestAsync(string userMessage)

    var responseString = request.downloadHandler.text;
    var responseObject = JsonUtility.FromJson<ChatGPTResponseModel>(responseString);
+   var responseMessage = responseObject.choices[0].message;
    Debug.Log("ChatGPT:" + responseMessage.content);
-   _messageList.Add(responseObject.choices[0].message);
-   return responseObject;
+   _messageList.Add(responseMessage);
+   return responseMessage.content;
//呼び出し側
static string OpenAiApiKey = "your_apikey"

var chatGPTConnection = new ChatGPTConnection(OpenAIApiKey);
-   chatGPTConnection.RequestAsync("{{AIに言いたいことをここに書く}}");
+   var response = chatGPTConnection.RequestAsync("{{AIに言いたいことをここに書く}}");

Azureで音声にしてしゃべらせてみる!

返答の生成ができたので次にテキストから音声にするTextToSpeechを追加していきます!
SpeechToTextでAzureを用いているのでこちらでもAzureで実装していきます!

static string SubscriptionKey = "your_subscriptionkey"
static string ServiceRegion = "japaneast";
static string RegionRecognitionLanguage = "ja-JP";
static string VoiceName = "ja-JP-NanamiNeural";

static string ssml = @$"<speak xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts' xmlns:emo='http://www.w3.org/2009/10/emotionml' version='1.0' xml:lang='ja-JP'>
                                <voice name='{VoiceName}'>
                                     <mstts:express-as style='cheerful' styledegree='2'>
                                        <prosody pitch='2%' rate='-2%'>
                                            TEXT
                                        </prosody>
                                    </mstts:express-as>
                                </voice>
                            </speak>";

static SpeechConfig speechConfig;
static AudioConfig audioConfig;
static SpeechRecognizer recognizer;
static SpeechSynthesizer synthesizer;

void start(){
    // speechConfig設定
    speechConfig = SpeechConfig.FromSubscription(SubscriptionKey, ServiceRegion);
    speechConfig.SpeechRecognitionLanguage = RegionRecognitionLanguage;
    speechConfig.SpeechSynthesisVoiceName = VoiceName;

    audioConfig = AudioConfig.FromDefaultMicrophoneInput();
    recognizer = new SpeechRecognizer(speechConfig, audioConfig);
    synthesizer = new SpeechSynthesizer(speechConfig);
}

void textToSpeech(String text){
    var ssml_text = ssml.Replace("TEXT", text);
    var speechSynthesisResult = await synthesizer.SpeakSsmlAsync(ssml_text);
    OutputSpeakTextResult(speechSynthesisResult);
}




参考サイト紹介
SpeechSynthesizer.StartSpeakingSsmlAsync(String) メソッド
SSML ドキュメントの構造とイベント

キャンセル処理がない!!!!

ということでここまで実装して気づいたのですが、「あれ、この子実行したら話し終わるまで一方的に話し続けてないか?」
このままではまずいので、話している途中に処理を止めれるようキャンセル処理を追加していきます!

//ChatGPT APIとやり取りをするクラス

- public async UniTask<string> RequestAsync(string userMessage)
+ public async UniTask<string> RequestAsync(string userMessage, CancellationToken cancelToken)
+       {
+           if (cancelToken.IsCancellationRequested)
+           {
+               Debug.Log("Canceled");
+               // キャンセルされたらTaskを終了する.
+               return null;
+           }
//呼び出し側
-   var response = chatGPTConnection.RequestAsync("{{AIに言いたいことをここに書く}}");
+   var response = chatGPTConnection.RequestAsync("{{AIに言いたいことをここに書く}}", cancelToken);
static Task Task;
CancellationTokenSource tokenSource;

    public void Speech()
    {
        tokenSource = new CancellationTokenSource();
        CancellationToken cancelToken = tokenSource.Token;
        Task = Task.Run(() => FromMic(cancelToken));
    }
    public void Cancel()
    {
        recognizer.StopContinuousRecognitionAsync();
        synthesizer.StopSpeakingAsync();
        tokenSource.Cancel();
    }

参考サイト紹介
【Unity】UniTaskのキャンセル処理まとめ・Taskとの比較
【Unity】UniTask Coroutineとの違いとキャンセル処理の挙動
【C#】Taskをキャンセルする
 SpeechSynthesizer.StopSpeakingAsync メソッド

まとめ

今回決まった音声を再生する状態から返答を考えそれを音声にして再生するようにしました!
キャンセル処理も実装しだいぶ形になってきたのではないかなっとおもいます。
閲覧いただきありがとうございました!
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?