cache: add track1 definition and loader
I am able to play the resulting midi file with javax.sound.midi.Sequencer
This commit is contained in:
30
cache/src/main/java/net/runelite/cache/definitions/Track1Definition.java
vendored
Normal file
30
cache/src/main/java/net/runelite/cache/definitions/Track1Definition.java
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.cache.definitions;
|
||||
|
||||
public class Track1Definition
|
||||
{
|
||||
public byte[] midi; // midi file contents
|
||||
}
|
||||
461
cache/src/main/java/net/runelite/cache/definitions/loaders/Track1Loader.java
vendored
Normal file
461
cache/src/main/java/net/runelite/cache/definitions/loaders/Track1Loader.java
vendored
Normal file
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.cache.definitions.loaders;
|
||||
|
||||
import net.runelite.cache.definitions.Track1Definition;
|
||||
import net.runelite.cache.io.InputStream;
|
||||
import net.runelite.cache.io.OutputStream;
|
||||
|
||||
public class Track1Loader
|
||||
{
|
||||
public Track1Definition load(byte[] b)
|
||||
{
|
||||
Track1Definition def = new Track1Definition();
|
||||
load(def, new InputStream(b));
|
||||
return def;
|
||||
}
|
||||
|
||||
private void load(Track1Definition def, InputStream var1)
|
||||
{
|
||||
// Some of the names are from https://www.rune-server.ee/runescape-development/rs-503-client-server/snippets/311669-rs-music-file-structure-conversion.html
|
||||
var1.setOffset(var1.getLength() - 3);
|
||||
int tracks = var1.readUnsignedByte();
|
||||
int division = var1.readUnsignedShort();
|
||||
int offset = 14 + tracks * 10;
|
||||
var1.setOffset(0);
|
||||
int tempoOpcodes = 0;
|
||||
int ctrlChangeOpcodes = 0;
|
||||
int noteOnOpcodes = 0;
|
||||
int noteOffOpcodes = 0;
|
||||
int wheelChangeOpcodes = 0;
|
||||
int chnnlAfterTchOpcodes = 0;
|
||||
int keyAfterTchOpcodes = 0;
|
||||
int progmChangeOpcodes = 0;
|
||||
|
||||
int var13;
|
||||
int opcode;
|
||||
int var15;
|
||||
for (var13 = 0; var13 < tracks; ++var13)
|
||||
{
|
||||
opcode = -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var15 = var1.readUnsignedByte();
|
||||
if (var15 != opcode)
|
||||
{
|
||||
++offset;
|
||||
}
|
||||
|
||||
opcode = var15 & 15;
|
||||
if (var15 == 7)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (var15 == 23)
|
||||
{
|
||||
++tempoOpcodes;
|
||||
}
|
||||
else if (opcode == 0)
|
||||
{
|
||||
++noteOnOpcodes;
|
||||
}
|
||||
else if (opcode == 1)
|
||||
{
|
||||
++noteOffOpcodes;
|
||||
}
|
||||
else if (opcode == 2)
|
||||
{
|
||||
++ctrlChangeOpcodes;
|
||||
}
|
||||
else if (opcode == 3)
|
||||
{
|
||||
++wheelChangeOpcodes;
|
||||
}
|
||||
else if (opcode == 4)
|
||||
{
|
||||
++chnnlAfterTchOpcodes;
|
||||
}
|
||||
else if (opcode == 5)
|
||||
{
|
||||
++keyAfterTchOpcodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcode != 6)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
++progmChangeOpcodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offset += 5 * tempoOpcodes;
|
||||
offset += 2 * (noteOnOpcodes + noteOffOpcodes + ctrlChangeOpcodes + wheelChangeOpcodes + keyAfterTchOpcodes);
|
||||
offset += chnnlAfterTchOpcodes + progmChangeOpcodes;
|
||||
var13 = var1.getOffset();
|
||||
opcode = tracks + tempoOpcodes + ctrlChangeOpcodes + noteOnOpcodes + noteOffOpcodes + wheelChangeOpcodes + chnnlAfterTchOpcodes + keyAfterTchOpcodes + progmChangeOpcodes;
|
||||
|
||||
for (var15 = 0; var15 < opcode; ++var15)
|
||||
{
|
||||
var1.readVarInt();
|
||||
}
|
||||
|
||||
offset += var1.getOffset() - var13;
|
||||
var15 = var1.getOffset();
|
||||
int var16 = 0;
|
||||
int var17 = 0;
|
||||
int var18 = 0;
|
||||
int var19 = 0;
|
||||
int var20 = 0;
|
||||
int var21 = 0;
|
||||
int var22 = 0;
|
||||
int var23 = 0;
|
||||
int var24 = 0;
|
||||
int var25 = 0;
|
||||
int var26 = 0;
|
||||
int var27 = 0;
|
||||
int var28 = 0;
|
||||
|
||||
int var29;
|
||||
for (var29 = 0; var29 < ctrlChangeOpcodes; ++var29)
|
||||
{
|
||||
var28 = var28 + var1.readUnsignedByte() & 127;
|
||||
if (var28 != 0 && var28 != 32)
|
||||
{
|
||||
if (var28 == 1)
|
||||
{
|
||||
++var16;
|
||||
}
|
||||
else if (var28 == 33)
|
||||
{
|
||||
++var17;
|
||||
}
|
||||
else if (var28 == 7)
|
||||
{
|
||||
++var18;
|
||||
}
|
||||
else if (var28 == 39)
|
||||
{
|
||||
++var19;
|
||||
}
|
||||
else if (var28 == 10)
|
||||
{
|
||||
++var20;
|
||||
}
|
||||
else if (var28 == 42)
|
||||
{
|
||||
++var21;
|
||||
}
|
||||
else if (var28 == 99)
|
||||
{
|
||||
++var22;
|
||||
}
|
||||
else if (var28 == 98)
|
||||
{
|
||||
++var23;
|
||||
}
|
||||
else if (var28 == 101)
|
||||
{
|
||||
++var24;
|
||||
}
|
||||
else if (var28 == 100)
|
||||
{
|
||||
++var25;
|
||||
}
|
||||
else if (var28 != 64 && var28 != 65 && var28 != 120 && var28 != 121 && var28 != 123)
|
||||
{
|
||||
++var27;
|
||||
}
|
||||
else
|
||||
{
|
||||
++var26;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++progmChangeOpcodes;
|
||||
}
|
||||
}
|
||||
|
||||
var29 = 0;
|
||||
int var30 = var1.getOffset();
|
||||
var1.skip(var26);
|
||||
int var31 = var1.getOffset();
|
||||
var1.skip(keyAfterTchOpcodes);
|
||||
int var32 = var1.getOffset();
|
||||
var1.skip(chnnlAfterTchOpcodes);
|
||||
int var33 = var1.getOffset();
|
||||
var1.skip(wheelChangeOpcodes);
|
||||
int var34 = var1.getOffset();
|
||||
var1.skip(var16);
|
||||
int var35 = var1.getOffset();
|
||||
var1.skip(var18);
|
||||
int var36 = var1.getOffset();
|
||||
var1.skip(var20);
|
||||
int var37 = var1.getOffset();
|
||||
var1.skip(noteOnOpcodes + noteOffOpcodes + keyAfterTchOpcodes);
|
||||
int var38 = var1.getOffset();
|
||||
var1.skip(noteOnOpcodes);
|
||||
int var39 = var1.getOffset();
|
||||
var1.skip(var27);
|
||||
int var40 = var1.getOffset();
|
||||
var1.skip(noteOffOpcodes);
|
||||
int var41 = var1.getOffset();
|
||||
var1.skip(var17);
|
||||
int var42 = var1.getOffset();
|
||||
var1.skip(var19);
|
||||
int var43 = var1.getOffset();
|
||||
var1.skip(var21);
|
||||
int var44 = var1.getOffset();
|
||||
var1.skip(progmChangeOpcodes);
|
||||
int var45 = var1.getOffset();
|
||||
var1.skip(wheelChangeOpcodes);
|
||||
int var46 = var1.getOffset();
|
||||
var1.skip(var22);
|
||||
int var47 = var1.getOffset();
|
||||
var1.skip(var23);
|
||||
int var48 = var1.getOffset();
|
||||
var1.skip(var24);
|
||||
int var49 = var1.getOffset();
|
||||
var1.skip(var25);
|
||||
int var50 = var1.getOffset();
|
||||
var1.skip(tempoOpcodes * 3);
|
||||
def.midi = new byte[offset];
|
||||
OutputStream var51 = new OutputStream(def.midi);
|
||||
var51.writeInt(1297377380); // MThd header
|
||||
var51.writeInt(6); // length of header
|
||||
var51.writeShort(tracks > 1 ? 1 : 0); // format
|
||||
var51.writeShort(tracks); // tracks
|
||||
var51.writeShort(division); // division
|
||||
var1.setOffset(var13);
|
||||
int var52 = 0;
|
||||
int var53 = 0;
|
||||
int var54 = 0;
|
||||
int var55 = 0;
|
||||
int var56 = 0;
|
||||
int var57 = 0;
|
||||
int var58 = 0;
|
||||
int[] var59 = new int[128];
|
||||
var28 = 0;
|
||||
|
||||
label361:
|
||||
for (int var60 = 0; var60 < tracks; ++var60)
|
||||
{
|
||||
var51.writeInt(1297379947); // MTrk
|
||||
var51.skip(4); // length gets written here later
|
||||
int var61 = var51.getOffset();
|
||||
int var62 = -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int var63 = var1.readVarInt();
|
||||
var51.writeVarInt(var63); // delta time
|
||||
int var64 = var1.getArray()[var29++] & 255;
|
||||
boolean var65 = var64 != var62;
|
||||
var62 = var64 & 15;
|
||||
if (var64 == 7)
|
||||
{
|
||||
//if (var65) -- client has this if, but it causes broken midi to be produced
|
||||
{
|
||||
var51.writeByte(255);
|
||||
}
|
||||
|
||||
var51.writeByte(47); // type - end of track
|
||||
var51.writeByte(0); // length
|
||||
var51.writeLengthFromMark(var51.getOffset() - var61);
|
||||
continue label361;
|
||||
}
|
||||
|
||||
if (var64 == 23)
|
||||
{
|
||||
//if (var65) -- client has this if, but it causes broken midi to be produced
|
||||
{
|
||||
var51.writeByte(255); // meta event FF
|
||||
}
|
||||
|
||||
var51.writeByte(81); // type - set tempo
|
||||
var51.writeByte(3); // length
|
||||
var51.writeByte(var1.getArray()[var50++]);
|
||||
var51.writeByte(var1.getArray()[var50++]);
|
||||
var51.writeByte(var1.getArray()[var50++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var52 ^= var64 >> 4;
|
||||
if (var62 == 0)
|
||||
{
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(144 + var52);
|
||||
}
|
||||
|
||||
var53 += var1.getArray()[var37++];
|
||||
var54 += var1.getArray()[var38++];
|
||||
var51.writeByte(var53 & 127);
|
||||
var51.writeByte(var54 & 127);
|
||||
}
|
||||
else if (var62 == 1)
|
||||
{
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(128 + var52);
|
||||
}
|
||||
|
||||
var53 += var1.getArray()[var37++];
|
||||
var55 += var1.getArray()[var40++];
|
||||
var51.writeByte(var53 & 127);
|
||||
var51.writeByte(var55 & 127);
|
||||
}
|
||||
else if (var62 == 2)
|
||||
{
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(176 + var52);
|
||||
}
|
||||
|
||||
var28 = var28 + var1.getArray()[var15++] & 127;
|
||||
var51.writeByte(var28);
|
||||
byte var66;
|
||||
if (var28 != 0 && var28 != 32)
|
||||
{
|
||||
if (var28 == 1)
|
||||
{
|
||||
var66 = var1.getArray()[var34++];
|
||||
}
|
||||
else if (var28 == 33)
|
||||
{
|
||||
var66 = var1.getArray()[var41++];
|
||||
}
|
||||
else if (var28 == 7)
|
||||
{
|
||||
var66 = var1.getArray()[var35++];
|
||||
}
|
||||
else if (var28 == 39)
|
||||
{
|
||||
var66 = var1.getArray()[var42++];
|
||||
}
|
||||
else if (var28 == 10)
|
||||
{
|
||||
var66 = var1.getArray()[var36++];
|
||||
}
|
||||
else if (var28 == 42)
|
||||
{
|
||||
var66 = var1.getArray()[var43++];
|
||||
}
|
||||
else if (var28 == 99)
|
||||
{
|
||||
var66 = var1.getArray()[var46++];
|
||||
}
|
||||
else if (var28 == 98)
|
||||
{
|
||||
var66 = var1.getArray()[var47++];
|
||||
}
|
||||
else if (var28 == 101)
|
||||
{
|
||||
var66 = var1.getArray()[var48++];
|
||||
}
|
||||
else if (var28 == 100)
|
||||
{
|
||||
var66 = var1.getArray()[var49++];
|
||||
}
|
||||
else if (var28 != 64 && var28 != 65 && var28 != 120 && var28 != 121 && var28 != 123)
|
||||
{
|
||||
var66 = var1.getArray()[var39++];
|
||||
}
|
||||
else
|
||||
{
|
||||
var66 = var1.getArray()[var30++];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var66 = var1.getArray()[var44++];
|
||||
}
|
||||
|
||||
int var67 = var66 + var59[var28];
|
||||
var59[var28] = var67;
|
||||
var51.writeByte(var67 & 127);
|
||||
}
|
||||
else if (var62 == 3)
|
||||
{
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(224 + var52);
|
||||
}
|
||||
|
||||
var56 += var1.getArray()[var45++];
|
||||
var56 += var1.getArray()[var33++] << 7;
|
||||
var51.writeByte(var56 & 127);
|
||||
var51.writeByte(var56 >> 7 & 127);
|
||||
}
|
||||
else if (var62 == 4)
|
||||
{
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(208 + var52);
|
||||
}
|
||||
|
||||
var57 += var1.getArray()[var32++];
|
||||
var51.writeByte(var57 & 127);
|
||||
}
|
||||
else if (var62 == 5)
|
||||
{
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(160 + var52);
|
||||
}
|
||||
|
||||
var53 += var1.getArray()[var37++];
|
||||
var58 += var1.getArray()[var31++];
|
||||
var51.writeByte(var53 & 127);
|
||||
var51.writeByte(var58 & 127);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (var62 != 6)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
if (var65)
|
||||
{
|
||||
var51.writeByte(192 + var52);
|
||||
}
|
||||
|
||||
var51.writeByte(var1.getArray()[var44++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,12 @@ public class InputStream extends java.io.InputStream
|
||||
this.buffer = ByteBuffer.wrap(buffer);
|
||||
}
|
||||
|
||||
public byte[] getArray()
|
||||
{
|
||||
assert buffer.hasArray();
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
@@ -150,7 +156,9 @@ public class InputStream extends java.io.InputStream
|
||||
int ch = this.readByte();
|
||||
|
||||
if (ch == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch >= 128 && ch < 160)
|
||||
{
|
||||
@@ -168,7 +176,6 @@ public class InputStream extends java.io.InputStream
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public String readStringOrNull()
|
||||
{
|
||||
if (this.peek() != 0)
|
||||
@@ -182,6 +189,19 @@ public class InputStream extends java.io.InputStream
|
||||
}
|
||||
}
|
||||
|
||||
public int readVarInt()
|
||||
{
|
||||
byte var1 = this.readByte();
|
||||
|
||||
int var2;
|
||||
for (var2 = 0; var1 < 0; var1 = this.readByte())
|
||||
{
|
||||
var2 = (var2 | var1 & 127) << 7;
|
||||
}
|
||||
|
||||
return var2 | var1;
|
||||
}
|
||||
|
||||
public byte[] getRemaining()
|
||||
{
|
||||
byte[] b = new byte[buffer.remaining()];
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.nio.ByteBuffer;
|
||||
public final class OutputStream extends java.io.OutputStream
|
||||
{
|
||||
private ByteBuffer buffer;
|
||||
|
||||
|
||||
public OutputStream(int capacity)
|
||||
{
|
||||
buffer = ByteBuffer.allocate(capacity);
|
||||
@@ -41,6 +41,17 @@ public final class OutputStream extends java.io.OutputStream
|
||||
this(16);
|
||||
}
|
||||
|
||||
public OutputStream(byte[] b)
|
||||
{
|
||||
buffer = ByteBuffer.wrap(b);
|
||||
}
|
||||
|
||||
public byte[] getArray()
|
||||
{
|
||||
assert buffer.hasArray();
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
private void ensureRemaining(int remaining)
|
||||
{
|
||||
while (remaining > buffer.remaining())
|
||||
@@ -63,6 +74,11 @@ public final class OutputStream extends java.io.OutputStream
|
||||
buffer.position(pos);
|
||||
}
|
||||
|
||||
public int getOffset()
|
||||
{
|
||||
return buffer.position();
|
||||
}
|
||||
|
||||
public void setOffset(int offset)
|
||||
{
|
||||
buffer.position(offset);
|
||||
@@ -78,7 +94,7 @@ public final class OutputStream extends java.io.OutputStream
|
||||
ensureRemaining(length);
|
||||
buffer.put(b, offset, length);
|
||||
}
|
||||
|
||||
|
||||
public void writeByte(int i)
|
||||
{
|
||||
ensureRemaining(1);
|
||||
@@ -112,6 +128,39 @@ public final class OutputStream extends java.io.OutputStream
|
||||
buffer.putInt(i);
|
||||
}
|
||||
|
||||
public void writeVarInt(int var1)
|
||||
{
|
||||
if ((var1 & -128) != 0)
|
||||
{
|
||||
if ((var1 & -16384) != 0)
|
||||
{
|
||||
if ((var1 & -2097152) != 0)
|
||||
{
|
||||
if ((var1 & -268435456) != 0)
|
||||
{
|
||||
this.writeByte(var1 >>> 28 | 128);
|
||||
}
|
||||
|
||||
this.writeByte(var1 >>> 21 | 128);
|
||||
}
|
||||
|
||||
this.writeByte(var1 >>> 14 | 128);
|
||||
}
|
||||
|
||||
this.writeByte(var1 >>> 7 | 128);
|
||||
}
|
||||
|
||||
this.writeByte(var1 & 127);
|
||||
}
|
||||
|
||||
public void writeLengthFromMark(int var1)
|
||||
{
|
||||
this.getArray()[this.getOffset() - var1 - 4] = (byte) (var1 >> 24);
|
||||
this.getArray()[this.getOffset() - var1 - 3] = (byte) (var1 >> 16);
|
||||
this.getArray()[this.getOffset() - var1 - 2] = (byte) (var1 >> 8);
|
||||
this.getArray()[this.getOffset() - var1 - 1] = (byte) var1;
|
||||
}
|
||||
|
||||
public byte[] flip()
|
||||
{
|
||||
buffer.flip();
|
||||
|
||||
125
cache/src/test/java/net/runelite/cache/Track1DumperTest.java
vendored
Normal file
125
cache/src/test/java/net/runelite/cache/Track1DumperTest.java
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.cache;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import javax.sound.midi.MidiSystem;
|
||||
import javax.sound.midi.Sequencer;
|
||||
import net.runelite.cache.definitions.Track1Definition;
|
||||
import net.runelite.cache.definitions.loaders.Track1Loader;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
import net.runelite.cache.fs.Index;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.cache.util.Djb2Manager;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Track1DumperTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(Track1DumperTest.class);
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void test() throws IOException
|
||||
{
|
||||
File dumpDir = folder.newFolder();
|
||||
int count = 0;
|
||||
|
||||
Djb2Manager djb2 = new Djb2Manager();
|
||||
djb2.load();
|
||||
|
||||
try (Store store = new Store(StoreLocation.LOCATION))
|
||||
{
|
||||
store.load();
|
||||
|
||||
Index index = store.getIndex(IndexType.TRACK1);
|
||||
|
||||
for (Archive archive : index.getArchives())
|
||||
{
|
||||
assert archive.getFiles().size() == 1;
|
||||
|
||||
net.runelite.cache.fs.File file = archive.getFiles().get(0);
|
||||
|
||||
Track1Loader loader = new Track1Loader();
|
||||
Track1Definition def = loader.load(file.getContents());
|
||||
|
||||
String name = djb2.getName(archive.getNameHash());
|
||||
if (name == null)
|
||||
{
|
||||
name = "" + archive.getNameHash();
|
||||
}
|
||||
|
||||
Files.write(def.midi, new File(dumpDir, name + ".midi"));
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Dumped {} sound tracks to {}", count, dumpDir);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void play() throws Exception
|
||||
{
|
||||
// Obtains the default Sequencer connected to a default device.
|
||||
Sequencer sequencer = MidiSystem.getSequencer();
|
||||
|
||||
// Opens the device, indicating that it should now acquire any
|
||||
// system resources it requires and become operational.
|
||||
sequencer.open();
|
||||
|
||||
try
|
||||
{
|
||||
// create a stream from a file
|
||||
java.io.InputStream is = new FileInputStream(new File("C:\\rs\\cache\\track1\\scape main.midi"));
|
||||
|
||||
// Sets the current sequence on which the sequencer operates.
|
||||
// The stream must point to MIDI file data.
|
||||
sequencer.setSequence(is);
|
||||
|
||||
// Starts playback of the MIDI data in the currently loaded sequence.
|
||||
sequencer.start();
|
||||
|
||||
while (sequencer.isRunning())
|
||||
{
|
||||
Thread.sleep(1000L);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
sequencer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user