score.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "score.h"
  2. #include "ustjkeys.h"
  3. #include "math.h"
  4. static bool endFlag(QString& str,QString e)
  5. {
  6. if(str.endsWith(e)) {
  7. str = str.remove(e);
  8. return true;
  9. }
  10. return false;
  11. }
  12. float QtauScore::checkInc(QString type, float lastpos)
  13. {
  14. if(lastpos<=0.0f) return 0.0f;
  15. if(type=="DYN")
  16. {
  17. if(last_DYN>=lastpos) lastpos = last_DYN + 0.001f;
  18. last_DYN = lastpos;
  19. qDebug() << "last_DYN" << last_DYN;
  20. }
  21. else if(type=="PIT")
  22. {
  23. if(last_PIT>=lastpos) lastpos = last_PIT + 0.001f;
  24. last_PIT = lastpos;
  25. }
  26. return lastpos;
  27. }
  28. void QtauScore::fillTrack(QString type,QStringList events,synthNote* note)
  29. {
  30. //special case: events.size == 0
  31. //type: DYN or PIT --> later pho
  32. for(int i=0;i<events.size();i++)
  33. {
  34. QStringList sub = events[i].split(",");
  35. if(sub.size()==2)
  36. {
  37. synthPoint p;
  38. auto x = sub[0];
  39. bool x_percent = endFlag(x,"%");
  40. auto y = sub[1];
  41. bool y_dB = endFlag(y,"dB");
  42. bool y_percent = endFlag(y,"%");
  43. p.x = QVariant(x).toFloat();
  44. p.y = QVariant(y).toFloat();
  45. if(y_dB && type=="DYN") {
  46. float old = p.y;
  47. p.y = static_cast<float>(pow(10,-p.y/20));
  48. qDebug() << "convert from dB" << old << "->" << p.y;
  49. }
  50. if(x_percent)
  51. {
  52. p.x *= 0.01f;
  53. }
  54. if(y_percent)
  55. {
  56. p.y *= 0.01f;
  57. }
  58. p.x = note->start + p.x * note->lenght; // set pos
  59. p.x = checkInc(type,p.x);
  60. //TODO check pos
  61. if(type=="DYN") note->dyn.push_back(p);
  62. if(type=="PIT") note->pit.push_back(p);
  63. // PIT units
  64. // midi note number : semitones
  65. // mudulation: add Hz
  66. // portamento -> take pitch of next note, 1p
  67. // UTAU mode2
  68. // portamento: p_length,p_start
  69. // VBR,v_len,v_cyc,v_dep,v_in,v_out,v_pha,v_pit
  70. }
  71. }
  72. // create common modulation ?
  73. }
  74. QtauScore::QtauScore(const QJsonArray& ust, TempoMap* tmap) {
  75. float lastNoteEndTime = 0;
  76. for (int i = 0; i < ust.count(); ++i) {
  77. auto o = ust[i].toObject();
  78. if (!o.contains(NOTE_KEY_NUMBER)) {
  79. continue;
  80. }
  81. synthNote note;
  82. int noteOffset = o[NOTE_PULSE_OFFSET].toInt();
  83. int noteLength = o[NOTE_PULSE_LENGTH].toInt();
  84. QString lyric = o[NOTE_LYRIC].toString();
  85. int pitch = o[NOTE_KEY_NUMBER].toInt();
  86. QString pit = o[NOTE_PITCH].toString();
  87. QString pho = o[NOTE_PHO].toString();
  88. QString dyn = o[NOTE_DYNAMICS].toString();
  89. DEVLOG_DEBUG("PIT"<<pit);
  90. DEVLOG_DEBUG("DYN"<<dyn);
  91. DEVLOG_DEBUG("PHO"<<pho);
  92. float timeSt;
  93. float timeEd;
  94. int barSt;
  95. int barEd;
  96. int st = noteOffset;
  97. int ed = noteOffset + noteLength - 1;
  98. tmap->getBar(st, timeSt, barSt, 0);
  99. tmap->getBar(ed, timeEd, barEd, 1);
  100. float rest = timeSt - lastNoteEndTime;
  101. if (rest < 0) {
  102. // invalid=true;
  103. break;
  104. }
  105. note.rest = rest;
  106. note.start = timeSt;
  107. note.lenght = timeEd - timeSt;
  108. note.pitch = pitch;
  109. note.lyric = lyric;
  110. note.pho = pho.split(" ");
  111. fillTrack("PIT",pit.split(" "),&note);
  112. fillTrack("DYN",dyn.split(" "),&note);
  113. lastNoteEndTime = timeEd;
  114. notes.push_back(note);
  115. }
  116. DEVLOG_DEBUG("done building score");
  117. }
  118. //TODO update interface
  119. int QtauScore::getNoteCount() {
  120. return static_cast<int>(notes.size());//XX use size_t here
  121. }
  122. synthNote QtauScore::getNote(int index) {
  123. return notes[static_cast<size_t>(index)];//XX size_t here
  124. }