/* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */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; /** * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams). * * @author Karl Helgason */public 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() { } public 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; } } /** X = X & Y */ private static final int DLS_CDL_AND = 0x0001; /** X = X | Y */ private static final int DLS_CDL_OR = 0x0002; /** X = X ^ Y */ private static final int DLS_CDL_XOR = 0x0003; /** X = X + Y */ private static final int DLS_CDL_ADD = 0x0004; /** X = X - Y */ private static final int DLS_CDL_SUBTRACT = 0x0005; /** X = X * Y */ private static final int DLS_CDL_MULTIPLY = 0x0006; /** X = X / Y */ private static final int DLS_CDL_DIVIDE = 0x0007; /** X = X && Y */ private static final int DLS_CDL_LOGICAL_AND = 0x0008; /** X = X || Y */ private static final int DLS_CDL_LOGICAL_OR = 0x0009; /** X = (X < Y) */ private static final int DLS_CDL_LT = 0x000A; /** X = (X <= Y) */ private static final int DLS_CDL_LE = 0x000B; /** X = (X > Y) */ private static final int DLS_CDL_GT = 0x000C; /** X = (X >= Y) */ private static final int DLS_CDL_GE = 0x000D; /** X = (X == Y) */ private static final int DLS_CDL_EQ = 0x000E; /** X = !X */ private static final int DLS_CDL_NOT = 0x000F; /** 32-bit constant */ private static final int DLS_CDL_CONST = 0x0010; /** 32-bit value returned from query */ private static final int DLS_CDL_QUERY = 0x0011; /** 32-bit value returned from query */ 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 DLSInfo info = new DLSInfo(); private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>(); private 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 // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2 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")) { // support for DLS level 2 regions 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")) { // support for DLS level 2 ARTLines 1–500 of 1287. Load more
/* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ 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; /** * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams). * * @author Karl Helgason */ public 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() { } public 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; } } /** X = X & Y */ private static final int DLS_CDL_AND = 0x0001; /** X = X | Y */ private static final int DLS_CDL_OR = 0x0002; /** X = X ^ Y */ private static final int DLS_CDL_XOR = 0x0003; /** X = X + Y */ private static final int DLS_CDL_ADD = 0x0004; /** X = X - Y */ private static final int DLS_CDL_SUBTRACT = 0x0005; /** X = X * Y */ private static final int DLS_CDL_MULTIPLY = 0x0006; /** X = X / Y */ private static final int DLS_CDL_DIVIDE = 0x0007; /** X = X && Y */ private static final int DLS_CDL_LOGICAL_AND = 0x0008; /** X = X || Y */ private static final int DLS_CDL_LOGICAL_OR = 0x0009; /** X = (X < Y) */ private static final int DLS_CDL_LT = 0x000A; /** X = (X <= Y) */ private static final int DLS_CDL_LE = 0x000B; /** X = (X > Y) */ private static final int DLS_CDL_GT = 0x000C; /** X = (X >= Y) */ private static final int DLS_CDL_GE = 0x000D; /** X = (X == Y) */ private static final int DLS_CDL_EQ = 0x000E; /** X = !X */ private static final int DLS_CDL_NOT = 0x000F; /** 32-bit constant */ private static final int DLS_CDL_CONST = 0x0010; /** 32-bit value returned from query */ private static final int DLS_CDL_QUERY = 0x0011; /** 32-bit value returned from query */ 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 DLSInfo info = new DLSInfo(); private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>(); private 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 // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2 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")) { // support for DLS level 2 regions 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")) { // support for DLS level 2 ART