Minimize a DLS soundbank

This is a useful piece of code if you have a DLS soundbank and want to minimize it with just the instruments/samples actually used in the song(s). If you for example bundle your soundbank in the jar-file, you can get some significant savings.

You’ll have to get the gervill.jar first which is available here:
http://java.net/projects/gervill/downloads



import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

import com.sun.media.sound.DLSInstrument;
import com.sun.media.sound.DLSRegion;
import com.sun.media.sound.DLSSample;
import com.sun.media.sound.DLSSoundbank;
import com.sun.media.sound.ModelPatch;

public class DLSUtils {

	public static DLSSoundbank createSimplifiedSoundbank(
			DLSSoundbank soundbank, Map<Integer, Collection<Integer>> patches,
			Map<Integer, Collection<Integer>> percussionKeys) {

		DLSSoundbank result = new DLSSoundbank();

		LinkedHashSet<DLSSample> samples = new LinkedHashSet<DLSSample>();

		for (Integer bank : patches.keySet()) {

			Collection<Integer> programs = patches.get(bank);
			for (Integer program : programs) {
				ModelPatch patch = new ModelPatch(bank, program, false);
				DLSInstrument instrument = (DLSInstrument) soundbank
						.getInstrument(patch);

				List<DLSRegion> regions = instrument.getRegions();

				for (DLSRegion region : regions) {
					DLSSample sample = region.getSample();
					samples.add(sample);
				}
				result.addInstrument(instrument);
			}
		}
		for (Integer program : percussionKeys.keySet()) {

			Collection<Integer> keys = percussionKeys.get(program);
			// for (Integer program : programs) {
			ModelPatch patch = new ModelPatch(0, program, true);
			DLSInstrument instrument = (DLSInstrument) soundbank
					.getInstrument(patch);

			List<DLSRegion> regions = instrument.getRegions();

			ArrayList<DLSRegion> toRemove = new ArrayList<DLSRegion>();
			for (DLSRegion region : regions) {
				boolean add = false;
				for (Integer key : keys) {
					if (region.getKeyfrom() <= key && region.getKeyto() >= key) {
						add = true;
						break;
					}
				}
				if (add) {
					DLSSample sample = region.getSample();
					samples.add(sample);
				} else {
					toRemove.add(region);
				}
			}
			regions.removeAll(toRemove);
			
			result.addInstrument(instrument);
		}
		for (DLSSample sample : samples) {
			result.addResource(sample);
		}

		return result;
	}

	public static void main(String[] args) throws Exception {
		DLSSoundbank sb = new DLSSoundbank(new FileInputStream(
				"thepath/gm.dls"));

		Map<Integer, Collection<Integer>> patches = new LinkedHashMap<Integer, Collection<Integer>>();
		Map<Integer, Collection<Integer>> percussionKeys = new LinkedHashMap<Integer, Collection<Integer>>();
		ArrayList<Integer> percussionKeysList = new ArrayList<Integer>();
		percussionKeysList.add(35);
		percussionKeysList.add(38);
		percussionKeys.put(0, percussionKeysList);

		ArrayList<Integer> melodicInstrumentList = new ArrayList<Integer>();
		melodicInstrumentList.add(0);
		patches.put(0, melodicInstrumentList);

		DLSSoundbank sbResult = createSimplifiedSoundbank(sb, patches,
				percussionKeys);

		sbResult
				.save(new File("thepath/gm2.dls"));

	}

}