mkxp-z / mkxp-z

Open-source cross-platform player for (some) RPG Maker XP / VX / VX Ace games. A very heavily modified fork of mkxp. RGSS on steroids with a stupid name.
https://github.com/mkxp-z/mkxp-z/wiki
GNU General Public License v2.0
140 stars 39 forks source link

Text to Speech #154

Open Splendide-Imaginarius opened 5 months ago

Splendide-Imaginarius commented 5 months ago

It might be interesting to support TTS in mkxp-z. Not sure what the implementation would look like, but Ren'Py has TTS, so maybe we could crib ideas from them.

(h/t @enumag and @Eblo)

enumag commented 5 months ago

I was trying to use FFI to call NVDA and have it read the text shown in game. After throwing ideas back and forth with @Splendide-Imaginarius I eventually managed to find a working solution:

$tts = Win32API.new("nvdaControllerClient64.dll", "nvdaController_speakText", "p", "v")

def tts(text)
  $tts.call(text.encode('utf-16le'))
end

Adjustments might be needed to use on platforms other than windows since the encoding would likely need to be different than utf-16le on other platforms. But it's enough for my needs. Big thanks for helping me out with this!

(You can consider this code snippet licensed under WTFPL.)

enumag commented 3 months ago

I recently made an improvement to this. There is a library called Tolk which is like an abstraction layer which can support multiple readers. I ended up using this fork which is more actively maintained. With this we're able to support more screen readers than just NVDA.

Win32API.new("libTolk.dll", "Tolk_Load", "", "v").call()
$tts = Win32API.new("libTolk.dll", "Tolk_Output", "p", "v")

def tts(text)
  $tts.call(text.encode('utf-16le'))
end

There is also an alternative library called UniversalSpeech. I didn't try it but it should work pretty much identically, just with different API.