view overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftTuning.java @ 843:bcba163568ac

Integrate Gervill. 2008-04-30 Mark Wielaard <mark@klomp.org> * Makefile.am (ICEDTEA_PATCHES): Add patches/icedtea-gervill.patch. * Makefile.in: Regenerated. * patches/icedtea-gervill.patch: New patch. * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/*: New Gervill files.
author Mark Wielaard <mark@klomp.org>
date Wed, 30 Apr 2008 22:09:08 +0200
parents
children
line wrap: on
line source

/*
 * Copyright 2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.media.sound;

import java.io.UnsupportedEncodingException;

import javax.sound.midi.Patch;

/**
 * 
 * A tuning program container, for use with MIDI Tuning. see:
 * http://www.midi.org
 * 
 * @version %I%, %E%
 * @author Karl Helgason
 */
public class SoftTuning {

	private String name = null;

	private double[] tuning = new double[128];

	private Patch patch = null;

	public SoftTuning() {
		name = "12-TET";
		for (int i = 0; i < tuning.length; i++)
			tuning[i] = i * 100;
	}

	public SoftTuning(byte[] data) {
		for (int i = 0; i < tuning.length; i++)
			tuning[i] = i * 100;
		load(data);
	}

	public SoftTuning(Patch patch) {
		this.patch = patch;
		name = "12-TET";
		for (int i = 0; i < tuning.length; i++)
			tuning[i] = i * 100;
	}

	public SoftTuning(Patch patch, byte[] data) {
		this.patch = patch;
		for (int i = 0; i < tuning.length; i++)
			tuning[i] = i * 100;
		load(data);
	}

	private boolean checksumOK(byte[] data) {
		int x = data[1] & 0xFF;
		for (int i = 2; i < data.length - 2; i++)
			x = x ^ (data[i] & 0xFF);
		return (data[data.length - 2] & 0xFF) == (x & 127);
	}

	/*
	private boolean checksumOK2(byte[] data) {
		int x = data[1] & 0xFF; // 7E
		x = x ^ (data[2] & 0xFF); // <device ID>
		x = x ^ (data[4] & 0xFF); // nn
		x = x ^ (data[5] & 0xFF); // tt
		for (int i = 22; i < data.length - 2; i++)
			x = x ^ (data[i] & 0xFF);
		return (data[data.length - 2] & 0xFF) == (x & 127);
	}*/

	public void load(byte[] data) {
		// Universal Non-Real-Time / Real-Time SysEx
		if ((data[1] & 0xFF) == 0x7E || (data[1] & 0xFF) == 0x7F) {
			int subid1 = data[3] & 0xFF;
			switch (subid1) {
			case 0x08: // MIDI Tuning Standard
				int subid2 = data[4] & 0xFF;
				switch (subid2) {
				case 0x01: // BULK TUNING DUMP (NON-REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning.shtml
					//if (!checksumOK2(data))
					//	break;
					try {
						name = new String(data, 6, 16, "ascii");
					} catch (UnsupportedEncodingException e) {
						name = null;
					}
					int r = 22;
					for (int i = 0; i < 128; i++) {
						int xx = data[r++] & 0xFF;
						int yy = data[r++] & 0xFF;
						int zz = data[r++] & 0xFF;
						if (!(xx == 127 && yy == 127 && zz == 127))
							tuning[i] = 100.0 * (((xx * 16384) + (yy * 128) + zz) / 16384.0);
					}
					break;
				}
				case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning.shtml
					int ll = data[6] & 0xFF;
					int r = 7;
					for (int i = 0; i < ll; i++) {
						int kk = data[r++] & 0xFF;
						int xx = data[r++] & 0xFF;
						int yy = data[r++] & 0xFF;
						int zz = data[r++] & 0xFF;
						if (!(xx == 127 && yy == 127 && zz == 127))
							tuning[kk] = 100.0 * (((xx * 16384) + (yy * 128) + zz) / 16384.0);
					}
					break;
				}
				case 0x04: // KEY-BASED TUNING DUMP (NON-REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning_extens.shtml
					if (!checksumOK(data))
						break;
					try {
						name = new String(data, 7, 16, "ascii");
					} catch (UnsupportedEncodingException e) {
						name = null;
					}
					int r = 23;
					for (int i = 0; i < 128; i++) {
						int xx = data[r++] & 0xFF;
						int yy = data[r++] & 0xFF;
						int zz = data[r++] & 0xFF;
						if (!(xx == 127 && yy == 127 && zz == 127))
							tuning[i] = 100.0 * (((xx * 16384) + (yy * 128) + zz) / 16384.0);
					}
					break;
				}
				case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
							// (NON-REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning_extens.shtml
					if (!checksumOK(data))
						break;
					try {
						name = new String(data, 7, 16, "ascii");
					} catch (UnsupportedEncodingException e) {
						name = null;
					}
					int[] octave_tuning = new int[12];
					for (int i = 0; i < 12; i++)
						octave_tuning[i] = (data[i + 23] & 0xFF) - 64;
					for (int i = 0; i < tuning.length; i++)
						tuning[i] = i * 100 + octave_tuning[i % 12];
					break;
				}
				case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
							// (NON-REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning_extens.shtml
					if (!checksumOK(data))
						break;
					try {
						name = new String(data, 7, 16, "ascii");
					} catch (UnsupportedEncodingException e) {
						name = null;
					}
					double[] octave_tuning = new double[12];
					for (int i = 0; i < 12; i++) {
						int v = (data[i * 2 + 23] & 0xFF) * 128
								+ (data[i * 2 + 24] & 0xFF);
						octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
					}
					for (int i = 0; i < tuning.length; i++)
						tuning[i] = i * 100 + octave_tuning[i % 12];
					break;
				}
				case 0x07: // SINGLE NOTE TUNING CHANGE (NON
							// REAL-TIME/REAL-TIME) (BANK)
					// http://www.midi.org/about-midi/tuning_extens.shtml
					int ll = data[7] & 0xFF;
					int r = 8;
					for (int i = 0; i < ll; i++) {
						int kk = data[r++] & 0xFF;
						int xx = data[r++] & 0xFF;
						int yy = data[r++] & 0xFF;
						int zz = data[r++] & 0xFF;
						if (!(xx == 127 && yy == 127 && zz == 127))
							tuning[kk] = 100.0 * (((xx * 16384) + (yy * 128) + zz) / 16384.0);
					}
					break;
				case 0x08: // scale/octave tuning 1-byte form (Non
							// Real-Time/REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning-scale.shtml
					int[] octave_tuning = new int[12];
					for (int i = 0; i < 12; i++)
						octave_tuning[i] = (data[i + 8] & 0xFF) - 64;
					for (int i = 0; i < tuning.length; i++)
						tuning[i] = i * 100 + octave_tuning[i % 12];
					break;
				}
				case 0x09: // scale/octave tuning 2-byte form (Non
							// Real-Time/REAL-TIME)
				{
					// http://www.midi.org/about-midi/tuning-scale.shtml
					double[] octave_tuning = new double[12];
					for (int i = 0; i < 12; i++) {
						int v = (data[i * 2 + 8] & 0xFF) * 128
								+ (data[i * 2 + 9] & 0xFF);
						octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
					}
					for (int i = 0; i < tuning.length; i++)
						tuning[i] = i * 100 + octave_tuning[i % 12];
					break;
				}
				default:
					break;
				}
			}
		}
	}

	public double[] getTuning() {
		return tuning;
	}

	public double getTuning(int noteNumber) {
		return tuning[noteNumber];
	}

	public Patch getPatch() {
		return patch;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}