import { TheoryINote, stepTypeMap, synthesizeSign } from "../interface/TheoryINote"; import { TheoryPitch } from "../util/TheoryPitch"; export class TheoryBasicNote { private _xmlID: number; private _noteAccounter: number; private _measureRecorder: string[]; public constructor() { this._xmlID = 0; this._noteAccounter = 0; this._measureRecorder = []; } public generateBasicNote(noteXML_: Element): TheoryINote { let note: TheoryINote = {} as TheoryINote; note.xmlID = this._xmlID; this._xmlID++; let stepList = noteXML_.getElementsByTagName("step"); if (stepList.length) { note.step = stepList[0].innerHTML; note.rollCall = stepTypeMap[note.step]; } else { note.step = null; note.rollCall = null; } // pitchOctave let octaveList = noteXML_.getElementsByTagName("octave"); octaveList.length ? (note.pitchOctave = parseInt(octaveList[0].innerHTML, 10)) : (note.pitchOctave = null); // alter let alterList = noteXML_.getElementsByTagName("alter"); alterList.length ? (note.alter = parseInt(alterList[0].innerHTML, 10)) : (note.alter = 0); // chord let chordList = noteXML_.getElementsByTagName("chord"); chordList.length ? (note.isChord = true) : (note.isChord = false); // rest let restList = noteXML_.getElementsByTagName("rest"); restList.length ? (note.isRest = true) : (note.isRest = false); // dot let dotList = noteXML_.getElementsByTagName("dot"); dotList.length ? (note.isDot = true) : (note.isDot = false); // print-object noteXML_.getAttribute("print-object") === "no" ? (note.isPrint = false) : (note.isPrint = true); // beam let beamList = noteXML_.getElementsByTagName("beam"); beamList.length ? (note.beamSituation = beamList[0].innerHTML) : (note.beamSituation = null); // Measure && xmlOrderOfMeasureIndex let measureID: string = noteXML_.parentElement!.getAttribute("number") as string; if (this._measureRecorder.indexOf(measureID) < 0) { this._measureRecorder.push(measureID); this._noteAccounter = 0; } else { this._noteAccounter++; } note.measureIndex = this._measureRecorder.length - 1; note.xmlOrderOfMeasure = this._noteAccounter; // staff let staffList = noteXML_.getElementsByTagName("staff"); staffList.length ? (note.staff = parseInt(staffList[0].innerHTML, 10)) : (note.staff = 0); // type let typeList = noteXML_.getElementsByTagName("type"); typeList.length ? (note.type = stepTypeMap[typeList[0].innerHTML]) : (note.type = 1); // beats note.beats = 64 / (note.type as number); // tuplet if (noteXML_.getElementsByTagName("time-modification").length) { let actual = parseInt(noteXML_.getElementsByTagName("actual-notes")[0].innerHTML, 10); let normal = parseInt(noteXML_.getElementsByTagName("normal-notes")[0].innerHTML, 10); note.actual = actual; // 如果是连音, 那么就需要重新算下这个 beats note.beats = (note.beats * normal) / actual; note.isTuplet = true; } else { note.actual = null; note.isTuplet = false; } // 存储 dot beats if (!note.isDot) { note.beatsDot = 0; } else { let dotAccount = noteXML_.getElementsByTagName("dot").length; note.beatsDot = note.beats * (1 - 1 / Math.pow(2, dotAccount)); } // staccato note.isStaccato = false; // voice let voiceList = noteXML_.getElementsByTagName("voice"); voiceList.length ? (note.voice = parseInt(voiceList[0].innerHTML, 10)) : (note.voice = 0); // grace let graceList = noteXML_.getElementsByTagName("grace"); graceList.length ? (note.isGrace = true) : (note.isGrace = false); // default-x let defaultX = noteXML_.getAttribute("default-x"); defaultX === null ? (note.defaultX = null) : (note.defaultX = parseFloat(defaultX)); // stem let stemList = noteXML_.getElementsByTagName("stem"); stemList.length ? (note.stem = stemList[0].innerHTML) : (note.stem = null); let accidentalList = noteXML_.getElementsByTagName("accidental"); accidentalList.length ? (note.accidental = accidentalList[0].innerHTML) : (note.accidental = null); // id note.id = note.measureIndex * 1000 + note.xmlOrderOfMeasure; // 因为休止符为 step 为 null // if (note.step !== null && note.pitchOctave !== null) { // note.synthesizeSign = TheoryFormat.convert2NoteSign(note.step, note.pitchOctave, note.accidental); // } // 计算 pitch 值 if (!note.isRest) { note.pitch = TheoryPitch.calculatePitch(note.step!, note.pitchOctave!, note.alter); } else { note.pitch = 0; } if (note.pitch !== 0) { note.synthesizeSign = synthesizeSign[`P${note.pitch}`]; } return note; } }