|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package com.sun.media.sound; |
|
|
|
import java.io.File; |
|
import java.io.FileInputStream; |
|
import java.io.IOException; |
|
import java.io.InputStream; |
|
import java.io.OutputStream; |
|
import java.net.URL; |
|
import java.util.ArrayList; |
|
import java.util.Arrays; |
|
import java.util.HashMap; |
|
import java.util.List; |
|
import java.util.Map; |
|
import java.util.Stack; |
|
|
|
import javax.sound.midi.Instrument; |
|
import javax.sound.midi.Patch; |
|
import javax.sound.midi.Soundbank; |
|
import javax.sound.midi.SoundbankResource; |
|
import javax.sound.sampled.AudioFormat; |
|
import javax.sound.sampled.AudioInputStream; |
|
import javax.sound.sampled.AudioSystem; |
|
import javax.sound.sampled.AudioFormat.Encoding; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public final class DLSSoundbank implements Soundbank { |
|
|
|
static private class DLSID { |
|
long i1; |
|
int s1; |
|
int s2; |
|
int x1; |
|
int x2; |
|
int x3; |
|
int x4; |
|
int x5; |
|
int x6; |
|
int x7; |
|
int x8; |
|
|
|
private DLSID() { |
|
} |
|
|
|
DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4, |
|
int x5, int x6, int x7, int x8) { |
|
this.i1 = i1; |
|
this.s1 = s1; |
|
this.s2 = s2; |
|
this.x1 = x1; |
|
this.x2 = x2; |
|
this.x3 = x3; |
|
this.x4 = x4; |
|
this.x5 = x5; |
|
this.x6 = x6; |
|
this.x7 = x7; |
|
this.x8 = x8; |
|
} |
|
|
|
public static DLSID read(RIFFReader riff) throws IOException { |
|
DLSID d = new DLSID(); |
|
d.i1 = riff.readUnsignedInt(); |
|
d.s1 = riff.readUnsignedShort(); |
|
d.s2 = riff.readUnsignedShort(); |
|
d.x1 = riff.readUnsignedByte(); |
|
d.x2 = riff.readUnsignedByte(); |
|
d.x3 = riff.readUnsignedByte(); |
|
d.x4 = riff.readUnsignedByte(); |
|
d.x5 = riff.readUnsignedByte(); |
|
d.x6 = riff.readUnsignedByte(); |
|
d.x7 = riff.readUnsignedByte(); |
|
d.x8 = riff.readUnsignedByte(); |
|
return d; |
|
} |
|
|
|
public int hashCode() { |
|
return (int)i1; |
|
} |
|
|
|
public boolean equals(Object obj) { |
|
if (!(obj instanceof DLSID)) { |
|
return false; |
|
} |
|
DLSID t = (DLSID) obj; |
|
return i1 == t.i1 && s1 == t.s1 && s2 == t.s2 |
|
&& x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4 |
|
&& x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8; |
|
} |
|
} |
|
|
|
|
|
private static final int DLS_CDL_AND = 0x0001; |
|
|
|
private static final int DLS_CDL_OR = 0x0002; |
|
|
|
private static final int DLS_CDL_XOR = 0x0003; |
|
|
|
private static final int DLS_CDL_ADD = 0x0004; |
|
|
|
private static final int DLS_CDL_SUBTRACT = 0x0005; |
|
|
|
private static final int DLS_CDL_MULTIPLY = 0x0006; |
|
|
|
private static final int DLS_CDL_DIVIDE = 0x0007; |
|
|
|
private static final int DLS_CDL_LOGICAL_AND = 0x0008; |
|
|
|
private static final int DLS_CDL_LOGICAL_OR = 0x0009; |
|
|
|
private static final int DLS_CDL_LT = 0x000A; |
|
|
|
private static final int DLS_CDL_LE = 0x000B; |
|
|
|
private static final int DLS_CDL_GT = 0x000C; |
|
|
|
private static final int DLS_CDL_GE = 0x000D; |
|
|
|
private static final int DLS_CDL_EQ = 0x000E; |
|
|
|
private static final int DLS_CDL_NOT = 0x000F; |
|
|
|
private static final int DLS_CDL_CONST = 0x0010; |
|
|
|
private static final int DLS_CDL_QUERY = 0x0011; |
|
|
|
private static final int DLS_CDL_QUERYSUPPORTED = 0x0012; |
|
|
|
private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24, |
|
0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); |
|
private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25, |
|
0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); |
|
private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26, |
|
0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); |
|
private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27, |
|
0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); |
|
private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5, |
|
0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6); |
|
private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28, |
|
0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12); |
|
private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181, |
|
0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); |
|
private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182, |
|
0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); |
|
private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713, |
|
0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8); |
|
|
|
private long major = -1; |
|
private long minor = -1; |
|
|
|
private final DLSInfo info = new DLSInfo(); |
|
|
|
private final List<DLSInstrument> instruments = new ArrayList<DLSInstrument>(); |
|
private final List<DLSSample> samples = new ArrayList<DLSSample>(); |
|
|
|
private boolean largeFormat = false; |
|
private File sampleFile; |
|
|
|
public DLSSoundbank() { |
|
} |
|
|
|
public DLSSoundbank(URL url) throws IOException { |
|
InputStream is = url.openStream(); |
|
try { |
|
readSoundbank(is); |
|
} finally { |
|
is.close(); |
|
} |
|
} |
|
|
|
public DLSSoundbank(File file) throws IOException { |
|
largeFormat = true; |
|
sampleFile = file; |
|
InputStream is = new FileInputStream(file); |
|
try { |
|
readSoundbank(is); |
|
} finally { |
|
is.close(); |
|
} |
|
} |
|
|
|
public DLSSoundbank(InputStream inputstream) throws IOException { |
|
readSoundbank(inputstream); |
|
} |
|
|
|
private void readSoundbank(InputStream inputstream) throws IOException { |
|
RIFFReader riff = new RIFFReader(inputstream); |
|
if (!riff.getFormat().equals("RIFF")) { |
|
throw new RIFFInvalidFormatException( |
|
"Input stream is not a valid RIFF stream!"); |
|
} |
|
if (!riff.getType().equals("DLS ")) { |
|
throw new RIFFInvalidFormatException( |
|
"Input stream is not a valid DLS soundbank!"); |
|
} |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
if (chunk.getFormat().equals("LIST")) { |
|
if (chunk.getType().equals("INFO")) |
|
readInfoChunk(chunk); |
|
if (chunk.getType().equals("lins")) |
|
readLinsChunk(chunk); |
|
if (chunk.getType().equals("wvpl")) |
|
readWvplChunk(chunk); |
|
} else { |
|
if (chunk.getFormat().equals("cdl ")) { |
|
if (!readCdlChunk(chunk)) { |
|
throw new RIFFInvalidFormatException( |
|
"DLS file isn't supported!"); |
|
} |
|
} |
|
if (chunk.getFormat().equals("colh")) { |
|
// skipped because we will load the entire bank into memory |
|
// long instrumentcount = chunk.readUnsignedInt(); |
|
// System.out.println("instrumentcount = "+ instrumentcount); |
|
} |
|
if (chunk.getFormat().equals("ptbl")) { |
|
// Pool Table Chunk |
|
// skipped because we will load the entire bank into memory |
|
} |
|
if (chunk.getFormat().equals("vers")) { |
|
major = chunk.readUnsignedInt(); |
|
minor = chunk.readUnsignedInt(); |
|
} |
|
} |
|
} |
|
|
|
for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) { |
|
entry.getKey().sample = samples.get((int)entry.getValue().longValue()); |
|
} |
|
|
|
temp_rgnassign = null; |
|
} |
|
|
|
private boolean cdlIsQuerySupported(DLSID uuid) { |
|
return uuid.equals(DLSID_GMInHardware) |
|
|| uuid.equals(DLSID_GSInHardware) |
|
|| uuid.equals(DLSID_XGInHardware) |
|
|| uuid.equals(DLSID_SupportsDLS1) |
|
|| uuid.equals(DLSID_SupportsDLS2) |
|
|| uuid.equals(DLSID_SampleMemorySize) |
|
|| uuid.equals(DLSID_ManufacturersID) |
|
|| uuid.equals(DLSID_ProductID) |
|
|| uuid.equals(DLSID_SamplePlaybackRate); |
|
} |
|
|
|
private long cdlQuery(DLSID uuid) { |
|
if (uuid.equals(DLSID_GMInHardware)) |
|
return 1; |
|
if (uuid.equals(DLSID_GSInHardware)) |
|
return 0; |
|
if (uuid.equals(DLSID_XGInHardware)) |
|
return 0; |
|
if (uuid.equals(DLSID_SupportsDLS1)) |
|
return 1; |
|
if (uuid.equals(DLSID_SupportsDLS2)) |
|
return 1; |
|
if (uuid.equals(DLSID_SampleMemorySize)) |
|
return Runtime.getRuntime().totalMemory(); |
|
if (uuid.equals(DLSID_ManufacturersID)) |
|
return 0; |
|
if (uuid.equals(DLSID_ProductID)) |
|
return 0; |
|
if (uuid.equals(DLSID_SamplePlaybackRate)) |
|
return 44100; |
|
return 0; |
|
} |
|
|
|
|
|
// Reading cdl-ck Chunk |
|
|
|
private boolean readCdlChunk(RIFFReader riff) throws IOException { |
|
|
|
DLSID uuid; |
|
long x; |
|
long y; |
|
Stack<Long> stack = new Stack<Long>(); |
|
|
|
while (riff.available() != 0) { |
|
int opcode = riff.readUnsignedShort(); |
|
switch (opcode) { |
|
case DLS_CDL_AND: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_OR: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_XOR: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(((x != 0) ^ (y != 0)) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_ADD: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(x + y)); |
|
break; |
|
case DLS_CDL_SUBTRACT: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(x - y)); |
|
break; |
|
case DLS_CDL_MULTIPLY: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(x * y)); |
|
break; |
|
case DLS_CDL_DIVIDE: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(x / y)); |
|
break; |
|
case DLS_CDL_LOGICAL_AND: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_LOGICAL_OR: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_LT: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf((x < y) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_LE: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf((x <= y) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_GT: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf((x > y) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_GE: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf((x >= y) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_EQ: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf((x == y) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_NOT: |
|
x = stack.pop(); |
|
y = stack.pop(); |
|
stack.push(Long.valueOf((x == 0) ? 1 : 0)); |
|
break; |
|
case DLS_CDL_CONST: |
|
stack.push(Long.valueOf(riff.readUnsignedInt())); |
|
break; |
|
case DLS_CDL_QUERY: |
|
uuid = DLSID.read(riff); |
|
stack.push(cdlQuery(uuid)); |
|
break; |
|
case DLS_CDL_QUERYSUPPORTED: |
|
uuid = DLSID.read(riff); |
|
stack.push(Long.valueOf(cdlIsQuerySupported(uuid) ? 1 : 0)); |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
if (stack.isEmpty()) |
|
return false; |
|
|
|
return stack.pop() == 1; |
|
} |
|
|
|
private void readInfoChunk(RIFFReader riff) throws IOException { |
|
info.name = null; |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
String format = chunk.getFormat(); |
|
if (format.equals("INAM")) |
|
info.name = chunk.readString(chunk.available()); |
|
else if (format.equals("ICRD")) |
|
info.creationDate = chunk.readString(chunk.available()); |
|
else if (format.equals("IENG")) |
|
info.engineers = chunk.readString(chunk.available()); |
|
else if (format.equals("IPRD")) |
|
info.product = chunk.readString(chunk.available()); |
|
else if (format.equals("ICOP")) |
|
info.copyright = chunk.readString(chunk.available()); |
|
else if (format.equals("ICMT")) |
|
info.comments = chunk.readString(chunk.available()); |
|
else if (format.equals("ISFT")) |
|
info.tools = chunk.readString(chunk.available()); |
|
else if (format.equals("IARL")) |
|
info.archival_location = chunk.readString(chunk.available()); |
|
else if (format.equals("IART")) |
|
info.artist = chunk.readString(chunk.available()); |
|
else if (format.equals("ICMS")) |
|
info.commissioned = chunk.readString(chunk.available()); |
|
else if (format.equals("IGNR")) |
|
info.genre = chunk.readString(chunk.available()); |
|
else if (format.equals("IKEY")) |
|
info.keywords = chunk.readString(chunk.available()); |
|
else if (format.equals("IMED")) |
|
info.medium = chunk.readString(chunk.available()); |
|
else if (format.equals("ISBJ")) |
|
info.subject = chunk.readString(chunk.available()); |
|
else if (format.equals("ISRC")) |
|
info.source = chunk.readString(chunk.available()); |
|
else if (format.equals("ISRF")) |
|
info.source_form = chunk.readString(chunk.available()); |
|
else if (format.equals("ITCH")) |
|
info.technician = chunk.readString(chunk.available()); |
|
} |
|
} |
|
|
|
private void readLinsChunk(RIFFReader riff) throws IOException { |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
if (chunk.getFormat().equals("LIST")) { |
|
if (chunk.getType().equals("ins ")) |
|
readInsChunk(chunk); |
|
} |
|
} |
|
} |
|
|
|
private void readInsChunk(RIFFReader riff) throws IOException { |
|
DLSInstrument instrument = new DLSInstrument(this); |
|
|
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
String format = chunk.getFormat(); |
|
if (format.equals("LIST")) { |
|
if (chunk.getType().equals("INFO")) { |
|
readInsInfoChunk(instrument, chunk); |
|
} |
|
if (chunk.getType().equals("lrgn")) { |
|
while (chunk.hasNextChunk()) { |
|
RIFFReader subchunk = chunk.nextChunk(); |
|
if (subchunk.getFormat().equals("LIST")) { |
|
if (subchunk.getType().equals("rgn ")) { |
|
DLSRegion split = new DLSRegion(); |
|
if (readRgnChunk(split, subchunk)) |
|
instrument.getRegions().add(split); |
|
} |
|
if (subchunk.getType().equals("rgn2")) { |
|
|
|
DLSRegion split = new DLSRegion(); |
|
if (readRgnChunk(split, subchunk)) |
|
instrument.getRegions().add(split); |
|
} |
|
} |
|
} |
|
} |
|
if (chunk.getType().equals("lart")) { |
|
List<DLSModulator> modlist = new ArrayList<DLSModulator>(); |
|
while (chunk.hasNextChunk()) { |
|
RIFFReader subchunk = chunk.nextChunk(); |
|
if (chunk.getFormat().equals("cdl ")) { |
|
if (!readCdlChunk(chunk)) { |
|
modlist.clear(); |
|
break; |
|
} |
|
} |
|
if (subchunk.getFormat().equals("art1")) |
|
readArt1Chunk(modlist, subchunk); |
|
} |
|
instrument.getModulators().addAll(modlist); |
|
} |
|
if (chunk.getType().equals("lar2")) { |
|
|
|
List<DLSModulator> modlist = new ArrayList<DLSModulator>(); |
|
while (chunk.hasNextChunk()) { |
|
RIFFReader subchunk = chunk.nextChunk(); |
|
if (chunk.getFormat().equals("cdl ")) { |
|
if (!readCdlChunk(chunk)) { |
|
modlist.clear(); |
|
break; |
|
} |
|
} |
|
if (subchunk.getFormat().equals("art2")) |
|
readArt2Chunk(modlist, subchunk); |
|
} |
|
instrument.getModulators().addAll(modlist); |
|
} |
|
} else { |
|
if (format.equals("dlid")) { |
|
instrument.guid = new byte[16]; |
|
chunk.readFully(instrument.guid); |
|
} |
|
if (format.equals("insh")) { |
|
chunk.readUnsignedInt(); |
|
|
|
int bank = chunk.read(); |
|
bank += (chunk.read() & 127) << 7; |
|
chunk.read(); |
|
int drumins = chunk.read(); |
|
|
|
int id = chunk.read() & 127; |
|
chunk.read(); |
|
chunk.read(); |
|
chunk.read(); |
|
|
|
instrument.bank = bank; |
|
instrument.preset = (int) id; |
|
instrument.druminstrument = (drumins & 128) > 0; |
|
//System.out.println("bank="+bank+" drumkit="+drumkit |
|
// +" id="+id); |
|
} |
|
|
|
} |
|
} |
|
instruments.add(instrument); |
|
} |
|
|
|
private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff) |
|
throws IOException { |
|
long size = riff.readUnsignedInt(); |
|
long count = riff.readUnsignedInt(); |
|
|
|
if (size - 8 != 0) |
|
riff.skip(size - 8); |
|
|
|
for (int i = 0; i < count; i++) { |
|
DLSModulator modulator = new DLSModulator(); |
|
modulator.version = 1; |
|
modulator.source = riff.readUnsignedShort(); |
|
modulator.control = riff.readUnsignedShort(); |
|
modulator.destination = riff.readUnsignedShort(); |
|
modulator.transform = riff.readUnsignedShort(); |
|
modulator.scale = riff.readInt(); |
|
modulators.add(modulator); |
|
} |
|
} |
|
|
|
private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff) |
|
throws IOException { |
|
long size = riff.readUnsignedInt(); |
|
long count = riff.readUnsignedInt(); |
|
|
|
if (size - 8 != 0) |
|
riff.skip(size - 8); |
|
|
|
for (int i = 0; i < count; i++) { |
|
DLSModulator modulator = new DLSModulator(); |
|
modulator.version = 2; |
|
modulator.source = riff.readUnsignedShort(); |
|
modulator.control = riff.readUnsignedShort(); |
|
modulator.destination = riff.readUnsignedShort(); |
|
modulator.transform = riff.readUnsignedShort(); |
|
modulator.scale = riff.readInt(); |
|
modulators.add(modulator); |
|
} |
|
} |
|
|
|
private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>(); |
|
|
|
private boolean readRgnChunk(DLSRegion split, RIFFReader riff) |
|
throws IOException { |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
String format = chunk.getFormat(); |
|
if (format.equals("LIST")) { |
|
if (chunk.getType().equals("lart")) { |
|
List<DLSModulator> modlist = new ArrayList<DLSModulator>(); |
|
while (chunk.hasNextChunk()) { |
|
RIFFReader subchunk = chunk.nextChunk(); |
|
if (chunk.getFormat().equals("cdl ")) { |
|
if (!readCdlChunk(chunk)) { |
|
modlist.clear(); |
|
break; |
|
} |
|
} |
|
if (subchunk.getFormat().equals("art1")) |
|
readArt1Chunk(modlist, subchunk); |
|
} |
|
split.getModulators().addAll(modlist); |
|
} |
|
if (chunk.getType().equals("lar2")) { |
|
|
|
List<DLSModulator> modlist = new ArrayList<DLSModulator>(); |
|
while (chunk.hasNextChunk()) { |
|
RIFFReader subchunk = chunk.nextChunk(); |
|
if (chunk.getFormat().equals("cdl ")) { |
|
if (!readCdlChunk(chunk)) { |
|
modlist.clear(); |
|
break; |
|
} |
|
} |
|
if (subchunk.getFormat().equals("art2")) |
|
readArt2Chunk(modlist, subchunk); |
|
} |
|
split.getModulators().addAll(modlist); |
|
} |
|
} else { |
|
|
|
if (format.equals("cdl ")) { |
|
if (!readCdlChunk(chunk)) |
|
return false; |
|
} |
|
if (format.equals("rgnh")) { |
|
split.keyfrom = chunk.readUnsignedShort(); |
|
split.keyto = chunk.readUnsignedShort(); |
|
split.velfrom = chunk.readUnsignedShort(); |
|
split.velto = chunk.readUnsignedShort(); |
|
split.options = chunk.readUnsignedShort(); |
|
split.exclusiveClass = chunk.readUnsignedShort(); |
|
} |
|
if (format.equals("wlnk")) { |
|
split.fusoptions = chunk.readUnsignedShort(); |
|
split.phasegroup = chunk.readUnsignedShort(); |
|
split.channel = chunk.readUnsignedInt(); |
|
long sampleid = chunk.readUnsignedInt(); |
|
temp_rgnassign.put(split, sampleid); |
|
} |
|
if (format.equals("wsmp")) { |
|
split.sampleoptions = new DLSSampleOptions(); |
|
readWsmpChunk(split.sampleoptions, chunk); |
|
} |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff) |
|
throws IOException { |
|
long size = riff.readUnsignedInt(); |
|
sampleOptions.unitynote = riff.readUnsignedShort(); |
|
sampleOptions.finetune = riff.readShort(); |
|
sampleOptions.attenuation = riff.readInt(); |
|
sampleOptions.options = riff.readUnsignedInt(); |
|
long loops = riff.readInt(); |
|
|
|
if (size > 20) |
|
riff.skip(size - 20); |
|
|
|
for (int i = 0; i < loops; i++) { |
|
DLSSampleLoop loop = new DLSSampleLoop(); |
|
long size2 = riff.readUnsignedInt(); |
|
loop.type = riff.readUnsignedInt(); |
|
loop.start = riff.readUnsignedInt(); |
|
loop.length = riff.readUnsignedInt(); |
|
sampleOptions.loops.add(loop); |
|
if (size2 > 16) |
|
riff.skip(size2 - 16); |
|
} |
|
} |
|
|
|
private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff) |
|
throws IOException { |
|
dlsinstrument.info.name = null; |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
String format = chunk.getFormat(); |
|
if (format.equals("INAM")) { |
|
dlsinstrument.info.name = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICRD")) { |
|
dlsinstrument.info.creationDate = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IENG")) { |
|
dlsinstrument.info.engineers = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IPRD")) { |
|
dlsinstrument.info.product = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICOP")) { |
|
dlsinstrument.info.copyright = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("ICMT")) { |
|
dlsinstrument.info.comments = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("ISFT")) { |
|
dlsinstrument.info.tools = chunk.readString(chunk.available()); |
|
} else if (format.equals("IARL")) { |
|
dlsinstrument.info.archival_location = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IART")) { |
|
dlsinstrument.info.artist = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICMS")) { |
|
dlsinstrument.info.commissioned = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IGNR")) { |
|
dlsinstrument.info.genre = chunk.readString(chunk.available()); |
|
} else if (format.equals("IKEY")) { |
|
dlsinstrument.info.keywords = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IMED")) { |
|
dlsinstrument.info.medium = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISBJ")) { |
|
dlsinstrument.info.subject = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISRC")) { |
|
dlsinstrument.info.source = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISRF")) { |
|
dlsinstrument.info.source_form = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("ITCH")) { |
|
dlsinstrument.info.technician = |
|
chunk.readString(chunk.available()); |
|
} |
|
} |
|
} |
|
|
|
private void readWvplChunk(RIFFReader riff) throws IOException { |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
if (chunk.getFormat().equals("LIST")) { |
|
if (chunk.getType().equals("wave")) |
|
readWaveChunk(chunk); |
|
} |
|
} |
|
} |
|
|
|
private void readWaveChunk(RIFFReader riff) throws IOException { |
|
DLSSample sample = new DLSSample(this); |
|
|
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
String format = chunk.getFormat(); |
|
if (format.equals("LIST")) { |
|
if (chunk.getType().equals("INFO")) { |
|
readWaveInfoChunk(sample, chunk); |
|
} |
|
} else { |
|
if (format.equals("dlid")) { |
|
sample.guid = new byte[16]; |
|
chunk.readFully(sample.guid); |
|
} |
|
|
|
if (format.equals("fmt ")) { |
|
int sampleformat = chunk.readUnsignedShort(); |
|
if (sampleformat != 1 && sampleformat != 3) { |
|
throw new RIFFInvalidDataException( |
|
"Only PCM samples are supported!"); |
|
} |
|
int channels = chunk.readUnsignedShort(); |
|
long samplerate = chunk.readUnsignedInt(); |
|
// bytes per sec |
|
chunk.readUnsignedInt(); |
|
|
|
int framesize = chunk.readUnsignedShort(); |
|
int bits = chunk.readUnsignedShort(); |
|
AudioFormat audioformat = null; |
|
if (sampleformat == 1) { |
|
if (bits == 8) { |
|
audioformat = new AudioFormat( |
|
Encoding.PCM_UNSIGNED, samplerate, bits, |
|
channels, framesize, samplerate, false); |
|
} else { |
|
audioformat = new AudioFormat( |
|
Encoding.PCM_SIGNED, samplerate, bits, |
|
channels, framesize, samplerate, false); |
|
} |
|
} |
|
if (sampleformat == 3) { |
|
audioformat = new AudioFormat( |
|
Encoding.PCM_FLOAT, samplerate, bits, |
|
channels, framesize, samplerate, false); |
|
} |
|
|
|
sample.format = audioformat; |
|
} |
|
|
|
if (format.equals("data")) { |
|
if (largeFormat) { |
|
sample.setData(new ModelByteBuffer(sampleFile, |
|
chunk.getFilePointer(), chunk.available())); |
|
} else { |
|
byte[] buffer = new byte[chunk.available()]; |
|
|
|
sample.setData(buffer); |
|
|
|
int read = 0; |
|
int avail = chunk.available(); |
|
while (read != avail) { |
|
if (avail - read > 65536) { |
|
chunk.readFully(buffer, read, 65536); |
|
read += 65536; |
|
} else { |
|
chunk.readFully(buffer, read, avail - read); |
|
read = avail; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (format.equals("wsmp")) { |
|
sample.sampleoptions = new DLSSampleOptions(); |
|
readWsmpChunk(sample.sampleoptions, chunk); |
|
} |
|
} |
|
} |
|
|
|
samples.add(sample); |
|
|
|
} |
|
|
|
private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff) |
|
throws IOException { |
|
dlssample.info.name = null; |
|
while (riff.hasNextChunk()) { |
|
RIFFReader chunk = riff.nextChunk(); |
|
String format = chunk.getFormat(); |
|
if (format.equals("INAM")) { |
|
dlssample.info.name = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICRD")) { |
|
dlssample.info.creationDate = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IENG")) { |
|
dlssample.info.engineers = chunk.readString(chunk.available()); |
|
} else if (format.equals("IPRD")) { |
|
dlssample.info.product = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICOP")) { |
|
dlssample.info.copyright = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICMT")) { |
|
dlssample.info.comments = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISFT")) { |
|
dlssample.info.tools = chunk.readString(chunk.available()); |
|
} else if (format.equals("IARL")) { |
|
dlssample.info.archival_location = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IART")) { |
|
dlssample.info.artist = chunk.readString(chunk.available()); |
|
} else if (format.equals("ICMS")) { |
|
dlssample.info.commissioned = |
|
chunk.readString(chunk.available()); |
|
} else if (format.equals("IGNR")) { |
|
dlssample.info.genre = chunk.readString(chunk.available()); |
|
} else if (format.equals("IKEY")) { |
|
dlssample.info.keywords = chunk.readString(chunk.available()); |
|
} else if (format.equals("IMED")) { |
|
dlssample.info.medium = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISBJ")) { |
|
dlssample.info.subject = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISRC")) { |
|
dlssample.info.source = chunk.readString(chunk.available()); |
|
} else if (format.equals("ISRF")) { |
|
dlssample.info.source_form = chunk.readString(chunk.available()); |
|
} else if (format.equals("ITCH")) { |
|
dlssample.info.technician = chunk.readString(chunk.available()); |
|
} |
|
} |
|
} |
|
|
|
public void save(String name) throws IOException { |
|
writeSoundbank(new RIFFWriter(name, "DLS ")); |
|
} |
|
|
|
public void save(File file) throws IOException { |
|
writeSoundbank(new RIFFWriter(file, "DLS ")); |
|
} |
|
|
|
public void save(OutputStream out) throws IOException { |
|
writeSoundbank(new RIFFWriter(out, "DLS ")); |
|
} |
|
|
|
private void writeSoundbank(RIFFWriter writer) throws IOException { |
|
RIFFWriter colh_chunk = writer.writeChunk("colh"); |
|
colh_chunk.writeUnsignedInt(instruments.size()); |
|
|
|
if (major != -1 && minor != -1) { |
|
RIFFWriter vers_chunk = writer.writeChunk("vers"); |
|
vers_chunk.writeUnsignedInt(major); |
|
vers_chunk.writeUnsignedInt(minor); |
|
} |
|
|
|
writeInstruments(writer.writeList("lins")); |
|
|
|
RIFFWriter ptbl = writer.writeChunk("ptbl"); |
|
ptbl.writeUnsignedInt(8); |
|
ptbl.writeUnsignedInt(samples.size()); |
|
long ptbl_offset = writer.getFilePointer(); |
|
for (int i = 0; i < samples.size(); i++) |
|
ptbl.writeUnsignedInt(0); |
|
|
|
RIFFWriter wvpl = writer.writeList("wvpl"); |
|
long off = wvpl.getFilePointer(); |
|
List<Long> offsettable = new ArrayList<Long>(); |
|
for (DLSSample sample : samples) { |
|
offsettable.add(Long.valueOf(wvpl.getFilePointer() - off)); |
|
writeSample(wvpl.writeList("wave"), sample); |
|
} |
|
|
|
|
|
long bak = writer.getFilePointer(); |
|
writer.seek(ptbl_offset); |
|
writer.setWriteOverride(true); |
|
for (Long offset : offsettable) |
|
writer.writeUnsignedInt(offset.longValue()); |
|
writer.setWriteOverride(false); |
|
writer.seek(bak); |
|
|
|
writeInfo(writer.writeList("INFO"), info); |
|
|
|
writer.close(); |
|
} |
|
|
|
private void writeSample(RIFFWriter writer, DLSSample sample) |
|
throws IOException { |
|
|
|
AudioFormat audioformat = sample.getFormat(); |
|
|
|
Encoding encoding = audioformat.getEncoding(); |
|
float sampleRate = audioformat.getSampleRate(); |
|
int sampleSizeInBits = audioformat.getSampleSizeInBits(); |
|
int channels = audioformat.getChannels(); |
|
int frameSize = audioformat.getFrameSize(); |
|
float frameRate = audioformat.getFrameRate(); |
|
boolean bigEndian = audioformat.isBigEndian(); |
|
|
|
boolean convert_needed = false; |
|
|
|
if (audioformat.getSampleSizeInBits() == 8) { |
|
if (!encoding.equals(Encoding.PCM_UNSIGNED)) { |
|
encoding = Encoding.PCM_UNSIGNED; |
|
convert_needed = true; |
|
} |
|
} else { |
|
if (!encoding.equals(Encoding.PCM_SIGNED)) { |
|
encoding = Encoding.PCM_SIGNED; |
|
convert_needed = true; |
|
} |
|
if (bigEndian) { |
|
bigEndian = false; |
|
convert_needed = true; |
|
} |
|
} |
|
|
|
if (convert_needed) { |
|
audioformat = new AudioFormat(encoding, sampleRate, |
|
sampleSizeInBits, channels, frameSize, frameRate, bigEndian); |
|
} |
|
|
|
|
|
RIFFWriter fmt_chunk = writer.writeChunk("fmt "); |
|
int sampleformat = 0; |
|
if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED)) |
|
sampleformat = 1; |
|
else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED)) |
|
sampleformat = 1; |
|
else if (audioformat.getEncoding().equals(Encoding.PCM_FLOAT)) |
|
sampleformat = 3; |
|
|
|
fmt_chunk.writeUnsignedShort(sampleformat); |
|
fmt_chunk.writeUnsignedShort(audioformat.getChannels()); |
|
fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate()); |
|
long srate = ((long)audioformat.getFrameRate())*audioformat.getFrameSize(); |
|
fmt_chunk.writeUnsignedInt(srate); |
|
fmt_chunk.writeUnsignedShort(audioformat.getFrameSize()); |
|
fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits()); |
|
fmt_chunk.write(0); |
|
fmt_chunk.write(0); |
|
|
|
writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions); |
|
|
|
if (convert_needed) { |
|
RIFFWriter data_chunk = writer.writeChunk("data"); |
|
AudioInputStream stream = AudioSystem.getAudioInputStream( |
|
audioformat, (AudioInputStream)sample.getData()); |
|
byte[] buff = new byte[1024]; |
|
int ret; |
|
while ((ret = stream.read(buff)) != -1) { |
|
data_chunk.write(buff, 0, ret); |
|
} |
|
} else { |
|
RIFFWriter data_chunk = writer.writeChunk("data"); |
|
ModelByteBuffer databuff = sample.getDataBuffer(); |
|
databuff.writeTo(data_chunk); |
|
/* |
|
data_chunk.write(databuff.array(), |
|
databuff.arrayOffset(), |
|
databuff.capacity()); |
|
*/ |
|
} |
|
|
|
writeInfo(writer.writeList("INFO"), sample.info); |
|
} |
|
|
|
private void writeInstruments(RIFFWriter writer) throws IOException { |
|
for (DLSInstrument instrument : instruments) { |
|
writeInstrument(writer.writeList("ins "), instrument); |
|
} |
|
} |
|
|
|
private void writeInstrument(RIFFWriter writer, DLSInstrument instrument) |
|
throws IOException { |
|
|
|
int art1_count = 0; |
|
int art2_count = 0; |
|
for (DLSModulator modulator : instrument.getModulators()) { |
|
if (modulator.version == 1) |
|
art1_count++; |
|
if (modulator.version == 2) |
|
art2_count++; |
|
} |
|
for (DLSRegion region : instrument.regions) { |
|
for (DLSModulator modulator : region.getModulators()) { |
|
if (modulator.version == 1) |
|
art1_count++; |
|
if (modulator.version == 2) |
|
art2_count++; |
|
} |
|
} |
|
|
|
int version = 1; |
|
if (art2_count > 0) |
|
version = 2; |
|
|
|
RIFFWriter insh_chunk = writer.writeChunk("insh"); |
|
insh_chunk.writeUnsignedInt(instrument.getRegions().size()); |
|
insh_chunk.writeUnsignedInt(instrument.bank + |
|
(instrument.druminstrument ? 2147483648L : 0)); |
|
insh_chunk.writeUnsignedInt(instrument.preset); |
|
|
|
RIFFWriter lrgn = writer.writeList("lrgn"); |
|
for (DLSRegion region: instrument.regions) |
|
writeRegion(lrgn, region, version); |
|
|
|
writeArticulators(writer, instrument.getModulators()); |
|
|
|
writeInfo(writer.writeList("INFO"), instrument.info); |
|
|
|
} |
|
|
|
private void writeArticulators(RIFFWriter writer, |
|
List<DLSModulator> modulators) throws IOException { |
|
int art1_count = 0; |
|
int art2_count = 0; |
|
for (DLSModulator modulator : modulators) { |
|
if (modulator.version == 1) |
|
art1_count++; |
|
if (modulator.version == 2) |
|
art2_count++; |
|
} |
|
if (art1_count > 0) { |
|
RIFFWriter lar1 = writer.writeList("lart"); |
|
RIFFWriter art1 = lar1.writeChunk("art1"); |
|
art1.writeUnsignedInt(8); |
|
art1.writeUnsignedInt(art1_count); |
|
for (DLSModulator modulator : modulators) { |
|
if (modulator.version == 1) { |
|
art1.writeUnsignedShort(modulator.source); |
|
art1.writeUnsignedShort(modulator.control); |
|
art1.writeUnsignedShort(modulator.destination); |
|
art1.writeUnsignedShort(modulator.transform); |
|
art1.writeInt(modulator.scale); |
|
} |
|
} |
|
} |
|
if (art2_count > 0) { |
|
RIFFWriter lar2 = writer.writeList("lar2"); |
|
RIFFWriter art2 = lar2.writeChunk("art2"); |
|
art2.writeUnsignedInt(8); |
|
art2.writeUnsignedInt(art2_count); |
|
for (DLSModulator modulator : modulators) { |
|
if (modulator.version == 2) { |
|
art2.writeUnsignedShort(modulator.source); |
|
art2.writeUnsignedShort(modulator.control); |
|
art2.writeUnsignedShort(modulator.destination); |
|
art2.writeUnsignedShort(modulator.transform); |
|
art2.writeInt(modulator.scale); |
|
} |
|
} |
|
} |
|
} |
|
|
|
private void writeRegion(RIFFWriter writer, DLSRegion region, int version) |
|
throws IOException { |
|
RIFFWriter rgns = null; |
|
if (version == 1) |
|
rgns = writer.writeList("rgn "); |
|
if (version == 2) |
|
rgns = writer.writeList("rgn2"); |
|
if (rgns == null) |
|
return; |
|
|
|
RIFFWriter rgnh = rgns.writeChunk("rgnh"); |
|
rgnh.writeUnsignedShort(region.keyfrom); |
|
rgnh.writeUnsignedShort(region.keyto); |
|
rgnh.writeUnsignedShort(region.velfrom); |
|
rgnh.writeUnsignedShort(region.velto); |
|
rgnh.writeUnsignedShort(region.options); |
|
rgnh.writeUnsignedShort(region.exclusiveClass); |
|
|
|
if (region.sampleoptions != null) |
|
writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions); |
|
|
|
if (region.sample != null) { |
|
if (samples.indexOf(region.sample) != -1) { |
|
RIFFWriter wlnk = rgns.writeChunk("wlnk"); |
|
wlnk.writeUnsignedShort(region.fusoptions); |
|
wlnk.writeUnsignedShort(region.phasegroup); |
|
wlnk.writeUnsignedInt(region.channel); |
|
wlnk.writeUnsignedInt(samples.indexOf(region.sample)); |
|
} |
|
} |
|
writeArticulators(rgns, region.getModulators()); |
|
rgns.close(); |
|
} |
|
|
|
private void writeSampleOptions(RIFFWriter wsmp, |
|
DLSSampleOptions sampleoptions) throws IOException { |
|
wsmp.writeUnsignedInt(20); |
|
wsmp.writeUnsignedShort(sampleoptions.unitynote); |
|
wsmp.writeShort(sampleoptions.finetune); |
|
wsmp.writeInt(sampleoptions.attenuation); |
|
wsmp.writeUnsignedInt(sampleoptions.options); |
|
wsmp.writeInt(sampleoptions.loops.size()); |
|
|
|
for (DLSSampleLoop loop : sampleoptions.loops) { |
|
wsmp.writeUnsignedInt(16); |
|
wsmp.writeUnsignedInt(loop.type); |
|
wsmp.writeUnsignedInt(loop.start); |
|
wsmp.writeUnsignedInt(loop.length); |
|
} |
|
} |
|
|
|
private void writeInfoStringChunk(RIFFWriter writer, |
|
String name, String value) throws IOException { |
|
if (value == null) |
|
return; |
|
RIFFWriter chunk = writer.writeChunk(name); |
|
chunk.writeString(value); |
|
int len = value.getBytes("ascii").length; |
|
chunk.write(0); |
|
len++; |
|
if (len % 2 != 0) |
|
chunk.write(0); |
|
} |
|
|
|
private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException { |
|
writeInfoStringChunk(writer, "INAM", info.name); |
|
writeInfoStringChunk(writer, "ICRD", info.creationDate); |
|
writeInfoStringChunk(writer, "IENG", info.engineers); |
|
writeInfoStringChunk(writer, "IPRD", info.product); |
|
writeInfoStringChunk(writer, "ICOP", info.copyright); |
|
writeInfoStringChunk(writer, "ICMT", info.comments); |
|
writeInfoStringChunk(writer, "ISFT", info.tools); |
|
writeInfoStringChunk(writer, "IARL", info.archival_location); |
|
writeInfoStringChunk(writer, "IART", info.artist); |
|
writeInfoStringChunk(writer, "ICMS", info.commissioned); |
|
writeInfoStringChunk(writer, "IGNR", info.genre); |
|
writeInfoStringChunk(writer, "IKEY", info.keywords); |
|
writeInfoStringChunk(writer, "IMED", info.medium); |
|
writeInfoStringChunk(writer, "ISBJ", info.subject); |
|
writeInfoStringChunk(writer, "ISRC", info.source); |
|
writeInfoStringChunk(writer, "ISRF", info.source_form); |
|
writeInfoStringChunk(writer, "ITCH", info.technician); |
|
} |
|
|
|
public DLSInfo getInfo() { |
|
return info; |
|
} |
|
|
|
public String getName() { |
|
return info.name; |
|
} |
|
|
|
public String getVersion() { |
|
return major + "." + minor; |
|
} |
|
|
|
public String getVendor() { |
|
return info.engineers; |
|
} |
|
|
|
public String getDescription() { |
|
return info.comments; |
|
} |
|
|
|
public void setName(String s) { |
|
info.name = s; |
|
} |
|
|
|
public void setVendor(String s) { |
|
info.engineers = s; |
|
} |
|
|
|
public void setDescription(String s) { |
|
info.comments = s; |
|
} |
|
|
|
public SoundbankResource[] getResources() { |
|
SoundbankResource[] resources = new SoundbankResource[samples.size()]; |
|
int j = 0; |
|
for (int i = 0; i < samples.size(); i++) |
|
resources[j++] = samples.get(i); |
|
return resources; |
|
} |
|
|
|
public DLSInstrument[] getInstruments() { |
|
DLSInstrument[] inslist_array = |
|
instruments.toArray(new DLSInstrument[instruments.size()]); |
|
Arrays.sort(inslist_array, new ModelInstrumentComparator()); |
|
return inslist_array; |
|
} |
|
|
|
public DLSSample[] getSamples() { |
|
return samples.toArray(new DLSSample[samples.size()]); |
|
} |
|
|
|
public Instrument getInstrument(Patch patch) { |
|
int program = patch.getProgram(); |
|
int bank = patch.getBank(); |
|
boolean percussion = false; |
|
if (patch instanceof ModelPatch) |
|
percussion = ((ModelPatch) patch).isPercussion(); |
|
for (Instrument instrument : instruments) { |
|
Patch patch2 = instrument.getPatch(); |
|
int program2 = patch2.getProgram(); |
|
int bank2 = patch2.getBank(); |
|
if (program == program2 && bank == bank2) { |
|
boolean percussion2 = false; |
|
if (patch2 instanceof ModelPatch) |
|
percussion2 = ((ModelPatch) patch2).isPercussion(); |
|
if (percussion == percussion2) |
|
return instrument; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
public void addResource(SoundbankResource resource) { |
|
if (resource instanceof DLSInstrument) |
|
instruments.add((DLSInstrument) resource); |
|
if (resource instanceof DLSSample) |
|
samples.add((DLSSample) resource); |
|
} |
|
|
|
public void removeResource(SoundbankResource resource) { |
|
if (resource instanceof DLSInstrument) |
|
instruments.remove((DLSInstrument) resource); |
|
if (resource instanceof DLSSample) |
|
samples.remove((DLSSample) resource); |
|
} |
|
|
|
public void addInstrument(DLSInstrument resource) { |
|
instruments.add(resource); |
|
} |
|
|
|
public void removeInstrument(DLSInstrument resource) { |
|
instruments.remove(resource); |
|
} |
|
|
|
public long getMajor() { |
|
return major; |
|
} |
|
|
|
public void setMajor(long major) { |
|
this.major = major; |
|
} |
|
|
|
public long getMinor() { |
|
return minor; |
|
} |
|
|
|
public void setMinor(long minor) { |
|
this.minor = minor; |
|
} |
|
} |