1   package fi.jyu.mit.Music;
2   
3   /**
4    * Luokka nuottien esittämiseen.
5    */
6   public class Note {
7       public static final int DELAY = -10000;
8   
9       private int note;
10      private int length;
11      private int velocity;
12      
13      /**
14       * Alutetaan nuotti
15       * @param note MIDI-nuotin arvo (21-108)
16       * @param length Kesto millisekunteina
17       * @param velocity Nuotin nk. painovoimakkuus. Oletus on 64.     
18       */
19      public Note(int note, int length, int velocity) {
20          this.setNote(note);
21          this.setLength(length);
22          this.setVelocity(velocity);
23      }
24  
25      
26      /**
27       * Taukoa kuvaava nuotti
28       * @author vesal
29       * @version 13.11.2010
30       */
31      public static class Delay extends Note {
32          /**
33           * Muodotetaan uusi tauko
34           * @param length
35           * @example
36           * <pre name="test">
37           *    Note n = new Note.Delay(200);
38           *    n.isDelay() === true;
39           *    n.getLength() === 200;
40           * </pre>
41           */
42          public Delay(int length) {
43              super(DELAY,length,DELAY);
44              super.setNote(DELAY);
45              super.setVelocity(DELAY);
46          }
47  
48          
49          /**
50           * Ei tee mitään tauko-luokassa
51           * @example
52           * <pre name="test">
53           *    Note n = new Note.Delay(200);
54           *    n.setNote(60);
55           *    n.isDelay() === true;    
56           * </pre>
57           */
58          @Override
59          public void setNote(int note) {
60          }
61          
62      }
63      
64      
65      /**
66       * Tehdään nuotista kopio
67       * @param n nuotti jolla uusi nuotti alustetaan.
68       */
69      public Note(Note n) {
70          this(n.note,n.length,n.velocity);
71      }
72      
73      
74      /**
75       * Alustetaan nuotin arvo. Negatiivinen on tauko.
76       * @param note MIDI-nuotin arvo (21-108)
77       * @example
78       * <pre name="test">
79       *   Note n = new Note(30,300,64);
80       *   n.getNote() === 30;
81       *   n.setNote(Note.DELAY);
82       *   n.isDelay() === true;
83       *   n.setNote(2);
84       *   n.getNote() === 21;
85       *   n.setNote(200);
86       *   n.getNote() === 108; 
87       *   n.setNote(-1);
88       *   n.isDelay() === true;
89       * </pre>
90       */
91      public void setNote(int note) {
92          this.note = note;
93          if ( note < 21 ) this.note = 21;
94          if ( note > 108 ) this.note = 108;
95          if ( note < 0 ) { this.note = DELAY; this.velocity = DELAY; }
96      }
97  
98      
99      /**
100      * @return MIDI-nuotin arvo (21-108)
101      */
102     public int getNote() {
103         return note;
104     }
105     
106     
107     /**
108      * @return true jos nuotti edustaa taukoa
109      */
110     public boolean isDelay() {
111         return getNote() < 0;
112     }
113     
114     
115     /**
116      * asetetaan nuotin pituus
117      * @param length asetettava pituus
118      */
119     public void setLength(int length) {
120         this.length = length;
121     }
122     
123     
124     /**
125      * @return nuotin pituus
126      */
127     public int getLength() {
128         return length;
129     }
130     
131     
132     /**
133      * Asetetaan kuinka voimakkaasti painetaan. 
134      * @param velocity Nuotin nk. painovoimakkuus. Oletus on 64.     
135      */
136     public void setVelocity(int velocity) {
137         this.velocity = velocity;
138     }
139     
140     
141     /**
142      * @return nuotin nk. painovoimakkuus. Oletus on 64.
143      */
144     public int getVelocity() {
145         return velocity;
146     }
147     
148     
149     /**
150      * Muuttaa modi-nuotin merkkijonoksi.  Tauko on "-" 
151      * @param note MIDI-nuotin arvo (21-108)
152      * @return midi-nuotin arvo merkkijonona.
153      * 
154      * @example
155      * <pre name="test">
156      *   Note.toString(21) === "A0";
157      *   Note.toString(22) === "Bb0";
158      *   Note.toString(23) === "B0";
159      *   Note.toString(24) === "C1";
160      *   Note.toString(25) === "C#1";
161      *   Note.toString(60) === "C4";
162      *   Note.toString(106) === "Bb7";
163      *   Note.toString(107) === "B7";
164      *   Note.toString(108) === "C8";
165      *   Note.toString(-1) === "-";
166      * </pre>
167      */
168     public static String toString(int note) {
169         if (note < 0) 
170             return "-";
171         StringBuffer sb = new StringBuffer();
172         int base = 24;
173         int noteIndex = 0;
174         int octave = 0;
175         // Jos nuotti > 23, ollaan nollaoktaavin puolella, jolloin pitää oktaavien lukumäärä vähentää nuotista.
176         if (note > 23) { 
177             octave = (note / 12) - 1;
178             noteIndex = note - (base + ((octave - 1) * 12));
179         } else {
180             noteIndex = note - 12;
181         }
182         if (noteIndex != 10) {
183             sb.append(MidiPlayer.ALLNOTES[noteIndex]);
184         } else {
185             sb.append("Bb");
186         }
187         // Lisää oktaavi
188         sb.append(octave);
189         return sb.toString();
190     }
191     
192     
193     /**
194      * Muuttaa nuotin merkkijonoksi
195      * @return nuotti merkkijonona
196      * @example
197      * <pre name="test">
198      *   Note n = new Note(60,250,64);
199      *   n.toString() === "C4";
200      * </pre>
201      */
202     public String toString() {
203         return toString(note);
204     }
205 
206     
207     /**
208      * Palauttaa nuottia vastaavan tulostettavan viestin
209      * 
210      * @param note MIDI-nuotin arvo (21-108)
211      * @param length Kesto millisekunteina
212      * @param velocity Nuotin nk. painovoimakkuus. Oletus on 64.     
213      * @return nuottia vastaava "debug"-viesti
214      * 
215      * @example
216      * <pre name="test">
217      *   Note.message(60,250,64) === "' 60' C4  kesto  250 ms";  
218      *   Note.message(-1,250,64) === "'   '     kesto  250 ms";  
219      * </pre>
220      */
221     public static String message(int note, int length, int velocity) {
222         if ( note < 0 )
223             return String.format("'%3s' %-3s kesto %4d ms", "","",length);
224           return String.format("'%3d' %-3s kesto %4d ms", note,toString(note),length);
225         
226     }
227     
228     /**
229      * Palauttaa nuottia vastaavan tulostettavan viestin
230      * 
231      * @example
232      * <pre name="test">
233      *   Note n = new Note(60,250,64);
234      *   n.message() === "' 60' C4  kesto  250 ms";
235      * </pre>
236      */
237     public String message() {
238         return message(getNote(),getLength(),getVelocity());
239     }
240     
241 }
242 
243 
244 
245