ティンカラー日記

こなゆき(a.k.a. p-snow)

20 Oct 2024

バッファ内のテキストをAIに喋らせる

Emacs内のテキストをマシンに喋らせるということは、これまでもけっこう拘ってやってきました。いくつか理由はあります。自分が弱視なのでスクリーンリーダー代わりに使いたいという欲求もありましたし、他のことに目を使っている間に耳で情報を摂取したいというズボラな動機もありました。

最近では、難しい英単語のより正確な発音を知りたいというのもあります。まあ、ブラウザ内で検索すればGoogle先生が即座にその願いを叶えてくれますが、バッファ内で完結するのがEmacserの矜持というものです。はい。

AIブーム前夜まではローカルに用意したエンジンに喋ってもらっていました。日本語なら OpenJTalk に、英語なら Festival に。

しかし今や、音声合成の技術の発達とともに、AIの力で行われる圧倒的な構文解釈能力をベースにして驚くほどに人間に近い発話が可能になりました。なので、API経由でリージョン内のテキストをChatGPTに喋らせるコードを書きました

Elisp Code for Text to Speech

(defun tts-openai-request (api-key input action)
  "Return audio file content from OpenAI API and save it to OUTPUT-FILE or play it.
INPUT is the text string sent to the API.
RESPONSE-FORMAT is the format of the audio file, defaults to 'mp3'.
ACTION is either 'save or 'play, determining what to do with the response."
  (let* ((auth-value (format "Bearer %s" api-key))
         (model "tts-1")
         (voice "nova")
         (speed nil)
         (response-format "opus")
         (url "https://api.openai.com/v1/audio/speech")
         (data (json-encode `(("model" . ,model)
                              ("input" . ,input)
                              ("voice" . ,voice)
                              ,@(when response-format `(("response_format" . ,response-format)))
                              ,@(when speed `(("speed" . ,speed)))))))
    (request
      url
      :type "POST"
      :data data
      :headers `(("Authorization" . ,auth-value) ("Content-Type" . "application/json"))
      :parser 'buffer-string
      :success (cl-function
                (lambda (&key data &allow-other-keys)
                  (let ((coding-system-for-write 'binary)
                        (speech-file (make-temp-file "tts-" nil ".opus")))
                    (with-temp-file speech-file
                      (insert data))
                    (when action (funcall action speech-file)))))
      :error (cl-function
              (lambda (&key error-thrown &allow-other-keys)
                (message "Error: %S" error-thrown))))))

はい。書き方を見ればおわかりのとおり、ちゃっかりパッケージ化を目論んだ書き方になってますね。もしご所望の方がおられましたらご一報ください。がんばってみます。

Tags: ai speech