< prev index next >

src/java.desktop/share/classes/com/sun/media/sound/SF2Instrument.java

Print this page




   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.util.ArrayList;
  28 import java.util.HashMap;
  29 import java.util.List;
  30 import java.util.Map;
  31 
  32 import javax.sound.midi.Patch;
  33 
  34 /**
  35  * Soundfont instrument.
  36  *
  37  * @author Karl Helgason
  38  */
  39 public final class SF2Instrument extends ModelInstrument {
  40 
  41     String name = "";
  42     int preset = 0;
  43     int bank = 0;
  44     long library = 0;
  45     long genre = 0;
  46     long morphology = 0;
  47     SF2GlobalRegion globalregion = null;
  48     List<SF2InstrumentRegion> regions
  49             = new ArrayList<SF2InstrumentRegion>();
  50 
  51     public SF2Instrument() {
  52         super(null, null, null, null);
  53     }
  54 
  55     public SF2Instrument(SF2Soundbank soundbank) {
  56         super(soundbank, null, null, null);
  57     }
  58 

  59     public String getName() {
  60         return name;
  61     }
  62 
  63     public void setName(String name) {
  64         this.name = name;
  65     }
  66 

  67     public Patch getPatch() {
  68         if (bank == 128)
  69             return new ModelPatch(0, preset, true);
  70         else
  71             return new ModelPatch(bank << 7, preset, false);
  72     }
  73 
  74     public void setPatch(Patch patch) {
  75         if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) {
  76             bank = 128;
  77             preset = patch.getProgram();
  78         } else {
  79             bank = patch.getBank() >> 7;
  80             preset = patch.getProgram();
  81         }
  82     }
  83 

  84     public Object getData() {
  85         return null;
  86     }
  87 
  88     public long getGenre() {
  89         return genre;
  90     }
  91 
  92     public void setGenre(long genre) {
  93         this.genre = genre;
  94     }
  95 
  96     public long getLibrary() {
  97         return library;
  98     }
  99 
 100     public void setLibrary(long library) {
 101         this.library = library;
 102     }
 103 
 104     public long getMorphology() {
 105         return morphology;
 106     }
 107 
 108     public void setMorphology(long morphology) {
 109         this.morphology = morphology;
 110     }
 111 
 112     public List<SF2InstrumentRegion> getRegions() {
 113         return regions;
 114     }
 115 
 116     public SF2GlobalRegion getGlobalRegion() {
 117         return globalregion;
 118     }
 119 
 120     public void setGlobalZone(SF2GlobalRegion zone) {
 121         globalregion = zone;
 122     }
 123 

 124     public String toString() {
 125         if (bank == 128)
 126             return "Drumkit: " + name + " preset #" + preset;
 127         else
 128             return "Instrument: " + name + " bank #" + bank
 129                     + " preset #" + preset;
 130     }
 131 

 132     public ModelPerformer[] getPerformers() {
 133         int performercount = 0;
 134         for (SF2InstrumentRegion presetzone : regions)
 135             performercount += presetzone.getLayer().getRegions().size();
 136         ModelPerformer[] performers = new ModelPerformer[performercount];
 137         int pi = 0;
 138 
 139         SF2GlobalRegion presetglobal = globalregion;
 140         for (SF2InstrumentRegion presetzone : regions) {
 141             Map<Integer, Short> pgenerators = new HashMap<Integer, Short>();
 142             pgenerators.putAll(presetzone.getGenerators());
 143             if (presetglobal != null)
 144                 pgenerators.putAll(presetglobal.getGenerators());
 145 
 146             SF2Layer layer = presetzone.getLayer();
 147             SF2GlobalRegion layerglobal = layer.getGlobalRegion();
 148             for (SF2LayerRegion layerzone : layer.getRegions()) {
 149                 ModelPerformer performer = new ModelPerformer();
 150                 if (layerzone.getSample() != null)
 151                     performer.setName(layerzone.getSample().getName());
 152                 else
 153                     performer.setName(layer.getName());
 154 
 155                 performers[pi++] = performer;
 156 
 157                 int keyfrom = 0;
 158                 int keyto = 127;
 159                 int velfrom = 0;
 160                 int velto = 127;
 161 


 250                     byte[] data = buff.array();
 251                     int off = (int)buff.arrayOffset() + startAddrsOffset*2;
 252                     int len = (int)buff.capacity() + endAddrsOffset*2;
 253                     if (off+len > data.length)
 254                         len = data.length - off;
 255                     buff = new ModelByteBuffer(data, off, len);
 256                     if(buff24 != null) {
 257                         data = buff.array();
 258                         off = (int)buff.arrayOffset() + startAddrsOffset;
 259                         len = (int)buff.capacity() + endAddrsOffset;
 260                         buff24 = new ModelByteBuffer(data, off, len);
 261                     }
 262                     */
 263                 }
 264 
 265                 ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
 266                         buff, sample.getFormat(), pitchcorrection);
 267                 if (buff24 != null)
 268                     osc.set8BitExtensionBuffer(buff24);
 269 
 270                 Map<Integer, Short> generators = new HashMap<Integer, Short>();
 271                 if (layerglobal != null)
 272                     generators.putAll(layerglobal.getGenerators());
 273                 generators.putAll(layerzone.getGenerators());
 274                 for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) {
 275                     short val;
 276                     if (!generators.containsKey(gen.getKey()))
 277                         val = layerzone.getShort(gen.getKey());
 278                     else
 279                         val = generators.get(gen.getKey());
 280                     val += gen.getValue();
 281                     generators.put(gen.getKey(), val);
 282                 }
 283 
 284                 // SampleMode:
 285                 // 0 indicates a sound reproduced with no loop
 286                 // 1 indicates a sound which loops continuously
 287                 // 2 is unused but should be interpreted as indicating no loop
 288                 // 3 indicates a sound which loops for the duration of key
 289                 //   depression then proceeds to play the remainder of the sample.
 290                 int sampleMode = getGeneratorValue(generators,


 591                                 new ModelDestination(dest)));
 592                     } else {
 593                         ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
 594                         performer.getConnectionBlocks().add(
 595                             new ModelConnectionBlock(null, rootkey * (100 - fvalue),
 596                                 new ModelDestination(dest)));
 597                     }
 598 
 599                     ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
 600                     ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
 601                     performer.getConnectionBlocks().add(
 602                         new ModelConnectionBlock(new ModelSource(src),
 603                             128 * fvalue, new ModelDestination(dest)));
 604 
 605                 }
 606 
 607                 performer.getConnectionBlocks().add(
 608                     new ModelConnectionBlock(
 609                         new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY,
 610                             new ModelTransform() {

 611                                 public double transform(double value) {
 612                                     if (value < 0.5)
 613                                         return 1 - value * 2;
 614                                     else
 615                                         return 0;
 616                                 }
 617                             }),
 618                         -2400,
 619                         new ModelDestination(
 620                             ModelDestination.DESTINATION_FILTER_FREQ)));
 621 
 622 
 623                 performer.getConnectionBlocks().add(
 624                     new ModelConnectionBlock(
 625                         new ModelSource(ModelSource.SOURCE_LFO2,
 626                             ModelStandardTransform.DIRECTION_MIN2MAX,
 627                             ModelStandardTransform.POLARITY_BIPOLAR,
 628                             ModelStandardTransform.TRANSFORM_LINEAR),
 629                         new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
 630                             ModelStandardTransform.DIRECTION_MIN2MAX,




   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 
  26 package com.sun.media.sound;
  27 
  28 import java.util.ArrayList;
  29 import java.util.HashMap;
  30 import java.util.List;
  31 import java.util.Map;
  32 
  33 import javax.sound.midi.Patch;
  34 
  35 /**
  36  * Soundfont instrument.
  37  *
  38  * @author Karl Helgason
  39  */
  40 public final class SF2Instrument extends ModelInstrument {
  41 
  42     String name = "";
  43     int preset = 0;
  44     int bank = 0;
  45     long library = 0;
  46     long genre = 0;
  47     long morphology = 0;
  48     SF2GlobalRegion globalregion = null;
  49     List<SF2InstrumentRegion> regions = new ArrayList<>();

  50 
  51     public SF2Instrument() {
  52         super(null, null, null, null);
  53     }
  54 
  55     public SF2Instrument(SF2Soundbank soundbank) {
  56         super(soundbank, null, null, null);
  57     }
  58 
  59     @Override
  60     public String getName() {
  61         return name;
  62     }
  63 
  64     public void setName(String name) {
  65         this.name = name;
  66     }
  67 
  68     @Override
  69     public Patch getPatch() {
  70         if (bank == 128)
  71             return new ModelPatch(0, preset, true);
  72         else
  73             return new ModelPatch(bank << 7, preset, false);
  74     }
  75 
  76     public void setPatch(Patch patch) {
  77         if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) {
  78             bank = 128;
  79             preset = patch.getProgram();
  80         } else {
  81             bank = patch.getBank() >> 7;
  82             preset = patch.getProgram();
  83         }
  84     }
  85 
  86     @Override
  87     public Object getData() {
  88         return null;
  89     }
  90 
  91     public long getGenre() {
  92         return genre;
  93     }
  94 
  95     public void setGenre(long genre) {
  96         this.genre = genre;
  97     }
  98 
  99     public long getLibrary() {
 100         return library;
 101     }
 102 
 103     public void setLibrary(long library) {
 104         this.library = library;
 105     }
 106 
 107     public long getMorphology() {
 108         return morphology;
 109     }
 110 
 111     public void setMorphology(long morphology) {
 112         this.morphology = morphology;
 113     }
 114 
 115     public List<SF2InstrumentRegion> getRegions() {
 116         return regions;
 117     }
 118 
 119     public SF2GlobalRegion getGlobalRegion() {
 120         return globalregion;
 121     }
 122 
 123     public void setGlobalZone(SF2GlobalRegion zone) {
 124         globalregion = zone;
 125     }
 126 
 127     @Override
 128     public String toString() {
 129         if (bank == 128)
 130             return "Drumkit: " + name + " preset #" + preset;
 131         else
 132             return "Instrument: " + name + " bank #" + bank
 133                     + " preset #" + preset;
 134     }
 135 
 136     @Override
 137     public ModelPerformer[] getPerformers() {
 138         int performercount = 0;
 139         for (SF2InstrumentRegion presetzone : regions)
 140             performercount += presetzone.getLayer().getRegions().size();
 141         ModelPerformer[] performers = new ModelPerformer[performercount];
 142         int pi = 0;
 143 
 144         SF2GlobalRegion presetglobal = globalregion;
 145         for (SF2InstrumentRegion presetzone : regions) {
 146             Map<Integer, Short> pgenerators = new HashMap<>();
 147             pgenerators.putAll(presetzone.getGenerators());
 148             if (presetglobal != null)
 149                 pgenerators.putAll(presetglobal.getGenerators());
 150 
 151             SF2Layer layer = presetzone.getLayer();
 152             SF2GlobalRegion layerglobal = layer.getGlobalRegion();
 153             for (SF2LayerRegion layerzone : layer.getRegions()) {
 154                 ModelPerformer performer = new ModelPerformer();
 155                 if (layerzone.getSample() != null)
 156                     performer.setName(layerzone.getSample().getName());
 157                 else
 158                     performer.setName(layer.getName());
 159 
 160                 performers[pi++] = performer;
 161 
 162                 int keyfrom = 0;
 163                 int keyto = 127;
 164                 int velfrom = 0;
 165                 int velto = 127;
 166 


 255                     byte[] data = buff.array();
 256                     int off = (int)buff.arrayOffset() + startAddrsOffset*2;
 257                     int len = (int)buff.capacity() + endAddrsOffset*2;
 258                     if (off+len > data.length)
 259                         len = data.length - off;
 260                     buff = new ModelByteBuffer(data, off, len);
 261                     if(buff24 != null) {
 262                         data = buff.array();
 263                         off = (int)buff.arrayOffset() + startAddrsOffset;
 264                         len = (int)buff.capacity() + endAddrsOffset;
 265                         buff24 = new ModelByteBuffer(data, off, len);
 266                     }
 267                     */
 268                 }
 269 
 270                 ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
 271                         buff, sample.getFormat(), pitchcorrection);
 272                 if (buff24 != null)
 273                     osc.set8BitExtensionBuffer(buff24);
 274 
 275                 Map<Integer, Short> generators = new HashMap<>();
 276                 if (layerglobal != null)
 277                     generators.putAll(layerglobal.getGenerators());
 278                 generators.putAll(layerzone.getGenerators());
 279                 for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) {
 280                     short val;
 281                     if (!generators.containsKey(gen.getKey()))
 282                         val = layerzone.getShort(gen.getKey());
 283                     else
 284                         val = generators.get(gen.getKey());
 285                     val += gen.getValue();
 286                     generators.put(gen.getKey(), val);
 287                 }
 288 
 289                 // SampleMode:
 290                 // 0 indicates a sound reproduced with no loop
 291                 // 1 indicates a sound which loops continuously
 292                 // 2 is unused but should be interpreted as indicating no loop
 293                 // 3 indicates a sound which loops for the duration of key
 294                 //   depression then proceeds to play the remainder of the sample.
 295                 int sampleMode = getGeneratorValue(generators,


 596                                 new ModelDestination(dest)));
 597                     } else {
 598                         ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
 599                         performer.getConnectionBlocks().add(
 600                             new ModelConnectionBlock(null, rootkey * (100 - fvalue),
 601                                 new ModelDestination(dest)));
 602                     }
 603 
 604                     ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
 605                     ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
 606                     performer.getConnectionBlocks().add(
 607                         new ModelConnectionBlock(new ModelSource(src),
 608                             128 * fvalue, new ModelDestination(dest)));
 609 
 610                 }
 611 
 612                 performer.getConnectionBlocks().add(
 613                     new ModelConnectionBlock(
 614                         new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY,
 615                             new ModelTransform() {
 616                                 @Override
 617                                 public double transform(double value) {
 618                                     if (value < 0.5)
 619                                         return 1 - value * 2;
 620                                     else
 621                                         return 0;
 622                                 }
 623                             }),
 624                         -2400,
 625                         new ModelDestination(
 626                             ModelDestination.DESTINATION_FILTER_FREQ)));
 627 
 628 
 629                 performer.getConnectionBlocks().add(
 630                     new ModelConnectionBlock(
 631                         new ModelSource(ModelSource.SOURCE_LFO2,
 632                             ModelStandardTransform.DIRECTION_MIN2MAX,
 633                             ModelStandardTransform.POLARITY_BIPOLAR,
 634                             ModelStandardTransform.TRANSFORM_LINEAR),
 635                         new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
 636                             ModelStandardTransform.DIRECTION_MIN2MAX,


< prev index next >