Although the code isn’t quite ready for prime time, I’m trying to get it to the point where I can get it to some beta testers.
Optimally, I’d like to be able to deliver synSinger as a single executable, rather than having the end user install Lua on their machine.
I’d written utilities like this before in Euphoria, so I figured I’d try rolling my own. My code simply looked for require statements, and, if it had not encountered that file before, replaced the require with the source code of the file the was being requested. It was rather brute force… and came to an abrupt halt when the Lua interpreter complained that the resulting code reached the upper limit of local variables.
The next step was to play around with Squish, a utility for packing multiple Lua scripts into a single file. Squish is very cool, and has a bunch of neat options.
Unfortunately, I had trouble getting it to work properly. But the gist is that
causes the required source code to be inserted into packed file, along the lines of:
package.preload['myPackage'] = (function (...)
...package source code...
Once I’d figured that out, it was fairly straightforward to create my own low-budget version of Squish.
The next order of business was to convert the CMU Pronouncing Dictionary data file into Lua source code, so it could be embedded, along the lines of:
This is where I hit another snag – Lua only allows a limited number of literals per module – and being about 129,000 lines long, the dictionary exceeded the limit.
Fortunately, splitting the dictionary up into a series of modules fixed that problem.
I wrote a similar data-to-code routine to embed the .wav files into the source code, and synSinger was finally a single file.
There’s a version of Lua called srlua by one of the authors of Lua that consists of a Lua executable and a glue program. Only the source code is provided, but a bit of searching will turn up pre-built binaries. Creating a stand-alone executable in srlua is just a matter of typing:
glue srlua.exe myProgram.lua myProgram.exe
This binds myProgram.lua to the srlua interpreter, and creates a stand-alone executable myProgram.exe.
That’s exactly what I was looking for. In a perfect world would be where this story ends.
However, synSinger runs a slow under “plain” Lua – it takes 1/2 second to generate 1 second of output. I haven’t even tried optimizing it yet, but that’s painfully slow!
But there’s faster Lua interpreter called luajit – and it runs synSinger about 10 times faster than plain Lua.
luapower looked very promising, but the MingWin toolchain installer won’t work on my machine.
I was able to create a stand-alone .exe using luvit. It seems to have some small issues, but it doesn’t look like they’ll be insurmountable.
So it looks like I might be using luvit to build synSinger distributables.