home *** CD-ROM | disk | FTP | other *** search
Java Source | 2017-09-21 | 5.3 KB | 185 lines |
- //int MID_C = 60;
- // #define NUM_KEYS 12 /* Number of enums in Key */
- // Keep these in order (most important first).
- // Why? See CScale::iStepUpNoteNum
- /* final int NUM_KEYS = 12;
- final int KP_ROOT = 0;
- final int KP_PRIMARY = 1; // "required"?
- final int KP_SECONDARY = 2; // "auxiliary"?
- final int KP_TERTIARY = 3; // "modal"?
- final int KP_CHROMATIC = 4;
- //} KeyPriority; // Hungarian: kp
- final int BST_NO_NOTE=0; // No note on this beat
- final int BST_WHISPER=1;
- final int BST_LIGHT=2; // Faint note
- final int BST_MEDIUM=3; // Normal note
- final int BST_HEAVY=4; // Emphsized note
- final int BST_BANG=5;
- } BeatStress; // Hungarian: bst
- */
-
- //-----------------------------------------------------
-
- // Value between 0 & 127 (MIDI), so sign doesn't matter.
- // typedef char PARAMVAL; // Hungarian: pv
- //-----------------------------------------------------
-
- public class CScale /* Hungarian: scl */
- {
- // Members
- int m_arrkpPriorities[];
-
- // Constants
- final int NUM_KEYS = 12;
- final int KP_ROOT = 0;
- final int KP_PRIMARY = 1; // "required"?
- final int KP_SECONDARY = 2; // "auxiliary"?
- final int KP_TERTIARY = 3; // "modal"?
- final int KP_CHROMATIC = 4;
- //======bogus global functions=====
- public int mod (int x, int y)
- { if (x>=0) return x%y;
- int iNegMod = (-x) % y;
- return (0==iNegMod) ? y-iNegMod : 0;
- }
- public void assert(boolean b) { if (!b) m_arrkpPriorities[-1] = 0; }
- public int rand() { return (int)(Math.random() * 9747); }
- //================================
-
- // Construction/Destruction
- CScale (String szInputString)
- { m_arrkpPriorities = new int[NUM_KEYS];
- if (!bSet(szInputString))
- assert(false);
- }
-
- public boolean bSet (String szInputString)
- { int pChar = 0;
- m_arrkpPriorities[0] = KP_ROOT;
- for(int C=1; C<NUM_KEYS; C++)
- { switch (szInputString.charAt(pChar))
- { case '1': m_arrkpPriorities[C] = KP_PRIMARY; break;
- case '2': m_arrkpPriorities[C] = KP_SECONDARY; break;
- case '3': m_arrkpPriorities[C] = KP_TERTIARY; break;
- case '4': m_arrkpPriorities[C] = KP_CHROMATIC; break;
- default: assert(false); return false;
- }
- pChar++; /* Go to next. */
- }
- return true;
- }
-
- public boolean bSet2 (char pvIndex)
- { if (pvIndex < 20)
- return bSet("42412414243");
- if (pvIndex < 40)
- return bSet("43423414344");
- if (pvIndex < 60)
- return bSet("43243413444");
- if (pvIndex < 80)
- return bSet("42142412443");
- // Charles's Chinese & Japanese scales:
- if (pvIndex < 100)
- return bSet("44142414424");
- // Indexes 012345678901
- return bSet("42144412444");
- }
-
- public char pvGet()
- {
- if (m_arrkpPriorities[8] == KP_CHROMATIC) {
- if (m_arrkpPriorities[2] == KP_CHROMATIC)
- return 99;
- if (m_arrkpPriorities[2] == KP_TERTIARY)
- return 39;
- return 19;
- }
- if (m_arrkpPriorities[8] == KP_TERTIARY)
- return 59;
- if (m_arrkpPriorities[5]== KP_CHROMATIC)
- return 127;
- return 79;
- }
-
- public int iStepUpNoteNum (int iCurrNoteNum,
- int iNumSteps /*= 1*/,
- int iRootNoteNum /*= MID_C*/,
- int kpThreshold /*= KP_TERTIARY*/)
- { int iOldIndex = iNoteNumToIndex(iCurrNoteNum, iRootNoteNum);
- int iNewIndex = iOldIndex;
- int iIncrement = (iNumSteps >= 0) ? 1 : -1;
-
- for (int C = 0; C != iNumSteps; C += iIncrement)
- for (iNewIndex += iIncrement;
- m_arrkpPriorities[mod(iNewIndex,NUM_KEYS)] > kpThreshold;
- iNewIndex += iIncrement) ;
- return iCurrNoteNum + iNewIndex - iOldIndex;
- }
-
- public int iRoundNoteNum (int iCurrNoteNum, int kpRound,
- int iRootNoteNum)
- { assert(KP_ROOT <= kpRound && kpRound <= KP_CHROMATIC);
- int iOldIndex = iNoteNumToIndex(iCurrNoteNum, iRootNoteNum);
- for (int C=0; C < NUM_KEYS; C++)
- { if (kpRound >=
- m_arrkpPriorities[mod(iOldIndex + C, NUM_KEYS)])
- return iCurrNoteNum + C;
- if (kpRound >=
- m_arrkpPriorities[mod(iOldIndex - C, NUM_KEYS)])
- return iCurrNoteNum - C;
- }
- assert(false);
- return -1;
- }
-
- private boolean bKP_SAME(int kp1, int kp2)
- { return ((kp1==KP_PRIMARY || kp1==KP_ROOT) ?
- (kp2==KP_PRIMARY || kp2==KP_ROOT) :
- (kp2==KP_SECONDARY || kp2==KP_TERTIARY));
- }
-
- public int iMatchNearestChord (int iCurrNoteNum, int kpRound,
- int iRootNoteNum)
- { int iOldIndex = iNoteNumToIndex(iCurrNoteNum, iRootNoteNum);
-
- // There's a chance we'll just match to the scale instead...
- if ((m_arrkpPriorities[iOldIndex] == KP_ROOT ||
- m_arrkpPriorities[iOldIndex] == KP_PRIMARY) &&
- rand()%3 == 0)
- return iCurrNoteNum;
-
- if (kpRound == KP_CHROMATIC ||
- bKP_SAME(kpRound, m_arrkpPriorities[iOldIndex]))
- return iCurrNoteNum;
- for (int C=1; C < NUM_KEYS; C++)
- { if (bKP_SAME(kpRound,
- m_arrkpPriorities[mod(iOldIndex + C, NUM_KEYS)]))
- return iCurrNoteNum + C;
- if (bKP_SAME(kpRound,
- m_arrkpPriorities[mod(iOldIndex - C, NUM_KEYS)]))
- return iCurrNoteNum - C;
- }
- assert(false);
- return -1;
- }
-
- // Return the priority of the given note number in this scale.
- public int kpGetPriority(int iNoteNum, int iRootNoteNum)
- { return m_arrkpPriorities[iNoteNumToIndex(iNoteNum,
- iRootNoteNum)];
- }
-
- // Implementation
- //protected void AddToScale (Key ky, int kp);
- int iNoteNumToIndex (int iCurrNoteNum, int iRootNoteNum)
- { iRootNoteNum %= NUM_KEYS;
- iCurrNoteNum %= NUM_KEYS;
- if (iRootNoteNum <= iCurrNoteNum)
- return iCurrNoteNum - iRootNoteNum;
- return iCurrNoteNum + NUM_KEYS - iRootNoteNum;
- }
-
- } // CScale
-
- //-------------------------------------------------------
-