runtime.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import { reactive } from "vue";
  2. import { IAbc, IMeasure, INote } from "../types";
  3. import { getImage } from "./images";
  4. export const ABC_DATA = {
  5. /** 音符 */
  6. types: [
  7. { name: "全音符", value: "4", icon: "icon-quanyinfu" },
  8. { name: "二分音符", value: "2", icon: "icon-a-2fenyinfu" },
  9. { name: "四分音符", value: "", icon: "icon-a-4fenyinfu" },
  10. { name: "八分音符", value: "/", icon: "icon-a-8fenyinfu" },
  11. { name: "十六分音符", value: "//", icon: "icon-a-16fenyinfu" },
  12. { name: "三十二分音符", value: "///", icon: "icon-a-32fenyinfu" },
  13. ],
  14. /** 休止符 */
  15. reset: [{ name: "休止符", value: "z", icon: "icon-a-4fenxiuzhifu" }],
  16. /** 临时升降记号 */
  17. accidentals: [
  18. { name: "重降号", value: "__", icon: getImage("icon_2.png") },
  19. { name: "降号", value: "_", icon: getImage("icon_3.png") },
  20. { name: "还原号", value: "=", icon: getImage("icon_4.png") },
  21. { name: "升号", value: "^", icon: getImage("icon_5.png") },
  22. { name: "重升号", value: "^^", icon: getImage("icon_6.png") },
  23. ],
  24. /** 谱号 */
  25. clef: [
  26. { name: "低音谱号", value: "K:bass", icon: "icon-puhao-diyinpuhao" },
  27. { name: "高音谱号", value: "K:treble", icon: "icon-puhao-gaoyinpuhao" },
  28. { name: "次中音谱号", value: "K:tenor", icon: "icon-puhao-cizhongyinpuhao" },
  29. { name: "中音谱号", value: "K:alto", icon: "icon-puhao-zhongyinpuhao" },
  30. { name: "打击乐谱号", value: "K:perc", icon: "icon-puhao-gupu" },
  31. ],
  32. /** 调号 */
  33. key: [
  34. { name: "C大调", value: "K:C", icon: "icon-a-diaohao-cdadiaoaxiaodiao1" },
  35. { name: "G大调", value: "K:G", icon: "icon-a-diaohao-Gdadiaoexiaodiao" },
  36. { name: "D大调", value: "K:D", icon: "icon-a-diaohao-Ddaxiaoexiaodiao" },
  37. { name: "A大调", value: "K:A", icon: "icon-a-diaohao-Adadiaofxiaodiao" },
  38. { name: "E大调", value: "K:E", icon: "icon-a-diaohao-edadiaocxiaodiao" },
  39. { name: "B大调", value: "K:B", icon: "icon-a-diaohao-bdadiaogxiaodiao" },
  40. { name: "F#大调", value: "K:F#", icon: "icon-a-diaohao-fdadiaodxiaodiao" },
  41. { name: "C#大调", value: "K:C#", icon: "icon-a-diaohao-cdadiaoaxiaodiao" },
  42. { name: "F大调", value: "K:F", icon: "icon-a-diaohao-fdadiaodxiaodiao1" },
  43. { name: "Bb大调", value: "K:Bb", icon: "icon-a-diaohao-bbdadiaogxiaodiao" },
  44. { name: "Eb大调", value: "K:Eb", icon: "icon-a-diaohao-ebdadiaocxiaodiao" },
  45. { name: "Ab大调", value: "K:Ab", icon: "icon-a-diaohao-abdadiaofxiaodiao" },
  46. { name: "Db大调", value: "K:Db", icon: "icon-a-diaohao-dbdadiaobbxiaodiao" },
  47. { name: "Gb大调", value: "K:Gb", icon: "icon-a-diaohao-gbdadiaoebxiaodiao" },
  48. { name: "Cb大调", value: "K:Cb", icon: "icon-a-diaohao-cbdadiaoabxiaodiao" },
  49. ],
  50. /** 拍号 */
  51. meter: [
  52. { name: "2/2", value: "M:2/2", icon: "icon-paihao-22" },
  53. { name: "2/4", value: "M:2/4", icon: "icon-paihao-24" },
  54. { name: "3/4", value: "M:3/4", icon: "icon-paihao-34" },
  55. { name: "4/4", value: "M:4/4", icon: "icon-paihao-44" },
  56. { name: "3/8", value: "M:3/8", icon: "icon-paihao-38" },
  57. { name: "6/8", value: "M:6/8", icon: "icon-paihao-68" },
  58. { name: "9/8", value: "M:9/8", icon: "icon-paihao-98" },
  59. { name: "12/8", value: "M:12/8", icon: "icon-a-paihao-128" },
  60. ],
  61. /** 演奏技法 */
  62. play: [
  63. { name: "加强音", value: "!marcato!", icon: getImage("icon_9.png") },
  64. { name: "重音", value: "!>!", icon: getImage("icon_10.png") },
  65. { name: "保持音", value: "!tenuto!", icon: getImage("icon_11.png") },
  66. { name: "断音", value: "!wedge!", icon: getImage("icon_12.png") },
  67. { name: "花型重复记号", value: "S", icon: "icon-fanfuyutiaoyue-sbiao" },
  68. { name: "Coda", value: "O", icon: "icon-fanfuyutiaoyue-weisheng" },
  69. { name: "波音", value: "P", icon: "icon-e1" },
  70. { name: "逆波音", value: "M", icon: "icon-d1" },
  71. { name: "换气符号(逗号)", value: "!breath!", icon: "icon-c1" },
  72. { name: "回音", value: "!turn!", icon: "icon-b" },
  73. // { name: "逆回音", value: "!turnx!", icon: "icon-b" },
  74. { name: "颤音", value: "T", icon: "icon-a1" },
  75. { name: "跳音", value: ".", icon: "icon-a-zoufajihao-duanzouhaoshang" },
  76. { name: "延迟音记号", value: "!fermata!", icon: "icon-f1" },
  77. ],
  78. /** 小节线 */
  79. bar: [
  80. { name: "单小节线", value: "|", icon: "icon-xiaojiexian-danxiaojiexian" },
  81. { name: "双小节线", value: "||", icon: "icon-xiaojiexian-shuangxiaojiexian" },
  82. { name: "结束线", value: "|]", icon: "icon-xiaojiexian-zhongzhixiaojiexian" },
  83. { name: "重复线开始", value: "|:", icon: "icon-a-xiaojiexian-zuoqishifanfuhao" },
  84. { name: "重复线结束", value: ":|", icon: "icon-a-xiaojiexian-youzhongzhifanfuhao" },
  85. { name: "双重复", value: "::", icon: "icon-xiaojiexian-jieshuyuqishifanfubiaozhi" },
  86. ],
  87. /** 连线 */
  88. tie: [
  89. { name: "延音线", value: "-", icon: getImage("icon_7.png") }, // 延音必须同音高
  90. { name: "连音线", value: ["(", ")"], icon: getImage("icon_8.png") }, // 需要是音符和结束音符,最低两个音符
  91. ],
  92. /** 8度线 */
  93. octave: [
  94. // 暂不支持
  95. { name: "高8度开始", value: ["!8va(!", "!8va)!"] },
  96. { name: "低8度", value: ["!8vb(!", "!8vb)!"] },
  97. ],
  98. /** 力度记号 */
  99. dynamics: [
  100. { name: "极弱", value: "!ppp!", icon: "icon-lidujihao-ppp" },
  101. { name: "很弱", value: "!pp!", icon: "icon-lidujihao-pp" },
  102. { name: "弱", value: "!p!", icon: "icon-lidujihao-p" },
  103. { name: "中弱", value: "!mp!", icon: "icon-lidujihao-mp" },
  104. { name: "中强", value: "!mf!", icon: "icon-lidujihao-mf" },
  105. { name: "强", value: "!f!", icon: "icon-lidujihao-f" },
  106. { name: "很强", value: "!ff!", icon: "icon-lidujihao-ff" },
  107. { name: "极强", value: "!fff!", icon: "icon-lidujihao-fff" },
  108. { name: "渐强", value: ["!<(!", "!<)!"], icon: "icon-lidujihao-jianqianghao" }, // 需要是音符范围,最低两个音
  109. { name: "渐弱", value: ["!>(!", "!>)!"], icon: "icon-lidujihao-jianruohao" }, //需要是音符范围,最低两个音
  110. ],
  111. repeat: [
  112. { name: "第一跳跃", value: "1", icon: "icon-fanfuyutiaoyue-diyitiaoyuehao" },
  113. { name: "第二跳跃", value: "2", icon: "icon-fanfuyutiaoyue-di2kaifangtiaoyuehao" },
  114. // { name: "重复3房", value: "3", icon: "" },
  115. // { name: "重复4房", value: "4", icon: "" },
  116. ],
  117. speeds: [
  118. { name: "60", value: "Q:1/4=60", icon: "" },
  119. { name: "70", value: "Q:1/4=70", icon: "" },
  120. { name: "80", value: "Q:1/4=80", icon: "" },
  121. { name: "90", value: "Q:1/4=90", icon: "" },
  122. { name: "100", value: "Q:1/4=100", icon: "" },
  123. { name: "120", value: "Q:1/4=120", icon: "" },
  124. ],
  125. slus: [
  126. { name: "3连音", value: '(3', icon: '' },
  127. { name: "4连音", value: '(4', icon: '' },
  128. { name: "5连音", value: '(5', icon: '' },
  129. { name: "6连音", value: '(6', icon: '' },
  130. { name: "7连音", value: '(7', icon: '' },
  131. ],
  132. /** 3连音等多连音
  133. * 1. 将连音的音符小括号起来,并在括号前加上数字表示连音的音符数
  134. */
  135. };
  136. export const settings = reactive({
  137. /** 光标跟随 音符, 节拍 */
  138. cursorType: 'note' as 'note' | 'beat',
  139. })
  140. export const createNote = (options: Partial<INote>): INote => {
  141. return {
  142. accidental: options.accidental || "",
  143. content: options.content || "",
  144. noteType: options.noteType || "",
  145. meter: options.meter || "",
  146. clef: options.clef || "",
  147. play: options.play || [],
  148. key: options.key || "",
  149. speed: options.speed || "",
  150. dynamics: options.dynamics || "",
  151. dCode: options.dCode || "",
  152. tie: options.tie || "",
  153. tCode: options.tCode || "",
  154. dot: options.dot || "",
  155. slus: options.slus || "",
  156. };
  157. };
  158. export const createMeasure = (): IMeasure => {
  159. return {
  160. notes: [
  161. createNote({
  162. content: "z",
  163. }),
  164. ],
  165. barline: "|",
  166. repeat: "",
  167. measureNumber: 0,
  168. celf: "",
  169. key: "",
  170. };
  171. };
  172. /** 生成小节 */
  173. export const renderMeasures = (abc: IAbc) => {
  174. // console.log("🚀 ~ abc:", abc)
  175. let text = `X:1\n`;
  176. abc.title && (text += abc.title + "\n");
  177. abc.celf && (text += abc.celf + "\n");
  178. abc.meter && (text += abc.meter + "\n");
  179. abc.minUnit && (text += abc.minUnit + "\n");
  180. abc.speed && (text += abc.speed + "\n");
  181. abc.key && (text += abc.key + "\n");
  182. const measures = abc.measures;
  183. for (let i = 0; i < measures.length; i++) {
  184. const measure = measures[i];
  185. text += measure.repeat;
  186. for (let j = 0; j < measure.notes.length; j++) {
  187. const note = measure.notes[j];
  188. const playStr = note.play?.join("") || "";
  189. text += note.clef; // 谱号
  190. text += note.key; // 调号
  191. text += note.speed; // 速度
  192. text += note.meter; // 拍号
  193. text += note.slus; // 3连音
  194. if (note.tie.includes("(")) {
  195. // 连音线 前
  196. text += note.tie;
  197. }
  198. text += `"<${i + "." + j}"`; // 音符 id
  199. text += playStr; // 演奏技法
  200. text += note.dynamics; // 力度符号
  201. text += note.accidental; // 临时升降记号
  202. text += note.content; // 音符
  203. text += note.noteType; // 音符类型
  204. text += note.dot; // 附点
  205. if (note.tie.includes(")")) {
  206. // 连音线 后
  207. text += note.tie;
  208. }
  209. }
  210. text += measure.barline;
  211. // text += `"${i}"` + measure.barline;
  212. if (i > 0 && i % 4 === 0) {
  213. text += "\n";
  214. }
  215. }
  216. // console.log(text)
  217. return text;
  218. };