Originally Posted by
Sgsrocks
Sounds weird because it's not in the right encoding. Mine is.
Originally Posted by
Jason
Impressive, good job. It would be even more beneficial to the community if you released a small tutorial on how you did it. I'm sure a lot of scrubs out there would be pleased. Give a man a fi...you know the rest.
Basically what I did was...
Used RuneLite and added a print statement in this method to print var1 and var2. Logged into RuneScape with RuneLite using my account.
https://github.com/runelite/runelite...fect.java#L128
var1 is the sound id, var2 seems to only print 0 so if you look further you'll see its a child file which none of these sounds have a child so its 0 https://github.com/runelite/runelite...Base.java#L248
This is how you'll easily identify the sounds btw
Code:
sound: 3141 0
sound: 3141 0
sound: 2274 0
sound: 3141 0
sound: 2266 0
sound: 2266 0
sound: 2266 0
sound: 2266 0
sound: 2266 0
sound: 2073 0
After the sound file is retrieved from the file system jagex calls method2115
https://github.com/runelite/runelite...ss110.java#L65
If you go to method2115 you'll see they mix the audio
https://github.com/runelite/runelite...ffect.java#L47
22050 is the sample rate in Hz. I know this because the sample rate is already refactored in the RawAudioNode class. https://github.com/runelite/runelite...oNode.java#L25
After this I exported one of the raw audio files and imported it into audacity as raw audio. audacity automatically detects the encoding as
signed 8-bit pcm
little-endian
I changed the channel to mono channel because 2 channels didn't sound right.
If you change sample rate to 22050 and play the raw audio (in audacity) it sounds identical to the original sound you can play on any runescape client.
after knowing the file format then I simply convert to wav format (I'm using OpenRS)
Code:
public static void main(String[] args) {
try (Cache cache = new Cache(FileStore.open(Constants.CACHE_PATH))) {
File dir = Paths.get("sounds").toFile();
if (!dir.exists()) {
dir.mkdirs();
}
export(cache, dir, true);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void export(Cache cache, File dir, boolean wav) {
ReferenceTable table = cache.getReferenceTable(CacheIndex.SOUND_EFFECT);
for (int i = 0; i < table.capacity(); i++) {
try {
SoundEffect effect = SoundEffect.decode(cache, i);
if (effect == null) {
continue;
}
// creates the raw audio binary in signed 8-bit PCM
byte[] data = effect.mix();
// converting to wave format
if (wav) {
// used audacity to determine the binary format encoding
// 8 comes from the signed 8-bit pcm
// 1 for 1 channel (mono)
// true means audio format is signed
// false means the audio format is not big endian
AudioFormat audioFormat = new AudioFormat(22_050, 8, 1, true, false);
AudioInputStream ais = new AudioInputStream(new ByteArrayInputStream(data), audioFormat, data.length);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, bos);
// binary of audio in wav format
data = bos.toByteArray();
}
try (FileOutputStream fos = new FileOutputStream(new File(dir, i + (wav ? ".wav" : ".dat")))) {
fos.write(data);
}
} catch (Exception ex) {
System.out.println("error decoding sound: " + i);
continue;
}
System.out.println("decoding sound: " + i);
}
System.out.println("decoded: " + table.capacity() + " sounds");
}
and wallah it works!