[ruby] ArgumentError: comparison of A with A failed

というエラーが出た。AとAなのになぜ…

原因はsort内で比較していた値にnilが入っていたからだったんだけど、特定のケースでエラーメッセージがわかりにくくなるようだった。

エラーじゃない

> nil <=> 1
=> nil

エラーだけどわかりやすい

> [1, nil].sort { |a, b| a <=> b }
ArgumentError: comparison of Integer with nil failed

なぜ…というエラーメッセージになる

> [{ id: 1 }, { id: nil }].sort { |a, b| a[:id] <=> b[:id] }
ArgumentError: comparison of Hash with Hash failed

なるほど。

MacからWindowsのVoicevoxにつなぐ

0.2.0

https://github.com/Hiroshiba/voicevox_engine/pull/2 がマージされたので楽になった(ngrok不要)

  • [Windows] .\run.ext --host 0.0.0.0
  • [Mac] .envに VUE_APP_ENGINE_URL=http://Windows機のIPアドレス:50021 を設定
  • [Mac] $ npm run electron:serve

0.1.1

  • [Windows] 製品版を起動
  • [Windows] ngrokを入れて、$ ngrok http 50021 する
  • [Mac] .envに VUE_APP_ENGINE_URL=http://****.ngrok.io を設定
  • [Mac] $ npm run electron:serve

動いた。書き出しも行けた。

Voicevox 生成部分のAPI呼び出しメモ

  • AudioDetail.vueのplay
    • PLAY_AUDIOをdispatch
  • audio.tsのPLAY_AUDIO
    • キャッシュがなければGENERATE_AUDIOを呼び出す

GENERATE_AUDIOを見れば生成処理がわかりそう。

api.synthesisSynthesisPostを呼んでいる。

{
  "audioQuery": {
    "accentPhrases": [
      {
        "moras": [
          {
            "text": "コ",
            "consonant": "k",
            "vowel": "o",
            "pitch": 5.618423938751221
          },
          {
            "text": "ン",
            "vowel": "N",
            "pitch": 5.660080432891846
          },
          {
            "text": "ニ",
            "consonant": "n",
            "vowel": "i",
            "pitch": 5.6727824211120605
          },
          {
            "text": "チ",
            "consonant": "ch",
            "vowel": "i",
            "pitch": 5.499634742736816
          },
          {
            "text": "ワ",
            "consonant": "w",
            "vowel": "a",
            "pitch": 5.505942344665527
          }
        ],
        "accent": 5
      }
    ],
    "speedScale": 1,
    "pitchScale": 0,
    "intonationScale": 1
  },
  "speaker": 0
}

この情報をどっかから得てこないといけない。

FETCH_ACCENT_PHRASESか。

accentPhrasesAccentPhrasesPostにtextとspeakerを投げればよさそう。

[
  {
    "moras": [
      {
        "text": "コ",
        "consonant": "k",
        "vowel": "o",
        "pitch": 5.618423938751221
      },
      {
        "text": "ン",
        "vowel": "N",
        "pitch": 5.660080432891846
      },
      {
        "text": "ニ",
        "consonant": "n",
        "vowel": "i",
        "pitch": 5.6727824211120605
      },
      {
        "text": "チ",
        "consonant": "ch",
        "vowel": "i",
        "pitch": 5.499634742736816
      },
      {
        "text": "ワ",
        "consonant": "w",
        "vowel": "a",
        "pitch": 5.505942344665527
      }
    ],
    "accent": 5
  }
]

で、このAPIは誰が提供してるのか?
runEngineすることで起動してる製品版のAPI?

50021ポートを使ってるのが run.exeだったのでそういうことっぽい。

ということは同じように起動してあげれば独自クライアントを作れそう。

同一ネットワーク内の他の端末からも叩けるのでは?と思ったけど、127.0.0.1でbindしてるっぽいのでダメだった。

host="127.0.0.1",

を変えればよさそうだけど、 8/2時点ではrun.pyがエラーで動かないらしい(READMEより)

Voicevox(クライアント)をローカルで動かす

突如公開された面白いやつ。
https://voicevox.hiroshiba.jp/

触った記録をどこかにちゃんとまとめたいけど、ひとまずここに雑にメモしておく。

クライアントアプリのソースコードはこちら。
TypeScript・Electron製。
https://github.com/Hiroshiba/voicevox

環境

普段Windowsはほぼ使わないけど、たまたま少し前のお仕事で環境を作っていたのでそちらを使う。

PowerShell 7.1.3
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS C:\Users\tnantoka> node -v
v14.16.0

.node-versionでv12が指定されてたけど、v14でも動くようだった。

起動

$ cat .\.env
ENGINE_PATH=C:\Users\tnantoka\Downloads\VOICEVOX-0.1.1-win\run.exe
VUE_APP_ENGINE_URL=http://127.0.0.1:50021

$ npm install

$ npm run electron:serve

これで動いた。(エラー出てるけど、再生までできた)

エラーはエンジンが起動されるまで待っている間に出るものか。

Gemfileでrailsを一番上に置かなきゃいけない?

という話があった。
確かにいくつかそういう記事も見つかった。

だけどrailsに関して言えば、application.rbでrailsをrequireした後にBundler.requireをしているので、気にしなくて良さそうにも見える。
rubocopのBundler/OrderedGemsも気にしていなそう)

だが、心配なので一応検証してみた。

Gemを用意

$ cd ~/Documents/Temporary/
$ bundle gem defined_rails_checker
$ cd defined_rails_checker/

$ vim defined_rails_checker.gemspec 
# TODOを適当に埋める

$ vim lib/defined_rails_checker.rb
puts "###### defined rails checker"
if defined?(Rails)
  puts "OK! I love rails."
else
  raise "NO!!! I need rails!"
end

アプリケーション

$ vim Gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

ruby '2.7.3'

gem 'defined_rails_checker', path: '~/Documents/Temporary/defined_rails_checker'
gem 'rails'

$ bundle
$ ./bin/rails s
###### defined rails checker
OK! I love rails.

というわけで、大丈夫そうだった。

以下のような行儀の悪い運用スクリプトとかがいて、
それをrunnerじゃなく、単体で実行したい場合とかには気にする必要がありそう?
(そんなケースはあるのか??)

# ActiveSupport使いたいだけだけど、全部読み込む!
Bundler.require