Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package com.sun.media.sound;
   26   
   27   import java.io.File;
   28   import java.io.FileInputStream;
   29   import java.io.IOException;
   30   import java.io.InputStream;
   31   import java.io.OutputStream;
   32   import java.net.URL;
   33   import java.util.ArrayList;
   34   import java.util.Arrays;
   35   import java.util.HashMap;
   36   import java.util.List;
   37   import java.util.Map;
   38   import java.util.Stack;
   39   
   40   import javax.sound.midi.Instrument;
   41   import javax.sound.midi.Patch;
   42   import javax.sound.midi.Soundbank;
   43   import javax.sound.midi.SoundbankResource;
   44   import javax.sound.sampled.AudioFormat;
   45   import javax.sound.sampled.AudioInputStream;
   46   import javax.sound.sampled.AudioSystem;
   47   import javax.sound.sampled.AudioFormat.Encoding;
   48   
   49   /**
   50    * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams).
   51    *
   52    * @author Karl Helgason
   53    */
   54   public class DLSSoundbank implements Soundbank {
   55   
   56       static private class DLSID {
   57           long i1;
   58           int s1;
   59           int s2;
   60           int x1;
   61           int x2;
   62           int x3;
   63           int x4;
   64           int x5;
   65           int x6;
   66           int x7;
   67           int x8;
   68   
   69           private DLSID() {
   70           }
   71   
   72           public DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
   73                   int x5, int x6, int x7, int x8) {
   74               this.i1 = i1;
   75               this.s1 = s1;
   76               this.s2 = s2;
   77               this.x1 = x1;
   78               this.x2 = x2;
   79               this.x3 = x3;
   80               this.x4 = x4;
   81               this.x5 = x5;
   82               this.x6 = x6;
   83               this.x7 = x7;
   84               this.x8 = x8;
   85           }
   86   
   87           public static DLSID read(RIFFReader riff) throws IOException {
   88               DLSID d = new DLSID();
   89               d.i1 = riff.readUnsignedInt();
   90               d.s1 = riff.readUnsignedShort();
   91               d.s2 = riff.readUnsignedShort();
   92               d.x1 = riff.readUnsignedByte();
   93               d.x2 = riff.readUnsignedByte();
   94               d.x3 = riff.readUnsignedByte();
   95               d.x4 = riff.readUnsignedByte();
   96               d.x5 = riff.readUnsignedByte();
   97               d.x6 = riff.readUnsignedByte();
   98               d.x7 = riff.readUnsignedByte();
   99               d.x8 = riff.readUnsignedByte();
  100               return d;
  101           }
  102   
  103           public int hashCode() {
  104               return (int)i1;
  105           }
  106   
  107           public boolean equals(Object obj) {
  108               if (!(obj instanceof DLSID)) {
  109                   return false;
  110               }
  111               DLSID t = (DLSID) obj;
  112               return i1 == t.i1 && s1 == t.s1 && s2 == t.s2
  113                   && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4
  114                   && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8;
  115           }
  116       }
  117   
  118       /** X = X & Y */
  119       private static final int DLS_CDL_AND = 0x0001;
  120       /** X = X | Y */
  121       private static final int DLS_CDL_OR = 0x0002;
  122       /** X = X ^ Y */
  123       private static final int DLS_CDL_XOR = 0x0003;
  124       /** X = X + Y */
  125       private static final int DLS_CDL_ADD = 0x0004;
  126       /** X = X - Y */
  127       private static final int DLS_CDL_SUBTRACT = 0x0005;
  128       /** X = X * Y */
  129       private static final int DLS_CDL_MULTIPLY = 0x0006;
  130       /** X = X / Y */
  131       private static final int DLS_CDL_DIVIDE = 0x0007;
  132       /** X = X && Y */
  133       private static final int DLS_CDL_LOGICAL_AND = 0x0008;
  134       /** X = X || Y */
  135       private static final int DLS_CDL_LOGICAL_OR = 0x0009;
  136       /** X = (X < Y) */
  137       private static final int DLS_CDL_LT = 0x000A;
  138       /** X = (X <= Y) */
  139       private static final int DLS_CDL_LE = 0x000B;
  140       /** X = (X > Y) */
  141       private static final int DLS_CDL_GT = 0x000C;
  142       /** X = (X >= Y) */
  143       private static final int DLS_CDL_GE = 0x000D;
  144       /** X = (X == Y) */
  145       private static final int DLS_CDL_EQ = 0x000E;
  146       /** X = !X */
  147       private static final int DLS_CDL_NOT = 0x000F;
  148       /** 32-bit constant */
  149       private static final int DLS_CDL_CONST = 0x0010;
  150       /** 32-bit value returned from query */
  151       private static final int DLS_CDL_QUERY = 0x0011;
  152       /** 32-bit value returned from query */
  153       private static final int DLS_CDL_QUERYSUPPORTED = 0x0012;
  154   
  155       private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24,
  156               0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  157       private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25,
  158               0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  159       private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26,
  160               0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  161       private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27,
  162               0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  163       private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5,
  164               0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
  165       private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28,
  166               0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
  167       private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181,
  168               0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
  169       private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182,
  170               0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
  171       private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713,
  172               0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
  173   
  174       private long major = -1;
  175       private long minor = -1;
  176   
  177       private DLSInfo info = new DLSInfo();
  178   
  179       private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>();
  180       private List<DLSSample> samples = new ArrayList<DLSSample>();
  181   
  182       private boolean largeFormat = false;
  183       private File sampleFile;
  184   
  185       public DLSSoundbank() {
  186       }
  187   
  188       public DLSSoundbank(URL url) throws IOException {
  189           InputStream is = url.openStream();
  190           try {
  191               readSoundbank(is);
  192           } finally {
  193               is.close();
  194           }
  195       }
  196   
  197       public DLSSoundbank(File file) throws IOException {
  198           largeFormat = true;
  199           sampleFile = file;
  200           InputStream is = new FileInputStream(file);
  201           try {
  202               readSoundbank(is);
  203           } finally {
  204               is.close();
  205           }
  206       }
  207   
  208       public DLSSoundbank(InputStream inputstream) throws IOException {
  209           readSoundbank(inputstream);
  210       }
  211   
  212       private void readSoundbank(InputStream inputstream) throws IOException {
  213           RIFFReader riff = new RIFFReader(inputstream);
  214           if (!riff.getFormat().equals("RIFF")) {
  215               throw new RIFFInvalidFormatException(
  216                       "Input stream is not a valid RIFF stream!");
  217           }
  218           if (!riff.getType().equals("DLS ")) {
  219               throw new RIFFInvalidFormatException(
  220                       "Input stream is not a valid DLS soundbank!");
  221           }
  222           while (riff.hasNextChunk()) {
  223               RIFFReader chunk = riff.nextChunk();
  224               if (chunk.getFormat().equals("LIST")) {
  225                   if (chunk.getType().equals("INFO"))
  226                       readInfoChunk(chunk);
  227                   if (chunk.getType().equals("lins"))
  228                       readLinsChunk(chunk);
  229                   if (chunk.getType().equals("wvpl"))
  230                       readWvplChunk(chunk);
  231               } else {
  232                   if (chunk.getFormat().equals("cdl ")) {
  233                       if (!readCdlChunk(chunk)) {
  234                           throw new RIFFInvalidFormatException(
  235                                   "DLS file isn't supported!");
  236                       }
  237                   }
  238                   if (chunk.getFormat().equals("colh")) {
  239                       // skipped because we will load the entire bank into memory
  240                       // long instrumentcount = chunk.readUnsignedInt();
  241                       // System.out.println("instrumentcount = "+ instrumentcount);
  242                   }
  243                   if (chunk.getFormat().equals("ptbl")) {
  244                       // Pool Table Chunk
  245                       // skipped because we will load the entire bank into memory
  246                   }
  247                   if (chunk.getFormat().equals("vers")) {
  248                       major = chunk.readUnsignedInt();
  249                       minor = chunk.readUnsignedInt();
  250                   }
  251               }
  252           }
  253   
  254           for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) {
  255               entry.getKey().sample = samples.get((int)entry.getValue().longValue());
  256           }
  257   
  258           temp_rgnassign = null;
  259       }
  260   
  261       private boolean cdlIsQuerySupported(DLSID uuid) {
  262           return uuid.equals(DLSID_GMInHardware)
  263               || uuid.equals(DLSID_GSInHardware)
  264               || uuid.equals(DLSID_XGInHardware)
  265               || uuid.equals(DLSID_SupportsDLS1)
  266               || uuid.equals(DLSID_SupportsDLS2)
  267               || uuid.equals(DLSID_SampleMemorySize)
  268               || uuid.equals(DLSID_ManufacturersID)
  269               || uuid.equals(DLSID_ProductID)
  270               || uuid.equals(DLSID_SamplePlaybackRate);
  271       }
  272   
  273       private long cdlQuery(DLSID uuid) {
  274           if (uuid.equals(DLSID_GMInHardware))
  275               return 1;
  276           if (uuid.equals(DLSID_GSInHardware))
  277               return 0;
  278           if (uuid.equals(DLSID_XGInHardware))
  279               return 0;
  280           if (uuid.equals(DLSID_SupportsDLS1))
  281               return 1;
  282           if (uuid.equals(DLSID_SupportsDLS2))
  283               return 1;
  284           if (uuid.equals(DLSID_SampleMemorySize))
  285               return Runtime.getRuntime().totalMemory();
  286           if (uuid.equals(DLSID_ManufacturersID))
  287               return 0;
  288           if (uuid.equals(DLSID_ProductID))
  289               return 0;
  290           if (uuid.equals(DLSID_SamplePlaybackRate))
  291               return 44100;
  292           return 0;
  293       }
  294   
  295   
  296       // Reading cdl-ck Chunk
  297       // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2
  298       private boolean readCdlChunk(RIFFReader riff) throws IOException {
  299   
  300           DLSID uuid;
  301           long x;
  302           long y;
  303           Stack<Long> stack = new Stack<Long>();
  304   
  305           while (riff.available() != 0) {
  306               int opcode = riff.readUnsignedShort();
  307               switch (opcode) {
  308               case DLS_CDL_AND:
  309                   x = stack.pop();
  310                   y = stack.pop();
  311                   stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
  312                   break;
  313               case DLS_CDL_OR:
  314                   x = stack.pop();
  315                   y = stack.pop();
  316                   stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
  317                   break;
  318               case DLS_CDL_XOR:
  319                   x = stack.pop();
  320                   y = stack.pop();
  321                   stack.push(Long.valueOf(((x != 0) ^ (y != 0)) ? 1 : 0));
  322                   break;
  323               case DLS_CDL_ADD:
  324                   x = stack.pop();
  325                   y = stack.pop();
  326                   stack.push(Long.valueOf(x + y));
  327                   break;
  328               case DLS_CDL_SUBTRACT:
  329                   x = stack.pop();
  330                   y = stack.pop();
  331                   stack.push(Long.valueOf(x - y));
  332                   break;
  333               case DLS_CDL_MULTIPLY:
  334                   x = stack.pop();
  335                   y = stack.pop();
  336                   stack.push(Long.valueOf(x * y));
  337                   break;
  338               case DLS_CDL_DIVIDE:
  339                   x = stack.pop();
  340                   y = stack.pop();
  341                   stack.push(Long.valueOf(x / y));
  342                   break;
  343               case DLS_CDL_LOGICAL_AND:
  344                   x = stack.pop();
  345                   y = stack.pop();
  346                   stack.push(Long.valueOf(((x != 0) && (y != 0)) ? 1 : 0));
  347                   break;
  348               case DLS_CDL_LOGICAL_OR:
  349                   x = stack.pop();
  350                   y = stack.pop();
  351                   stack.push(Long.valueOf(((x != 0) || (y != 0)) ? 1 : 0));
  352                   break;
  353               case DLS_CDL_LT:
  354                   x = stack.pop();
  355                   y = stack.pop();
  356                   stack.push(Long.valueOf((x < y) ? 1 : 0));
  357                   break;
  358               case DLS_CDL_LE:
  359                   x = stack.pop();
  360                   y = stack.pop();
  361                   stack.push(Long.valueOf((x <= y) ? 1 : 0));
  362                   break;
  363               case DLS_CDL_GT:
  364                   x = stack.pop();
  365                   y = stack.pop();
  366                   stack.push(Long.valueOf((x > y) ? 1 : 0));
  367                   break;
  368               case DLS_CDL_GE:
  369                   x = stack.pop();
  370                   y = stack.pop();
  371                   stack.push(Long.valueOf((x >= y) ? 1 : 0));
  372                   break;
  373               case DLS_CDL_EQ:
  374                   x = stack.pop();
  375                   y = stack.pop();
  376                   stack.push(Long.valueOf((x == y) ? 1 : 0));
  377                   break;
  378               case DLS_CDL_NOT:
  379                   x = stack.pop();
  380                   y = stack.pop();
  381                   stack.push(Long.valueOf((x == 0) ? 1 : 0));
  382                   break;
  383               case DLS_CDL_CONST:
  384                   stack.push(Long.valueOf(riff.readUnsignedInt()));
  385                   break;
  386               case DLS_CDL_QUERY:
  387                   uuid = DLSID.read(riff);
  388                   stack.push(cdlQuery(uuid));
  389                   break;
  390               case DLS_CDL_QUERYSUPPORTED:
  391                   uuid = DLSID.read(riff);
  392                   stack.push(Long.valueOf(cdlIsQuerySupported(uuid) ? 1 : 0));
  393                   break;
  394               default:
  395                   break;
  396               }
  397           }
  398           if (stack.isEmpty())
  399               return false;
  400   
  401           return stack.pop() == 1;
  402       }
  403   
  404       private void readInfoChunk(RIFFReader riff) throws IOException {
  405           info.name = null;
  406           while (riff.hasNextChunk()) {
  407               RIFFReader chunk = riff.nextChunk();
  408               String format = chunk.getFormat();
  409               if (format.equals("INAM"))
  410                   info.name = chunk.readString(chunk.available());
  411               else if (format.equals("ICRD"))
  412                   info.creationDate = chunk.readString(chunk.available());
  413               else if (format.equals("IENG"))
  414                   info.engineers = chunk.readString(chunk.available());
  415               else if (format.equals("IPRD"))
  416                   info.product = chunk.readString(chunk.available());
  417               else if (format.equals("ICOP"))
  418                   info.copyright = chunk.readString(chunk.available());
  419               else if (format.equals("ICMT"))
  420                   info.comments = chunk.readString(chunk.available());
  421               else if (format.equals("ISFT"))
  422                   info.tools = chunk.readString(chunk.available());
  423               else if (format.equals("IARL"))
  424                   info.archival_location = chunk.readString(chunk.available());
  425               else if (format.equals("IART"))
  426                   info.artist = chunk.readString(chunk.available());
  427               else if (format.equals("ICMS"))
  428                   info.commissioned = chunk.readString(chunk.available());
  429               else if (format.equals("IGNR"))
  430                   info.genre = chunk.readString(chunk.available());
  431               else if (format.equals("IKEY"))
  432                   info.keywords = chunk.readString(chunk.available());
  433               else if (format.equals("IMED"))
  434                   info.medium = chunk.readString(chunk.available());
  435               else if (format.equals("ISBJ"))
  436                   info.subject = chunk.readString(chunk.available());
  437               else if (format.equals("ISRC"))
  438                   info.source = chunk.readString(chunk.available());
  439               else if (format.equals("ISRF"))
  440                   info.source_form = chunk.readString(chunk.available());
  441               else if (format.equals("ITCH"))
  442                   info.technician = chunk.readString(chunk.available());
  443           }
  444       }
  445   
  446       private void readLinsChunk(RIFFReader riff) throws IOException {
  447           while (riff.hasNextChunk()) {
  448               RIFFReader chunk = riff.nextChunk();
  449               if (chunk.getFormat().equals("LIST")) {
  450                   if (chunk.getType().equals("ins "))
  451                       readInsChunk(chunk);
  452               }
  453           }
  454       }
  455   
  456       private void readInsChunk(RIFFReader riff) throws IOException {
  457           DLSInstrument instrument = new DLSInstrument(this);
  458   
  459           while (riff.hasNextChunk()) {
  460               RIFFReader chunk = riff.nextChunk();
  461               String format = chunk.getFormat();
  462               if (format.equals("LIST")) {
  463                   if (chunk.getType().equals("INFO")) {
  464                       readInsInfoChunk(instrument, chunk);
  465                   }
  466                   if (chunk.getType().equals("lrgn")) {
  467                       while (chunk.hasNextChunk()) {
  468                           RIFFReader subchunk = chunk.nextChunk();
  469                           if (subchunk.getFormat().equals("LIST")) {
  470                               if (subchunk.getType().equals("rgn ")) {
  471                                   DLSRegion split = new DLSRegion();
  472                                   if (readRgnChunk(split, subchunk))
  473                                       instrument.getRegions().add(split);
  474                               }
  475                               if (subchunk.getType().equals("rgn2")) {
  476                                   // support for DLS level 2 regions
  477                                   DLSRegion split = new DLSRegion();
  478                                   if (readRgnChunk(split, subchunk))
  479                                       instrument.getRegions().add(split);
  480                               }
  481                           }
  482                       }
  483                   }
  484                   if (chunk.getType().equals("lart")) {
  485                       List<DLSModulator> modlist = new ArrayList<DLSModulator>();
  486                       while (chunk.hasNextChunk()) {
  487                           RIFFReader subchunk = chunk.nextChunk();
  488                           if (chunk.getFormat().equals("cdl ")) {
  489                               if (!readCdlChunk(chunk)) {
  490                                   modlist.clear();
  491                                   break;
  492                               }
  493                           }
  494                           if (subchunk.getFormat().equals("art1"))
  495                               readArt1Chunk(modlist, subchunk);
  496                       }
  497                       instrument.getModulators().addAll(modlist);
  498                   }
  499                   if (chunk.getType().equals("lar2")) {
  500                       // support for DLS level 2 ART
  501                       List<DLSModulator> modlist = new ArrayList<DLSModulator>();
  502                       while (chunk.hasNextChunk()) {
  503                           RIFFReader subchunk = chunk.nextChunk();
  504                           if (chunk.getFormat().equals("cdl ")) {
  505                               if (!readCdlChunk(chunk)) {
  506                                   modlist.clear();
  507                                   break;
  508                               }
  509                           }
  510                           if (subchunk.getFormat().equals("art2"))
  511                               readArt2Chunk(modlist, subchunk);
  512                       }
  513                       instrument.getModulators().addAll(modlist);
  514                   }
  515               } else {
  516                   if (format.equals("dlid")) {
  517                       instrument.guid = new byte[16];
  518                       chunk.readFully(instrument.guid);
  519                   }
  520                   if (format.equals("insh")) {
  521                       chunk.readUnsignedInt(); // Read Region Count - ignored
  522   
  523                       int bank = chunk.read();             // LSB
  524                       bank += (chunk.read() & 127) << 7;   // MSB
  525                       chunk.read(); // Read Reserved byte
  526                       int drumins = chunk.read();          // Drum Instrument
  527   
  528                       int id = chunk.read() & 127; // Read only first 7 bits
  529                       chunk.read(); // Read Reserved byte
  530                       chunk.read(); // Read Reserved byte
  531                       chunk.read(); // Read Reserved byte
  532   
  533                       instrument.bank = bank;
  534                       instrument.preset = (int) id;
  535                       instrument.druminstrument = (drumins & 128) > 0;
  536                       //System.out.println("bank="+bank+" drumkit="+drumkit
  537                       //        +" id="+id);
  538                   }
  539   
  540               }
  541           }
  542           instruments.add(instrument);
  543       }
  544   
  545       private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff)
  546               throws IOException {
  547           long size = riff.readUnsignedInt();
  548           long count = riff.readUnsignedInt();
  549   
  550           if (size - 8 != 0)
  551               riff.skipBytes(size - 8);
  552   
  553           for (int i = 0; i < count; i++) {
  554               DLSModulator modulator = new DLSModulator();
  555               modulator.version = 1;
  556               modulator.source = riff.readUnsignedShort();
  557               modulator.control = riff.readUnsignedShort();
  558               modulator.destination = riff.readUnsignedShort();
  559               modulator.transform = riff.readUnsignedShort();
  560               modulator.scale = riff.readInt();
  561               modulators.add(modulator);
  562           }
  563       }
  564   
  565       private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff)
  566               throws IOException {
  567           long size = riff.readUnsignedInt();
  568           long count = riff.readUnsignedInt();
  569   
  570           if (size - 8 != 0)
  571               riff.skipBytes(size - 8);
  572   
  573           for (int i = 0; i < count; i++) {
  574               DLSModulator modulator = new DLSModulator();
  575               modulator.version = 2;
  576               modulator.source = riff.readUnsignedShort();
  577               modulator.control = riff.readUnsignedShort();
  578               modulator.destination = riff.readUnsignedShort();
  579               modulator.transform = riff.readUnsignedShort();
  580               modulator.scale = riff.readInt();
  581               modulators.add(modulator);
  582           }
  583       }
  584   
  585       private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>();
  586   
  587       private boolean readRgnChunk(DLSRegion split, RIFFReader riff)
  588               throws IOException {
  589           while (riff.hasNextChunk()) {
  590               RIFFReader chunk = riff.nextChunk();
  591               String format = chunk.getFormat();
  592               if (format.equals("LIST")) {
  593                   if (chunk.getType().equals("lart")) {
  594                       List<DLSModulator> modlist = new ArrayList<DLSModulator>();
  595                       while (chunk.hasNextChunk()) {
  596                           RIFFReader subchunk = chunk.nextChunk();
  597                           if (chunk.getFormat().equals("cdl ")) {
  598                               if (!readCdlChunk(chunk)) {
  599                                   modlist.clear();
  600                                   break;
  601                               }
  602                           }
  603                           if (subchunk.getFormat().equals("art1"))
  604                               readArt1Chunk(modlist, subchunk);
  605                       }
  606                       split.getModulators().addAll(modlist);
  607                   }
  608                   if (chunk.getType().equals("lar2")) {
  609                       // support for DLS level 2 ART
  610                       List<DLSModulator> modlist = new ArrayList<DLSModulator>();
  611                       while (chunk.hasNextChunk()) {
  612                           RIFFReader subchunk = chunk.nextChunk();
  613                           if (chunk.getFormat().equals("cdl ")) {
  614                               if (!readCdlChunk(chunk)) {
  615                                   modlist.clear();
  616                                   break;
  617                               }
  618                           }
  619                           if (subchunk.getFormat().equals("art2"))
  620                               readArt2Chunk(modlist, subchunk);
  621                       }
  622                       split.getModulators().addAll(modlist);
  623                   }
  624               } else {
  625   
  626                   if (format.equals("cdl ")) {
  627                       if (!readCdlChunk(chunk))
  628                           return false;
  629                   }
  630                   if (format.equals("rgnh")) {
  631                       split.keyfrom = chunk.readUnsignedShort();
  632                       split.keyto = chunk.readUnsignedShort();
  633                       split.velfrom = chunk.readUnsignedShort();
  634                       split.velto = chunk.readUnsignedShort();
  635                       split.options = chunk.readUnsignedShort();
  636                       split.exclusiveClass = chunk.readUnsignedShort();
  637                   }
  638                   if (format.equals("wlnk")) {
  639                       split.fusoptions = chunk.readUnsignedShort();
  640                       split.phasegroup = chunk.readUnsignedShort();
  641                       split.channel = chunk.readUnsignedInt();
  642                       long sampleid = chunk.readUnsignedInt();
  643                       temp_rgnassign.put(split, sampleid);
  644                   }
  645                   if (format.equals("wsmp")) {
  646                       split.sampleoptions = new DLSSampleOptions();
  647                       readWsmpChunk(split.sampleoptions, chunk);
  648                   }
  649               }
  650           }
  651           return true;
  652       }
  653   
  654       private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff)
  655               throws IOException {
  656           long size = riff.readUnsignedInt();
  657           sampleOptions.unitynote = riff.readUnsignedShort();
  658           sampleOptions.finetune = riff.readShort();
  659           sampleOptions.attenuation = riff.readInt();
  660           sampleOptions.options = riff.readUnsignedInt();
  661           long loops = riff.readInt();
  662   
  663           if (size > 20)
  664               riff.skipBytes(size - 20);
  665   
  666           for (int i = 0; i < loops; i++) {
  667               DLSSampleLoop loop = new DLSSampleLoop();
  668               long size2 = riff.readUnsignedInt();
  669               loop.type = riff.readUnsignedInt();
  670               loop.start = riff.readUnsignedInt();
  671               loop.length = riff.readUnsignedInt();
  672               sampleOptions.loops.add(loop);
  673               if (size2 > 16)
  674                   riff.skipBytes(size2 - 16);
  675           }
  676       }
  677   
  678       private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff)
  679               throws IOException {
  680           dlsinstrument.info.name = null;
  681           while (riff.hasNextChunk()) {
  682               RIFFReader chunk = riff.nextChunk();
  683               String format = chunk.getFormat();
  684               if (format.equals("INAM")) {
  685                   dlsinstrument.info.name = chunk.readString(chunk.available());
  686               } else if (format.equals("ICRD")) {
  687                   dlsinstrument.info.creationDate =
  688                           chunk.readString(chunk.available());
  689               } else if (format.equals("IENG")) {
  690                   dlsinstrument.info.engineers =
  691                           chunk.readString(chunk.available());
  692               } else if (format.equals("IPRD")) {
  693                   dlsinstrument.info.product = chunk.readString(chunk.available());
  694               } else if (format.equals("ICOP")) {
  695                   dlsinstrument.info.copyright =
  696                           chunk.readString(chunk.available());
  697               } else if (format.equals("ICMT")) {
  698                   dlsinstrument.info.comments =
  699                           chunk.readString(chunk.available());
  700               } else if (format.equals("ISFT")) {
  701                   dlsinstrument.info.tools = chunk.readString(chunk.available());
  702               } else if (format.equals("IARL")) {
  703                   dlsinstrument.info.archival_location =
  704                           chunk.readString(chunk.available());
  705               } else if (format.equals("IART")) {
  706                   dlsinstrument.info.artist = chunk.readString(chunk.available());
  707               } else if (format.equals("ICMS")) {
  708                   dlsinstrument.info.commissioned =
  709                           chunk.readString(chunk.available());
  710               } else if (format.equals("IGNR")) {
  711                   dlsinstrument.info.genre = chunk.readString(chunk.available());
  712               } else if (format.equals("IKEY")) {
  713                   dlsinstrument.info.keywords =
  714                           chunk.readString(chunk.available());
  715               } else if (format.equals("IMED")) {
  716                   dlsinstrument.info.medium = chunk.readString(chunk.available());
  717               } else if (format.equals("ISBJ")) {
  718                   dlsinstrument.info.subject = chunk.readString(chunk.available());
  719               } else if (format.equals("ISRC")) {
  720                   dlsinstrument.info.source = chunk.readString(chunk.available());
  721               } else if (format.equals("ISRF")) {
  722                   dlsinstrument.info.source_form =
  723                           chunk.readString(chunk.available());
  724               } else if (format.equals("ITCH")) {
  725                   dlsinstrument.info.technician =
  726                           chunk.readString(chunk.available());
  727               }
  728           }
  729       }
  730   
  731       private void readWvplChunk(RIFFReader riff) throws IOException {
  732           while (riff.hasNextChunk()) {
  733               RIFFReader chunk = riff.nextChunk();
  734               if (chunk.getFormat().equals("LIST")) {
  735                   if (chunk.getType().equals("wave"))
  736                       readWaveChunk(chunk);
  737               }
  738           }
  739       }
  740   
  741       private void readWaveChunk(RIFFReader riff) throws IOException {
  742           DLSSample sample = new DLSSample(this);
  743   
  744           while (riff.hasNextChunk()) {
  745               RIFFReader chunk = riff.nextChunk();
  746               String format = chunk.getFormat();
  747               if (format.equals("LIST")) {
  748                   if (chunk.getType().equals("INFO")) {
  749                       readWaveInfoChunk(sample, chunk);
  750                   }
  751               } else {
  752                   if (format.equals("dlid")) {
  753                       sample.guid = new byte[16];
  754                       chunk.readFully(sample.guid);
  755                   }
  756   
  757                   if (format.equals("fmt ")) {
  758                       int sampleformat = chunk.readUnsignedShort();
  759                       if (sampleformat != 1 && sampleformat != 3) {
  760                           throw new RIFFInvalidDataException(
  761                                   "Only PCM samples are supported!");
  762                       }
  763                       int channels = chunk.readUnsignedShort();
  764                       long samplerate = chunk.readUnsignedInt();
  765                       // bytes per sec
  766                       /* long framerate = */ chunk.readUnsignedInt();
  767                       // block align, framesize
  768                       int framesize = chunk.readUnsignedShort();
  769                       int bits = chunk.readUnsignedShort();
  770                       AudioFormat audioformat = null;
  771                       if (sampleformat == 1) {
  772                           if (bits == 8) {
  773                               audioformat = new AudioFormat(
  774                                       Encoding.PCM_UNSIGNED, samplerate, bits,
  775                                       channels, framesize, samplerate, false);
  776                           } else {
  777                               audioformat = new AudioFormat(
  778                                       Encoding.PCM_SIGNED, samplerate, bits,
  779                                       channels, framesize, samplerate, false);
  780                           }
  781                       }
  782                       if (sampleformat == 3) {
  783                           audioformat = new AudioFormat(
  784                                   Encoding.PCM_FLOAT, samplerate, bits,
  785                                   channels, framesize, samplerate, false);
  786                       }
  787   
  788                       sample.format = audioformat;
  789                   }
  790   
  791                   if (format.equals("data")) {
  792                       if (largeFormat) {
  793                           sample.setData(new ModelByteBuffer(sampleFile,
  794                                   chunk.getFilePointer(), chunk.available()));
  795                       } else {
  796                           byte[] buffer = new byte[chunk.available()];
  797                           //  chunk.read(buffer);
  798                           sample.setData(buffer);
  799   
  800                           int read = 0;
  801                           int avail = chunk.available();
  802                           while (read != avail) {
  803                               if (avail - read > 65536) {
  804                                   chunk.readFully(buffer, read, 65536);
  805                                   read += 65536;
  806                               } else {
  807                                   chunk.readFully(buffer, read, avail - read);
  808                                   read = avail;
  809                               }
  810                           }
  811                       }
  812                   }
  813   
  814                   if (format.equals("wsmp")) {
  815                       sample.sampleoptions = new DLSSampleOptions();
  816                       readWsmpChunk(sample.sampleoptions, chunk);
  817                   }
  818               }
  819           }
  820   
  821           samples.add(sample);
  822   
  823       }
  824   
  825       private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff)
  826               throws IOException {
  827           dlssample.info.name = null;
  828           while (riff.hasNextChunk()) {
  829               RIFFReader chunk = riff.nextChunk();
  830               String format = chunk.getFormat();
  831               if (format.equals("INAM")) {
  832                   dlssample.info.name = chunk.readString(chunk.available());
  833               } else if (format.equals("ICRD")) {
  834                   dlssample.info.creationDate =
  835                           chunk.readString(chunk.available());
  836               } else if (format.equals("IENG")) {
  837                   dlssample.info.engineers = chunk.readString(chunk.available());
  838               } else if (format.equals("IPRD")) {
  839                   dlssample.info.product = chunk.readString(chunk.available());
  840               } else if (format.equals("ICOP")) {
  841                   dlssample.info.copyright = chunk.readString(chunk.available());
  842               } else if (format.equals("ICMT")) {
  843                   dlssample.info.comments = chunk.readString(chunk.available());
  844               } else if (format.equals("ISFT")) {
  845                   dlssample.info.tools = chunk.readString(chunk.available());
  846               } else if (format.equals("IARL")) {
  847                   dlssample.info.archival_location =
  848                           chunk.readString(chunk.available());
  849               } else if (format.equals("IART")) {
  850                   dlssample.info.artist = chunk.readString(chunk.available());
  851               } else if (format.equals("ICMS")) {
  852                   dlssample.info.commissioned =
  853                           chunk.readString(chunk.available());
  854               } else if (format.equals("IGNR")) {
  855                   dlssample.info.genre = chunk.readString(chunk.available());
  856               } else if (format.equals("IKEY")) {
  857                   dlssample.info.keywords = chunk.readString(chunk.available());
  858               } else if (format.equals("IMED")) {
  859                   dlssample.info.medium = chunk.readString(chunk.available());
  860               } else if (format.equals("ISBJ")) {
  861                   dlssample.info.subject = chunk.readString(chunk.available());
  862               } else if (format.equals("ISRC")) {
  863                   dlssample.info.source = chunk.readString(chunk.available());
  864               } else if (format.equals("ISRF")) {
  865                   dlssample.info.source_form = chunk.readString(chunk.available());
  866               } else if (format.equals("ITCH")) {
  867                   dlssample.info.technician = chunk.readString(chunk.available());
  868               }
  869           }
  870       }
  871   
  872       public void save(String name) throws IOException {
  873           writeSoundbank(new RIFFWriter(name, "DLS "));
  874       }
  875   
  876       public void save(File file) throws IOException {
  877           writeSoundbank(new RIFFWriter(file, "DLS "));
  878       }
  879   
  880       public void save(OutputStream out) throws IOException {
  881           writeSoundbank(new RIFFWriter(out, "DLS "));
  882       }
  883   
  884       private void writeSoundbank(RIFFWriter writer) throws IOException {
  885           RIFFWriter colh_chunk = writer.writeChunk("colh");
  886           colh_chunk.writeUnsignedInt(instruments.size());
  887   
  888           if (major != -1 && minor != -1) {
  889               RIFFWriter vers_chunk = writer.writeChunk("vers");
  890               vers_chunk.writeUnsignedInt(major);
  891               vers_chunk.writeUnsignedInt(minor);
  892           }
  893   
  894           writeInstruments(writer.writeList("lins"));
  895   
  896           RIFFWriter ptbl = writer.writeChunk("ptbl");
  897           ptbl.writeUnsignedInt(8);
  898           ptbl.writeUnsignedInt(samples.size());
  899           long ptbl_offset = writer.getFilePointer();
  900           for (int i = 0; i < samples.size(); i++)
  901               ptbl.writeUnsignedInt(0);
  902   
  903           RIFFWriter wvpl = writer.writeList("wvpl");
  904           long off = wvpl.getFilePointer();
  905           List<Long> offsettable = new ArrayList<Long>();
  906           for (DLSSample sample : samples) {
  907               offsettable.add(Long.valueOf(wvpl.getFilePointer() - off));
  908               writeSample(wvpl.writeList("wave"), sample);
  909           }
  910   
  911           // small cheat, we are going to rewrite data back in wvpl
  912           long bak = writer.getFilePointer();
  913           writer.seek(ptbl_offset);
  914           writer.setWriteOverride(true);
  915           for (Long offset : offsettable)
  916               writer.writeUnsignedInt(offset.longValue());
  917           writer.setWriteOverride(false);
  918           writer.seek(bak);
  919   
  920           writeInfo(writer.writeList("INFO"), info);
  921   
  922           writer.close();
  923       }
  924   
  925       private void writeSample(RIFFWriter writer, DLSSample sample)
  926               throws IOException {
  927   
  928           AudioFormat audioformat = sample.getFormat();
  929   
  930           Encoding encoding = audioformat.getEncoding();
  931           float sampleRate = audioformat.getSampleRate();
  932           int sampleSizeInBits = audioformat.getSampleSizeInBits();
  933           int channels = audioformat.getChannels();
  934           int frameSize = audioformat.getFrameSize();
  935           float frameRate = audioformat.getFrameRate();
  936           boolean bigEndian = audioformat.isBigEndian();
  937   
  938           boolean convert_needed = false;
  939   
  940           if (audioformat.getSampleSizeInBits() == 8) {
  941               if (!encoding.equals(Encoding.PCM_UNSIGNED)) {
  942                   encoding = Encoding.PCM_UNSIGNED;
  943                   convert_needed = true;
  944               }
  945           } else {
  946               if (!encoding.equals(Encoding.PCM_SIGNED)) {
  947                   encoding = Encoding.PCM_SIGNED;
  948                   convert_needed = true;
  949               }
  950               if (bigEndian) {
  951                   bigEndian = false;
  952                   convert_needed = true;
  953               }
  954           }
  955   
  956           if (convert_needed) {
  957               audioformat = new AudioFormat(encoding, sampleRate,
  958                       sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
  959           }
  960   
  961           // fmt
  962           RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
  963           int sampleformat = 0;
  964           if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED))
  965               sampleformat = 1;
  966           else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
  967               sampleformat = 1;
  968           else if (audioformat.getEncoding().equals(Encoding.PCM_FLOAT))
  969               sampleformat = 3;
  970   
  971           fmt_chunk.writeUnsignedShort(sampleformat);
  972           fmt_chunk.writeUnsignedShort(audioformat.getChannels());
  973           fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate());
  974           long srate = ((long)audioformat.getFrameRate())*audioformat.getFrameSize();
  975           fmt_chunk.writeUnsignedInt(srate);
  976           fmt_chunk.writeUnsignedShort(audioformat.getFrameSize());
  977           fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits());
  978           fmt_chunk.write(0);
  979           fmt_chunk.write(0);
  980   
  981           writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions);
  982   
  983           if (convert_needed) {
  984               RIFFWriter data_chunk = writer.writeChunk("data");
  985               AudioInputStream stream = AudioSystem.getAudioInputStream(
  986                       audioformat, (AudioInputStream)sample.getData());
  987               byte[] buff = new byte[1024];
  988               int ret;
  989               while ((ret = stream.read(buff)) != -1) {
  990                   data_chunk.write(buff, 0, ret);
  991               }
  992           } else {
  993               RIFFWriter data_chunk = writer.writeChunk("data");
  994               ModelByteBuffer databuff = sample.getDataBuffer();
  995               databuff.writeTo(data_chunk);
  996               /*
  997               data_chunk.write(databuff.array(),
  998               databuff.arrayOffset(),
  999               databuff.capacity());
 1000                */
 1001           }
 1002   
 1003           writeInfo(writer.writeList("INFO"), sample.info);
 1004       }
 1005   
 1006       private void writeInstruments(RIFFWriter writer) throws IOException {
 1007           for (DLSInstrument instrument : instruments) {
 1008               writeInstrument(writer.writeList("ins "), instrument);
 1009           }
 1010       }
 1011   
 1012       private void writeInstrument(RIFFWriter writer, DLSInstrument instrument)
 1013               throws IOException {
 1014   
 1015           int art1_count = 0;
 1016           int art2_count = 0;
 1017           for (DLSModulator modulator : instrument.getModulators()) {
 1018               if (modulator.version == 1)
 1019                   art1_count++;
 1020               if (modulator.version == 2)
 1021                   art2_count++;
 1022           }
 1023           for (DLSRegion region : instrument.regions) {
 1024               for (DLSModulator modulator : region.getModulators()) {
 1025                   if (modulator.version == 1)
 1026                       art1_count++;
 1027                   if (modulator.version == 2)
 1028                       art2_count++;
 1029               }
 1030           }
 1031   
 1032           int version = 1;
 1033           if (art2_count > 0)
 1034               version = 2;
 1035   
 1036           RIFFWriter insh_chunk = writer.writeChunk("insh");
 1037           insh_chunk.writeUnsignedInt(instrument.getRegions().size());
 1038           insh_chunk.writeUnsignedInt(instrument.bank +
 1039                   (instrument.druminstrument ? 2147483648L : 0));
 1040           insh_chunk.writeUnsignedInt(instrument.preset);
 1041   
 1042           RIFFWriter lrgn = writer.writeList("lrgn");
 1043           for (DLSRegion region: instrument.regions)
 1044               writeRegion(lrgn, region, version);
 1045   
 1046           writeArticulators(writer, instrument.getModulators());
 1047   
 1048           writeInfo(writer.writeList("INFO"), instrument.info);
 1049   
 1050       }
 1051   
 1052       private void writeArticulators(RIFFWriter writer,
 1053               List<DLSModulator> modulators) throws IOException {
 1054           int art1_count = 0;
 1055           int art2_count = 0;
 1056           for (DLSModulator modulator : modulators) {
 1057               if (modulator.version == 1)
 1058                   art1_count++;
 1059               if (modulator.version == 2)
 1060                   art2_count++;
 1061           }
 1062           if (art1_count > 0) {
 1063               RIFFWriter lar1 = writer.writeList("lart");
 1064               RIFFWriter art1 = lar1.writeChunk("art1");
 1065               art1.writeUnsignedInt(8);
 1066               art1.writeUnsignedInt(art1_count);
 1067               for (DLSModulator modulator : modulators) {
 1068                   if (modulator.version == 1) {
 1069                       art1.writeUnsignedShort(modulator.source);
 1070                       art1.writeUnsignedShort(modulator.control);
 1071                       art1.writeUnsignedShort(modulator.destination);
 1072                       art1.writeUnsignedShort(modulator.transform);
 1073                       art1.writeInt(modulator.scale);
 1074                   }
 1075               }
 1076           }
 1077           if (art2_count > 0) {
 1078               RIFFWriter lar2 = writer.writeList("lar2");
 1079               RIFFWriter art2 = lar2.writeChunk("art2");
 1080               art2.writeUnsignedInt(8);
 1081               art2.writeUnsignedInt(art2_count);
 1082               for (DLSModulator modulator : modulators) {
 1083                   if (modulator.version == 2) {
 1084                       art2.writeUnsignedShort(modulator.source);
 1085                       art2.writeUnsignedShort(modulator.control);
 1086                       art2.writeUnsignedShort(modulator.destination);
 1087                       art2.writeUnsignedShort(modulator.transform);
 1088                       art2.writeInt(modulator.scale);
 1089                   }
 1090               }
 1091           }
 1092       }
 1093   
 1094       private void writeRegion(RIFFWriter writer, DLSRegion region, int version)
 1095               throws IOException {
 1096           RIFFWriter rgns = null;
 1097           if (version == 1)
 1098               rgns = writer.writeList("rgn ");
 1099           if (version == 2)
 1100               rgns = writer.writeList("rgn2");
 1101           if (rgns == null)
 1102               return;
 1103   
 1104           RIFFWriter rgnh = rgns.writeChunk("rgnh");
 1105           rgnh.writeUnsignedShort(region.keyfrom);
 1106           rgnh.writeUnsignedShort(region.keyto);
 1107           rgnh.writeUnsignedShort(region.velfrom);
 1108           rgnh.writeUnsignedShort(region.velto);
 1109           rgnh.writeUnsignedShort(region.options);
 1110           rgnh.writeUnsignedShort(region.exclusiveClass);
 1111   
 1112           if (region.sampleoptions != null)
 1113               writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions);
 1114   
 1115           if (region.sample != null) {
 1116               if (samples.indexOf(region.sample) != -1) {
 1117                   RIFFWriter wlnk = rgns.writeChunk("wlnk");
 1118                   wlnk.writeUnsignedShort(region.fusoptions);
 1119                   wlnk.writeUnsignedShort(region.phasegroup);
 1120                   wlnk.writeUnsignedInt(region.channel);
 1121                   wlnk.writeUnsignedInt(samples.indexOf(region.sample));
 1122               }
 1123           }
 1124           writeArticulators(rgns, region.getModulators());
 1125           rgns.close();
 1126       }
 1127   
 1128       private void writeSampleOptions(RIFFWriter wsmp,
 1129               DLSSampleOptions sampleoptions) throws IOException {
 1130           wsmp.writeUnsignedInt(20);
 1131           wsmp.writeUnsignedShort(sampleoptions.unitynote);
 1132           wsmp.writeShort(sampleoptions.finetune);
 1133           wsmp.writeInt(sampleoptions.attenuation);
 1134           wsmp.writeUnsignedInt(sampleoptions.options);
 1135           wsmp.writeInt(sampleoptions.loops.size());
 1136   
 1137           for (DLSSampleLoop loop : sampleoptions.loops) {
 1138               wsmp.writeUnsignedInt(16);
 1139               wsmp.writeUnsignedInt(loop.type);
 1140               wsmp.writeUnsignedInt(loop.start);
 1141               wsmp.writeUnsignedInt(loop.length);
 1142           }
 1143       }
 1144   
 1145       private void writeInfoStringChunk(RIFFWriter writer,
 1146               String name, String value) throws IOException {
 1147           if (value == null)
 1148               return;
 1149           RIFFWriter chunk = writer.writeChunk(name);
 1150           chunk.writeString(value);
 1151           int len = value.getBytes("ascii").length;
 1152           chunk.write(0);
 1153           len++;
 1154           if (len % 2 != 0)
 1155               chunk.write(0);
 1156       }
 1157   
 1158       private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException {
 1159           writeInfoStringChunk(writer, "INAM", info.name);
 1160           writeInfoStringChunk(writer, "ICRD", info.creationDate);
 1161           writeInfoStringChunk(writer, "IENG", info.engineers);
 1162           writeInfoStringChunk(writer, "IPRD", info.product);
 1163           writeInfoStringChunk(writer, "ICOP", info.copyright);
 1164           writeInfoStringChunk(writer, "ICMT", info.comments);
 1165           writeInfoStringChunk(writer, "ISFT", info.tools);
 1166           writeInfoStringChunk(writer, "IARL", info.archival_location);
 1167           writeInfoStringChunk(writer, "IART", info.artist);
 1168           writeInfoStringChunk(writer, "ICMS", info.commissioned);
 1169           writeInfoStringChunk(writer, "IGNR", info.genre);
 1170           writeInfoStringChunk(writer, "IKEY", info.keywords);
 1171           writeInfoStringChunk(writer, "IMED", info.medium);
 1172           writeInfoStringChunk(writer, "ISBJ", info.subject);
 1173           writeInfoStringChunk(writer, "ISRC", info.source);
 1174           writeInfoStringChunk(writer, "ISRF", info.source_form);
 1175           writeInfoStringChunk(writer, "ITCH", info.technician);
 1176       }
 1177   
 1178       public DLSInfo getInfo() {
 1179           return info;
 1180       }
 1181   
 1182       public String getName() {
 1183           return info.name;
 1184       }
 1185   
 1186       public String getVersion() {
 1187           return major + "." + minor;
 1188       }
 1189   
 1190       public String getVendor() {
 1191           return info.engineers;
 1192       }
 1193   
 1194       public String getDescription() {
 1195           return info.comments;
 1196       }
 1197   
 1198       public void setName(String s) {
 1199           info.name = s;
 1200       }
 1201   
 1202       public void setVendor(String s) {
 1203           info.engineers = s;
 1204       }
 1205   
 1206       public void setDescription(String s) {
 1207           info.comments = s;
 1208       }
 1209   
 1210       public SoundbankResource[] getResources() {
 1211           SoundbankResource[] resources = new SoundbankResource[samples.size()];
 1212           int j = 0;
 1213           for (int i = 0; i < samples.size(); i++)
 1214               resources[j++] = samples.get(i);
 1215           return resources;
 1216       }
 1217   
 1218       public DLSInstrument[] getInstruments() {
 1219           DLSInstrument[] inslist_array =
 1220                   instruments.toArray(new DLSInstrument[instruments.size()]);
 1221           Arrays.sort(inslist_array, new ModelInstrumentComparator());
 1222           return inslist_array;
 1223       }
 1224   
 1225       public DLSSample[] getSamples() {
 1226           return samples.toArray(new DLSSample[samples.size()]);
 1227       }
 1228   
 1229       public Instrument getInstrument(Patch patch) {
 1230           int program = patch.getProgram();
 1231           int bank = patch.getBank();
 1232           boolean percussion = false;
 1233           if (patch instanceof ModelPatch)
 1234               percussion = ((ModelPatch) patch).isPercussion();
 1235           for (Instrument instrument : instruments) {
 1236               Patch patch2 = instrument.getPatch();
 1237               int program2 = patch2.getProgram();
 1238               int bank2 = patch2.getBank();
 1239               if (program == program2 && bank == bank2) {
 1240                   boolean percussion2 = false;
 1241                   if (patch2 instanceof ModelPatch)
 1242                       percussion2 = ((ModelPatch) patch2).isPercussion();
 1243                   if (percussion == percussion2)
 1244                       return instrument;
 1245               }
 1246           }
 1247           return null;
 1248       }
 1249   
 1250       public void addResource(SoundbankResource resource) {
 1251           if (resource instanceof DLSInstrument)
 1252               instruments.add((DLSInstrument) resource);
 1253           if (resource instanceof DLSSample)
 1254               samples.add((DLSSample) resource);
 1255       }
 1256   
 1257       public void removeResource(SoundbankResource resource) {
 1258           if (resource instanceof DLSInstrument)
 1259               instruments.remove((DLSInstrument) resource);
 1260           if (resource instanceof DLSSample)
 1261               samples.remove((DLSSample) resource);
 1262       }
 1263   
 1264       public void addInstrument(DLSInstrument resource) {
 1265           instruments.add(resource);
 1266       }
 1267   
 1268       public void removeInstrument(DLSInstrument resource) {
 1269           instruments.remove(resource);
 1270       }
 1271   
 1272       public long getMajor() {
 1273           return major;
 1274       }
 1275   
 1276       public void setMajor(long major) {
 1277           this.major = major;
 1278       }
 1279   
 1280       public long getMinor() {
 1281           return minor;
 1282       }
 1283   
 1284       public void setMinor(long minor) {
 1285           this.minor = minor;
 1286       }
 1287   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]