Voice Patch Programming Notes

A forum for a tentative translation project of Legend of Heroes Ao no Kiseki.
Post Reply
flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Voice Patch Programming Notes

Post by flamethrower » Tue Aug 16, 2016 11:06 am

15Aug16
Decided to start taking a look at this.

0x088FD384 - loading "script code numbers"
0x088FD3F4 - checking "script code letters" hex(ord('V')) = 0x56 so our branch is at 0x088FD44C
0x088FD488 - branch target - jumps to 0x088FCB14 which is "back to the beginning"
so it reads our codes on a 2nd pass

2nd pass code:
0x088FD190 - start
0x088FD1CC - branch condition - when a non-digit character is read.
0x088FD0FC - checking for script code characters - our branch is at 0x088FD150
0x088FD1E4 - branch target
OK this code doesn't do anything either, it just copies the opcode to somewhere else in RAM, destination is 0x0971F023 or thereabouts

3rd pass:
0x088FC324 - start
0x088FC380 - branch condition
0x088FC3E4 - V character branch
0x088FC724 - branch target
Eventually hits 088FC760 jal z_un_08832a00 (a1 = voice clip ID number)

Much later...
0x088311a0 - slti v0,a1,0x1068 0x1068 = 4200 The number of voice clips in Ao? 4135. This is explicitly checking for a valid number.

0x08A5B098 jump to 0x08A5C1C0
then jump to 0x08A5C18C
then jump to 0x08A5BA5C
0x08A5BF00 loads again the 0xCEA value (= 3306, the first voice clip ID)

0x0BFFF3C0 "ed7v3306" eventually formed, based on ed7v%04d string in EBOOT
08A56EE8 - bookmark

Some experiment results:
Changing to a voice clip that's not "loaded" (not sure how loading works yet) results in the regular voice clip playing. How does it know?
Changing to a voice clip that is "loaded" results in that voice clip playing.
---------------------------
16Aug16
It seems like voice files are being loaded from \cclm\map4\{1}u{2}e
where 1 is the script file name, e.g., m4000 and
where 2 is the script ID number in hex plus 1, e.g., 0b for the 10th script (0xb = 11)
will need a better FALCOM compressor than I have now, I think. My current one doesn't work well because it doesn't implement all features. Maybe it doesn't matter because VAG are already compressed. These files use the FALCOM3 compression scheme. VAG are already compressed, they won't compress much.
The real question: how does it know. If I delete the entry ed7v3306.vag including the filename, it still "knows" the backup should be loaded from \se\ed7v3306.vag and I don't know how it knows that.
------------------------------
Well that was easier than I thought. There are two copies of the script in memory and you need to change the second one (when using memory viewer) for your changes to show up.

I have 20,000 voice files. Well, the script supports only up to #9999 because the file format is ed7v#### (4 digits). So I will need to change it to something like e7v##### (5 digits). I'll just try changing it to "not existing file" to see what happens.



The result for "not existing file" is no clip plays. It does not crash the game.

For the next test, we'll add a new file to the game, and then try to play it.
--------------------------------------------------------
17Aug16
For right now, the sub-task is working on "data.lst rebuilder". It's different than data.lst updater. Basically its going to build data.lst and the file list from scratch based on your folder structure.
----------------------------------------------------------------------
20Aug16
Finished the rebuilder.

It's hard just thinking about this:
1) Rename new files with 5-digit numbers. Keep track of old ID number vs new.
2) Look through new script files. Get the text that goes with each voice clip ID number.
3) Go through old (original) script files. Split the text into dialog boxes.
4) Assign voice file IDs for each dialog box that's an exact match for the text and set those aside. For each match, get the function number of the match and add it to a list of "scenario functions," whose purpose is to convey the story.
5) Delete text data associated with non-scenario functions. It does not need to be matched.
6) For each remaining original dialog box that was not matched, choose the remaining best voice clip to go with it using fuzzy matching. Log these to a file for manual review.
7) Insert

On "success" (4 and 6), we mark down "new voice clip ID" and "offset"

For insert, we are:
1) removing original voice clip if any
2) inserting new voice clip

Insert goes by dialog box (not by opcode) but that shouldn't be a problem.
-----------------------------------
t_se._dt has to be modified.
It's a bunch of halfword entries at the top, exactly 9. Those point to 8-byte entries of some kind- one for each voice file. They point to entries for clip ID 0, 500, 1000, 1500, 2000, 2500, 3000, 3500 and 4000 (4135 clips in the original game). For each entry, obviously one of the parameters is clip ID. I don't know what the other parameters do. I'm just going to copy the story voice clip parameters and hope for the best. The game will not load clips that don't have a parameter in this table.

The next task will be to break out the script tool and see if I can't get the info I need out of it.
1) Analyze script for "chunk start" and text. Chunk start = start of the opcode or start of the dialog box.
2) Match up Evo clip IDs to PSP game text and assign Evo clip IDs to chunks that have a voice file
2A) Pass1: Exact match
2B) Pass2: Fuzzy match
3) For each chunk, remove existing voice clip ID if any, add new clip and update pointers.
-------------------------
packed file extension list:
.mc1, .mc2, .mc3, .mcc, .mce, .mcp, .mcc, .dat, .bcc
-------------------------
Modification of t_se loader routine:
088FD0FC - giant switch statement looking at the letter at the end of the # codes. V is 0x56 in hex.
V jumps to 088FCC88
But it doesn't get read on this pass, it gets read on a 2nd pass

088FC390 giant switch statement
088FC3E8 on "V" goto
088FC724
08832A00 - subroutine, a1 is voiceID parameter
088311A0 - eventually get to this sub, a1 is voiceID parameter
088311B4 - load t_se._dt address
The header entries go every 500 number counts, so 0x0 points to sample 0, 0x2 points to sample 500 and so on
088311DC - sll a1,v0,0x1 Expand 500-key to 2-bytes so it can be used as a header offset
change to sll a1,v0,0x2 Expand 500-key to 4-bytes so it can be used as a header offset (for modified t_se._dt file)
088311F0 - lhu a0,0x0(a1) Load header halfword
change to lw a0, 0x0(a1) Load header word

josejl
Programmer
Posts: 193
Joined: Mon Apr 13, 2015 6:49 pm
Location: Spain
Contact:

Re: Voice Patch Programming Notes

Post by josejl » Tue Aug 16, 2016 9:53 pm

This is interesting, the only other string I can find is "ed7v". I can see some .vag string as well in the function that it's used.

IDA says it's loc_DA0C8. There was some way to change the memory mapping so it could use the same addresses as PSP, but I can't get it right.

What I don't really understand, where do you delete the entry from? From data.lst?

Also, about the FALCOM3 compressor. It seems I've almost figured out the VPA8 entries, but now I need to recompress them.

Supposedly this compresses back to FALCOM2 if I understood correctly http://www.mediafire.com/download/iboe6 ... mpress.cpp, but the file size is quite big (49 kb original compression/111 kb uncompressed,99 kb recompressed), so I'm not sure if this is what I should try to use.

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Tue Aug 16, 2016 10:34 pm

You can use my FALCOM compression library. Mine is just a copy of that, the results should be the same. Mine has a wrapper for FALCOM3 compression.
FALCOM compression library: http://pastebin.com/hE5f3i6L

It is bad because the compression is not fully implemented. The look back window is just 0xFF long while the real algo can use a window of up to 0x3FFF, I think. The flag bits for "long look back" are weird. Can you try to improve either one so it implements the full algo?

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Tue Aug 23, 2016 11:53 am

I need a VAG encoder that will do VAG version 6, the version used in Ao no Kiseki.
MFAudio will not work.

josejl
Programmer
Posts: 193
Joined: Mon Apr 13, 2015 6:49 pm
Location: Spain
Contact:

Re: Voice Patch Programming Notes

Post by josejl » Tue Aug 23, 2016 1:51 pm

Hmmm, that looks like a sample rate issue to me, as far as I can tell the voice clip is playing correctly, except that it's way slower.

Original Ao VAG files use 22050 Hz as sample rate, what are you using?

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Tue Aug 23, 2016 5:08 pm

I used the default. I think it's 44.1 kHz but I'm not sure. I'll try again with 22.1 kHz.
What I don't really understand, where do you delete the entry from? From data.lst?
It's a PSP thing. You don't need to worry about it. There are these packed files. They are in /cclm/map4. Even if you delete most of the other files on the ROM, it won't matter. Those packed files have all the files the game needs, compressed with FALCOM3. I am guessing when a script file is loaded, the packed files are loaded, and the data within is decompressed as the game needs it. If you look in the packed files, you will see in the header the FAT right there. If you delete the FAT entry for a file within a packed file, it will "miss" and try to load the file from the backup location. It will give up on loading the file if the backup file is also missing. The voice loading routine is going to \se\ed7v####.vag to get its backups. #### is given by a parameter. data.lst I think is used to help the game know the location of each file, whether the original packed file or the backup.

For PC I don't think packed files are used. For even older hard disks, performance is extreme compared to UMD. So doing 50-100 random file accesses won't take that long. Additionally, PC has more RAM than PSP and won't need to load as often (even though PC data sizes are bigger by a lot). On UMD, random access takes a long time. To shorten loading time, these packed files are used. Once loaded, the data is decompressed as needed. Only two or three random accesses are needed when scena files are changed.

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Thu Aug 25, 2016 1:15 am

I tested in game, working and hearable. Still a failed test though, see below.

I tried testing in game and the sound that plays is too soft. i.e., volume is too low.
I tried comparing the .wav exported by at9tool and the .wav exported by MFAudio when converting the Evolution and the original files respectively.
I used Audacity to do this. You can see the amplitude of ed7v3306 is a lot higher than v0000000249
4.png
4.png (35.83 KiB) Viewed 3854 times
Nevermind. I just randomly picked a softer file. The others are louder.
Test successful.


flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Mon Aug 29, 2016 2:15 pm

Ran into a problem where I cannot add the files into the se folder.
Will try again using just random files to see what exactly the problem is.
I added 22,000 files (all of them) -> crash
Then I added 2000 extra files to the se folder and it worked; adding 4000 extra also crashed UMDgen.
Could it be a problem with a specific file?
The limit (UMDgen) is 3000 files exactly. I found another program wqsgumdr31. I will give that a try.
There is a newer version of this tool. The author's website is here: http://wqsg.ys168.com/ No, I don't know Chinese.
My other idea is to just update the packed files. Since the packed files are just one file (each), the UMDgen limit won't matter.
We know enough now to modify packed files as needed but it would be better if we had a better FALCOM2 compressor. The current one I have doesn't implement all features of the FALCOM2 spec.
---------------------
wqsgumdr31 did not work. It complains there's not enough space in the path table to accomodate the files.

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Sat Oct 01, 2016 8:52 pm

Alright. We should be good now. You can give this a try if you want.
Guess what? Is it now EASY and FAST to modify the Falcom ISOs that use data.lst.

Ys Seven does not work with this, and Ao no Kiseki does, and I have not tested the others. It is likely that they also work.

Do a test run.
The original image is something like 1.41 GB. If you extract and then rebuild (no changes), you get an image that's 1.34 GB (approx. 70 MB smaller).
I know Ao no Kiseki doesn't use all its files, but I'm not sure how to tell which to delete to make the image smaller apart from guess and check.

There's a readme included with instructions on how to run. You need Python 3 to run it.
ISO_builder.7z
(527.05 KiB) Downloaded 43 times
Nope, fail. In AnK, "illegal" filenames are used. I am thinking just os.walk and trash anything illegal prior to further processing. Those files aren't needed by the game anyway.

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Sun Oct 02, 2016 2:35 pm

Here's the v2 with the following changes:

v2 02Oct16
-Added python unpack of ISO.
-As a pre-processing step, will discard files with non-ASCII characters in the
filename
ISO_builder_v2.7z
(526.68 KiB) Downloaded 35 times
Should work now. It "works" by discarding the non-ASCII filenames that were causing the problem.

v2.1 02Oct16
-Part 1 builds data.lst in the current folder (of filelist_builder_part1.py)
instead of hard coded.
ISO_builder_v2_1.7z
(527.29 KiB) Downloaded 41 times
Thanks to josejl for helping test this.

ahokcasi
Posts: 4
Joined: Sat Nov 12, 2016 4:34 am

Re: Voice Patch Programming Notes

Post by ahokcasi » Mon Nov 14, 2016 10:35 pm

Hello! I am a recently-graduated game developer and I would like to lend my help to this project if you'll have me! I could work as a programmer and help with the translation as well

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Mon Nov 14, 2016 10:49 pm

Why not try downloading that tool there and see if you can get it to work.

1. Unpack and then rebuild. You should end up with a ROM that's much smaller.
2. Change something and then rebuild to prove to yourself that it works.
As for what to change, I recommend something on the title screen.
This is the "normal" balance message: 標準的なバランスです。適度な刺激を楽しみたい方に。中級者向け。
You can display that text by selecting "new game" from the title screen.

Now you need to change it:
Decrypt EBOOT, you can do so using PPSSPP, Google it.
Change that text to be whatever you want, then rebuild, and we'll go from there I guess.

josejl
Programmer
Posts: 193
Joined: Mon Apr 13, 2015 6:49 pm
Location: Spain
Contact:

Re: Voice Patch Programming Notes

Post by josejl » Tue Nov 15, 2016 9:28 am

ahokcasi wrote:Hello! I am a recently-graduated game developer and I would like to lend my help to this project if you'll have me! I could work as a programmer and help with the translation as well
Oh, game developer studies, huh? I'm curious about what you studied.

I did a master's degree on game development, and really, I've learnt a lot more while working on these games, so if you want to learn new stuff, I think you're making a good choice.

ahokcasi
Posts: 4
Joined: Sat Nov 12, 2016 4:34 am

Re: Voice Patch Programming Notes

Post by ahokcasi » Tue Nov 15, 2016 4:10 pm

josejl wrote:
ahokcasi wrote:Hello! I am a recently-graduated game developer and I would like to lend my help to this project if you'll have me! I could work as a programmer and help with the translation as well
Oh, game developer studies, huh? I'm curious about what you studied.

I did a master's degree on game development, and really, I've learnt a lot more while working on these games, so if you want to learn new stuff, I think you're making a good choice.

I studied mostly c++, in visual studio, direct x, we also worked with unity and unreal, AI, RTA, occlusion culling, collision, physics and alright I will download the tools and try and change something

[EDIT]: Which python editor is the standard for this team?

josejl
Programmer
Posts: 193
Joined: Mon Apr 13, 2015 6:49 pm
Location: Spain
Contact:

Re: Voice Patch Programming Notes

Post by josejl » Tue Nov 15, 2016 6:17 pm

Oh, that looks nice, all that might come in handy. I just hope you aren't scared of assembler and low level stuff.

As for Python editor, do you mean the Python version we are using , or an IDE?
I think we haven't decided on an "official" version, there are scripts in both Python 2 and 3.

If you meant an IDE, I like Pycharm.

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Tue Nov 15, 2016 8:04 pm

I'm not a real programmer, never will be.
I use IDLE from the Python 3.5 standard distribution. I didn't know there were others.
Anything that's Python 3.5 compatible should work, right?

For Ao we should use the latest Python version (I think 3.5); there's this (Falcom ISO Builder) and the script tools thus far which are both Python 3.5.

ahokcasi
Posts: 4
Joined: Sat Nov 12, 2016 4:34 am

Re: Voice Patch Programming Notes

Post by ahokcasi » Tue Nov 15, 2016 8:23 pm

Alright I'll use that one as well. As of right now I should just like mess with and change some of the text just to get used to it, I suppose.

flamethrower
Programmer
Posts: 831
Joined: Mon Mar 09, 2015 3:03 pm

Re: Voice Patch Programming Notes

Post by flamethrower » Wed Jun 28, 2017 3:21 am

Reposting because our database got destroyed, lol.
Attachments
ISO_builder_v2_1.7z
(527.29 KiB) Downloaded 116 times

Hijack44
Posts: 1
Joined: Thu Jul 13, 2017 7:17 am

Re: Voice Patch Programming Notes

Post by Hijack44 » Wed Jul 26, 2017 8:57 am

Is there no way to save your project ?
As I can see it still miss some part, i hope this project can be the same as the zero no kiseki.
So I pray for your project to complete, good luck !

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest