Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 190 lines 5.5 kB view raw
1package org.bukkit; 2 3import java.util.HashMap; 4import java.util.Map; 5 6/** 7 * A note class to store a specific note. 8 */ 9public class Note { 10 11 /** 12 * An enum holding tones. 13 */ 14 public enum Tone { 15 F((byte) -0x1, true), G((byte) 0x1, true), A((byte) 0x3, true), B((byte) 0x5, false), C((byte) 0x6, true), D((byte) 0x8, true), E((byte) 0xA, false); 16 17 private final boolean sharpable; 18 private final byte id; 19 private static final Map<Byte, Note.Tone> tones = new HashMap<Byte, Note.Tone>(); 20 /** 21 * The number of tones including sharped tones. 22 */ 23 public static final byte TONES_COUNT; 24 25 private Tone(byte id, boolean sharpable) { 26 this.id = id; 27 this.sharpable = sharpable; 28 } 29 30 /** 31 * Returns the not sharped id of this tone. 32 * 33 * @return the not sharped id of this tone. 34 */ 35 public byte getId() { 36 return getId(false); 37 } 38 39 /** 40 * Returns the id of this tone. These method allows to return the 41 * sharped id of the tone. If the tone couldn't be sharped it always 42 * return the not sharped id of this tone. 43 * 44 * @param sharped Set to true to return the sharped id. 45 * @return the id of this tone. 46 */ 47 public byte getId(boolean sharped) { 48 byte tempId = (byte) (sharped && sharpable ? id + 1 : id); 49 50 while (tempId < 0) { 51 tempId += TONES_COUNT; 52 } 53 return (byte) (tempId % TONES_COUNT); 54 } 55 56 /** 57 * Returns if this tone could be sharped. 58 * 59 * @return if this tone could be sharped. 60 */ 61 public boolean isSharpable() { 62 return sharpable; 63 } 64 65 /** 66 * Returns if this tone id is the sharped id of the tone. 67 * 68 * @param id the id of the tone. 69 * @return if the tone id is the sharped id of the tone. 70 * @throws IllegalArgumentException if neither the tone nor the semitone have the id. 71 */ 72 public boolean isSharped(byte id) { 73 if (id == getId(false)) { 74 return false; 75 } else if (id == getId(true)) { 76 return true; 77 } else { 78 // The id isn't matching to the tone! 79 throw new IllegalArgumentException("The id isn't matching to the tone."); 80 } 81 } 82 83 /** 84 * Returns the tone to id. Also returning the semitones. 85 * 86 * @param id the id of the tone. 87 * @return the tone to id. 88 */ 89 public static Tone getToneById(byte id) { 90 return tones.get(id); 91 } 92 93 static { 94 byte lowest = F.id; 95 byte highest = F.id; 96 for (Tone tone : Tone.values()) { 97 byte id = tone.id; 98 tones.put(id, tone); 99 if (id < lowest) { 100 lowest = id; 101 } 102 if (tone.isSharpable()) { 103 id++; 104 tones.put(id, tone); 105 } 106 if (id > highest) { 107 highest = id; 108 } 109 } 110 111 TONES_COUNT = (byte) (highest - lowest + 1); 112 tones.put((byte) (TONES_COUNT - 1), F); 113 } 114 } 115 116 private final byte note; 117 118 /** 119 * Creates a new note. 120 * 121 * @param note Internal note id. {@link #getId()} always return this value. 122 * The value has to be in the interval [0;&nbsp;24]. 123 */ 124 public Note(byte note) { 125 if (note < 0 || note > 24) { 126 throw new IllegalArgumentException("The note value has to be between 0 and 24."); 127 } 128 this.note = note; 129 } 130 131 /** 132 * Creates a new note. 133 * 134 * @param octave The octave where the note is in. Has to be 0 - 2. 135 * @param note The tone within the octave. If the octave is 2 the note has to 136 * be F#. 137 * @param sharped Set it the tone is sharped (e.g. for F#). 138 */ 139 public Note(byte octave, Tone note, boolean sharped) { 140 if (sharped && !note.isSharpable()) { 141 throw new IllegalArgumentException("This tone could not be sharped."); 142 } 143 if (octave < 0 || octave > 2 || (octave == 2 && !(note == Tone.F && sharped))) { 144 throw new IllegalArgumentException("Tone and octave have to be between F#0 and F#2"); 145 } 146 this.note = (byte) (octave * Tone.TONES_COUNT + note.getId(sharped)); 147 } 148 149 /** 150 * Returns the internal id of this note. 151 * 152 * @return the internal id of this note. 153 */ 154 public byte getId() { 155 return note; 156 } 157 158 /** 159 * Returns the octave of this note. 160 * 161 * @return the octave of this note. 162 */ 163 public int getOctave() { 164 return note / Tone.TONES_COUNT; 165 } 166 167 private byte getToneByte() { 168 return (byte) (note % Tone.TONES_COUNT); 169 } 170 171 /** 172 * Returns the tone of this note. 173 * 174 * @return the tone of this note. 175 */ 176 public Tone getTone() { 177 return Tone.getToneById(getToneByte()); 178 } 179 180 /** 181 * Returns if this note is sharped. 182 * 183 * @return if this note is sharped. 184 */ 185 public boolean isSharped() { 186 byte note = getToneByte(); 187 return Tone.getToneById(note).isSharped(note); 188 } 189 190}