This was figured out in reference to: https://github.com/nshusa/spitfire-155-client
In the client, there is a class with methods to load from both cache indices 4 and 14 (Sound Effects and Instrument Samples), called SoundBank. For Sound Effects, there's a class called SoundEffects.java, which loads data from Index 4 through a buffer, then you can call the method in the SoundEffect class to mix the processed data into an audio file (It has a byte array (byte[]) return value). It comes out as raw data, but can be opened with a program called Audacity by choosing File > Import > Raw Data... and exported to a file type of choice.
For the other part (Index 14), there's a processing method that reads an integer and then an integer array (int[]), but you can leave the int[] value as null when calling it. The basic int/number is the only thing that matters, to tell it which file ID to process. It does a little check and sends the process to another method where it eventually calls the Sfx1 class, loading the index file... and decoding it to an audio file. However, the final return value is not the byte array like in the SoundEffect class, and you'll have to find the byte array and write that to a new file. The byte array is found above the MusicNote class return value, it's not too far away. This comes out as raw data as well.
Lastly, for decoding (Index 15), you'll have to make a new class loading the SoundBank class with Index 4 and 14, then loading the InstrumentDef class with a file from Index 15 as a byte array. Then you call a boolean method containing the SoundBank, byte array with data, and an int array (which can also be null). You'll also have to add printed messages to the console where needed in the 3 classes called SoundEffect, Sfx1 and InstrumentDef.
Examples of what they should print are as follows - using Alex's FileStore:
SoundEffect -
Code:
public static SoundEffect staticMethod44(Index js5index_0, int i_1, int i_2) {
byte[] bytes_3 = js5index_0.getFile(i_1, i_2);
System.out.println("Sound 1 (SampleID_NoteID): " + i_1 + "_");
return bytes_3 == null ? null : new SoundEffect(new Buffer(bytes_3));
}
Sfx1 -
Code:
static Sfx1 staticMethod375(Index js5index_0, int i_1, int i_2) {
if (!staticMethod374(js5index_0)) {
js5index_0.fileExists(i_1, i_2);
return null;
} else {
byte[] bytes_3 = js5index_0.getFile(i_1, i_2);
System.out.print("Sound2 (SampleID_NoteID): " + i_1 + "_");
return bytes_3 == null ? null : new Sfx1(bytes_3);
}
}
InstrumentDef -
Code:
static boolean method490(SoundBank soundbank_1, byte[] bytes_2, int[] ints_3) throws IOException {
boolean bool_5 = true;
int i_6 = 0;
MusicNote musicnote_7 = null;
for (int i_8 = 0; i_8 < 128; i_8++)
if (bytes_2 == null || bytes_2[i_8] != 0) {
int i_9 = intArray50[i_8];
if (i_9 != 0) {
if (i_9 != i_6) {
i_6 = i_9--;
if ((i_9 & 0x1) == 0) {
musicnote_7 = soundbank_1.method158(i_9 >> 2, ints_3);
System.out.print(i_8 + " ");
}
else {
musicnote_7 = soundbank_1.method159(i_9 >> 2, ints_3);
System.out.print(i_8 + " ");
}
I've also posted a modified version of the Spitfire client here using Alex's FileStore, it contains 3 additional classes to help you dump sounds the same way I did (Sound1Dumper, Sound2Dumper, Sound3Dumper): https://github.com/lequietriot/Modif...ire-155-Client
Edit: Also when importing the raw data to Audacity, make sure the Sample Rate is 22050 Hz, otherwise it won't sound correct.