/Users/lyon/j4p/src/sound/musica/MusicalScaleToMidi.java

1    package sound.musica; 
2    /** 
3     * Created by IntelliJ IDEA. 
4     * User: Carl 
5     * Date: Oct 3, 2003 
6     * Time: 3:34:29 PM 
7     * To change this template use Options | File Templates. 
8     */ 
9    public class MusicalScaleToMidi { 
10       public static final int midiMinNote = 0; 
11       public static final int midiMaxNote = 127; 
12       public static final int midiNoteRange = 128; // 0-127 possible midi notes 
13       public static final int midiOctaveSpan = 12; // intrinsic 12 tone chromatic intervalScale 
14       public static final int numMidiOctaves = 2 + midiNoteRange / midiOctaveSpan; //round up midi range on both ends 
15    
16       private int[] intervalScale;// Programmer chooses type of intervalScale from Scales.java 
17       private int[] sequenceScale;// Scale sequence (ref to one octave) derived here from intervalScale 
18       private int lengthOfScale; // simplify clumsy references to array length 
19       private int userSequenceLo; // Lowest note in sequence scale, ref to 0 of scale 
20       private int userSequenceHi; // Highest note in sequence scale, ref to 0 of scale 
21       private int midiStartOfUserScale;  // Programmer chooses where to start interval Scale 
22       private int[][] midiUserScaleProgression;  // "keyboard" [octave][note] mapping to midi output 
23       // Program computes limits of octave-note inputs 
24       private int lowestUserOctave;  // Lowest within midi, in user octave numbers 
25       private int highestUserOctave; // Highest within midi, in user octave numbers 
26       private int lowestUserNote = midiMinNote;    // Lowest note within midi in lowest octave 
27       private int highestUserNote = midiMaxNote;  // Highest note within midi in highest octave 
28       /** 
29        * @param _intervalScale    choice of intervalScale from Scales class 
30        * @param _midiStartOfScale    insertion point of intervalScale[0] in midi 0-127 
31        */ 
32       public MusicalScaleToMidi(int _intervalScale[], int _midiStartOfScale) { 
33           this.intervalScale = _intervalScale;   // Programmer responsible for reasonable numbers 
34           this.midiStartOfUserScale = _midiStartOfScale;    // 0 - 127 
35           lengthOfScale = intervalScale.length; 
36           sequenceScale = new int[intervalScale.length]; 
37           computeSequenceScale(); 
38           midiUserScaleProgression = new int[numMidiOctaves][lengthOfScale]; 
39           computeUserToMidiOctaveOffsets(); 
40           createNoteArray(); 
41       } 
42       /** 
43        * Computes actual scale sequence from interval scale 
44        */ 
45       private void computeSequenceScale() { 
46           sequenceScale[0] = intervalScale[0]; 
47           for (int i = 1; i < intervalScale.length; i++) { 
48               sequenceScale[i] = sequenceScale[i - 1] + intervalScale[i]; 
49           } 
50           userSequenceLo = sequenceScale[0];  // 1st note may not be at scale base (e.g. black notes) 
51           userSequenceHi = sequenceScale[lengthOfScale - 1]; // top note in scale, under octave top 
52       } 
53    
54       private void computeUserToMidiOctaveOffsets() { 
55           int pointer = midiStartOfUserScale; //midi of user note 0 in any octave 
56           int counter = 0; // counts octave offset from user octave 0 
57    
58           // First: Drop the pointer to below the midi range, if not there already 
59           while (pointer + userSequenceHi >= midiMinNote) { 
60               pointer -= midiOctaveSpan; 
61               counter--; 
62           } 
63    
64           // Second: Raise pointer until first scale notes appear in midi range 
65           while (pointer + userSequenceHi < midiMinNote) { 
66               pointer += midiOctaveSpan; 
67               counter++; 
68           } 
69           lowestUserOctave = counter; 
70           int i = 0; 
71           while (pointer + sequenceScale[i] < midiMinNote) { // find first note above midiMin 
72               i++; 
73           } 
74           lowestUserNote = i; 
75    
76           // Third: Raise the pointer above the midi range 
77           while (pointer + userSequenceLo <= midiMaxNote) { 
78               pointer += midiOctaveSpan; 
79               counter++; 
80           } 
81    
82           // Fourth: Drop back within range 
83           pointer -= midiOctaveSpan; 
84           counter--; 
85           highestUserOctave = counter; 
86           i = lengthOfScale - 1; // point to top of scale 
87           while (pointer + sequenceScale[i] > midiMaxNote) { // find first note within range 
88               i--; 
89           } 
90           highestUserNote = i; 
91       } 
92    
93       private void createNoteArray() { 
94           int tempNote; 
95           for (int arrayOctaveNumber = 0; arrayOctaveNumber < numMidiOctaves; arrayOctaveNumber++) { 
96               for (int noteNumber = 0; noteNumber < lengthOfScale; noteNumber++) { 
97                   tempNote = mapToMidi(arrayOctaveNumber + lowestUserOctave, sequenceScale[noteNumber]); 
98                   midiUserScaleProgression[arrayOctaveNumber][noteNumber] = tempNote; 
99               } 
100          } 
101      } 
102   
103      private int mapToMidi(int playersOctaveNumber, int noteInOctave) { 
104          //  return midiNote; 
105          return midiStartOfUserScale + midiOctaveSpan * playersOctaveNumber + noteInOctave; 
106      } 
107   
108      // Getters, toString, main 
109      public int[][] getMidiUserScaleProgression() { 
110          return midiUserScaleProgression; 
111      } 
112   
113      public int[] getIntervalScale() { 
114          return intervalScale; 
115      } 
116   
117      public int getMidiStartOfUserScale() { 
118          return midiStartOfUserScale; 
119      } 
120   
121      public int getLowestUserOctave() { 
122          return lowestUserOctave; 
123      } 
124   
125      public int getHighestUserOctave() { 
126          return highestUserOctave; 
127      } 
128   
129      public int getLowestUserNote() { 
130          return lowestUserNote; 
131      } 
132   
133      public int getHighestUserNote() { 
134          return highestUserNote; 
135      } 
136   
137      public String toString() { 
138          String s = ""; 
139          for (int octaveNumber = 0; octaveNumber < midiUserScaleProgression.length; octaveNumber++) { 
140              s += "\n"; 
141              for (int noteNumber = 0; noteNumber < midiUserScaleProgression[0].length; noteNumber++) { 
142                  s += midiUserScaleProgression[octaveNumber][noteNumber] + "\t"; 
143              } 
144          } 
145          s += "\nmidiStartOfUserScale: " + midiStartOfUserScale; 
146          s+= "\nlowOctave; " + lowestUserOctave + "; \tlowNote = " + lowestUserNote; 
147          s+= "\nhighOctave; " + highestUserOctave + "; \thighNote = " + highestUserNote; 
148          return s; 
149      } 
150   
151      public static void main(String[] args) { 
152          int startNote = 127; 
153          MusicalScaleToMidi pro = 
154                  new MusicalScaleToMidi(ScaleManager.BLACK_KEYS, startNote); 
155          System.out.println(pro.toString()); 
156      } 
157  }