Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2023 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "brailleinput.h"
24 :
25 : using namespace mu::notation;
26 :
27 : namespace mu::engraving {
28 : BrailleInputState brailleInputState;
29 :
30 0 : QString parseBrailleKeyInput(QString keys)
31 : {
32 : static const std::map<std::string, std::string > braille_input_keys = {
33 : { "S", "3" }, { "D", "2" }, { "F", "1" },
34 : { "J", "4" }, { "K", "5" }, { "L", "6" }
35 0 : };
36 :
37 0 : QStringList lst = keys.split(QString::fromStdString("+"));
38 :
39 0 : std::vector<std::string> nlst;
40 0 : for (int i = 0; i < lst.size(); i++) {
41 0 : std::string key = lst.at(i).toStdString();
42 :
43 0 : auto it = braille_input_keys.find(key);
44 0 : if (it != braille_input_keys.end()) {
45 0 : nlst.push_back(it->second);
46 : }
47 0 : }
48 0 : std::sort(nlst.begin(), nlst.end());
49 :
50 0 : QString buff = QString();
51 0 : for (auto n : nlst) {
52 0 : buff.append(QString::fromStdString(n));
53 0 : }
54 :
55 0 : return buff;
56 0 : }
57 :
58 0 : NoteName getNoteName(const braille_code* code)
59 : {
60 0 : char c = code->tag[0];
61 0 : switch (c) {
62 0 : case 'A': case 'a':
63 0 : return NoteName::A;
64 0 : case 'B': case 'b':
65 0 : return NoteName::B;
66 0 : case 'C': case 'c':
67 0 : return NoteName::C;
68 0 : case 'D': case 'd':
69 0 : return NoteName::D;
70 0 : case 'E': case 'e':
71 0 : return NoteName::E;
72 0 : case 'F': case 'f':
73 0 : return NoteName::F;
74 0 : case 'G': case 'g':
75 0 : return NoteName::G;
76 : }
77 0 : return NoteName::C;
78 : }
79 :
80 0 : std::vector<DurationType> getNoteDurations(const braille_code* code)
81 : {
82 0 : for (int i=0; i < 7; i++) {
83 0 : if (code->code == Braille_wholeNotes[i]->code) {
84 : //return {DurationType::V_WHOLE, DurationType::V_16TH, DurationType::V_256TH};
85 0 : return { DurationType::V_WHOLE, DurationType::V_16TH };
86 : }
87 : }
88 :
89 0 : for (int i=0; i < 7; i++) {
90 0 : if (code->code == Braille_halfNotes[i]->code) {
91 : //return {DurationType::V_HALF, DurationType::V_32ND, DurationType::V_512TH};
92 0 : return { DurationType::V_HALF, DurationType::V_32ND };
93 : }
94 : }
95 :
96 0 : for (int i=0; i < 7; i++) {
97 0 : if (code->code == Braille_quarterNotes[i]->code) {
98 : //return {DurationType::V_QUARTER, DurationType::V_64TH, DurationType::V_1024TH};
99 0 : return { DurationType::V_QUARTER, DurationType::V_64TH };
100 : }
101 : }
102 :
103 0 : for (int i=0; i < 7; i++) {
104 0 : if (code->code == Braille_8thNotes[i]->code) {
105 0 : return { DurationType::V_EIGHTH, DurationType::V_128TH };
106 : }
107 : }
108 :
109 0 : return {};
110 : }
111 :
112 0 : std::vector<DurationType> getRestDurations(const braille_code* code)
113 : {
114 0 : if (code->code == Braille_RestWhole.code) {
115 0 : return { DurationType::V_WHOLE, DurationType::V_16TH };
116 : }
117 :
118 0 : if (code->code == Braille_RestHalf.code) {
119 0 : return { DurationType::V_HALF, DurationType::V_32ND };
120 : }
121 :
122 0 : if (code->code == Braille_RestQuarter.code) {
123 0 : return { DurationType::V_QUARTER, DurationType::V_64TH };
124 : }
125 :
126 0 : if (code->code == Braille_Rest8th.code) {
127 0 : return { DurationType::V_EIGHTH, DurationType::V_128TH };
128 : }
129 :
130 0 : return {};
131 : }
132 :
133 0 : int getInterval(const braille_code* code)
134 : {
135 0 : char c = code->tag.back();
136 :
137 0 : IF_ASSERT_FAILED(c >= '2' && c <= '8') {
138 0 : return -1;
139 : }
140 :
141 0 : return c - '0';
142 : }
143 :
144 0 : bool isNoteName(const braille_code* code)
145 : {
146 : static const std::vector<std::string> note_names = {
147 : "aMaxima", "aLonga", "aBreve", "aWhole", "aHalf",
148 : "aQuarter", "a8th", "a16th", "a32nd", "a64th", "a128th",
149 : "a256th", "a512th", "a128th", "a2048th", "aBreveAlt",
150 :
151 : "bMaxima", "bLonga", "bBreve", "bWhole", "bHalf",
152 : "bQuarter", "b8th", "b16th", "b32nd", "b64th", "b128th",
153 : "b256th", "b512th", "b128th", "b2048th", "bBreveAlt",
154 :
155 : "cMaxima", "cLonga", "cBreve", "cWhole", "cHalf",
156 : "cQuarter", "c8th", "c16th", "c32nd", "c64th", "c128th",
157 : "c256th", "c512th", "c128th", "c2048th", "cBreveAlt",
158 :
159 : "dMaxima", "dLonga", "dBreve", "dWhole", "dHalf",
160 : "dQuarter", "d8th", "d16th", "d32nd", "d64th", "d128th",
161 : "d256th", "d512th", "d128th", "d2048th", "dBreveAlt",
162 :
163 : "eMaxima", "eLonga", "eBreve", "eWhole", "eHalf",
164 : "eQuarter", "e8th", "e16th", "e32nd", "e64th", "e128th",
165 : "e256th", "e512th", "e128th", "e2048th", "eBreveAlt",
166 :
167 : "fMaxima", "fLonga", "fBreve", "fWhole", "fHalf",
168 : "fQuarter", "f8th", "f16th", "f32nd", "f64th", "f128th",
169 : "f256th", "f512th", "f128th", "f2048th", "fBreveAlt",
170 :
171 : "gMaxima", "gLonga", "gBreve", "gWhole", "gHalf",
172 : "gQuarter", "g8th", "g16th", "g32nd", "g64th", "g128th",
173 : "g256th", "g512th", "g128th", "g2048th", "gBreveAlt",
174 0 : };
175 :
176 0 : return std::find(note_names.begin(), note_names.end(), code->tag) != note_names.end();
177 : }
178 :
179 0 : QString fromNoteName(NoteName notename)
180 : {
181 0 : switch (notename) {
182 0 : case NoteName::A:
183 0 : return "A";
184 0 : case NoteName::B:
185 0 : return "B";
186 0 : case NoteName::C:
187 0 : return "C";
188 0 : case NoteName::D:
189 0 : return "D";
190 0 : case NoteName::E:
191 0 : return "E";
192 0 : case NoteName::F:
193 0 : return "F";
194 0 : case NoteName::G:
195 0 : return "G";
196 0 : default:
197 0 : return "";
198 : }
199 : }
200 :
201 0 : AccidentalType getAccidentalType(const braille_code* code)
202 : {
203 0 : if (code->tag == "NaturalAccidental") {
204 0 : return AccidentalType::NATURAL;
205 : }
206 :
207 0 : if (code->tag == "SharpAccidental") {
208 0 : return AccidentalType::SHARP;
209 : }
210 :
211 0 : if (code->tag == "FlatAccidental") {
212 0 : return AccidentalType::FLAT;
213 : }
214 :
215 0 : return AccidentalType::NONE;
216 : }
217 :
218 0 : SymbolId getArticulation(const braille_code* code)
219 : {
220 : static const std::map<std::string, SymbolId> articulations = {
221 0 : { "Finger0", SymbolId::fingering0 },
222 0 : { "Finger1", SymbolId::fingering1 },
223 0 : { "Finger2", SymbolId::fingering2 },
224 0 : { "Finger3", SymbolId::fingering3 },
225 0 : { "Finger4", SymbolId::fingering4 },
226 0 : { "Finger5", SymbolId::fingering5 },
227 0 : };
228 :
229 0 : auto it = articulations.find(code->tag);
230 0 : if (it != articulations.end()) {
231 0 : return it->second;
232 : }
233 :
234 0 : return SymbolId::noSym;
235 0 : }
236 :
237 0 : int getOctave(const braille_code* code)
238 : {
239 : static const std::map<std::string, int> octaves = {
240 0 : { "Octave1", 1 }, { "Octave2", 2 }, { "Octave3", 3 }, { "Octave4", 4 },
241 0 : { "Octave5", 5 }, { "Octave6", 6 }, { "Octave7", 7 },
242 0 : };
243 :
244 0 : auto it = octaves.find(code->tag);
245 0 : if (it != octaves.end()) {
246 0 : return it->second;
247 : }
248 0 : return -1;
249 0 : }
250 :
251 : // Given a note (dest) that lacks an octave mark, compute its octave relative
252 : // to a previous note (source) for which the octave is already known.
253 0 : int getOctaveDiff(NoteName source, NoteName dest)
254 : {
255 : // Calculate interval between notes assuming they are in the same octave.
256 0 : int interval = std::abs(static_cast<int>(dest) - static_cast<int>(source));
257 0 : ++interval; // so unison == 1
258 :
259 0 : if (interval >= 6) {
260 : // Impossible because notes separated by a 6th or more require octave
261 : // marks. Therefore, the dest note must be in a neighboring octave.
262 : // actual_interval = 8 - interval;
263 0 : return (source > dest) ? 1 : -1; // octave above or below
264 : }
265 :
266 0 : return 0; // same octave
267 : }
268 :
269 : // Given a starting note (source), and an interval and direction, compute the
270 : // resulting note and its octave relative to the octave of the starting note.
271 0 : std::pair<NoteName, int> applyInterval(NoteName source, int interval, IntervalDirection direction)
272 : {
273 0 : IF_ASSERT_FAILED(interval >= 1) {
274 0 : return std::make_pair(source, 0);
275 : }
276 :
277 0 : --interval; // so unison == 0
278 :
279 0 : int pitch = static_cast<int>(source);
280 0 : int octave_diff = 0;
281 :
282 0 : switch (direction) {
283 0 : case IntervalDirection::Up:
284 0 : pitch += interval;
285 0 : octave_diff = pitch / 7;
286 0 : break;
287 0 : case IntervalDirection::Down:
288 0 : pitch -= interval;
289 0 : while (pitch < 0) {
290 0 : pitch += 7;
291 0 : --octave_diff;
292 : }
293 0 : break;
294 : }
295 :
296 0 : return std::make_pair(static_cast<NoteName>(pitch % 7), octave_diff);
297 : }
298 :
299 1 : BrailleInputState::BrailleInputState()
300 : {
301 1 : initialize();
302 1 : }
303 :
304 1 : BrailleInputState::~BrailleInputState()
305 : {
306 1 : _input_buffer.clear();
307 1 : }
308 :
309 1 : void BrailleInputState::initialize()
310 : {
311 1 : _accidental = AccidentalType::NONE;
312 1 : _note_name = NoteName::C;
313 1 : _articulation = SymbolId::noSym;
314 1 : _octave = 4;
315 1 : _voice = 0;
316 1 : _dots = 0;
317 1 : _input_buffer.clear();
318 1 : _code_num = 0;
319 1 : _note_slur = _long_slur_start = _long_slur_stop = _tie = false;
320 1 : _note_group = NoteGroup::Group1;
321 1 : _intervals.clear();
322 1 : _accord = false;
323 1 : _tuplet_number = -1;
324 1 : }
325 :
326 0 : void BrailleInputState::reset()
327 : {
328 0 : _input_buffer = QString();
329 0 : _accidental = AccidentalType::NONE;
330 0 : _articulation = SymbolId::noSym;
331 0 : _dots = 0;
332 0 : _code_num = 0;
333 0 : _note_slur = _long_slur_start = _long_slur_stop = _tie = false;
334 0 : _added_octave = -1;
335 0 : _accord = false;
336 0 : _tuplet_indicator = false;
337 0 : }
338 :
339 0 : void BrailleInputState::resetBuffer()
340 : {
341 0 : _input_buffer = QString();
342 0 : _code_num = 0;
343 0 : }
344 :
345 0 : void BrailleInputState::insertToBuffer(const QString code)
346 : {
347 0 : if (_input_buffer.isEmpty()) {
348 0 : _input_buffer = code;
349 0 : _code_num = 0;
350 : } else {
351 0 : _input_buffer.append("-").append(code);
352 0 : _code_num++;
353 : }
354 0 : }
355 :
356 0 : BieSequencePatternType BrailleInputState::parseBraille(IntervalDirection direction)
357 : {
358 0 : std::string braille = translate2Braille(_input_buffer.toStdString());
359 0 : BieSequencePattern* pattern = BieRecognize(braille, tupletIndicator());
360 :
361 0 : if (pattern == NULL) {
362 0 : return BieSequencePatternType::Undefined;
363 : }
364 :
365 0 : switch (pattern->type()) {
366 0 : case BieSequencePatternType::Note: {
367 0 : clearIntervals();
368 :
369 0 : braille_code* code = pattern->res("note");
370 :
371 0 : NoteName note_name = getNoteName(code);
372 :
373 0 : setNoteDurations(getNoteDurations(code));
374 :
375 0 : code = pattern->res("octave");
376 0 : if (code != NULL) {
377 0 : setAddedOctave(getOctave(code));
378 0 : } else if (chordBaseNoteOctave() != -1) {
379 0 : int octave_diff = getOctaveDiff(chordBaseNoteName(), note_name);
380 0 : setAddedOctave(chordBaseNoteOctave() + octave_diff);
381 : } else {
382 0 : setAddedOctave(-1); // unknown octave
383 : }
384 :
385 0 : setNoteName(note_name, true); // do this after determining the octave
386 :
387 0 : code = pattern->res("accidental");
388 0 : if (code != NULL) {
389 0 : setAccidental(getAccidentalType(code));
390 : }
391 :
392 0 : code = pattern->res("long-slur-start");
393 0 : if (code != NULL) {
394 0 : setLongSlurStart(true);
395 : }
396 :
397 0 : code = pattern->res("accord");
398 0 : if (code != NULL) {
399 0 : setAccord(true);
400 : }
401 0 : break;
402 : }
403 0 : case BieSequencePatternType::Rest: {
404 0 : braille_code* code = pattern->res("rest");
405 0 : setNoteDurations(getRestDurations(code));
406 :
407 0 : code = pattern->res("accord");
408 0 : if (code != NULL) {
409 0 : setAccord(true);
410 : }
411 0 : break;
412 : }
413 0 : case BieSequencePatternType::Interval: {
414 0 : braille_code* code = pattern->res("interval");
415 0 : int interval = getInterval(code);
416 0 : interval = addInterval(interval);
417 0 : std::pair<NoteName, int> applied = applyInterval(chordBaseNoteName(), interval, direction);
418 :
419 0 : setNoteName(applied.first, false);
420 :
421 0 : code = pattern->res("octave");
422 0 : if (code != NULL) {
423 0 : setAddedOctave(getOctave(code));
424 : } else {
425 0 : setAddedOctave(chordBaseNoteOctave() + applied.second);
426 : }
427 :
428 0 : code = pattern->res("accidental");
429 0 : if (code != NULL) {
430 0 : setAccidental(getAccidentalType(code));
431 : }
432 :
433 0 : break;
434 : }
435 0 : case BieSequencePatternType::Tuplet3: {
436 0 : setTupletNumber(3);
437 0 : setTupletDuration(Duration(DurationType::V_EIGHTH));
438 0 : break;
439 : }
440 0 : case BieSequencePatternType::Tuplet: {
441 0 : braille_code* code = pattern->res("tuplet-number");
442 0 : setTupletNumber(code->tag.back() - '0');
443 :
444 0 : code = pattern->res("c-note");
445 :
446 0 : std::string stateTuplet;
447 0 : stateTuplet = "Tuplet " + std::to_string(tupletNumber()) + " " + code->tag;
448 0 : LOGD() << stateTuplet;
449 0 : if (code->tag == "cWhole") {
450 0 : setTupletDuration(Duration(DurationType::V_WHOLE));
451 0 : } else if (code->tag == "cHalf") {
452 0 : setTupletDuration(Duration(DurationType::V_HALF));
453 0 : } else if (code->tag == "cQuarter") {
454 0 : setTupletDuration(Duration(DurationType::V_QUARTER));
455 0 : } else if (code->tag == "c8th") {
456 0 : setTupletDuration(Duration(DurationType::V_EIGHTH));
457 : } else {
458 0 : setTupletDuration(Duration(DurationType::V_INVALID));
459 : }
460 0 : break;
461 0 : }
462 0 : case BieSequencePatternType::Tie: {
463 0 : braille_code* code = pattern->res("tie");
464 0 : if (code != NULL) {
465 0 : setTie(true);
466 : }
467 0 : break;
468 : }
469 0 : case BieSequencePatternType::NoteSlur: {
470 0 : braille_code* code = pattern->res("note-slur");
471 0 : if (code != NULL) {
472 0 : setNoteSlur(true);
473 : }
474 0 : break;
475 : }
476 0 : case BieSequencePatternType::LongSlurStop: {
477 0 : braille_code* code = pattern->res("long-slur-stop");
478 0 : if (code != NULL) {
479 0 : setLongSlurStop(true);
480 : }
481 0 : break;
482 : }
483 0 : case BieSequencePatternType::Dot: {
484 0 : braille_code* code = pattern->res("dot");
485 0 : if (code != NULL) {
486 0 : setDots(1);
487 : }
488 0 : break;
489 : }
490 0 : default: {
491 0 : break;
492 : }
493 : }
494 :
495 0 : return pattern->type();
496 0 : }
497 :
498 0 : QString BrailleInputState::buffer()
499 : {
500 0 : return _input_buffer;
501 : }
502 :
503 0 : AccidentalType BrailleInputState::accidental()
504 : {
505 0 : return _accidental;
506 : }
507 :
508 0 : NoteName BrailleInputState::noteName()
509 : {
510 0 : return _note_name;
511 : }
512 :
513 0 : NoteName BrailleInputState::chordBaseNoteName()
514 : {
515 0 : return _chordbase_note_name;
516 : }
517 :
518 0 : NoteGroup BrailleInputState::noteGroup()
519 : {
520 0 : return _note_group;
521 : }
522 :
523 0 : DurationType BrailleInputState::currentDuration()
524 : {
525 0 : return _current_duration;
526 : }
527 :
528 0 : std::vector<DurationType> BrailleInputState::noteDurations()
529 : {
530 0 : return _note_durations;
531 : }
532 :
533 0 : bool BrailleInputState::isDurationMatch()
534 : {
535 0 : return std::find(_note_durations.begin(), _note_durations.end(), _current_duration) != _note_durations.end();
536 : }
537 :
538 0 : DurationType BrailleInputState::getCloseDuration()
539 : {
540 0 : switch (_note_group) {
541 0 : case NoteGroup::Group1: {
542 0 : return _note_durations[0];
543 : break;
544 : }
545 0 : case NoteGroup::Group2: {
546 0 : return _note_durations[1];
547 : break;
548 : }
549 0 : case NoteGroup::Group3: {
550 0 : return _note_durations[2];
551 : break;
552 : }
553 0 : default: {
554 0 : if (isDurationMatch()) {
555 0 : return _current_duration;
556 : } else {
557 0 : for (auto d : _note_durations) {
558 0 : if (d > _current_duration) {
559 0 : return d;
560 : }
561 : }
562 : }
563 : }
564 : }
565 0 : return _note_durations.back();
566 : }
567 :
568 0 : SymbolId BrailleInputState::articulation()
569 : {
570 0 : return _articulation;
571 : }
572 :
573 0 : int BrailleInputState::octave()
574 : {
575 0 : return _octave;
576 : }
577 :
578 0 : int BrailleInputState::dots()
579 : {
580 0 : return _dots;
581 : }
582 :
583 0 : int BrailleInputState::addedOctave()
584 : {
585 0 : return _added_octave;
586 : }
587 :
588 0 : int BrailleInputState::chordBaseNoteOctave()
589 : {
590 0 : return _chordbase_note_octave;
591 : }
592 :
593 0 : voice_idx_t BrailleInputState::voice()
594 : {
595 0 : return _voice;
596 : }
597 :
598 0 : void BrailleInputState::setAccidental(const AccidentalType accidental)
599 : {
600 0 : _accidental = accidental;
601 0 : }
602 :
603 0 : void BrailleInputState::setNoteName(const NoteName notename, const bool chord_base)
604 : {
605 0 : _note_name = notename;
606 0 : if (chord_base) {
607 0 : _chordbase_note_name = notename;
608 : }
609 0 : }
610 :
611 0 : void BrailleInputState::setNoteGroup(const NoteGroup notegroup)
612 : {
613 0 : LOGD() << (int)notegroup;
614 0 : _note_group = notegroup;
615 0 : }
616 :
617 0 : void BrailleInputState::setCurrentDuration(const DurationType duration)
618 : {
619 0 : _current_duration = duration;
620 0 : }
621 :
622 0 : void BrailleInputState::setNoteDurations(const std::vector<DurationType> durations)
623 : {
624 0 : _note_durations = durations;
625 0 : }
626 :
627 0 : void BrailleInputState::setArticulation(const SymbolId articulation)
628 : {
629 0 : _articulation = articulation;
630 0 : }
631 :
632 0 : void BrailleInputState::setOctave(const int octave, const bool chord_base)
633 : {
634 0 : _octave = octave;
635 :
636 0 : if (chord_base) {
637 0 : _chordbase_note_octave = octave;
638 : }
639 0 : }
640 :
641 0 : void BrailleInputState::setDots(const int dots)
642 : {
643 0 : _dots = dots;
644 0 : }
645 :
646 0 : void BrailleInputState::setAddedOctave(const int octave)
647 : {
648 0 : LOGD() << octave;
649 0 : _added_octave = octave;
650 0 : }
651 :
652 0 : void BrailleInputState::setVoice(const voice_idx_t voice)
653 : {
654 0 : _voice = voice;
655 0 : }
656 :
657 0 : std::vector<int> BrailleInputState::intervals()
658 : {
659 0 : return _intervals;
660 : }
661 :
662 0 : void BrailleInputState::removeLastInterval()
663 : {
664 0 : if (!_intervals.empty()) {
665 0 : _intervals.pop_back();
666 : }
667 0 : }
668 :
669 0 : void BrailleInputState::clearIntervals()
670 : {
671 0 : _intervals.clear();
672 0 : }
673 :
674 0 : int BrailleInputState::addInterval(int interval)
675 : {
676 0 : if (!intervals().empty()) {
677 0 : int last = _intervals.back();
678 0 : while (interval < last) {
679 0 : interval += 7;
680 : }
681 : }
682 :
683 0 : _intervals.push_back(interval);
684 0 : return interval;
685 : }
686 :
687 0 : bool BrailleInputState::tie()
688 : {
689 0 : return _tie;
690 : }
691 :
692 0 : void BrailleInputState::setTie(const bool s)
693 : {
694 0 : _tie = s;
695 0 : }
696 :
697 0 : Note* BrailleInputState::tieStartNote()
698 : {
699 0 : return _tie_start_note;
700 : }
701 :
702 0 : void BrailleInputState::setTieStartNote(Note* note)
703 : {
704 0 : _tie_start_note = note;
705 0 : }
706 :
707 0 : void BrailleInputState::clearTie()
708 : {
709 0 : _tie_start_note = NULL;
710 0 : }
711 :
712 0 : void BrailleInputState::setNoteSlur(const bool s)
713 : {
714 0 : _note_slur = s;
715 0 : }
716 :
717 0 : void BrailleInputState::setLongSlurStart(const bool s)
718 : {
719 0 : _long_slur_start = s;
720 0 : }
721 :
722 0 : void BrailleInputState::setLongSlurStop(const bool s)
723 : {
724 0 : _long_slur_stop = s;
725 0 : }
726 :
727 0 : bool BrailleInputState::noteSlur()
728 : {
729 0 : return _note_slur;
730 : }
731 :
732 0 : bool BrailleInputState::longSlurStart()
733 : {
734 0 : return _long_slur_start;
735 : }
736 :
737 0 : bool BrailleInputState::longSlurStop()
738 : {
739 0 : return _long_slur_stop;
740 : }
741 :
742 0 : Note* BrailleInputState::slurStartNote()
743 : {
744 0 : return _slur_start_note;
745 : }
746 :
747 0 : Note* BrailleInputState::longSlurStartNote()
748 : {
749 0 : return _long_slur_start_note;
750 : }
751 :
752 0 : void BrailleInputState::setSlurStartNote(Note* note)
753 : {
754 0 : _slur_start_note = note;
755 0 : }
756 :
757 0 : void BrailleInputState::setLongSlurStartNote(Note* note)
758 : {
759 0 : _long_slur_start_note = note;
760 0 : }
761 :
762 0 : void BrailleInputState::clearSlur()
763 : {
764 0 : _slur_start_note = NULL;
765 0 : }
766 :
767 0 : void BrailleInputState::clearLongSlur()
768 : {
769 0 : _long_slur_start_note = NULL;
770 0 : }
771 :
772 0 : bool BrailleInputState::accord()
773 : {
774 0 : return _accord;
775 : }
776 :
777 0 : void BrailleInputState::setAccord(const bool val)
778 : {
779 0 : _accord = val;
780 0 : }
781 :
782 0 : int BrailleInputState::tupletNumber()
783 : {
784 0 : return _tuplet_number;
785 : }
786 :
787 0 : void BrailleInputState::setTupletNumber(const int num)
788 : {
789 0 : _tuplet_number = num;
790 0 : }
791 :
792 0 : Duration BrailleInputState::tupletDuration()
793 : {
794 0 : return _tuplet_duration;
795 : }
796 :
797 0 : void BrailleInputState::setTupletDuration(const Duration d)
798 : {
799 0 : switch (noteGroup()) {
800 0 : case NoteGroup::Group2: {
801 0 : switch (d.type()) {
802 0 : case DurationType::V_WHOLE: {
803 0 : _tuplet_duration = Duration(DurationType::V_16TH);
804 0 : break;
805 : }
806 0 : case DurationType::V_HALF: {
807 0 : _tuplet_duration = Duration(DurationType::V_32ND);
808 0 : break;
809 : }
810 0 : case DurationType::V_QUARTER: {
811 0 : _tuplet_duration = Duration(DurationType::V_64TH);
812 0 : break;
813 : }
814 0 : case DurationType::V_EIGHTH: {
815 0 : _tuplet_duration = Duration(DurationType::V_128TH);
816 0 : break;
817 : }
818 0 : default: {
819 0 : _tuplet_duration = Duration(DurationType::V_INVALID);
820 0 : break;
821 : }
822 : }
823 0 : break;
824 : }
825 0 : case NoteGroup::Group3: {
826 0 : switch (d.type()) {
827 0 : case DurationType::V_WHOLE: {
828 0 : _tuplet_duration = Duration(DurationType::V_256TH);
829 0 : break;
830 : }
831 0 : case DurationType::V_HALF: {
832 0 : _tuplet_duration = Duration(DurationType::V_512TH);
833 0 : break;
834 : }
835 0 : case DurationType::V_QUARTER: {
836 0 : _tuplet_duration = Duration(DurationType::V_1024TH);
837 0 : break;
838 : }
839 0 : case DurationType::V_EIGHTH: {
840 0 : _tuplet_duration = Duration(DurationType::V_INVALID);
841 0 : break;
842 : }
843 0 : default: {
844 0 : _tuplet_duration = Duration(DurationType::V_INVALID);
845 0 : break;
846 : }
847 : }
848 0 : break;
849 : }
850 0 : default: {
851 0 : _tuplet_duration = d;
852 0 : break;
853 : }
854 : }
855 0 : }
856 :
857 0 : void BrailleInputState::clearTuplet()
858 : {
859 0 : _tuplet_number = -1;
860 0 : _tuplet_duration = Duration(DurationType::V_INVALID);
861 0 : }
862 :
863 0 : bool BrailleInputState::tupletIndicator()
864 : {
865 0 : return _tuplet_indicator;
866 : }
867 :
868 0 : void BrailleInputState::setTupletIndicator(bool val)
869 : {
870 0 : _tuplet_indicator = val;
871 0 : }
872 : }
|