Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Request] Relic's AIFC (.aifr) #907

Open
gero-pardo opened this issue Jul 31, 2021 · 15 comments
Open

[Request] Relic's AIFC (.aifr) #907

gero-pardo opened this issue Jul 31, 2021 · 15 comments

Comments

@gero-pardo
Copy link

Relic ran a series of AIFF-Compressed variants during it's earliest days.
It consisted of a custom lossy compression algorithm for AIFF coded by Relic, maintained through most of the 2000s across various games.
The format was developed and renamed multiple times across the company's life, originally AIFR (AIF-Relic), then FDA (Fast Digital Audio), all sharing the same AIFC encoding as late as 2006's Company of Heroes.

From my personal rips, I know of some formats:

.aifr - Homeworld and Homeworld: Cataclysm
First gen .fda (Homeworld 2) & Second gen .fda (Dawn of War, Company of Heroes & presumably Impossible Creatures) -- Already implemented for this project.

"Officially", the aifc encoder, decoder and an aif* Winamp plugin, all made by a Relic dev, surfaced in the early 2000s.

I've tried to make the plugin myself, but I quickly realized my meagre Js programming expertise will not be enough to figure out how to decompile and analyse the decoder and compile a foobar2000 plugin in a mere winter vacation's time. I believe your reconstructed decoder should work, but I'm adding all relevant links in the strange case it doesn't:

Sample files :

Off topic question: May I ask how you decompiled dec.exe?

@bnnm
Copy link
Collaborator

bnnm commented Jul 31, 2021

Those files aren't proper AIFC so they fail. Rename to .aif (or .aifc, .fda, etc), and add 4 bytes to the FORM and SSND sizes (32b value at 0x04 and 0x4c), then they'll play.

Homeworld / Cataclysm don't use .aifr but raw-ish data. Presumably the extraction tool took this data, pasted an AIFC header (with wrong sizes) and a new extension. Generally we don't add support for made-up extensions or wrong files if not found as-is in games.

Instead I made a quick python script to fix your files: aifr-fixer.zip (makes separate .fda)

dec.exe was decompiled using IDA and standard tricks (unpacking UPX first). If you are interested here is the dec.c file I made before adding to vgmstream: https://gist.github.com/bnnm/bf6d4d3cb4335ff1d09ff46481eea2f4

@gero-pardo
Copy link
Author

Homeworld / Cataclysm don't use .aifr but raw-ish data. Presumably the extraction tool took this data, pasted an AIFC header (with wrong sizes) and a new extension. Generally we don't add support for made-up extensions or wrong files if not found as-is in games.

Ah, my apologies! I extracted using tools made by the fanbase (a tool named Penesound), didn't occur to me they were jury-rigging files.
Raw-ish data? You mean it's like an uncut audio rip? Or if I were to extract the original container files (.bnk, .wxd and vce) I could obtain the original file format?

@bnnm
Copy link
Collaborator

bnnm commented Aug 1, 2021

Original data in .wxd/vce has no AIFC header, it's just plain Relic audio data (what comes after "SSND" in .aif/fda) pasted together one after another. Tools separate that and put a new AIFC in front, but data is unchanged.

An AIFC header contains audio info (mono/stereo, sample rate, etc), but game just hardcodes this (wxd=stereo, vce=mono, etc) so has no need for a header. Later games do use a standard AIFC or FDA though.

The AIFC is needed for external players since they can't figure out format otherwise, there is no difference in data or audio. Other players aren't that picky and will accept not-quite proper, made-up AIFC, but vgmstream wants a bit more exact files to avoid bad rips, so the python script only fixes the wonky AIFC header.

@gero-pardo
Copy link
Author

gero-pardo commented Aug 1, 2021

Original data in .wxd/vce has no AIFC header, it's just plain Relic audio data (what comes after "SSND" in .aif/fda) pasted together one after another. Tools separate that and put a new AIFC in front, but data is unchanged.

Would it mean the tracks were indicated by a segment in the file akin to a .cue file? The tool I extracted them with knew the start and end of each track after all. I suppose that also means the "original audio files" would be those containers themselves.

Is it in the scope of the project to make those files readable?

The AIFC is needed for external players since they can't figure out format otherwise, there is no difference in data or audio.

Aaah. I comprehend now. There's no way per-se to play the original files without retouching them in some form. A shame, really.

@bnnm
Copy link
Collaborator

bnnm commented Aug 3, 2021

Oh right, there is a CUE-like .wxh header file, but inside the main .big (can be extracted with tools like BigViewer.exe). It has the offsets/info the engine uses to play data in the .wxd. I could add this format if you have both .wxd+.wxh in the same dir, that would be the closest to keeping it untouched.
For voices I think they use various .lut instead that are a bit different.

@gero-pardo
Copy link
Author

I could add this format if you have both .wxd+.wxh in the same dir, that would be the closest to keeping it untouched.

Right, here's both games' WXD, VCE and the soundfx folder with the BNK sound effects containers and their associated LUT and WXH files.
It seems multiple LUTs call different sections of the VCE and BNK files. Does this complicate matters?

HM: https://mega.nz/file/SrBXRAYa#SqDF3DlbX_rZog08IiPGOzRrmSOwBrFEb5oUPWbMvMA
HM Cataclysm: https://mega.nz/file/3rAVCaiS#iTFIjHRvfNqyb_n5CLjH8LJ3V2yz61LqZ7Fsy6UQPdo

@bnnm
Copy link
Collaborator

bnnm commented Aug 5, 2021

Can you post some of the .aifr made by your tool from bnk/vce? I'm having trouble to decode them so an alt file for comparison would probably help.

@gero-pardo
Copy link
Author

I can give you the tool itself: https://subversion.assembla.com/svn/homeworld-and-homeworld-2-tool-box/HW1%20-%20Penesound/
Here's a collection of samples: https://mega.nz/file/ruwUCJAD#pTz1dI2S4CNMw4O23LXhBx3CCrxbvYgU_J8xFbvqwvg
wrote a small readme with details and some notes. Comments in this vid claim hardcoded filtering for each clip, but I can't confirm it's verasity: https://www.youtube.com/watch?v=nfClyVeC-S

@bnnm
Copy link
Collaborator

bnnm commented Aug 8, 2021

Added .whx+wxh and .bnk, I've yet to think how to handle .vce

@gero-pardo
Copy link
Author

What's so particular about them?

@bnnm
Copy link
Collaborator

bnnm commented Aug 10, 2021

The *sentence.lut seem to have header/offsets, but there are a lot of dummy entries and don't follow .vce order, plus may be linked to *phrase.lut somehow. Need to think how to make them usable or if there are better ways to get offsets.

@gero-pardo
Copy link
Author

I downloaded the current build in the f2k component and tried the files out. I saw an interesting behaviour:

The wxh-wxd work perfectly, except that tracks that may loop don't seem to update their track length properly.
All tracks that can loop ahve their length set to the strandard vgstream loop config (2 loops 10 sec delay). Setting the config to not loop or giving it more than preset values at leaves the wxd with broken track lengths that when clicking on a section past the track real length may skip to the following tracks or be stuck at the end still playing.

Is there a way to update the tracklengths to reflect non-preset settings?

@bnnm
Copy link
Collaborator

bnnm commented Aug 12, 2021

Try selecting playlist > shift + right click > Tagging > Reload info from file(s), also see here

@gero-pardo
Copy link
Author

Understood. Thanks. Should I close the issue?

@bnnm
Copy link
Collaborator

bnnm commented Aug 14, 2021

If you still want .vce support you can leave it open, it may take a while tho.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants