Miscellaneous Forums > Scripting and Reverse Engineering

FF7 PSX sound effects format

(1/9) > >>

Phanoo:
UPDATE : the format is mostly understood at this point, check the work here : http://sdamo.io/ff7/index.php


Hello

This always puzzled me, the PC version using hundred of megabytes worth of wave files for sound effects, while the PSX version only used a tiny 50Kb file (EFFECT.ALL).
After some searches, there seems to be nobody interested into reverse engineering this, please correct me if I'm wrong ?

I just did an attempt this evening, to get a better understaning of this format. I'm interested in sound synthesis, in fact I'm the developer of a music software called FM Composer.

So, here's my findings.


The data from byte 4 to 2829 is an offset table for each individual sounds. Each entry is 2-byte long. Some entries are "0xFFFF", I don't know why, let's say we ignore them. After byte #2829 there is an empty block made of 0xFF bytes then the actual sound data. Following this table I can extract 936 sounds from the file.
You can extract them with this little code I made, you need to put EFFECT.ALL in the same dir and create an 'out' folder. Compiled version here : http://sdamo.io/ff7sfx.zip
Or all the sounds directly extracted here : http://sdamo.io/ff7/out.zip

--- Code: ---int main()
{
FILE *fp=fopen("EFFECT.ALL", "rb");
fseek(fp,8,SEEK_SET);
vector<int> offsets;

offsets.push_back(0);
unsigned short temp;

printf("Analyzing...\n");

int endcount=0;
do
{
fread((char*)&temp,2,1,fp);

if (temp == 0xFFFF) {
endcount++;
continue;
}
else
endcount=0;

offsets.push_back(temp);

}while (endcount<3);

printf("%d sounds found.\n",offsets.size());
printf("Extracting...\n");

fseek(fp,4096,SEEK_SET);

char *sound_data;

for (unsigned i = 0; i < offsets.size()-1; i++)
{

int size=offsets[i+1]-offsets[i];
if (size<=0)
continue;


sound_data = (char*)malloc(size);

fread(sound_data,size,1,fp);

FILE *fp2=fopen(string("out/"+to_string(i)).c_str(), "wb");
fwrite(sound_data, size, 1,fp2);
fclose(fp2);
free(sound_data);

}

fclose(fp);
printf("Done.\n");
}


--- End code ---

All sounds seems to finish with an '0xA0' byte.

Okay it's nice but the hardest part is to figure how the format works. I've messed with the first sound of the file (which is the menu beep sound), by modifying random bytes directly in the ISO image, then restarting the game with an emulator, and yeah I've got more or less interesting results !

Check this : http://sdamo.io/ff7/sounds.zip It's the altered beep sounds, depending on which bytes i modified (naming : chk-[bytes modified])

Some results are really interesting, with some delays, pitch or noises...

Anyone interested in helping me to find how those parameters works ? (basically, which bytes/values affects which sound parameter).

DLPB_:
I am very interested in this....  Been waiting for someone to tackle it, as I am sadly at a loss.  No idea where to start with it.  But kudos for you delving in.

It's amazing that after all these years the effects data file in psx version is so poorly understood.

Phanoo:
Yes, i'm really surprised nobody wrote some tools to deal with them.

Some more investigation with the menu beep sound, here's its contents :

--- Code: ---A1 01 A5 05 A4 05 0F B1 2C 81 A0 A1 00 A5 06 B1 2E A4 08 0C 08 A0
--- End code ---

As I said, A0 is the end marker for each sound, but this one has an A0 right in the middle. It means the final sound is made of two sounds layered (played at the same time) :
EDIT : I was wrong, there is no layering thing in the sounds itself. The menu beep is just two independent sounds, that are triggered at the same time.


--- Code: ---A1 01 A5 05 A4 05 0F B1 2C 81 A0
--- End code ---
... creates this sound : http://sdamo.io/ff7/beep_1st.wav


--- Code: ---A1 00 A5 06 B1 2E A4 08 0C 08 A0
--- End code ---
... creates this sound : http://sdamo.io/ff7/beep_2nd.wav

About this A0 byte, it seems to follow the opcodes discovered here for the AKAO frames : http://archive.is/0PE01

The page lists other opcodes, which may help :

--- Code: ---0xA0 (Finish Channel)
0xA1 (Load Instrument)
0xA3 (Volume Modifier)
0xA5 (Pitch Divider)
0xA8 (Channel Volume)
0xAA (Channel Pan)
0xC8 (Loop Point)
0xCA (Return to Loop Point)
0xE8 (Tempo)
0xEA (Reverb Depth)
0xC2 (Turn On Reverb)
--- End code ---

Maybe the SFX engine and music engine share the same code, the SFX simply having more advanced opcodes for doing complex time-based things and modulations.

DLPB_:
the problem ishow do you faithfully recreate the sounds from that alone. the psx sound chip needs emulating too?

Phanoo:
ATM i'm directly replacing the hex contents in my FF7 iso image, then run the game from an emulator (ePSXe) so I can hear how my changes affects the sound.

If we manage to guess the whole format, I dunno how hard it would be to create some rough emulation so a software could play the sounds. In fact i didnt thought about emulation, more like a little sound engine written from scratch (not sounding perfect but just to give an idea), with an editor allowing to have fun with parameters and a save feature. I know nothing about emulators, but i'm not bad at dealing with MIDI, sound synthesis and such things

Navigation

[0] Message Index

[#] Next page

Go to full version