open_jtalk_elixir

Hex versionCI

Use Open JTalk from Elixir. This package builds a local open_jtalk CLI and, by default, bundles a UTF-8 dictionary and an HTS voice (you can disable this), exposing convenient functions:

Install

Add the dependency to your mix.exs:

def deps do
  [
    {:open_jtalk_elixir, "~> 0.3"}
  ]
end

Then:

mix deps.get
mix compile

On first compile the project may download and build MeCab, HTS Engine API, and Open JTalk. By default it also downloads and bundles a UTF-8 dictionary and a Mei voice into priv/ (you can turn this off with OPENJTALK_BUNDLE_ASSETS=0).

Build requirements

You’ll need common build tools: gcc/g++, make, curl, tar, unzip. On macOS Xcode Command Line Tools are sufficient.

Optional environment flags (honored by the Makefile):

Tested platforms

Host builds (compile and run on the same machine):

Cross-compile (host → target):

Quick start

# play via system audio player (aplay/paplay/afplay/play)
OpenJTalk.say("元氣ですかあ 、元氣が有れば、なんでもできる")

Options

All synthesis calls accept the same options (values are clamped):

Concatenate WAVs

You can combine multiple WAVs (same format: channels/rate/bit depth/etc.) into one:

{:ok, a} = OpenJTalk.to_wav_binary("これは一つ目。")
{:ok, b} = OpenJTalk.to_wav_binary("これは二つ目。")
{:ok, c} = OpenJTalk.to_wav_binary("これは三つ目。")

{:ok, merged} = OpenJTalk.Wav.concat_binaries([a, b, c])
# or from files:
# {:ok, merged} = OpenJTalk.Wav.concat_files(["a.wav", "b.wav", "c.wav"])

How asset resolution works

The package resolves required assets in this order:

  1. Environment variable override
  2. Bundled asset in priv/
  3. System-installed location

CLI binary (open_jtalk)

Dictionary (sys.dic)

Voice (.htsvoice)

If you change environment variables at runtime (or move files), refresh the cached paths:

OpenJTalk.Assets.reset_cache()

Using with Nerves

This library is Nerves-aware. When MIX_TARGET is set the build defaults to:

So for many projects no extra configuration is needed.

Quick Nerves flow

export MIX_TARGET=rpi4
mix deps.get
mix compile
mix firmware

On the device:

{:ok, info} = OpenJTalk.info()
# bundled assets should show up as :bundled

OpenJTalk.say("こんにちは")

Audio on Nerves

OpenJTalk.say/2 requires a system audio player. Most Nerves images use ALSA aplay. If your image does not include a player:

Firmware size notes

Bundling the full dictionary + voice + binary increases firmware size. Approximate (uncompressed) sizes:

If that’s too large you can avoid bundling at compile time and provision assets separately (rootfs overlay, /data, OTA, etc.):

MIX_TARGET=rpi4 OPENJTALK_BUNDLE_ASSETS=0 mix deps.compile open_jtalk_elixir

Then point the library to the provisioned assets (for example in config/runtime.exs):

System.put_env("OPENJTALK_CLI", "/data/open_jtalk/bin/open_jtalk")
System.put_env("OPENJTALK_DICTIONARY_DIR", "/data/open_jtalk/dic")
System.put_env("OPENJTALK_VOICE", "/data/open_jtalk/voices/mei_normal.htsvoice")

OpenJTalk.Assets.reset_cache()

How you provision those files into your image is outside the scope of this library.

Third-party components and licenses

This package does not redistribute third-party assets by default. At compile time it may download and build the following components: