home *** CD-ROM | disk | FTP | other *** search
/ Internet 1996 World Exposition / park.org.s3.amazonaws.com.7z / park.org.s3.amazonaws.com / Cdrom / Pavilions / BrainOpera / online / net-music / net-instrument / CScale.java < prev    next >
Encoding:
Java Source  |  2017-09-21  |  5.3 KB  |  185 lines

  1. //int MID_C = 60;
  2. // #define NUM_KEYS 12 /* Number of enums in Key */
  3. // Keep these in order (most important first).
  4. // Why? See CScale::iStepUpNoteNum
  5. /*    final int NUM_KEYS = 12;
  6.     final int KP_ROOT = 0;
  7.     final int KP_PRIMARY = 1;    // "required"?
  8.     final int KP_SECONDARY = 2;    // "auxiliary"?
  9.     final int KP_TERTIARY = 3;    // "modal"?
  10.     final int KP_CHROMATIC = 4;
  11. //} KeyPriority;        // Hungarian: kp
  12.     final int BST_NO_NOTE=0;    // No note on this beat
  13.     final int BST_WHISPER=1;
  14.     final int BST_LIGHT=2;    // Faint note
  15.     final int BST_MEDIUM=3;    // Normal note
  16.     final int BST_HEAVY=4;    // Emphsized note
  17.     final int BST_BANG=5;
  18. } BeatStress;    // Hungarian: bst
  19. */
  20.  
  21. //-----------------------------------------------------
  22.  
  23. // Value between 0 & 127 (MIDI), so sign doesn't matter.
  24. // typedef char PARAMVAL;    // Hungarian: pv
  25. //-----------------------------------------------------
  26.  
  27. public class CScale /* Hungarian: scl */
  28. {
  29. // Members
  30.     int m_arrkpPriorities[];
  31.  
  32. // Constants
  33.     final int NUM_KEYS = 12;
  34.     final int KP_ROOT = 0;
  35.     final int KP_PRIMARY = 1;    // "required"?
  36.     final int KP_SECONDARY = 2;    // "auxiliary"?
  37.     final int KP_TERTIARY = 3;    // "modal"?
  38.     final int KP_CHROMATIC = 4;
  39. //======bogus global functions=====
  40. public int mod (int x, int y)
  41. {    if (x>=0) return x%y;
  42.     int iNegMod = (-x) % y;
  43.     return (0==iNegMod) ? y-iNegMod : 0;
  44. }
  45. public void assert(boolean b) { if (!b) m_arrkpPriorities[-1] = 0; }
  46. public int rand() { return (int)(Math.random() * 9747); }
  47. //================================
  48.  
  49. // Construction/Destruction
  50. CScale (String szInputString)
  51. {    m_arrkpPriorities = new int[NUM_KEYS];
  52.     if (!bSet(szInputString))
  53.         assert(false);
  54. }
  55.  
  56. public boolean bSet (String szInputString)
  57. {    int pChar = 0;
  58.     m_arrkpPriorities[0] = KP_ROOT;
  59.     for(int C=1; C<NUM_KEYS; C++)
  60.     {    switch (szInputString.charAt(pChar))
  61.         {    case '1': m_arrkpPriorities[C] = KP_PRIMARY; break;
  62.             case '2': m_arrkpPriorities[C] = KP_SECONDARY; break;
  63.             case '3': m_arrkpPriorities[C] = KP_TERTIARY; break;
  64.             case '4': m_arrkpPriorities[C] = KP_CHROMATIC; break;
  65.             default: assert(false); return false;
  66.         }
  67.         pChar++;    /* Go to next. */
  68.     }
  69.     return true;
  70. }
  71.  
  72. public boolean bSet2 (char pvIndex)
  73. {    if (pvIndex < 20)
  74.         return bSet("42412414243");
  75.     if (pvIndex < 40)
  76.         return bSet("43423414344");
  77.     if (pvIndex < 60)
  78.         return bSet("43243413444");
  79.     if (pvIndex < 80)
  80.         return bSet("42142412443");
  81.     // Charles's Chinese & Japanese scales:
  82.     if (pvIndex < 100)
  83.         return bSet("44142414424");
  84.     // Indexes      012345678901
  85.         return bSet("42144412444");
  86. }
  87.  
  88. public char pvGet()
  89. {
  90.     if (m_arrkpPriorities[8] == KP_CHROMATIC) {
  91.         if (m_arrkpPriorities[2] == KP_CHROMATIC)
  92.             return 99;
  93.         if (m_arrkpPriorities[2] == KP_TERTIARY)
  94.             return 39;
  95.         return 19;
  96.     }    
  97.     if (m_arrkpPriorities[8] == KP_TERTIARY)
  98.         return 59;
  99.     if (m_arrkpPriorities[5]== KP_CHROMATIC)
  100.         return 127;
  101.     return 79;
  102. }
  103.  
  104. public int iStepUpNoteNum (int iCurrNoteNum,
  105.     int iNumSteps /*= 1*/,
  106.     int iRootNoteNum /*= MID_C*/,
  107.     int kpThreshold /*= KP_TERTIARY*/)
  108. {    int iOldIndex = iNoteNumToIndex(iCurrNoteNum, iRootNoteNum);
  109.     int iNewIndex = iOldIndex;
  110.     int iIncrement = (iNumSteps >= 0) ? 1 : -1;
  111.     
  112.     for (int C = 0; C != iNumSteps; C += iIncrement)
  113.         for (iNewIndex += iIncrement;
  114.             m_arrkpPriorities[mod(iNewIndex,NUM_KEYS)] > kpThreshold;
  115.             iNewIndex += iIncrement) ;
  116.     return iCurrNoteNum + iNewIndex - iOldIndex;
  117. }
  118.  
  119. public int iRoundNoteNum (int iCurrNoteNum, int kpRound,
  120.         int iRootNoteNum)
  121. {    assert(KP_ROOT <= kpRound && kpRound <= KP_CHROMATIC);
  122.     int iOldIndex = iNoteNumToIndex(iCurrNoteNum, iRootNoteNum);
  123.     for (int C=0; C < NUM_KEYS; C++)
  124.     {    if (kpRound >= 
  125.             m_arrkpPriorities[mod(iOldIndex + C, NUM_KEYS)])
  126.             return iCurrNoteNum + C;
  127.         if (kpRound >=
  128.             m_arrkpPriorities[mod(iOldIndex - C, NUM_KEYS)])
  129.             return iCurrNoteNum - C;
  130.     }
  131.     assert(false);
  132.     return -1;
  133. }
  134.  
  135. private boolean bKP_SAME(int kp1, int kp2)
  136. {    return ((kp1==KP_PRIMARY || kp1==KP_ROOT) ?
  137.         (kp2==KP_PRIMARY || kp2==KP_ROOT) :
  138.         (kp2==KP_SECONDARY || kp2==KP_TERTIARY));
  139. }
  140.  
  141. public int iMatchNearestChord (int iCurrNoteNum, int kpRound,
  142.         int iRootNoteNum)
  143. {    int iOldIndex = iNoteNumToIndex(iCurrNoteNum, iRootNoteNum);
  144.  
  145.     // There's a chance we'll just match to the scale instead...
  146.     if ((m_arrkpPriorities[iOldIndex] == KP_ROOT ||
  147.         m_arrkpPriorities[iOldIndex] == KP_PRIMARY) &&
  148.         rand()%3 == 0)
  149.         return iCurrNoteNum;
  150.  
  151.     if (kpRound == KP_CHROMATIC || 
  152.         bKP_SAME(kpRound, m_arrkpPriorities[iOldIndex]))
  153.         return iCurrNoteNum;
  154.     for (int C=1; C < NUM_KEYS; C++)
  155.     {    if (bKP_SAME(kpRound,
  156.             m_arrkpPriorities[mod(iOldIndex + C, NUM_KEYS)]))
  157.             return iCurrNoteNum + C;
  158.         if (bKP_SAME(kpRound,
  159.             m_arrkpPriorities[mod(iOldIndex - C, NUM_KEYS)]))
  160.             return iCurrNoteNum - C;
  161.     }
  162.     assert(false);
  163.     return -1;
  164. }
  165.     
  166. // Return the priority of the given note number in this scale.
  167. public int kpGetPriority(int iNoteNum, int iRootNoteNum)
  168. {    return m_arrkpPriorities[iNoteNumToIndex(iNoteNum,
  169.         iRootNoteNum)];
  170. }
  171.     
  172. // Implementation
  173. //protected void AddToScale (Key ky, int kp);
  174. int iNoteNumToIndex (int iCurrNoteNum, int iRootNoteNum)
  175. {    iRootNoteNum %= NUM_KEYS;
  176.     iCurrNoteNum %= NUM_KEYS;
  177.     if (iRootNoteNum <= iCurrNoteNum)
  178.         return iCurrNoteNum - iRootNoteNum;
  179.     return iCurrNoteNum + NUM_KEYS - iRootNoteNum;    
  180. }
  181.  
  182. }    // CScale
  183.  
  184. //-------------------------------------------------------
  185.