|
Java example source code file (SF2Soundbank.java)
This example Java source code file (SF2Soundbank.java) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Learn more about this Java project at its project page.
The SF2Soundbank.java Java example source code
/*
* Copyright (c) 2007, 2013, 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.Iterator;
import java.util.List;
import java.util.Map;
import javax.sound.midi.Instrument;
import javax.sound.midi.Patch;
import javax.sound.midi.Soundbank;
import javax.sound.midi.SoundbankResource;
/**
* A SoundFont 2.04 soundbank reader.
*
* Based on SoundFont 2.04 specification from:
* <p> http://developer.creative.com
* http://www.soundfont.com/ ;
*
* @author Karl Helgason
*/
public final class SF2Soundbank implements Soundbank {
// version of the Sound Font RIFF file
int major = 2;
int minor = 1;
// target Sound Engine
String targetEngine = "EMU8000";
// Sound Font Bank Name
String name = "untitled";
// Sound ROM Name
String romName = null;
// Sound ROM Version
int romVersionMajor = -1;
int romVersionMinor = -1;
// Date of Creation of the Bank
String creationDate = null;
// Sound Designers and Engineers for the Bank
String engineers = null;
// Product for which the Bank was intended
String product = null;
// Copyright message
String copyright = null;
// Comments
String comments = null;
// The SoundFont tools used to create and alter the bank
String tools = null;
// The Sample Data loaded from the SoundFont
private ModelByteBuffer sampleData = null;
private ModelByteBuffer sampleData24 = null;
private File sampleFile = null;
private boolean largeFormat = false;
private final List<SF2Instrument> instruments = new ArrayList();
private final List<SF2Layer> layers = new ArrayList();
private final List<SF2Sample> samples = new ArrayList();
public SF2Soundbank() {
}
public SF2Soundbank(URL url) throws IOException {
InputStream is = url.openStream();
try {
readSoundbank(is);
} finally {
is.close();
}
}
public SF2Soundbank(File file) throws IOException {
largeFormat = true;
sampleFile = file;
InputStream is = new FileInputStream(file);
try {
readSoundbank(is);
} finally {
is.close();
}
}
public SF2Soundbank(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("sfbk")) {
throw new RIFFInvalidFormatException(
"Input stream is not a valid SoundFont!");
}
while (riff.hasNextChunk()) {
RIFFReader chunk = riff.nextChunk();
if (chunk.getFormat().equals("LIST")) {
if (chunk.getType().equals("INFO"))
readInfoChunk(chunk);
if (chunk.getType().equals("sdta"))
readSdtaChunk(chunk);
if (chunk.getType().equals("pdta"))
readPdtaChunk(chunk);
}
}
}
private void readInfoChunk(RIFFReader riff) throws IOException {
while (riff.hasNextChunk()) {
RIFFReader chunk = riff.nextChunk();
String format = chunk.getFormat();
if (format.equals("ifil")) {
major = chunk.readUnsignedShort();
minor = chunk.readUnsignedShort();
} else if (format.equals("isng")) {
this.targetEngine = chunk.readString(chunk.available());
} else if (format.equals("INAM")) {
this.name = chunk.readString(chunk.available());
} else if (format.equals("irom")) {
this.romName = chunk.readString(chunk.available());
} else if (format.equals("iver")) {
romVersionMajor = chunk.readUnsignedShort();
romVersionMinor = chunk.readUnsignedShort();
} else if (format.equals("ICRD")) {
this.creationDate = chunk.readString(chunk.available());
} else if (format.equals("IENG")) {
this.engineers = chunk.readString(chunk.available());
} else if (format.equals("IPRD")) {
this.product = chunk.readString(chunk.available());
} else if (format.equals("ICOP")) {
this.copyright = chunk.readString(chunk.available());
} else if (format.equals("ICMT")) {
this.comments = chunk.readString(chunk.available());
} else if (format.equals("ISFT")) {
this.tools = chunk.readString(chunk.available());
}
}
}
private void readSdtaChunk(RIFFReader riff) throws IOException {
while (riff.hasNextChunk()) {
RIFFReader chunk = riff.nextChunk();
if (chunk.getFormat().equals("smpl")) {
if (!largeFormat) {
byte[] sampleData = new byte[chunk.available()];
int read = 0;
int avail = chunk.available();
while (read != avail) {
if (avail - read > 65536) {
chunk.readFully(sampleData, read, 65536);
read += 65536;
} else {
chunk.readFully(sampleData, read, avail - read);
read = avail;
}
}
this.sampleData = new ModelByteBuffer(sampleData);
//chunk.read(sampleData);
} else {
this.sampleData = new ModelByteBuffer(sampleFile,
chunk.getFilePointer(), chunk.available());
}
}
if (chunk.getFormat().equals("sm24")) {
if (!largeFormat) {
byte[] sampleData24 = new byte[chunk.available()];
//chunk.read(sampleData24);
int read = 0;
int avail = chunk.available();
while (read != avail) {
if (avail - read > 65536) {
chunk.readFully(sampleData24, read, 65536);
read += 65536;
} else {
chunk.readFully(sampleData24, read, avail - read);
read = avail;
}
}
this.sampleData24 = new ModelByteBuffer(sampleData24);
} else {
this.sampleData24 = new ModelByteBuffer(sampleFile,
chunk.getFilePointer(), chunk.available());
}
}
}
}
private void readPdtaChunk(RIFFReader riff) throws IOException {
List<SF2Instrument> presets = new ArrayList();
List<Integer> presets_bagNdx = new ArrayList();
List<SF2InstrumentRegion> presets_splits_gen
= new ArrayList<SF2InstrumentRegion>();
List<SF2InstrumentRegion> presets_splits_mod
= new ArrayList<SF2InstrumentRegion>();
List<SF2Layer> instruments = new ArrayList();
List<Integer> instruments_bagNdx = new ArrayList();
List<SF2LayerRegion> instruments_splits_gen
= new ArrayList<SF2LayerRegion>();
List<SF2LayerRegion> instruments_splits_mod
= new ArrayList<SF2LayerRegion>();
while (riff.hasNextChunk()) {
RIFFReader chunk = riff.nextChunk();
String format = chunk.getFormat();
if (format.equals("phdr")) {
// Preset Header / Instrument
if (chunk.available() % 38 != 0)
throw new RIFFInvalidDataException();
int count = chunk.available() / 38;
for (int i = 0; i < count; i++) {
SF2Instrument preset = new SF2Instrument(this);
preset.name = chunk.readString(20);
preset.preset = chunk.readUnsignedShort();
preset.bank = chunk.readUnsignedShort();
presets_bagNdx.add(chunk.readUnsignedShort());
preset.library = chunk.readUnsignedInt();
preset.genre = chunk.readUnsignedInt();
preset.morphology = chunk.readUnsignedInt();
presets.add(preset);
if (i != count - 1)
this.instruments.add(preset);
}
} else if (format.equals("pbag")) {
// Preset Zones / Instruments splits
if (chunk.available() % 4 != 0)
throw new RIFFInvalidDataException();
int count = chunk.available() / 4;
// Skip first record
{
int gencount = chunk.readUnsignedShort();
int modcount = chunk.readUnsignedShort();
while (presets_splits_gen.size() < gencount)
presets_splits_gen.add(null);
while (presets_splits_mod.size() < modcount)
presets_splits_mod.add(null);
count--;
}
int offset = presets_bagNdx.get(0);
// Offset should be 0 (but just case)
for (int i = 0; i < offset; i++) {
if (count == 0)
throw new RIFFInvalidDataException();
int gencount = chunk.readUnsignedShort();
int modcount = chunk.readUnsignedShort();
while (presets_splits_gen.size() < gencount)
presets_splits_gen.add(null);
while (presets_splits_mod.size() < modcount)
presets_splits_mod.add(null);
count--;
}
for (int i = 0; i < presets_bagNdx.size() - 1; i++) {
int zone_count = presets_bagNdx.get(i + 1)
- presets_bagNdx.get(i);
SF2Instrument preset = presets.get(i);
for (int ii = 0; ii < zone_count; ii++) {
if (count == 0)
throw new RIFFInvalidDataException();
int gencount = chunk.readUnsignedShort();
int modcount = chunk.readUnsignedShort();
SF2InstrumentRegion split = new SF2InstrumentRegion();
preset.regions.add(split);
while (presets_splits_gen.size() < gencount)
presets_splits_gen.add(split);
while (presets_splits_mod.size() < modcount)
presets_splits_mod.add(split);
count--;
}
}
} else if (format.equals("pmod")) {
// Preset Modulators / Split Modulators
for (int i = 0; i < presets_splits_mod.size(); i++) {
SF2Modulator modulator = new SF2Modulator();
modulator.sourceOperator = chunk.readUnsignedShort();
modulator.destinationOperator = chunk.readUnsignedShort();
modulator.amount = chunk.readShort();
modulator.amountSourceOperator = chunk.readUnsignedShort();
modulator.transportOperator = chunk.readUnsignedShort();
SF2InstrumentRegion split = presets_splits_mod.get(i);
if (split != null)
split.modulators.add(modulator);
}
} else if (format.equals("pgen")) {
// Preset Generators / Split Generators
for (int i = 0; i < presets_splits_gen.size(); i++) {
int operator = chunk.readUnsignedShort();
short amount = chunk.readShort();
SF2InstrumentRegion split = presets_splits_gen.get(i);
if (split != null)
split.generators.put(operator, amount);
}
} else if (format.equals("inst")) {
// Instrument Header / Layers
if (chunk.available() % 22 != 0)
throw new RIFFInvalidDataException();
int count = chunk.available() / 22;
for (int i = 0; i < count; i++) {
SF2Layer layer = new SF2Layer(this);
layer.name = chunk.readString(20);
instruments_bagNdx.add(chunk.readUnsignedShort());
instruments.add(layer);
if (i != count - 1)
this.layers.add(layer);
}
} else if (format.equals("ibag")) {
// Instrument Zones / Layer splits
if (chunk.available() % 4 != 0)
throw new RIFFInvalidDataException();
int count = chunk.available() / 4;
// Skip first record
{
int gencount = chunk.readUnsignedShort();
int modcount = chunk.readUnsignedShort();
while (instruments_splits_gen.size() < gencount)
instruments_splits_gen.add(null);
while (instruments_splits_mod.size() < modcount)
instruments_splits_mod.add(null);
count--;
}
int offset = instruments_bagNdx.get(0);
// Offset should be 0 (but just case)
for (int i = 0; i < offset; i++) {
if (count == 0)
throw new RIFFInvalidDataException();
int gencount = chunk.readUnsignedShort();
int modcount = chunk.readUnsignedShort();
while (instruments_splits_gen.size() < gencount)
instruments_splits_gen.add(null);
while (instruments_splits_mod.size() < modcount)
instruments_splits_mod.add(null);
count--;
}
for (int i = 0; i < instruments_bagNdx.size() - 1; i++) {
int zone_count = instruments_bagNdx.get(i + 1) - instruments_bagNdx.get(i);
SF2Layer layer = layers.get(i);
for (int ii = 0; ii < zone_count; ii++) {
if (count == 0)
throw new RIFFInvalidDataException();
int gencount = chunk.readUnsignedShort();
int modcount = chunk.readUnsignedShort();
SF2LayerRegion split = new SF2LayerRegion();
layer.regions.add(split);
while (instruments_splits_gen.size() < gencount)
instruments_splits_gen.add(split);
while (instruments_splits_mod.size() < modcount)
instruments_splits_mod.add(split);
count--;
}
}
} else if (format.equals("imod")) {
// Instrument Modulators / Split Modulators
for (int i = 0; i < instruments_splits_mod.size(); i++) {
SF2Modulator modulator = new SF2Modulator();
modulator.sourceOperator = chunk.readUnsignedShort();
modulator.destinationOperator = chunk.readUnsignedShort();
modulator.amount = chunk.readShort();
modulator.amountSourceOperator = chunk.readUnsignedShort();
modulator.transportOperator = chunk.readUnsignedShort();
SF2LayerRegion split = instruments_splits_gen.get(i);
if (split != null)
split.modulators.add(modulator);
}
} else if (format.equals("igen")) {
// Instrument Generators / Split Generators
for (int i = 0; i < instruments_splits_gen.size(); i++) {
int operator = chunk.readUnsignedShort();
short amount = chunk.readShort();
SF2LayerRegion split = instruments_splits_gen.get(i);
if (split != null)
split.generators.put(operator, amount);
}
} else if (format.equals("shdr")) {
// Sample Headers
if (chunk.available() % 46 != 0)
throw new RIFFInvalidDataException();
int count = chunk.available() / 46;
for (int i = 0; i < count; i++) {
SF2Sample sample = new SF2Sample(this);
sample.name = chunk.readString(20);
long start = chunk.readUnsignedInt();
long end = chunk.readUnsignedInt();
sample.data = sampleData.subbuffer(start * 2, end * 2, true);
if (sampleData24 != null)
sample.data24 = sampleData24.subbuffer(start, end, true);
/*
sample.data = new ModelByteBuffer(sampleData, (int)(start*2),
(int)((end - start)*2));
if (sampleData24 != null)
sample.data24 = new ModelByteBuffer(sampleData24,
(int)start, (int)(end - start));
*/
sample.startLoop = chunk.readUnsignedInt() - start;
sample.endLoop = chunk.readUnsignedInt() - start;
if (sample.startLoop < 0)
sample.startLoop = -1;
if (sample.endLoop < 0)
sample.endLoop = -1;
sample.sampleRate = chunk.readUnsignedInt();
sample.originalPitch = chunk.readUnsignedByte();
sample.pitchCorrection = chunk.readByte();
sample.sampleLink = chunk.readUnsignedShort();
sample.sampleType = chunk.readUnsignedShort();
if (i != count - 1)
this.samples.add(sample);
}
}
}
Iterator<SF2Layer> liter = this.layers.iterator();
while (liter.hasNext()) {
SF2Layer layer = liter.next();
Iterator<SF2LayerRegion> siter = layer.regions.iterator();
SF2Region globalsplit = null;
while (siter.hasNext()) {
SF2LayerRegion split = siter.next();
if (split.generators.get(SF2LayerRegion.GENERATOR_SAMPLEID) != null) {
int sampleid = split.generators.get(
SF2LayerRegion.GENERATOR_SAMPLEID);
split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
split.sample = samples.get(sampleid);
} else {
globalsplit = split;
}
}
if (globalsplit != null) {
layer.getRegions().remove(globalsplit);
SF2GlobalRegion gsplit = new SF2GlobalRegion();
gsplit.generators = globalsplit.generators;
gsplit.modulators = globalsplit.modulators;
layer.setGlobalZone(gsplit);
}
}
Iterator<SF2Instrument> iiter = this.instruments.iterator();
while (iiter.hasNext()) {
SF2Instrument instrument = iiter.next();
Iterator<SF2InstrumentRegion> siter = instrument.regions.iterator();
SF2Region globalsplit = null;
while (siter.hasNext()) {
SF2InstrumentRegion split = siter.next();
if (split.generators.get(SF2LayerRegion.GENERATOR_INSTRUMENT) != null) {
int instrumentid = split.generators.get(
SF2InstrumentRegion.GENERATOR_INSTRUMENT);
split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
split.layer = layers.get(instrumentid);
} else {
globalsplit = split;
}
}
if (globalsplit != null) {
instrument.getRegions().remove(globalsplit);
SF2GlobalRegion gsplit = new SF2GlobalRegion();
gsplit.generators = globalsplit.generators;
gsplit.modulators = globalsplit.modulators;
instrument.setGlobalZone(gsplit);
}
}
}
public void save(String name) throws IOException {
writeSoundbank(new RIFFWriter(name, "sfbk"));
}
public void save(File file) throws IOException {
writeSoundbank(new RIFFWriter(file, "sfbk"));
}
public void save(OutputStream out) throws IOException {
writeSoundbank(new RIFFWriter(out, "sfbk"));
}
private void writeSoundbank(RIFFWriter writer) throws IOException {
writeInfo(writer.writeList("INFO"));
writeSdtaChunk(writer.writeList("sdta"));
writePdtaChunk(writer.writeList("pdta"));
writer.close();
}
private void writeInfoStringChunk(RIFFWriter writer, String name,
String value) throws IOException {
if (value == null)
return;
RIFFWriter chunk = writer.writeChunk(name);
chunk.writeString(value);
int len = value.getBytes("ascii").length;
chunk.write(0);
len++;
if (len % 2 != 0)
chunk.write(0);
}
private void writeInfo(RIFFWriter writer) throws IOException {
if (this.targetEngine == null)
this.targetEngine = "EMU8000";
if (this.name == null)
this.name = "";
RIFFWriter ifil_chunk = writer.writeChunk("ifil");
ifil_chunk.writeUnsignedShort(this.major);
ifil_chunk.writeUnsignedShort(this.minor);
writeInfoStringChunk(writer, "isng", this.targetEngine);
writeInfoStringChunk(writer, "INAM", this.name);
writeInfoStringChunk(writer, "irom", this.romName);
if (romVersionMajor != -1) {
RIFFWriter iver_chunk = writer.writeChunk("iver");
iver_chunk.writeUnsignedShort(this.romVersionMajor);
iver_chunk.writeUnsignedShort(this.romVersionMinor);
}
writeInfoStringChunk(writer, "ICRD", this.creationDate);
writeInfoStringChunk(writer, "IENG", this.engineers);
writeInfoStringChunk(writer, "IPRD", this.product);
writeInfoStringChunk(writer, "ICOP", this.copyright);
writeInfoStringChunk(writer, "ICMT", this.comments);
writeInfoStringChunk(writer, "ISFT", this.tools);
writer.close();
}
private void writeSdtaChunk(RIFFWriter writer) throws IOException {
byte[] pad = new byte[32];
RIFFWriter smpl_chunk = writer.writeChunk("smpl");
for (SF2Sample sample : samples) {
ModelByteBuffer data = sample.getDataBuffer();
data.writeTo(smpl_chunk);
/*
smpl_chunk.write(data.array(),
data.arrayOffset(),
data.capacity());
*/
smpl_chunk.write(pad);
smpl_chunk.write(pad);
}
if (major < 2)
return;
if (major == 2 && minor < 4)
return;
for (SF2Sample sample : samples) {
ModelByteBuffer data24 = sample.getData24Buffer();
if (data24 == null)
return;
}
RIFFWriter sm24_chunk = writer.writeChunk("sm24");
for (SF2Sample sample : samples) {
ModelByteBuffer data = sample.getData24Buffer();
data.writeTo(sm24_chunk);
/*
sm24_chunk.write(data.array(),
data.arrayOffset(),
data.capacity());*/
smpl_chunk.write(pad);
}
}
private void writeModulators(RIFFWriter writer, List<SF2Modulator> modulators)
throws IOException {
for (SF2Modulator modulator : modulators) {
writer.writeUnsignedShort(modulator.sourceOperator);
writer.writeUnsignedShort(modulator.destinationOperator);
writer.writeShort(modulator.amount);
writer.writeUnsignedShort(modulator.amountSourceOperator);
writer.writeUnsignedShort(modulator.transportOperator);
}
}
private void writeGenerators(RIFFWriter writer, Map<Integer, Short> generators)
throws IOException {
Short keyrange = (Short) generators.get(SF2Region.GENERATOR_KEYRANGE);
Short velrange = (Short) generators.get(SF2Region.GENERATOR_VELRANGE);
if (keyrange != null) {
writer.writeUnsignedShort(SF2Region.GENERATOR_KEYRANGE);
writer.writeShort(keyrange);
}
if (velrange != null) {
writer.writeUnsignedShort(SF2Region.GENERATOR_VELRANGE);
writer.writeShort(velrange);
}
for (Map.Entry<Integer, Short> generator : generators.entrySet()) {
if (generator.getKey() == SF2Region.GENERATOR_KEYRANGE)
continue;
if (generator.getKey() == SF2Region.GENERATOR_VELRANGE)
continue;
writer.writeUnsignedShort(generator.getKey());
writer.writeShort(generator.getValue());
}
}
private void writePdtaChunk(RIFFWriter writer) throws IOException {
RIFFWriter phdr_chunk = writer.writeChunk("phdr");
int phdr_zone_count = 0;
for (SF2Instrument preset : this.instruments) {
phdr_chunk.writeString(preset.name, 20);
phdr_chunk.writeUnsignedShort(preset.preset);
phdr_chunk.writeUnsignedShort(preset.bank);
phdr_chunk.writeUnsignedShort(phdr_zone_count);
if (preset.getGlobalRegion() != null)
phdr_zone_count += 1;
phdr_zone_count += preset.getRegions().size();
phdr_chunk.writeUnsignedInt(preset.library);
phdr_chunk.writeUnsignedInt(preset.genre);
phdr_chunk.writeUnsignedInt(preset.morphology);
}
phdr_chunk.writeString("EOP", 20);
phdr_chunk.writeUnsignedShort(0);
phdr_chunk.writeUnsignedShort(0);
phdr_chunk.writeUnsignedShort(phdr_zone_count);
phdr_chunk.writeUnsignedInt(0);
phdr_chunk.writeUnsignedInt(0);
phdr_chunk.writeUnsignedInt(0);
RIFFWriter pbag_chunk = writer.writeChunk("pbag");
int pbag_gencount = 0;
int pbag_modcount = 0;
for (SF2Instrument preset : this.instruments) {
if (preset.getGlobalRegion() != null) {
pbag_chunk.writeUnsignedShort(pbag_gencount);
pbag_chunk.writeUnsignedShort(pbag_modcount);
pbag_gencount += preset.getGlobalRegion().getGenerators().size();
pbag_modcount += preset.getGlobalRegion().getModulators().size();
}
for (SF2InstrumentRegion region : preset.getRegions()) {
pbag_chunk.writeUnsignedShort(pbag_gencount);
pbag_chunk.writeUnsignedShort(pbag_modcount);
if (layers.indexOf(region.layer) != -1) {
// One generator is used to reference to instrument record
pbag_gencount += 1;
}
pbag_gencount += region.getGenerators().size();
pbag_modcount += region.getModulators().size();
}
}
pbag_chunk.writeUnsignedShort(pbag_gencount);
pbag_chunk.writeUnsignedShort(pbag_modcount);
RIFFWriter pmod_chunk = writer.writeChunk("pmod");
for (SF2Instrument preset : this.instruments) {
if (preset.getGlobalRegion() != null) {
writeModulators(pmod_chunk,
preset.getGlobalRegion().getModulators());
}
for (SF2InstrumentRegion region : preset.getRegions())
writeModulators(pmod_chunk, region.getModulators());
}
pmod_chunk.write(new byte[10]);
RIFFWriter pgen_chunk = writer.writeChunk("pgen");
for (SF2Instrument preset : this.instruments) {
if (preset.getGlobalRegion() != null) {
writeGenerators(pgen_chunk,
preset.getGlobalRegion().getGenerators());
}
for (SF2InstrumentRegion region : preset.getRegions()) {
writeGenerators(pgen_chunk, region.getGenerators());
int ix = (int) layers.indexOf(region.layer);
if (ix != -1) {
pgen_chunk.writeUnsignedShort(SF2Region.GENERATOR_INSTRUMENT);
pgen_chunk.writeShort((short) ix);
}
}
}
pgen_chunk.write(new byte[4]);
RIFFWriter inst_chunk = writer.writeChunk("inst");
int inst_zone_count = 0;
for (SF2Layer instrument : this.layers) {
inst_chunk.writeString(instrument.name, 20);
inst_chunk.writeUnsignedShort(inst_zone_count);
if (instrument.getGlobalRegion() != null)
inst_zone_count += 1;
inst_zone_count += instrument.getRegions().size();
}
inst_chunk.writeString("EOI", 20);
inst_chunk.writeUnsignedShort(inst_zone_count);
RIFFWriter ibag_chunk = writer.writeChunk("ibag");
int ibag_gencount = 0;
int ibag_modcount = 0;
for (SF2Layer instrument : this.layers) {
if (instrument.getGlobalRegion() != null) {
ibag_chunk.writeUnsignedShort(ibag_gencount);
ibag_chunk.writeUnsignedShort(ibag_modcount);
ibag_gencount
+= instrument.getGlobalRegion().getGenerators().size();
ibag_modcount
+= instrument.getGlobalRegion().getModulators().size();
}
for (SF2LayerRegion region : instrument.getRegions()) {
ibag_chunk.writeUnsignedShort(ibag_gencount);
ibag_chunk.writeUnsignedShort(ibag_modcount);
if (samples.indexOf(region.sample) != -1) {
// One generator is used to reference to instrument record
ibag_gencount += 1;
}
ibag_gencount += region.getGenerators().size();
ibag_modcount += region.getModulators().size();
}
}
ibag_chunk.writeUnsignedShort(ibag_gencount);
ibag_chunk.writeUnsignedShort(ibag_modcount);
RIFFWriter imod_chunk = writer.writeChunk("imod");
for (SF2Layer instrument : this.layers) {
if (instrument.getGlobalRegion() != null) {
writeModulators(imod_chunk,
instrument.getGlobalRegion().getModulators());
}
for (SF2LayerRegion region : instrument.getRegions())
writeModulators(imod_chunk, region.getModulators());
}
imod_chunk.write(new byte[10]);
RIFFWriter igen_chunk = writer.writeChunk("igen");
for (SF2Layer instrument : this.layers) {
if (instrument.getGlobalRegion() != null) {
writeGenerators(igen_chunk,
instrument.getGlobalRegion().getGenerators());
}
for (SF2LayerRegion region : instrument.getRegions()) {
writeGenerators(igen_chunk, region.getGenerators());
int ix = samples.indexOf(region.sample);
if (ix != -1) {
igen_chunk.writeUnsignedShort(SF2Region.GENERATOR_SAMPLEID);
igen_chunk.writeShort((short) ix);
}
}
}
igen_chunk.write(new byte[4]);
RIFFWriter shdr_chunk = writer.writeChunk("shdr");
long sample_pos = 0;
for (SF2Sample sample : samples) {
shdr_chunk.writeString(sample.name, 20);
long start = sample_pos;
sample_pos += sample.data.capacity() / 2;
long end = sample_pos;
long startLoop = sample.startLoop + start;
long endLoop = sample.endLoop + start;
if (startLoop < start)
startLoop = start;
if (endLoop > end)
endLoop = end;
shdr_chunk.writeUnsignedInt(start);
shdr_chunk.writeUnsignedInt(end);
shdr_chunk.writeUnsignedInt(startLoop);
shdr_chunk.writeUnsignedInt(endLoop);
shdr_chunk.writeUnsignedInt(sample.sampleRate);
shdr_chunk.writeUnsignedByte(sample.originalPitch);
shdr_chunk.writeByte(sample.pitchCorrection);
shdr_chunk.writeUnsignedShort(sample.sampleLink);
shdr_chunk.writeUnsignedShort(sample.sampleType);
sample_pos += 32;
}
shdr_chunk.writeString("EOS", 20);
shdr_chunk.write(new byte[26]);
}
public String getName() {
return name;
}
public String getVersion() {
return major + "." + minor;
}
public String getVendor() {
return engineers;
}
public String getDescription() {
return comments;
}
public void setName(String s) {
name = s;
}
public void setVendor(String s) {
engineers = s;
}
public void setDescription(String s) {
comments = s;
}
public SoundbankResource[] getResources() {
SoundbankResource[] resources
= new SoundbankResource[layers.size() + samples.size()];
int j = 0;
for (int i = 0; i < layers.size(); i++)
resources[j++] = layers.get(i);
for (int i = 0; i < samples.size(); i++)
resources[j++] = samples.get(i);
return resources;
}
public SF2Instrument[] getInstruments() {
SF2Instrument[] inslist_array
= instruments.toArray(new SF2Instrument[instruments.size()]);
Arrays.sort(inslist_array, new ModelInstrumentComparator());
return inslist_array;
}
public SF2Layer[] getLayers() {
return layers.toArray(new SF2Layer[layers.size()]);
}
public SF2Sample[] getSamples() {
return samples.toArray(new SF2Sample[samples.size()]);
}
public Instrument getInstrument(Patch patch) {
int program = patch.getProgram();
int bank = patch.getBank();
boolean percussion = false;
if (patch instanceof ModelPatch)
percussion = ((ModelPatch)patch).isPercussion();
for (Instrument instrument : instruments) {
Patch patch2 = instrument.getPatch();
int program2 = patch2.getProgram();
int bank2 = patch2.getBank();
if (program == program2 && bank == bank2) {
boolean percussion2 = false;
if (patch2 instanceof ModelPatch)
percussion2 = ((ModelPatch) patch2).isPercussion();
if (percussion == percussion2)
return instrument;
}
}
return null;
}
public String getCreationDate() {
return creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
public String getProduct() {
return product;
}
public void setProduct(String product) {
this.product = product;
}
public String getRomName() {
return romName;
}
public void setRomName(String romName) {
this.romName = romName;
}
public int getRomVersionMajor() {
return romVersionMajor;
}
public void setRomVersionMajor(int romVersionMajor) {
this.romVersionMajor = romVersionMajor;
}
public int getRomVersionMinor() {
return romVersionMinor;
}
public void setRomVersionMinor(int romVersionMinor) {
this.romVersionMinor = romVersionMinor;
}
public String getTargetEngine() {
return targetEngine;
}
public void setTargetEngine(String targetEngine) {
this.targetEngine = targetEngine;
}
public String getTools() {
return tools;
}
public void setTools(String tools) {
this.tools = tools;
}
public void addResource(SoundbankResource resource) {
if (resource instanceof SF2Instrument)
instruments.add((SF2Instrument)resource);
if (resource instanceof SF2Layer)
layers.add((SF2Layer)resource);
if (resource instanceof SF2Sample)
samples.add((SF2Sample)resource);
}
public void removeResource(SoundbankResource resource) {
if (resource instanceof SF2Instrument)
instruments.remove((SF2Instrument)resource);
if (resource instanceof SF2Layer)
layers.remove((SF2Layer)resource);
if (resource instanceof SF2Sample)
samples.remove((SF2Sample)resource);
}
public void addInstrument(SF2Instrument resource) {
instruments.add(resource);
}
public void removeInstrument(SF2Instrument resource) {
instruments.remove(resource);
}
}
Other Java examples (source code examples)
Here is a short list of links related to this Java SF2Soundbank.java source code file:
|