SongPart.ck 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. public class SongPart
  2. {
  3. "subclass responsibility - do not instantiate this class" => string ABSTRACT_CLASS_MSG ;
  4. "index out of range" => string OOB_MSG ; 0::ms => dur ZERO_DURATION ;
  5. float NOTES[128] ; 10 => int HIGHEST_OCTAVE ; 12 => int N_NOTES_PER_OCTAVE ;
  6. for (1 => int octaveN ; octaveN <= HIGHEST_OCTAVE ; ++octaveN)
  7. {
  8. // notes below e1 (20.6hz) will not be triggered and equivelant to rests
  9. octaveN * N_NOTES_PER_OCTAVE => float c ;
  10. c => NOTES["c" + octaveN] ;
  11. c + 1.0 => NOTES["c#" + octaveN] ;
  12. c + 1.0 => NOTES["db" + octaveN] ;
  13. c + 2.0 => NOTES["d" + octaveN] ;
  14. c + 3.0 => NOTES["d#" + octaveN] ;
  15. c + 3.0 => NOTES["eb" + octaveN] ;
  16. c + 4.0 => NOTES["e" + octaveN] ;
  17. c + 5.0 => NOTES["f" + octaveN] ;
  18. c + 6.0 => NOTES["f#" + octaveN] ;
  19. c + 6.0 => NOTES["gb" + octaveN] ;
  20. c + 7.0 => NOTES["g" + octaveN] ;
  21. if (octaveN == HIGHEST_OCTAVE) continue ;
  22. c + 8.0 => NOTES["g#" + octaveN] ;
  23. c + 8.0 => NOTES["ab" + octaveN] ;
  24. c + 9.0 => NOTES["a" + octaveN] ;
  25. c + 10.0 => NOTES["a#" + octaveN] ;
  26. c + 10.0 => NOTES["bb" + octaveN] ;
  27. c + 11.0 => NOTES["b" + octaveN] ;
  28. }
  29. string notes[] ;
  30. float frequencies[] ;
  31. dur durations[] ;
  32. dur quarterNote ;
  33. dur runningTime ;
  34. fun void setInstrument(Mandolin anInstrument) { <<< ABSTRACT_CLASS_MSG >>> ; }
  35. fun void setTempo(float tempo)
  36. {
  37. // <<< "setTempo() tempo=" , tempo >>> ;
  38. 60::second / tempo => quarterNote ;
  39. }
  40. // fun void clearNotes() { string empty[] @=> notes ; parseNotes() ; }
  41. fun void setNotes(string someNotes[]) { someNotes @=> notes ; parseNotes() ; }
  42. fun void setSomeNotes(string someNotes[] , int fromIdx , int nNewNotes)
  43. { setNotes(subList(someNotes , fromIdx , nNewNotes)) ; }
  44. fun void setNote(string note , int idx) { note => notes[idx] ; parseNotes() ; }
  45. fun void insertNotes(string someNotes[] , int idx)
  46. {
  47. // <<< "insertNotes() nOldNotes=" , notes.cap() , " nInsertNotes=" , someNotes.cap() , " nNewNotes=" , notes.cap() + someNotes.cap() >>> ;
  48. if (idx < 0 || idx > notes.cap()) return ;
  49. notes.cap() => int nOldNotes ; someNotes.cap() => int nNewNotes ;
  50. string newNotes[nOldNotes + nNewNotes] ;
  51. for (0 => int i ; i < idx ; ++i) notes[i] => newNotes[i] ;
  52. for (0 => int i ; i < nNewNotes ; ++i) someNotes[i] => newNotes[idx + i] ;
  53. for (idx => int i ; i < nOldNotes ; ++i) notes[i] => newNotes[nNewNotes + i] ;
  54. newNotes @=> notes ; parseNotes() ;
  55. // <<< "insertNotes() nNotesOUT=" , notes.cap() >>> ; for (0 => int i ; i < notes.cap() ; ++i) <<< "notes[" , i , "]='" , notes[i] , "'" >>> ;
  56. }
  57. fun string[] subList(string someNotes[] , int fromIdx , int nNewNotes)
  58. {
  59. // <<< "addSomeNotes() nOldNotes=" , notes.cap() , " fromIdx=" , fromIdx , " nNewNotes=" , nNewNotes , " of nNotes=" , someNotes.cap() >>> ;
  60. string newNotes[nNewNotes] ;
  61. if (nNewNotes < 0 || fromIdx + nNewNotes > someNotes.cap() ||
  62. fromIdx < 0 || fromIdx >= someNotes.cap()) <<< OOB_MSG >>> ;
  63. else for (0 => int i ; i < nNewNotes ; ++i) someNotes[fromIdx + i] => newNotes[i] ;
  64. return newNotes ;
  65. }
  66. fun void addSomeNotes(string someNotes[] , int fromIdx , int nNewNotes)
  67. { insertNotes(subList(someNotes , fromIdx , nNewNotes) , notes.cap()) ; }
  68. fun void addNotes(string someNotes[]) { addSomeNotes(someNotes , 0 , someNotes.cap()) ; }
  69. fun void parseNotes()
  70. {
  71. // <<< "parseNotes() nNotes=" , notes.cap() >>> ;
  72. notes.cap() => int nNotes ; StringTokenizer tok ;
  73. float freqs[nNotes] ; dur durs[nNotes] ; 1::samp => dur time ;
  74. for(0 => int noteN ; noteN < nNotes ; ++noteN)
  75. {
  76. // <<< "parseNotes() noteN=" , noteN >>> ;
  77. tok.set(notes[noteN]) ;
  78. if (tok.more()) Std.mtof(NOTES[tok.next()]) => freqs[noteN] ;
  79. if (tok.more()) Std.atof(tok.next()) * quarterNote => durs[noteN] ;
  80. durs[noteN] +=> time ;
  81. }
  82. freqs @=> frequencies ; durs @=> durations ; time => runningTime ;
  83. // <<< "parseNotes() nFrequencies=" , frequencies.cap() , " nDurations=" , durations.cap() , " runningTime=" , runningTime >>> ;
  84. }
  85. fun dur playNote(int noteN) { <<< ABSTRACT_CLASS_MSG >>> ; return ZERO_DURATION ; }
  86. fun dur stopNote(int noteN) { <<< ABSTRACT_CLASS_MSG >>> ; return ZERO_DURATION ; }
  87. }