├── .github
└── FUNDING.yml
├── .gitignore
├── images
├── +.png
├── b.png
├── d.png
├── n.png
├── s.png
├── u.png
├── v.png
├── x.png
├── bb.png
├── bbu.png
├── bbv.png
├── bu.png
├── bu1.png
├── bu2.png
├── bu3.png
├── bv.png
├── bv1.png
├── bv2.png
├── bv3.png
├── db.png
├── s+.png
├── su.png
├── su1.png
├── su2.png
├── su3.png
├── sv.png
├── sv1.png
├── sv2.png
├── sv3.png
├── u1.png
├── u2.png
├── u3.png
├── v1.png
├── v2.png
├── v3.png
├── xu.png
├── xu1.png
├── xu2.png
├── xu3.png
├── xv.png
├── xv1.png
├── xv2.png
├── xv3.png
├── bbu1.png
├── bbu2.png
├── bbu3.png
├── bbv1.png
├── bbv2.png
├── bbv3.png
├── new
│ ├── ^4.png
│ ├── v4.png
│ ├── #^4.png
│ ├── #v4.png
│ ├── b^4.png
│ ├── bb^4.png
│ ├── bbv4.png
│ ├── bv4.png
│ ├── x^4.png
│ ├── xv4.png
│ └── 94 edo demo.png
├── key-sig-example.png
└── microtonal-plugin-screenshot.png
├── .idea
├── vcs.xml
├── .gitignore
├── modules.xml
└── musescore-31-tet-plugin.iml
├── CHANGELOG.md
├── LICENSE
├── README.md
└── tune n-edo.qml
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: euwbah
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.qmlc
2 | test.qml
3 |
--------------------------------------------------------------------------------
/images/+.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/+.png
--------------------------------------------------------------------------------
/images/b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/b.png
--------------------------------------------------------------------------------
/images/d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/d.png
--------------------------------------------------------------------------------
/images/n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/n.png
--------------------------------------------------------------------------------
/images/s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/s.png
--------------------------------------------------------------------------------
/images/u.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/u.png
--------------------------------------------------------------------------------
/images/v.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/v.png
--------------------------------------------------------------------------------
/images/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/x.png
--------------------------------------------------------------------------------
/images/bb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bb.png
--------------------------------------------------------------------------------
/images/bbu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbu.png
--------------------------------------------------------------------------------
/images/bbv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbv.png
--------------------------------------------------------------------------------
/images/bu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bu.png
--------------------------------------------------------------------------------
/images/bu1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bu1.png
--------------------------------------------------------------------------------
/images/bu2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bu2.png
--------------------------------------------------------------------------------
/images/bu3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bu3.png
--------------------------------------------------------------------------------
/images/bv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bv.png
--------------------------------------------------------------------------------
/images/bv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bv1.png
--------------------------------------------------------------------------------
/images/bv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bv2.png
--------------------------------------------------------------------------------
/images/bv3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bv3.png
--------------------------------------------------------------------------------
/images/db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/db.png
--------------------------------------------------------------------------------
/images/s+.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/s+.png
--------------------------------------------------------------------------------
/images/su.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/su.png
--------------------------------------------------------------------------------
/images/su1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/su1.png
--------------------------------------------------------------------------------
/images/su2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/su2.png
--------------------------------------------------------------------------------
/images/su3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/su3.png
--------------------------------------------------------------------------------
/images/sv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/sv.png
--------------------------------------------------------------------------------
/images/sv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/sv1.png
--------------------------------------------------------------------------------
/images/sv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/sv2.png
--------------------------------------------------------------------------------
/images/sv3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/sv3.png
--------------------------------------------------------------------------------
/images/u1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/u1.png
--------------------------------------------------------------------------------
/images/u2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/u2.png
--------------------------------------------------------------------------------
/images/u3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/u3.png
--------------------------------------------------------------------------------
/images/v1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/v1.png
--------------------------------------------------------------------------------
/images/v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/v2.png
--------------------------------------------------------------------------------
/images/v3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/v3.png
--------------------------------------------------------------------------------
/images/xu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xu.png
--------------------------------------------------------------------------------
/images/xu1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xu1.png
--------------------------------------------------------------------------------
/images/xu2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xu2.png
--------------------------------------------------------------------------------
/images/xu3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xu3.png
--------------------------------------------------------------------------------
/images/xv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xv.png
--------------------------------------------------------------------------------
/images/xv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xv1.png
--------------------------------------------------------------------------------
/images/xv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xv2.png
--------------------------------------------------------------------------------
/images/xv3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/xv3.png
--------------------------------------------------------------------------------
/images/bbu1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbu1.png
--------------------------------------------------------------------------------
/images/bbu2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbu2.png
--------------------------------------------------------------------------------
/images/bbu3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbu3.png
--------------------------------------------------------------------------------
/images/bbv1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbv1.png
--------------------------------------------------------------------------------
/images/bbv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbv2.png
--------------------------------------------------------------------------------
/images/bbv3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/bbv3.png
--------------------------------------------------------------------------------
/images/new/^4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/^4.png
--------------------------------------------------------------------------------
/images/new/v4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/v4.png
--------------------------------------------------------------------------------
/images/new/#^4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/#^4.png
--------------------------------------------------------------------------------
/images/new/#v4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/#v4.png
--------------------------------------------------------------------------------
/images/new/b^4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/b^4.png
--------------------------------------------------------------------------------
/images/new/bb^4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/bb^4.png
--------------------------------------------------------------------------------
/images/new/bbv4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/bbv4.png
--------------------------------------------------------------------------------
/images/new/bv4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/bv4.png
--------------------------------------------------------------------------------
/images/new/x^4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/x^4.png
--------------------------------------------------------------------------------
/images/new/xv4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/xv4.png
--------------------------------------------------------------------------------
/images/key-sig-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/key-sig-example.png
--------------------------------------------------------------------------------
/images/new/94 edo demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/new/94 edo demo.png
--------------------------------------------------------------------------------
/images/microtonal-plugin-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/euwbah/musescore-microtonal-edo-plugin/HEAD/images/microtonal-plugin-screenshot.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/musescore-31-tet-plugin.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Changelog
2 |
3 | ### 2.3.3
4 | - Adopted val calculation to improve extensibility
5 |
6 | ### 2.3.2
7 | - Fixed perfect (sharp-0) EDOs not working properly, 35 EDO infinite loop
8 | - Fixed typo in getOverLimitEnharmonicEquivalent causing overlimit semitone nominals to be calculated
9 | using whole tone nominals/return NaN, which breaks semitone nominals of uncommon EDOs.
10 | - Refactored console logging to improve performance
11 |
12 | ### 2.3.1
13 | - Implemented extensible config object; added showallaccidentals feature to always show courtesy accidentals.
14 |
15 | ### 2.3.0
16 | - Added support for transposing instruments via transposition annotation. Only regular fifth-based transpositions
17 | are supported (regular accidentals only).
18 | - Clean up readme.
19 |
20 | ### 2.2.9
21 | - Fixed pitch down invoking pitch-up command when rests/text/non-note elements are selected
22 | - Fixed pitch up not correcting an exceeded enharmonic (bug fix #31)
23 |
24 | ### 2.2.8
25 | - Fixed critical bug:
26 | - localized name used for staff/system text causing the plugin to not work
27 | when MuseScore is not set to use English.
28 |
29 | ### 2.2.7
30 | - Fixed critical bugs:
31 | - two notes in same segment, voice, tick, and line, yields wrong accidentals when transposed.
32 | (getMostRecentAccidentalInBar did not handle 'before' processing correctly. 'before' was tick based
33 | but should've been based on voice and visual positioning).
34 | - Wayyyy more robust setAccidental function which ensures set accidentals persist in
35 | code even after the note is edited and traversed.
36 | This actually allows for a lot of the parms state nonsense to be removed with some refactoring.
37 | Perhaps in a future version the code base can be a lot cleaner.
38 |
39 | ### 2.2.6
40 | - Fixed critical bugs:
41 | - getMostRecentAcc gave the wrong accidental when there are notes on the same staff line
42 | in different voices, causes pitch up/down to get stuck on one note.
43 | - Tune N-EDO plugin: key signature/edo/frequency center annotation texts broken when multiple voices are present in the bar where the annotation texts are declared (Bug fix #25)
44 |
45 | ### 2.2.5
46 | - Fixed critical bugs:
47 | - Some grace notes break the plugin due to a typo in getMostRecentAccidentalInBar.
48 | Some grace notes were indexed as notes[i] instead of notes[j] due to careless copy-pasting typo.
49 | - Pitch up with arrows not working
50 |
51 | ### 2.2.4
52 | - Fixed critical bug:
53 | - if a note were to have an explicit natural accidental after pitching up/down,
54 | and the inherited accidental prior to the current note was a regular accidental,
55 | any following notes in the selection with the same pitch will be affected by the first regular accidental,
56 | and not the second one.
57 | - Fixed typo in NoteType.APPOGIATURE => NoteType.APPOGGIATURA
58 |
59 | ### 2.2.3
60 | - Fixed issue where an accidental in the next bar affects an accidental before when the accidental in the
61 | next bar is of a lower voice index than the current selected individual note(s).
62 | This issue only happens when noteheads are selected rather than entire group selections,
63 | and the noteheads are of voice 2, 3 or 4.
64 |
65 | ### 2.2.2
66 | - Fixed incorrect tuning of up/down arrows where regular sharps/flats are applicable.
67 |
68 | ### 2.2.1
69 | - Bug fix (#17)
70 |
71 | ### 2.2.0
72 | - Added support for custom tuning centers.
73 |
74 | ### 2.1.2
75 | - Added 'no dt' version, which prioritizes up/down arrows over semi/sesqui sharps and flats wherever possible.
76 |
77 | ### 2.1.1
78 | - Fixed formatted StaffText/SystemText causing tuning system parsing to fail
79 | - Fixed certain accidentals fail to reflect in tuning plugin
80 | - Caused by unexpected coercion of accidentalType to string.
81 |
82 | ### 2.1.0
83 | - Implement generic n-EDO plugin for flat-2 to sharp-8 EDOs. (Most EDOs from 5 to 72 are covered, except 59, 66, and 71)
84 |
85 | ### 2.0.3
86 | - Fixed local vs. global key signatures not working.
87 |
88 | ### 2.0.2
89 | - Fixed transposing breaking down on grace notes
90 | - `note.parent.parent.tick` vs. `note.parent.parent.parent.tick` for grace notes abstracted by `getTick()`
91 | - Fixed grace notes not regarding sibling grace notes and parent chord notes as possible candidates
92 | for followingOldLine and followingNewLine.
93 | - Fixed accidentals on prior grace notes on the current chord segment not accounted for.
94 | - Fixed cursor relocation on getAccidental causing havoc. getAccidental will now return cursor to original position.
95 | - Relocate cursor to individually selected notes when transposing
96 |
97 | ### 2.0.1
98 | - Fixed reading accidentals for transposition doesn't work when accidentals are in
99 | the last bar.
100 |
101 | ### 2.0.0
102 | - Added stepwise note transposition feature for edostep to replace up/down arrow keys
103 | function.
104 | - Refactored accidental state reading to be stateless. (for transposition plugins)
105 | - Fixed up/downs notation accidentals to follow best-fifths convention as per [NOTATION GUIDE FOR EDOS 5-72](http://tallkite.com/misc_files/notation%20guide%20for%20edos%205-72.pdf).
106 | - ~~Handle playback for notes exceeding offset bounds of +/-200 cents.~~ (Unnecessary,
107 | [pitch offset may exceed 200/300 cents even if not reflected in UI](https://www.reddit.com/r/microtonal/comments/gssrnk/made_this_31_22_edo_microtonal_plugin_for/fs7frcg?utm_source=share&utm_medium=web2x))
108 | - Support for ties in transposition
109 |
110 | ### 1.3.7
111 | - Fixed custom key signatures before selection not being applied to selection.
112 | - Fixed accidentals in same bar before selection not being accounted for
113 | - Fixed partial selection not working
114 | - Improved handling of two notes with the same line at the same time.
115 | - Fixed custom key signatures in partial selections not working.
116 | - Fixed cursor rewind calls to use the Only Right Way That Works :tm: for whatever reason.
117 |
118 | ### 1.3.6
119 | - Fixed fermatas and other non-text annotations breaking the plugin
120 |
121 | ### 1.3.5
122 | - Added 22-edo superpyth version.
123 | - Fixed custom key signatures not affecting other voices (even system text)
124 | - Fixed accidentals on notes of higher voices not affecting lower voices
125 |
126 | ### 1.3.4
127 | - Fixed meantone double accidentals not accounting for accidental's default double
128 | sharp/flat effect (https://musescore.org/en/node/285449)
129 |
130 | ### 1.3.3
131 | - Fixed custom key signatures not working if multiple annotations exist on same segment
132 | (caused by JavaScript insanity)
133 | - Fixed explicit natural accidentals not affecting custom key signatures
134 |
135 | ### 1.3.2
136 |
137 | - Now supports MuseScore version 3!
138 |
139 | ### 1.3
140 |
141 | - Removed unecessary GUI dialog --- planning to make a 31-TET suite of micro-plugin features which
142 | users can take advantage of custom-assigned plugin key bindings to improve workflow.
143 | (E.g. Alt + W to transpose up 1 diesis, Alt + S to transpose down 1 diesis, Alt + E to rotate enharmonical equivalents)
144 | - Added meantone mode
145 | - Fixed microtonal accidentals from notes in same staff not affecting subsequent notes of other voices in same staff in measure.
146 |
147 | ### 1.2
148 |
149 | - Fixed non-naturalised explicit natural accidental in note affected by a custom key signature
150 | - Added support for declaring custom key signature changes in SystemText/StaffText
151 | - Added usage guide in this file
152 | - Preparing for meantone quartertone-accidental mode support
153 |
154 | ### 1.1
155 |
156 | - Fixed occassional bug where microtonal accidentals carry over the bar line when it shouldn't
157 | - Attempted to fix UI bug in Windows, haven't tested it yet though :/
158 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Microtonal plugin for Musescore 3.4+: Retune + Transpose in almost any EDO.
2 |
3 |
4 |
5 | ## ⚠️ This project is deprecated ⚠️
6 |
7 | This project is no longer maintained. Please use [euwbah/musescore-xen-tuner](https://github.com/euwbah/musescore-xen-tuner) instead, which is a much more powerful and general solution for microtonality in MuseScore 3. Supports JI, EDOs, stretched tunings, non-octave tunings, NEJI, Bohlen-Pierce, negative staves, chromatic staves, custom/variable nominals, accidental ligatures (HEJI & Sagittal). MS 4 support is being worked on.
8 |
9 | -----
10 |
11 | 
12 |
13 | ## Features
14 |
15 | - Retuning notes to match any [supported edo](#appendix-a-list-of-supported-edos-according-to-sharpness-classification) of choice
16 | - Special thanks to [Flora Canou](https://github.com/FloraCanou/musescore-n-tet-plugins) for providing the generalized method for evaluating cent offsets for any EDO.
17 | - Support for key signatures via [Key signature annotations](#key-signatures)
18 | - Transposing individual notes/selections by 1 EDO step while automatically assigning accidentals
19 | - Tuning, key signatures, and reference pitches can be changed mid score;
20 | - Each staff can be assigned its own tunings, key signatures, and reference pitches independently.
21 | - Based on [Kite Giedraitis' ups and downs notation](http://tallkite.com/misc_files/notation%20guide%20for%20edos%205-72.pdf)
22 |
23 | ## Support me
24 |
25 | Support this plugin + fund my xenharmonic music creation and research.
26 | Any amount would be greatly appreciated!
27 |
28 | [](https://github.com/sponsors/euwbah)
29 |
30 | ## Quick start
31 |
32 | **Make sure you are using MuseScore 3.4 or newer. The plugin will not work in previous versions**
33 |
34 | ### 1. [Download the project](https://github.com/euwbah/musescore-n-tet-plugins/archive/master.zip) and unzip into [MuseScore's plugins directory](https://musescore.org/en/handbook/3/plugins#windows)
35 |
36 | ### 2. [Enable](https://musescore.org/en/handbook/3/plugins#enable-disable-plugins) the following plugins
37 |
38 | - `tune n-edo`: Tunes the selected notes, or entire score if nothing selected. Notes are not automatically tuned
39 | as they are entered, so it is important to run this regularly for accurate playback.
40 | - `pitch up` & `pitch down`: Transposes selected notes by 1 edostep, then updates their tuning.
41 | Equivalent to MuseScore's up/down arrow shortcuts. If you prefer arrow notation over semi/sesqui
42 | sharp/flat quartertone notation, use `pitch up no dt` & `pitch down no dt` instead.
43 |
44 | ### 3. Set up keyboard shortcuts for the plugins
45 | (optional, highly recommended for the best experience)
46 |
47 | - First, clear/change the default shortcuts that uses the up/down arrow keys.
48 | You can find these in _Edit -> Preferences -> Shortcuts_. Search for the following shortcut names,
49 | select them and click the _Clear_ button.
50 | - _Pitch up or move text or articulation up_
51 | - _Pitch down or move text or articulation down_
52 | - _Select string above_
53 | - _Select string below_
54 | - To define a shortcut for a plugin, go to: _Plugins -> Plugin Manager -> Select plugin name in the list -> Define Shortcut_.
55 | - Set `tune n-edo` to use `Alt-R`.
56 | - Set `pitch up`/`pitch up no dt` to use the up arrow. This shortcut should only be assigned on either one of the plugins.
57 | - Set `pitch down`/`pitch down no dt` to use the down arrow. This shortcut should only be assigned on either one of the plugins.
58 |
59 | ### 4. Select a tuning system
60 |
61 | Create a System Text (`Ctrl-Shift-T`) and type `___ edo`, fill in the blank with any
62 | of the [supported edo tunings](#appendix-a-list-of-supported-edos-according-to-sharpness-classification). This will
63 | affect all staves/parts from the bar where the text was placed onwards.
64 |
65 | If you wish to only change the tuning of
66 | one staff, but not the others, use Staff Text (`Ctrl-T`) instead. You should not place a tuning system change
67 | halfway through a bar.
68 |
69 | If a tuning system has not been specified for a part, it defaults to 12 edo.
70 | The text is case-insensitive.
71 |
72 | ### 5. Annotate key signatures
73 |
74 | For each key signature, create one System Text (`Ctrl-Shift-T`) at the start of the same
75 | bar as the key signature, then type `.x.x.x.x.x.x.x`, where each 'x'
76 | represents an [accidental](#accidental-code) applied on the notes C, D, E, F, G, A, and B respectively.
77 | If a note should have no accidental, you can leave it blank or put any other placeholder character.
78 | For example, the key signature for D major can look like: `.#...#...` representing C# and F#.
79 | There should always be 7 dots (`.`) in the key signature annotation. Refer to the
80 | [list of supported key signatures](#accidental-code).
81 |
82 | If there are staves which have a separate key signatures from the others,
83 | as in [local key signatures](https://musescore.org/en/handbook/3/key-signatures#add-key-sig-to-one-staff),
84 | or transposing instruments, you can assign a key signature annotation for just that
85 | staff using Staff Text (`Ctrl-T`) instead of System Text.
86 |
87 | > :warning: Due to current technical limitations of MuseScore,
88 | **all** key signatures, even standard non-custom ones, must be accompanied by key signature annotations.
89 | >
90 | > :warning: It is necessary to adjust the key signature annotations when toggling between concert and tranposing pitch
91 | display modes.
92 |
93 | If a key signature annotation has not been specified, the plugin assumes that there are no accidentals in the key
94 | signature. The text is case-insensitive.
95 |
96 | ### 6. Annotate transposing instruments
97 |
98 | If a part uses a transposing instrument, create a Staff Text (`Ctrl-T`) at
99 | the start of the first bar of the part, or at the start of the bar where an instrument change to
100 | a transposing instrument of a different transposition is performed. In this staff text,
101 | type `t: Bb` for Bb instruments, `t: Eb` for Eb instruments, etc. All fifth-based transpositions
102 | are supported - meaning you can use the accidentals `x`, `#`, `b`, `bb`.
103 |
104 | This step is required as MuseScore implements transpositions as offsets in 12-edo.
105 | Placing the transposition annotation will correct the offset into the current tuning system.
106 | Note that if [Concert Pitch](https://musescore.org/en/handbook/3/concert-pitch) display mode is active,
107 | the transposition annotation will not take effect and all parts will be treated as C instruments.
108 |
109 | If no transposition annotations were specified, the part is assumed to be a C instrument.
110 | The text is case-insensitive.
111 |
112 | ### 7. Select a reference pitch
113 |
114 | This step is optional and reference pitch is defaulted to `A4: 440 Hz`.
115 |
116 | To change reference pitch for all parts, create a System Text (`Ctrl-Shift-T`) and
117 | type `{note}: {f} Hz`:
118 | - `{note}` represents any note A through G followed by
119 | its octave without spaces. Middle C is written as `C4`.
120 | - `{f}` represents the frequency of the above reference note in Hertz
121 | - the _'Hz'_ is optional
122 |
123 | To change reference pitch for only one part, use Staff Text (`Ctrl-T`) instead.
124 | The text is case-insensitive.
125 |
126 | ### 8. Done!
127 |
128 | You can now use the up and down arrow keys to adjust a note according
129 | to the tuning system of choice! Here are some things to take note of:
130 | - You can make the text annotations invisible by selecting them and pressing `V`.
131 | - Make sure each System/Staff Text only contains one modifier; don't combine
132 | tuning selection and key signature annotation in one Text element.
133 | - Remember to run the `tune n-edo` plugin regularly to update the pitches of
134 | notes that are not yet tuned/transposed.
135 | - Recall that:
136 | - System Text (`Ctrl-Shift-T`) = annotation applies to all staves
137 | - Staff Text (`Ctrl-T`) = annotation applies to current staff only.
138 |
139 | ----------------------
140 |
141 | ### Additional Settings
142 |
143 | In a separate Staff/System Text annotation, type `config: {showallaccidentals: true}` (verbatim)
144 | to turn on courtesy accidentals for all notes (helpful for atonal pieces or scores without barlines).
145 |
146 | ------------------------
147 |
148 | ## Accidental Code
149 |
150 | 
151 |
152 | | Accidental | Textual representation |
153 | | ----: | :---- |
154 | |  | `bbv3` |
155 | |  | `bbv2` |
156 | |  | `bbv` or `bbv1` |
157 | |  | `bb` |
158 | |  | `bb^` or `bb^1` |
159 | |  | `bb^2` |
160 | |  | `bb^3` |
161 | |  | `db` or `bd` |
162 | |  | `bv3` |
163 | |  | `bv2` |
164 | |  | `bv` or `bv1` |
165 | |  | `b` |
166 | |  | `b^` or `b^1` |
167 | |  | `b^2` |
168 | |  | `b^3` |
169 | |  | `v3` |
170 | |  | `v2` |
171 | |  | `v` or `v1` |
172 | |  | `d` |
173 | |  | Leave blank / any other character |
174 | |  | `+` |
175 | |  | `^` or `^1` |
176 | |  | `^2` |
177 | |  | `^3` |
178 | |  | `#v3` |
179 | |  | `#v2` |
180 | |  | `#v` or `#v1` |
181 | |  | `#` |
182 | |  | `#^` or `#^1` |
183 | |  | `#^2` |
184 | |  | `#^3` |
185 | |  | `#+` or `+#` |
186 | |  | `xv3` |
187 | |  | `xv2` |
188 | |  | `xv` or `xv1` |
189 | |  | `x` |
190 | |  | `x^` or `x^1` |
191 | |  | `x^2` |
192 | |  | `x^3` |
193 |
194 | ## Modification
195 |
196 | 原插件issue https://github.com/euwbah/musescore-microtonal-edo-plugin/issues/36 的权宜之计:使用10个Musescore内存在的变音号代替不存在的4箭头变音号,从而使得sharp-9、sharp-10律制可以使用。
197 |
198 | 
199 |
200 | #### 新的变音号
201 |
202 | | 变音号 | 名称 | 内部名称 | 选择原因 |
203 | | :---- | :---- | :---- | :---- |
204 | |  | `v4` | `LOWER_ONE_SEPTIMAL_COMMA` | 看起来像还原号的左半边 |
205 | |  | `^4` | `RAISE_ONE_SEPTIMAL_COMMA` | 和上面那个符号相对应 |
206 | |  | `#v4` | `RAISE_ONE_TRIDECIMAL_QUARTERTONE` | 升记号少一横,表示少升一点 |
207 | |  | `#^4` | `SHARP_SLASH2` | 同上,升记号多一横,表示多升一点 |
208 | |  | `bv4` | `THREE_TWELFTH_FLAT` | 降记号上面加点东西表示比普通的降记号高 |
209 | |  | `b^4` | `FOUR_TWELFTH_FLAT` | 降记号下面加点东西表示比普通的降记号低 |
210 | |  | `bbv4` | `NINE_TWELFTH_FLAT` | 同上,额外加一个普通的降记号 |
211 | |  | `bb^4` | `TEN_TWELFTH_FLAT` | 同上,额外加一个普通的降记号 |
212 | |  | `x^4` | `DOUBLE_SHARP_EQUAL_TEMPERED` | 重升号上面加点东西表示比普通的重升号高 |
213 | |  | `xv4` | `SAGITTAL_SHARP25SD` | 实在找不到合适的记号就随便找了个不会混淆的 |
214 |
215 | ### English
216 |
217 | A simple and straight-forward solution to issue https://github.com/euwbah/musescore-microtonal-edo-plugin/issues/36 : Include 10 extra accidentals supported by Musescore representing 4-arrow accidentals so that the plugin can tune sharp-9 & sharp-10 EDOs.
218 |
219 | #### New accidental
220 |
221 | | Accidental | Text | Internal name | Reason |
222 | | :---- | :---- | :---- | :---- |
223 | |  | `v4` | `LOWER_ONE_SEPTIMAL_COMMA` | It looks like the left half of the natural |
224 | |  | `^4` | `RAISE_ONE_SEPTIMAL_COMMA` | Pairing with the symbol above |
225 | |  | `#v4` | `RAISE_ONE_TRIDECIMAL_QUARTERTONE` | The sharp, but missing a bar, indicating less sharped |
226 | |  | `#^4` | `SHARP_SLASH2` | The sharp, but having an extra bar, indicating more sharped |
227 | |  | `bv4` | `THREE_TWELFTH_FLAT` | The flat, but with bars above, indicating sharper than flat |
228 | |  | `b^4` | `FOUR_TWELFTH_FLAT` | The flat, but with signs below, indicating flatter than flat |
229 | |  | `bbv4` | `NINE_TWELFTH_FLAT` | As above, an extra flat is added |
230 | |  | `bb^4` | `TEN_TWELFTH_FLAT` | As above, an extra flat is added |
231 | |  | `x^4` | `DOUBLE_SHARP_EQUAL_TEMPERED` | The double sharp, but with signs above, indicating sharper than double sharp |
232 | |  | `xv4` | `SAGITTAL_SHARP25SD` | I cannot find an appropriate accidental, so I choose an arbitary one |
233 |
234 | -----------------
235 |
236 | ## Notation system
237 |
238 | The plugin follows notation standards as per [Kite Giedraitis' ups and downs notation](http://tallkite.com/misc_files/notation%20guide%20for%20edos%205-72.pdf),
239 | which is a generalized system for notating any EDO.
240 |
241 | Here is a brief summary of the contents of the document:
242 |
243 | ### Tuning of nominals C D E F G A B
244 |
245 | In this system, the nominals F C G D A E B are tuned according to a chain of **best fifths**,
246 | which is the best representation of the perfect 3:2 just fifth that the EDO has to offer.\
247 | The exact pitches of the notes are calculated based on the frequency of the reference note, which is defined by the
248 | reference frequency selector, or A4: 440 Hz by default.
249 |
250 |
251 | How to calculate an EDO's best fifth?
252 |
253 | The number of steps a fifth is in x-edo = `round(x * log2(3/2))`
254 |
255 | `3/2` represents the frequency ratio of a fifth in just intonation.\
256 | `log2(3/2)` represents how many octaves are there in a fifth (approx 0.584962)\
257 | `x * log2(3/2)` represents how many steps of x-edo are there in a fifth\
258 | `round()` rounds it up/down to the nearest whole edostep.
259 |
260 | E.g's:
261 | - The best fifth in 12 edo is 7 steps. Thus, the distance between F-C, C-G, G-D, etc.. is 7 steps of 12 edo.
262 | - The best fifth in 22 edo is 13 steps. Thus, the distance between C-G, etc.. is 13 steps of 22 edo.
263 |
264 |
265 |
266 |
267 | ### Tuning of regular pythagorean accidentals
268 |
269 |    
270 |
271 | The standard accidentals Double Flat (`bb`), Flat (`b`), Sharp (`#`), Double Sharp (`x`) are based on
272 | the circle of fifths.
273 |
274 | To give an example in 12-edo, going 7 fifths up from C4 yields C4-G4-D5-A5-E6-B6-F#7-C#8.\
275 | A best fifth in 12-edo is 7 steps of 12 edo.\
276 | Going up 7 fifths in 12-edo yields a total of 7*7 = 49 steps (which brings C4 to C#8)\
277 | Going down 4 octaves to bring C#8 down to C#4 reduces the steps by 4 * 12 = 48 steps.\
278 | Thus, a sharp symbol in 12-edo is defined as going up 49 steps, then down 48 steps, yielding a +1 step difference.
279 |
280 | The number of edosteps a sharp symbol raises the pitch by is known as an EDO's **sharpness** value,
281 | also known as the size of the **apotome**.\
282 | Thus, the sharpness of 12-edo is 1, which classifies it as a **sharp-1** EDO.\
283 | Consequently, a double sharp raises the pitch by 2 times of the sharpness value, thus 2 steps.\
284 | A flat lowers the pitch by the sharpness value, thus lowering it by 1 step.\
285 | A double flat lowers the pitch by 2 times of the sharpness value, thus lowering it by 2 steps.
286 |
287 | To give another example in 23-edo:
288 | A best fifth in 23-edo is 13 edosteps.\
289 | Going up 7 fifths (From C4 to C#8) = going up 7 * 13 = 91 steps.\
290 | Going down 4 octaves (From C#8 to C#4) = going down 4 * 23 = 92 steps.\
291 | Thus, a sharp symbol in 23-edo is defined as going up 91 steps and down 92 steps, yielding a -1 step difference.\
292 | A sharp symbol in 23-edo, surprisingly, __lowers__ the pitch by 1 step, instead of raising it.\
293 | Consequently, the flat symbol raises the pitch by 1 step.\
294 | The apotome size of 23-edo is -1, which classifies it as a **flat-1** EDO.
295 |
296 | Note: in EDOs such as 7, 14 and 21, the sharp and flats do not raise nor lower the pitch, and thus
297 | they are known as **perfect** EDOs, i.e. **Sharp-0**.
298 |
299 | [Here is the full list of supported EDOs and their respective sharpness values.](#appendix-a-list-of-supported-edos-according-to-sharpness-classification)
300 |
301 | The plugin only supports up to 2 flats and sharps. Triple flats and sharps and not supported as
302 | MuseScore does not provide these accidentals.
303 |
304 | ### Tuning of up/down arrows
305 |
306 |   
307 |
308 | Arrows on the natural, sharp/flat, double sharp/flat accidentals offsets the pitch of the note by
309 | the same number of steps of the EDO as there are arrows on the accidental.
310 |
311 | An upwards arrow always raises the pitch by 1 step, regardless of whether the sharp symbol raises or lowers the pitch of the
312 | note. Vice versa, a downwards arrow always lowers the pitch by 1 step.
313 |
314 | Thus the interval between C and C^ is +1 step. And so is the interval between C# and C#^, Cbv and Cb, etc..
315 |
316 | A maximum of 3 arrows are allowed on each accidental, as MuseScore currently does not provide accidentals
317 | with more than 3 arrows. Due to these limitations, and with the help of quartertone accidentals, the plugin
318 | can only handle EDOs with a sharpness rating of up to 8.
319 |
320 | [Here is the full list of supported EDOs and their respective sharpness values.](#appendix-a-list-of-supported-edos-according-to-sharpness-classification)
321 |
322 | The up/down arrow accidentals this plugin uses are Helmholtz-Ellis Just Intonation accidentals.\
323 | Gould arrow quartertone symbols look very similar to the single up/down arrow Helmholtz-Ellis accidentals,
324 | and may be used interchangeably, although the plugin defaults to Helmholtz-Ellis when transposing.
325 | To differentiate the two, Gould arrow symbols appear slightly larger than the Helmholtz-Ellis ones.
326 |
327 | ### Tuning of quartertone (semisharp/semiflat) accidentals
328 |
329 |    
330 |
331 | Stein-Zimmermann quartertone accidentals represent an offset of half or one-and-a-half times of the standard sharpness
332 | of the accidental. They only work when the EDO has an even-number sharpness rating which can be divided
333 | by 2 evenly.
334 |
335 | For example, in 31-edo, where the sharpness rating is sharp-2:
336 | -  lowers the pitch by 1.5 x 2 = -3 steps
337 | -  lowers the pitch by 0.5 x 2 = -1 step
338 | -  raises the pitch by 0.5 x 2 = +1 step
339 | -  raises the pitch by 1.5 x 2 = +3 steps
340 |
341 |
342 | --------
343 |
344 |
345 | ## Known issues:
346 |
347 | - Cross staff notation doesn't work properly, the accidentals in the staff that the notes are transferred to
348 | do not affect the notes that originally belonged in that staff that the notes were transferred to.
349 | Please refrain from using cross-staff notation, or submit a PR for this fix.
350 |
351 | - Accidentals of grace notes that comes after rather than before are handled as if they were before, and also
352 | not in the right order. This causes huge problems when transposing.
353 | Please refrain from using grace notes that attach after main notes, or submit a PR for this fix.
354 |
355 | - The plugin tries its best to handle chords with pairs of mirrored notes that
356 | share the same line (e.g. an F and F# on the same staff line) but due to plugin API
357 | limitations and the way MuseScore natively handles them, its behavior is somewhat janky.
358 | When dealing with them, ALWAYS use explicit accidentals on the mirrored notes to
359 | ensure the Accidentals are all registered correctly. This way it is clear to read
360 | and also for the plugin to read and understand which accidentals belong to which
361 | notes.
362 | - The exact order the plugin reads and performs operations on its notes of each chord segment are as follows:
363 | 1. grace notes (in similar fashion to step 2)
364 | 2. For notes in the same chord, left to right, then bottom to top, as they appear in the score.
365 |
366 | -------------
367 |
368 | ## Appendix A: List of supported EDOs according to sharpness classification.
369 |
370 | | Sharpness (steps of an apotome) | EDOs |
371 | | -------: | :------- |
372 | | flat-2 | 4, 11 |
373 | | flat-1 | 2, 9, 16, 23 |
374 | | perfect | 7, 14, 21, 28, 35 |
375 | | sharp-1 | 5, 12, 19, 26, 33, 40, 47 |
376 | | sharp-2 | 3, 10, 17, 24, 31, 38, 45, 52 |
377 | | sharp-3 | 1, 8, 15, 22, 29, 36, 43, 50, 57, 64 |
378 | | sharp-4 | 6, 13, 20, 27, 34, 41, 48, 55, 62, 69, 76 |
379 | | sharp-5 | 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88 |
380 | | sharp-6 | 30, 37, 44, 51, 58, 65, 72, 79, 86, 93, 100 |
381 | | sharp-7 | 42, 49, 56, 63, 70, 77, 84, 91, 98, 105 |
382 | | sharp-8 | 54, 61, 68, 75, 82, 89, 96, 103, 110, 117 |
383 |
384 | ---------------
385 |
386 | ## Note to self / developers:
387 |
388 | ### IMPORTANT basic info on undocumented Plugin API mechanics!
389 |
390 | CURSOR REWIND MECHANICS ARE WEIRD!
391 | - If rewinding to start of selection `cursor.rewind(1)`, set `cursor.staffIdx` and `cursor.voice` after
392 | `rewind(1)`.
393 | - If rewinding to start of score, IT IS STILL NECESSARY TO CALL `cursor.rewind(1)`, then set `staffIdx` and `voice`,
394 | THEN call `cursor.rewind(0)` AFTERWARDS. \
395 | Apparently, based on the (add courtesy accidentals)[https://github.com/heuchi/courtesyAccidentals/blob/master/addCourtesyAccidentals.qml#L160] plugin, `cursor.track` has to be set to 0 in order for `cursor.rewind(0)` to work.
396 |
397 |
398 | It is an invalid operation to set cursor voice/staffIdx without rewinding.
399 |
400 | IMPORTANT! DO NOT USE `===` or `!==` to compare equivalence of accidentalType to Accidental enum values.
401 |
402 | When assigning `Note.accidentalType` to variables or passing it into a function as a parameter,
403 | ensure that the value read is in integer format to invoke the getter of the
404 | integer enumeration instead of the stringified value of the accidental type.
405 |
406 | ```js
407 | noteData.explicitAccidental = note.accidentalType;
408 | console.log(explicitAccidental); // NATURAL_ARROW_UP
409 | noteData.explicitAccidental = 0 + note.accidentalType;
410 | console.log(explicitAccidental); // 11 (enumerated value equivalent of NATURAL_ARROW_UP)
411 |
412 | console.log(Accidental.NATURAL_ARROW_UP); // 11
413 |
414 | console.log(note.accidentalType); // NATURAL_ARROW_UP
415 | console.log(0 + note.accidentalType) // 11
416 | ```
417 |
418 | There is a very specific method to update an existing note's accidental
419 | such that there are minimal race/state errors. Refer to the ]
420 | [`setAccidental()`](https://github.com/euwbah/musescore-n-tet-plugins/blob/56aa8cc3697ac04d31eff82ba59edc177a55d88f/pitch%20down.qml#L3457) function.
421 |
422 | `Note.accidental` and `Note.accidentalType` properties of transposed notes that contain new accidental values of standardized
423 | accidentals are not present in a new cursor instance. The plugin uses tpc as a workaround, but it makes it impossible to
424 | determine if a prior note's accidental was implicit or explicit.\
425 | [See this forum post here.](https://musescore.org/en/node/305977)
426 |
427 | ##### Important properties:
428 |
429 | **IMPORTANT `Note.accidental` vs. `Note.accidentalType`**:
430 | : `accidental` represents the accidental Element object itself,
431 | : whereas, accidentalType is a value of the Accidental enumeration!!
432 |
433 | `tpc`
434 | : Tonal pitch class. Circle of fifths starting from Fbb with value of -1.
435 | : Cbb = 0, Gbb = 1, Dbb = 2, etc...
436 |
437 | `segment.annotations[idx].textStyleType`
438 | : 22 if Staff Text,
439 | : 21 if System Text
440 |
441 | `segment.annotations[idx].text`
442 | : Contains given text
443 |
444 | `MuseScore.curScore.selection.elements`
445 | : An array of elements containing individual elements the user has selected
446 | : with ctrl + click. Especially useful for applying an action to certain notes in particular.
447 |
448 |
449 | #### Musescore Enums
450 |
451 | ##### Accidentals (used in project)
452 |
453 | ```
454 | Accidental.NONE (no explicit accidental)
455 | Accidental.DOUBLE_SHARP_ONE_ARROW_UP x^
456 | Accidental.DOUBLE_SHARP_TWO_ARROWS_UP x^2
457 | Accidental.DOUBLE_SHARP_THREE_ARROWS_UP x^3
458 | Accidental.SHARP2 x
459 | Accidental.DOUBLE_SHARP_ONE_ARROW_DOWN xv
460 | Accidental.DOUBLE_SHARP_TWO_ARROWS_DOWN xv2
461 | Accidental.DOUBLE_SHARP_THREE_ARROWS_DOWN xv3
462 | Accidental.SHARP_SLASH4 #+
463 | Accidental.SHARP_ONE_ARROW_UP #^
464 | Accidental.SHARP_TWO_ARROWS_UP #^2
465 | Accidental.SHARP_THREE_ARROWS_UP #^3
466 | Accidental.SHARP #
467 | Accidental.SHARP_ONE_ARROW_DOWN #v
468 | Accidental.SHARP_TWO_ARROWS_DOWN #v2
469 | Accidental.SHARP_THREE_ARROWS_DOWN #v3
470 | Accidental.SHARP_SLASH +
471 | Accidental.NATURAL_ONE_ARROW_UP ^
472 | Accidental.NATURAL_TWO_ARROWS_UP ^2
473 | Accidental.NATURAL_THREE_ARROWS_UP ^3
474 | Accidental.NATURAL natural
475 | Accidental.NATURAL_ONE_ARROW_DOWN v
476 | Accidental.NATURAL_TWO_ARROWS_DOWN v2
477 | Accidental.NATURAL_THREE_ARROWS_DOWN v3
478 | Accidental.MIRRORED_FLAT d
479 | Accidental.FLAT_ONE_ARROW_UP b^
480 | Accidental.FLAT_TWO_ARROWS_UP b^2
481 | Accidental.FLAT_THREE_ARROWS_UP b^3
482 | Accidental.FLAT b
483 | Accidental.FLAT_ONE_ARROW_DOWN bv
484 | Accidental.FLAT_TWO_ARROWS_DOWN bv2
485 | Accidental.FLAT_THREE_ARROWS_DOWN bv3
486 | Accidental.MIRRORED_FLAT2 db
487 | Accidental.DOUBLE_FLAT_ONE_ARROW_UP bb^
488 | Accidental.DOUBLE_FLAT_TWO_ARROWS_UP bb^2
489 | Accidental.DOUBLE_FLAT_THREE_ARROWS_UP bb^3
490 | Accidental.FLAT2 bb
491 | Accidental.DOUBLE_FLAT_ONE_ARROW_DOWN bbv
492 | Accidental.DOUBLE_FLAT_TWO_ARROWS_DOWN bbv2
493 | Accidental.DOUBLE_FLAT_THREE_ARROWS_DOWN bbv3
494 | ```
495 |
496 | #### Custom object types in up/down step transposition plugins
497 |
498 | ##### Key signature object:
499 |
500 | ```
501 | {
502 | c: {steps: , type: Accidental enum value}
503 | d: ...
504 | e: ...
505 | etc...
506 | }
507 | ```
508 |
509 | ##### Accidental object:
510 |
511 | ```
512 | {
513 | offset: number of diesis offset,
514 | type: accidental type as Accidental enum value
515 | }
516 | ```
517 |
518 | ##### Enharmonics object:
519 |
520 | ```
521 | {
522 | above: {baseNote: 'a' through 'g', offset: diesis offset}
523 | below: {baseNote: 'a' through 'g', offset: diesis offset}
524 | }
525 | ```
526 |
527 | ##### Note pitch data:
528 |
529 | ```
530 | {
531 | baseNote: a string from 'a' to 'g',
532 | line: the note.line property referring to height of the note on the staff
533 | tpc: the tonal pitch class of the note (as per note.tpc)
534 | tick: the tick position of the note
535 | explicitAccidental: Accidental enum of the explicit accidental attatched to this note (if any)
536 | implicitAccidental: Accidental enum of the implicit accidental of this note (non null)
537 | (if explicitAccidental exists, implicitAccidental = explicitAccidental)
538 | diesisOffset: the number of edo steps offset from the base note this note is
539 | }
540 | ```
541 |
542 | ## [Changelog](./CHANGELOG.md)
543 |
544 | ### TODO:
545 |
546 | - Handle cross-staff notation (ctrl + shift + up/down in connected staves, e.g. grand staff) where note appears to be in another staff
547 | other than the cursor's staffIdx. Currently, accidentals in the cross-staff do not work on the notes that came from another staff.
548 | See Add Courtesy Accidentals plugin for how to do this
549 | - Implement toggling between enharmonic equivalences
550 | - Make tune n-edo plugin use stateless accidental detection also.
551 |
--------------------------------------------------------------------------------
/tune n-edo.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1
2 | import QtQuick.Controls 1.3
3 | import QtQuick.Controls.Styles 1.3
4 | import MuseScore 3.0
5 |
6 | MuseScore {
7 | version: "2.3.3"
8 | description: "Retune selection to any EDO temperament, or whole score if nothing selected."
9 | menuPath: "Plugins.n-EDO.Tune"
10 |
11 | // WARNING! This doesn't validate the accidental code!
12 | property variant customKeySigRegex: /\.(.*)\.(.*)\.(.*)\.(.*)\.(.*)\.(.*)\.(.*)/g
13 |
14 | // these lookups are for transposition annotations
15 | property variant fifthsFromC: {
16 | 'f': -1,
17 | 'c': 0,
18 | 'g': 1,
19 | 'd': 2,
20 | 'a': 3,
21 | 'e': 4,
22 | 'b': 5
23 | }
24 |
25 | property variant standardAccFifths: {
26 | 'bb': -14,
27 | 'b': -7,
28 | '': 0,
29 | '#': 7,
30 | 'x': 14
31 | }
32 |
33 | // Enumeration of custom names to map MuseScore symbols, text, and accidentals
34 | // to a consistent accidental enumeration called AccType instead of Accidental.
35 | property variant accType: (function() {
36 | var symbols =
37 | [
38 | 'NONE',
39 | 'NATURAL',
40 | 'SHARP_SLASH4',
41 | 'SHARP_SLASH',
42 | 'MIRRORED_FLAT',
43 | 'MIRRORED_FLAT2',
44 | 'DOUBLE_SHARP_THREE_ARROWS_UP',
45 | 'DOUBLE_SHARP_TWO_ARROWS_UP',
46 | 'SHARP2_ARROW_UP',
47 | 'DOUBLE_SHARP_ONE_ARROW_UP',
48 | 'SHARP2',
49 | 'SHARP2_ARROW_DOWN',
50 | 'DOUBLE_SHARP_ONE_ARROW_DOWN',
51 | 'DOUBLE_SHARP_TWO_ARROWS_DOWN',
52 | 'DOUBLE_SHARP_THREE_ARROWS_DOWN',
53 | 'SHARP_THREE_ARROWS_UP',
54 | 'SHARP_TWO_ARROWS_UP',
55 | 'SHARP_ARROW_UP',
56 | 'SHARP_ONE_ARROW_UP',
57 | 'SHARP',
58 | 'SHARP_ARROW_DOWN',
59 | 'SHARP_ONE_ARROW_DOWN',
60 | 'SHARP_TWO_ARROWS_DOWN',
61 | 'SHARP_THREE_ARROWS_DOWN',
62 | 'NATURAL_THREE_ARROWS_UP',
63 | 'NATURAL_TWO_ARROWS_UP',
64 | 'NATURAL_ARROW_UP',
65 | 'NATURAL_ONE_ARROW_UP',
66 | 'NATURAL_ARROW_DOWN',
67 | 'NATURAL_ONE_ARROW_DOWN',
68 | 'NATURAL_TWO_ARROWS_DOWN',
69 | 'NATURAL_THREE_ARROWS_DOWN',
70 | 'FLAT_THREE_ARROWS_UP',
71 | 'FLAT_TWO_ARROWS_UP',
72 | 'FLAT_ARROW_UP',
73 | 'FLAT_ONE_ARROW_UP',
74 | 'FLAT',
75 | 'FLAT_ARROW_DOWN',
76 | 'FLAT_ONE_ARROW_DOWN',
77 | 'FLAT_TWO_ARROWS_DOWN',
78 | 'FLAT_THREE_ARROWS_DOWN',
79 | 'DOUBLE_FLAT_THREE_ARROWS_UP',
80 | 'DOUBLE_FLAT_TWO_ARROWS_UP',
81 | 'FLAT2_ARROW_UP',
82 | 'DOUBLE_FLAT_ONE_ARROW_UP',
83 | 'FLAT2',
84 | 'FLAT2_ARROW_DOWN',
85 | 'DOUBLE_FLAT_ONE_ARROW_DOWN',
86 | 'DOUBLE_FLAT_TWO_ARROWS_DOWN',
87 | 'DOUBLE_FLAT_THREE_ARROWS_DOWN',
88 |
89 | // Addon
90 | 'LOWER_ONE_SEPTIMAL_COMMA', // v4
91 | 'RAISE_ONE_SEPTIMAL_COMMA', // ^4
92 | 'RAISE_ONE_TRIDECIMAL_QUARTERTONE', // #v4
93 | 'SHARP_SLASH2', // #^4
94 | 'THREE_TWELFTH_FLAT', // bv4
95 | 'FOUR_TWELFTH_FLAT', // b^4
96 | 'SAGITTAL_SHARP25SD', // xv4
97 | 'DOUBLE_SHARP_EQUAL_TEMPERED', // x^4
98 | 'NINE_TWELFTH_FLAT', // bbv4
99 | 'TEN_TWELFTH_FLAT' // bb^4
100 | ];
101 | var enumeration = {};
102 | for (var i = 0; i < symbols.length; i++) {
103 | enumeration[symbols[i]] = i;
104 | }
105 | Object.freeze(enumeration);
106 | return enumeration;
107 | })()
108 |
109 | // An object class for defining all possible accidentals, including
110 | // multi-accidentals, etc...
111 | property var acc: (function() {
112 | var clazz = function() {
113 | this.type = AccType.NONE;
114 | };
115 |
116 | clazz.prototype.calculatePitchOffset = function(tuningSystem) {
117 |
118 | };
119 |
120 | clazz.prototype.readFromNote = function(note) {
121 |
122 | };
123 | })()
124 |
125 | // MuseScore's annotations contain formatting code in angle brackets if the
126 | // annotation text formatting is not default. This function removes
127 | // all text within angle brackets including the brackets themselves
128 | function removeFormattingCode(str) {
129 | if (typeof(str) == 'string')
130 | return str.replace(/<[^>]*>/g, '');
131 | else
132 | return null;
133 | }
134 |
135 | // Calculates the number of cents to detune the default musescore note by.
136 | // noteName: the note nominal alphabet from 'f' thru 'b'
137 | // stepOffset: offset the nominal by this many steps of the EDO
138 | // regAcc: number of regular accidentals
139 | // edo: how many notes per octave in the tuning system.
140 | // center: the central note and its frequency in Hz (by default A4, 440)
141 | //
142 | // Special credits to @FloraCanou (https://github.com/FloraCanou) for conceiving this method
143 | // method edited by @euwbah to set A as the normalised frequency instead of D
144 |
145 | /**
146 | noteName: nominal of note to tune
147 | stepOffset: number of edosteps away from nominal
148 | regAcc: number of sharps in the accidental of this note is a regular accidental
149 | edo: edo to tune to
150 | center: Reference pitch e.g. {note: 'a4', freq: 440}
151 | transFifths: number of fifths this part is transposed by if transposing instrument and
152 | concert pitch mode is off. E.g. Bb clarinet should be -2.
153 | Only regular fifth-based transpositions can be used.
154 | Rationale for this is that musescore's transposing instruments
155 | are transposed in 12 edo, so an additional offset must be applied
156 | to convert it to a fifth-based transposition in n-edo.
157 | */
158 | function getCentOffset(noteName, stepOffset, regAcc, edo, center, transFifths) {
159 | var stepSize = 1200.0 / edo;
160 | var val = [2, 3].map (function (q) {return Math.round(edo * Math.log(q) / Math.LN2);});
161 | var fifthStep = -val[0] + val[1];
162 | var sharpValue = -11*val[0] + 7*val[1];
163 | var twelveFifthVsEdoFifthCents = 700 - (fifthStep * stepSize);
164 | var transpositionCorrection = -transFifths * twelveFifthVsEdoFifthCents;
165 |
166 | // Offset caused by custom central frequency
167 | var centOffset = 1200*Math.log (center.freq / 440) / Math.LN2;
168 | // Offset caused by custom central note
169 | var centerValue;
170 | switch (center.note.substring(0, 1)) {
171 | case 'f':
172 | centOffset += 400;
173 | centerValue = 3;
174 | break;
175 | case 'c':
176 | centOffset += 900;
177 | centerValue = 2;
178 | break;
179 | case 'g':
180 | centOffset += 200;
181 | centerValue = 1;
182 | break;
183 | case 'd':
184 | centOffset += 700;
185 | centerValue = 0;
186 | break;
187 | case 'a':
188 | centOffset += 0;
189 | centerValue = -1;
190 | break;
191 | case 'e':
192 | centOffset += 500;
193 | centerValue = -2;
194 | break;
195 | case 'b':
196 | centOffset += -200;
197 | centerValue = -3;
198 | break;
199 | }
200 | centOffset += -1200*(parseInt(center.note.substring(1, 2)) - 4);
201 |
202 | var nominalOffset = 0;
203 | var nominalOffset = 0;
204 | switch (noteName) {
205 | case 'f':
206 | nominalOffset = (centerValue - 3)*(stepSize*fifthStep - 700);
207 | break;
208 | case 'c':
209 | nominalOffset = (centerValue - 2)*(stepSize*fifthStep - 700);
210 | break;
211 | case 'g':
212 | nominalOffset = (centerValue - 1)*(stepSize*fifthStep - 700);
213 | break;
214 | case 'd':
215 | nominalOffset = centerValue*(stepSize*fifthStep - 700);
216 | break;
217 | case 'a':
218 | nominalOffset = (centerValue + 1)*(stepSize*fifthStep - 700);
219 | break;
220 | case 'e':
221 | nominalOffset = (centerValue + 2)*(stepSize*fifthStep - 700);
222 | break;
223 | case 'b':
224 | nominalOffset = (centerValue + 3)*(stepSize*fifthStep - 700);
225 | break;
226 | }
227 |
228 | return stepSize*stepOffset - 100*regAcc + nominalOffset + centOffset + transpositionCorrection;
229 | }
230 |
231 | function convertAccidentalToStepsOrNull(acc, edo) {
232 | var val = [2, 3].map (function (q) {return Math.round(edo * Math.log(q) / Math.LN2);});
233 | var fifthStep = -val[0] + val[1];
234 | var sharpValue = -11*val[0] + 7*val[1];
235 | switch(acc.trim()) {
236 | case 'db':
237 | case 'bd':
238 | return -3*sharpValue/2;
239 | case 'd':
240 | return -sharpValue/2;
241 | case '+':
242 | return sharpValue/2;
243 | case '#+':
244 | case '+#':
245 | return 3*sharpValue/2;
246 | case 'bbv3':
247 | return -2*sharpValue - 3;
248 | case 'bbv2':
249 | return -2*sharpValue - 2;
250 | case 'bbv1':
251 | case 'bbv':
252 | return -2*sharpValue - 1;
253 | case 'bb':
254 | return -2*sharpValue;
255 | case 'bb^':
256 | case 'bb^1':
257 | return -2*sharpValue + 1;
258 | case 'bb^2':
259 | return -2*sharpValue + 2;
260 | case 'bb^3':
261 | return -2*sharpValue + 3;
262 | case 'bv3':
263 | return -sharpValue - 3;
264 | case 'bv2':
265 | return -sharpValue - 2;
266 | case 'bv1':
267 | case 'bv':
268 | return -sharpValue - 1;
269 | case 'b':
270 | return -sharpValue;
271 | case 'b^':
272 | case 'b^1':
273 | return -sharpValue + 1;
274 | case 'b^2':
275 | return -sharpValue + 2;
276 | case 'b^3':
277 | return -sharpValue + 3;
278 | case 'v3':
279 | return -3;
280 | case 'v2':
281 | return -2;
282 | case 'v1':
283 | case 'v':
284 | return -1;
285 | case '':
286 | return 0;
287 | case '^':
288 | case '^1':
289 | return 1;
290 | case '^2':
291 | return 2;
292 | case '^3':
293 | return 3;
294 | case '#v3':
295 | return sharpValue - 3;
296 | case '#v2':
297 | return sharpValue - 2;
298 | case '#v1':
299 | case '#v':
300 | return sharpValue - 1;
301 | case '#':
302 | return sharpValue;
303 | case '#^':
304 | case '#^1':
305 | return sharpValue + 1;
306 | case '#^2':
307 | return sharpValue + 2;
308 | case '#^3':
309 | return sharpValue + 3;
310 | case 'xv3':
311 | return 2*sharpValue - 3;
312 | case 'xv2':
313 | return 2*sharpValue - 2;
314 | case 'xv1':
315 | case 'xv':
316 | return 2*sharpValue - 1;
317 | case 'x':
318 | return 2*sharpValue;
319 | case 'x^':
320 | case 'x^1':
321 | return 2*sharpValue + 1;
322 | case 'x^2':
323 | return 2*sharpValue + 2;
324 | case 'x^3':
325 | return 2*sharpValue + 3;
326 |
327 | // Addon
328 | case '^4':
329 | return 4;
330 | case 'v4':
331 | return -4;
332 | case '#^4':
333 | return sharpValue + 4;
334 | case '#v4':
335 | return sharpValue - 4;
336 | case 'b^4':
337 | return -sharpValue + 4;
338 | case 'bv4':
339 | return -sharpValue - 4;
340 | case 'x^4':
341 | return 2*sharpValue + 4;
342 | case 'xv4':
343 | return 2*sharpValue - 4;
344 | case 'bb^4':
345 | return -2*sharpValue + 4;
346 | case 'bbv4':
347 | return -2*sharpValue - 4;
348 |
349 | default:
350 | return null;
351 | }
352 | }
353 |
354 | // Takes in annotations[].text and returns either
355 | // a key signature object if str is a valid custom key sig code or null.
356 | //
357 | // Valid key sig code is denoted as such:
358 | // .c.d.e.f.g.a.b
359 | // where identifiers c thru b denote a valid accidental code of which
360 | // will apply to the respective notes.
361 | //
362 | // For example, this is F-down major: .v.v.v.v.v.v.bv
363 | //
364 | // whitespace can be placed between dots and accidentals for readability.
365 | //
366 | // For the natural accidental, blank or whitespace will both work.
367 | //
368 | // Assign the key signature object to the parms.currKeySig field!
369 | function scanCustomKeySig(str, edo) {
370 | if (typeof (str) !== 'string')
371 | return null;
372 | str = str.trim();
373 | var keySig = {};
374 | var res = str.match(customKeySigRegex);
375 | // For code golfing
376 | var notes = [null, 'c', 'd', 'e', 'f', 'g', 'a', 'b'];
377 |
378 | if (res === null)
379 | return null;
380 |
381 | for (var i = 1; i <= 7; i++) {
382 | var acc = convertAccidentalToStepsOrNull(res[i].trim(), edo);
383 | console.log('keySig ' + i + ', steps: ' + acc);
384 | if (acc !== null)
385 | keySig[notes[i]] = acc;
386 | else
387 | keySig[notes[i]] = 0;
388 | }
389 | return keySig;
390 | }
391 |
392 | // Apply the given function to all notes in selection
393 | // or, if nothing is selected, in the entire score
394 |
395 | function applyToNotesInSelection(func, parms) {
396 | var cursor = curScore.newCursor();
397 | cursor.rewind(1);
398 | var startStaff;
399 | var endStaff;
400 | var endTick;
401 | var fullScore = false;
402 | if (!cursor.segment) { // no selection
403 | fullScore = true;
404 | startStaff = 0; // start with 1st staff
405 | endStaff = curScore.nstaves - 1; // and end with last
406 | } else {
407 | startStaff = cursor.staffIdx;
408 | cursor.rewind(2);
409 | if (cursor.tick == 0) {
410 | // this happens when the selection includes
411 | // the last measure of the score.
412 | // rewind(2) goes behind the last segment (where
413 | // there's none) and sets tick=0
414 | endTick = curScore.lastSegment.tick + 1;
415 | } else {
416 | endTick = cursor.tick;
417 | }
418 | endStaff = cursor.staffIdx;
419 | }
420 | console.log(startStaff + " - " + endStaff + " - " + endTick);
421 | // -------------- Actual thing here -----------------------
422 |
423 |
424 | for (var staff = startStaff; staff <= endStaff; staff++) {
425 |
426 | // Reset accidentals at the start of every staff.
427 | parms.accidentals = {};
428 |
429 |
430 |
431 | // Even if system text is used for key sig, the text
432 | // won't carry over for all voices (if the text was placed on voice 1, only
433 | // voice 1 will see the text)
434 | //
435 | // Therefore, all the diff custom key sig texts across all 4 voices
436 | // need to be aggregated into this array before the notes can be
437 | // tuned.
438 | var staffKeySigHistory = [];
439 | var staffCenterHistory = [];
440 | var staffEDOHistory = [];
441 | var staffTranspositionHistory = [];
442 |
443 | // initial run to populate custom key signatures
444 | for (var voice = 0; voice < 4; voice++) {
445 |
446 | // Note: either ways, it is still necesssary to go to the start of the score before
447 | // applying to notes in selection as custom key signatures may precede the selection
448 | // that should still apply to the score.
449 |
450 | // NOTE: THIS IS THE ONLY RIGHT WAY (TM) TO REWIND THE CURSOR TO THE START OF THE SCORE.
451 | // ANY OTHER METHOD WOULD RESULT IN CATASTROPHIC FAILURE FOR WHATEVER REASON.
452 | cursor.rewind(1);
453 | cursor.voice = voice;
454 | cursor.staffIdx = staff;
455 | cursor.rewind(0);
456 |
457 | var measureCount = 0;
458 | console.log("processing custom key signatures staff: " + staff + ", voice: " + voice);
459 |
460 | while (true) {
461 | if (cursor.segment) {
462 | // scan edo & tuning center first. key signature parsing is dependant on edo used.
463 | for (var i = 0; i < cursor.segment.annotations.length; i++) {
464 | var annotation = cursor.segment.annotations[i];
465 | console.log("found annotation type: " + annotation.name);
466 | if ((annotation.name == 'StaffText' && Math.floor(annotation.track / 4) == staff) ||
467 | (annotation.name == 'SystemText')) {
468 | var text = removeFormattingCode(annotation.text);
469 | if (text.toLowerCase().trim().endsWith('edo')) {
470 | var edo = parseInt(text.substring(0, text.length - 3));
471 | if (edo !== NaN || edo !== undefined || edo !== null) {
472 | console.log('found EDO annotation: ' + text)
473 | staffEDOHistory.push({
474 | tick: cursor.tick,
475 | edo: edo
476 | });
477 | }
478 | } else if (text.trim().search(/[a-g][0-9]:/i) == 0) {
479 | var txt = text.toLowerCase().trim();
480 | if (txt.endsWith('hz'))
481 | txt = txt.substring(0, txt.length - 2);
482 | var center = {note: txt.substring(0, 2), freq: parseFloat(txt.substring(3))};
483 | if (center.freq !== NaN || center.freq !== undefined || center.freq !== null) {
484 | console.log('found tuning center annotation: ' + text)
485 | staffCenterHistory.push({
486 | tick: cursor.tick,
487 | center: center
488 | });
489 | }
490 | }
491 | }
492 | }
493 |
494 | // Check for StaffText key signature changes, then update staffKeySigHistory
495 | for (var i = 0; i < cursor.segment.annotations.length; i++) {
496 | var annotation = cursor.segment.annotations[i];
497 | console.log("found annotation type: " + annotation.name);
498 | if ((annotation.name == 'StaffText' && Math.floor(annotation.track / 4) == staff) ||
499 | (annotation.name == 'SystemText')) {
500 | var t = annotation.text.toLowerCase().trim();
501 | if (t.startsWith('t:')) {
502 | t = t.substring(2).trim();
503 | var nominal = t.substring(0, 1);
504 | var acc = t.substring(1).trim();
505 | if (fifthsFromC[nominal] !== undefined && standardAccFifths[acc] !== undefined) {
506 | staffTranspositionHistory.push({
507 | tick: cursor.tick,
508 | fifths: fifthsFromC[nominal] + standardAccFifths[acc]
509 | });
510 | }
511 | } else {
512 | var text = removeFormattingCode(t);
513 | var mostRecentEDO = staffEDOHistory.length !== 0 ? staffEDOHistory[staffEDOHistory.length - 1].edo : null;
514 | if (!mostRecentEDO)
515 | mostRecentEDO = 12;
516 | var maybeKeySig = scanCustomKeySig(text, mostRecentEDO);
517 | if (maybeKeySig !== null) {
518 | console.log("detected new custom keySig: " + text + ", staff: " + staff + ", voice: " + voice);
519 | staffKeySigHistory.push({
520 | tick: cursor.tick,
521 | keySig: maybeKeySig
522 | });
523 | }
524 | }
525 | }
526 | }
527 |
528 | if (cursor.segment.tick == cursor.measure.firstSegment.tick && voice === 0) {
529 | // once new bar is reached, denote new bar in the parms.accidentals.bars object
530 | // so that getAccidental will reset. Only do this for the first voice in a staff
531 | // since voices in a staff shares the same barrings.
532 | if (!parms.accidentals.bars)
533 | parms.accidentals.bars = [];
534 |
535 | parms.accidentals.bars.push(cursor.segment.tick);
536 | measureCount ++;
537 | console.log("New bar - " + measureCount);
538 | }
539 | }
540 |
541 | if (!cursor.next())
542 | break;
543 | }
544 | }
545 |
546 | // 2 passes - one to ensure all accidentals are represented acorss
547 | // all 4 voices, then the second one to apply those accidentals.
548 | for (var rep = 0; rep < 2; rep++) {
549 | // After every staff, reset the keySig and tuning states back to default
550 | parms.currKeySig = parms.keySig;
551 | parms.currEdo = 12;
552 | parms.currCenter = {note: 'a4', freq: 440};
553 | parms.currTranspose = 0;
554 | for (var voice = 0; voice < 4; voice++) {
555 | // if first pass go to start of score so that anchors.all
556 | // accidentals are accounted for
557 | // otherwise, go to the start of the selection to begin tuning
558 |
559 | // NOTE: FOR WHATEVER REASON, rewind(1) must be called BEFORE assigning voice and staffIdx,
560 | // and rewind(0) MUST be called AFTER rewind(1), AND AFTER assigning voice and staffIdx.
561 | cursor.rewind(1);
562 | cursor.voice = voice; //voice has to be set after goTo
563 | cursor.staffIdx = staff;
564 | if (fullScore || rep == 0)
565 | cursor.rewind(0);
566 |
567 | var measureCount = 0;
568 |
569 | console.log("processing staff: " + staff + ", voice: " + voice);
570 |
571 | // Loop elements of a voice
572 | while (cursor.segment && (fullScore || cursor.tick < endTick)) {
573 | // Note that the parms.accidentals object now stores accidentals
574 | // from all 4 voices in a staff since microtonal accidentals from one voice
575 | // should affect subsequent notes on the same line in other voices as well.
576 |
577 | var mostRecentKeySigTick = -1;
578 | for (var i = 0; i < staffKeySigHistory.length; i++) {
579 | var keySig = staffKeySigHistory[i];
580 | if (keySig.tick <= cursor.tick && keySig.tick >= mostRecentKeySigTick) {
581 | parms.currKeySig = keySig.keySig;
582 | mostRecentKeySigTick = keySig.tick;
583 | }
584 | }
585 |
586 | var mostRecentEDOTick = -1;
587 | for (var i = 0; i < staffEDOHistory.length; i++) {
588 | var edo = staffEDOHistory[i];
589 | if (edo.tick <= cursor.tick && edo.tick >= mostRecentEDOTick) {
590 | parms.currEdo = edo.edo;
591 | mostRecentEDOTick = edo.tick;
592 | }
593 | }
594 |
595 | var mostRecentCenterTick = -1;
596 | for (var i = 0; i < staffCenterHistory.length; i++) {
597 | var center = staffCenterHistory[i];
598 | if (center.tick <= cursor.tick && center.tick >= mostRecentCenterTick) {
599 | parms.currCenter = center.center;
600 | mostRecentCenterTick = center.tick;
601 | }
602 | }
603 |
604 | var mostRecentTransposeTick = -1;
605 | for (var i = 0; i < staffTranspositionHistory.length; i++) {
606 | var trans = staffTranspositionHistory[i];
607 | if (trans.tick <= cursor.tick && trans.tick >= mostRecentTransposeTick) {
608 | parms.currTranspose = trans.fifths;
609 | mostRecentTransposeTick = trans.tick;
610 | }
611 | }
612 |
613 | if (cursor.element) {
614 | if (cursor.element.type == Ms.CHORD) {
615 | var graceChords = cursor.element.graceNotes;
616 | for (var i = 0; i < graceChords.length; i++) {
617 | // iterate through all grace chords
618 | var notes = graceChords[i].notes;
619 | for (var j = 0; j < notes.length; j++)
620 | func(notes[j], cursor.segment, parms, rep === 0);
621 | }
622 | var notes = cursor.element.notes;
623 | for (var i = 0; i < notes.length; i++) {
624 | var note = notes[i];
625 | // find other symbols (aux accidentals) attached to the note
626 | // for (var j = 0; j < note.elements.length; j++) {
627 | // if (note.elements[j].symbol)
628 | // console.log(note.elements[j].symbol);
629 | // }
630 | func(note, cursor.segment, parms, rep === 0);
631 | }
632 | }
633 | }
634 | cursor.next();
635 | }
636 | }
637 | }
638 | }
639 | }
640 |
641 | // This will register an accidental's offset value and tick position.
642 | // Unified accidental registry is necessary so that special accidentals across
643 | // different voices in the same staff will affect each other as it should.
644 | //
645 | // Only microtonal accidentals need to be registered. Musescore properly handles
646 | // normal accidentals with TPCs.
647 | //
648 | // Remember to reset the parms.accidentals array after every bar & staff!
649 | function registerAccidental(noteLine, tick, stepOffset, parms) {
650 | if (!parms.accidentals[noteLine]) {
651 | parms.accidentals[noteLine] = [];
652 | }
653 |
654 | parms.accidentals[noteLine].push({
655 | tick: tick,
656 | offset: stepOffset
657 | });
658 | }
659 |
660 | // Returns the step offset if a prior microtonal accidental exists
661 | // before or at the given tick value.
662 | // Null if there are no explicit microtonal accidentals
663 | // WARNING: DON'T USE !getAccidental() to check for Null because !0 IS TRUE!
664 | function getAccidental(noteLine, tick, parms) {
665 | // Tick of the most recent measure just before current tick
666 | var mostRecentBar = 0;
667 |
668 | for (var i = 0; i < parms.accidentals.bars.length; i++) {
669 | var barTick = parms.accidentals.bars[i];
670 |
671 | if (barTick > mostRecentBar && barTick <= tick) {
672 | mostRecentBar = barTick;
673 | }
674 | }
675 |
676 | var oldTick = -1;
677 | var offset = null;
678 |
679 | if (!parms.accidentals[noteLine])
680 | return null;
681 |
682 | for (var i = 0; i < parms.accidentals[noteLine].length; i++) {
683 | var acc = parms.accidentals[noteLine][i];
684 |
685 | // Accidentals only count if
686 | // 1. They are in the same bar as the current note
687 | // 2. They are before or at the current note's tick
688 | // 3. It is the most recent accidental that fulfills 1. and 2.
689 | if (acc.tick >= mostRecentBar && acc.tick <= tick && acc.tick >= oldTick) {
690 | console.log('note line: ' + noteLine + ', steps: ' + acc.offset + ', tick: ' + acc.tick);
691 | console.log('acc.tick: ' + acc.tick + ', mostRecentBar: ' + mostRecentBar + ', tick: ' + tick + ', oldTick: ' + oldTick);
692 | offset = acc.offset;
693 | oldTick = acc.tick;
694 | }
695 | }
696 | return offset;
697 | }
698 |
699 | // Note: if scanOnly is true, accidentals will be registered but the note
700 | // will not be tuned.
701 | function tuneNote(note, segment, parms, scanOnly) {
702 | var tpc = note.tpc;
703 | var val = [2, 3].map (function (q) {return Math.round(parms.currEdo * Math.log(q) / Math.LN2);});
704 | var fifthStep = -val[0] + val[1];
705 | var sharpValue = -11*val[0] + 7*val[1];
706 |
707 | // If tpc is non-natural, there's no need to go through additional steps,
708 | // since accidentals and key sig are already taken into consideration
709 | // to produce a non-screw-up tpc.
710 |
711 | // However, if tpc is natural, it needs to be checked against acc and
712 | // the key signature to truly determine what note it is.
713 |
714 | switch(tpc) {
715 | case -1: //Fbb
716 | note.tuning = getCentOffset ('f', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
717 | return;
718 | case 0: //Cbb
719 | note.tuning = getCentOffset ('c', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
720 | return;
721 | case 1: //Gbb
722 | note.tuning = getCentOffset ('g', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
723 | return;
724 | case 2: //Dbb
725 | note.tuning = getCentOffset ('d', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
726 | return;
727 | case 3: //Abb
728 | note.tuning = getCentOffset ('a', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
729 | return;
730 | case 4: //Ebb
731 | note.tuning = getCentOffset ('e', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
732 | return;
733 | case 5: //Bbb
734 | note.tuning = getCentOffset ('b', -2*sharpValue, -2, parms.currEdo, parms.currCenter, parms.currTranspose);
735 | return;
736 |
737 | case 6: //Fb
738 | note.tuning = getCentOffset ('f', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
739 | return;
740 | case 7: //Cb
741 | note.tuning = getCentOffset ('c', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
742 | return;
743 | case 8: //Gb
744 | note.tuning = getCentOffset ('g', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
745 | return;
746 | case 9: //Db
747 | note.tuning = getCentOffset ('d', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
748 | return;
749 | case 10: //Ab
750 | note.tuning = getCentOffset ('a', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
751 | return;
752 | case 11: //Eb
753 | note.tuning = getCentOffset ('e', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
754 | return;
755 | case 12: //Bb
756 | note.tuning = getCentOffset ('b', -sharpValue, -1, parms.currEdo, parms.currCenter, parms.currTranspose);
757 | return;
758 |
759 | case 20: //F#
760 | note.tuning = getCentOffset ('f', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
761 | return;
762 | case 21: //C#
763 | note.tuning = getCentOffset ('c', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
764 | return;
765 | case 22: //G#
766 | note.tuning = getCentOffset ('g', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
767 | return;
768 | case 23: //D#
769 | note.tuning = getCentOffset ('d', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
770 | return;
771 | case 24: //A#
772 | note.tuning = getCentOffset ('a', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
773 | return;
774 | case 25: //E#
775 | note.tuning = getCentOffset ('e', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
776 | return;
777 | case 26: //B#
778 | note.tuning = getCentOffset ('b', sharpValue, 1, parms.currEdo, parms.currCenter, parms.currTranspose);
779 | return;
780 |
781 | case 27: //Fx
782 | note.tuning = getCentOffset ('f', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
783 | return;
784 | case 28: //Cx
785 | note.tuning = getCentOffset ('c', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
786 | return;
787 | case 29: //Gx
788 | note.tuning = getCentOffset ('g', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
789 | return;
790 | case 30: //Dx
791 | note.tuning = getCentOffset ('d', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
792 | return;
793 | case 31: //Ax
794 | note.tuning = getCentOffset ('a', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
795 | return;
796 | case 32: //Ex
797 | note.tuning = getCentOffset ('e', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
798 | return;
799 | case 33: //Bx
800 | note.tuning = getCentOffset ('b', 2*sharpValue, 2, parms.currEdo, parms.currCenter, parms.currTranspose);
801 | return;
802 | }
803 |
804 | // in the event that tpc is considered natural by
805 | // MuseScore's playback, it would mean that it is
806 | // either a natural note, or a microtonal accidental.
807 |
808 | var baseNote;
809 | switch(tpc) {
810 | case 13:
811 | baseNote = 'f';
812 | break;
813 | case 14:
814 | baseNote = 'c';
815 | break;
816 | case 15:
817 | baseNote = 'g';
818 | break;
819 | case 16:
820 | baseNote = 'd';
821 | break;
822 | case 17:
823 | baseNote = 'a';
824 | break;
825 | case 18:
826 | baseNote = 'e';
827 | break;
828 | case 19:
829 | baseNote = 'b';
830 | break;
831 | }
832 |
833 | //NOTE: Only special accidentals need to be remembered.
834 | var accOffset = null;
835 | if (note.accidental) {
836 | console.log('Note: ' + baseNote + ', Line: ' + note.line +
837 | ', Special Accidental: ' + note.accidentalType);
838 | switch(0 + note.accidentalType) {
839 | case Accidental.NATURAL:
840 | accOffset = 0;
841 | break;
842 | case Accidental.SHARP_SLASH4:
843 | accOffset = 3*sharpValue/2;
844 | break;
845 | case Accidental.SHARP_SLASH:
846 | accOffset = sharpValue/2;
847 | break;
848 | case Accidental.MIRRORED_FLAT:
849 | accOffset = -sharpValue/2;
850 | break;
851 | case Accidental.MIRRORED_FLAT2:
852 | accOffset = -3*sharpValue/2;
853 | break;
854 | case Accidental.DOUBLE_SHARP_THREE_ARROWS_UP:
855 | accOffset = 2*sharpValue + 3;
856 | break;
857 | case Accidental.DOUBLE_SHARP_TWO_ARROWS_UP:
858 | accOffset = 2*sharpValue + 2;
859 | break;
860 | case Accidental.SHARP2_ARROW_UP:
861 | case Accidental.DOUBLE_SHARP_ONE_ARROW_UP:
862 | accOffset = 2*sharpValue + 1;
863 | break;
864 | case Accidental.SHARP2_ARROW_DOWN:
865 | case Accidental.DOUBLE_SHARP_ONE_ARROW_DOWN:
866 | accOffset = 2*sharpValue - 1;
867 | break;
868 | case Accidental.DOUBLE_SHARP_TWO_ARROWS_DOWN:
869 | accOffset = 2*sharpValue - 2;
870 | break;
871 | case Accidental.DOUBLE_SHARP_THREE_ARROWS_DOWN:
872 | accOffset = 2*sharpValue - 3;
873 | break;
874 | case Accidental.SHARP_THREE_ARROWS_UP:
875 | accOffset = sharpValue + 3;
876 | break;
877 | case Accidental.SHARP_TWO_ARROWS_UP:
878 | accOffset = sharpValue + 2;
879 | break;
880 | case Accidental.SHARP_ARROW_UP:
881 | case Accidental.SHARP_ONE_ARROW_UP:
882 | accOffset = sharpValue + 1;
883 | break;
884 | case Accidental.SHARP_ARROW_DOWN:
885 | case Accidental.SHARP_ONE_ARROW_DOWN:
886 | accOffset = sharpValue - 1;
887 | break;
888 | case Accidental.SHARP_TWO_ARROWS_DOWN:
889 | accOffset = sharpValue - 2;
890 | break;
891 | case Accidental.SHARP_THREE_ARROWS_DOWN:
892 | accOffset = sharpValue - 3;
893 | break;
894 | case Accidental.NATURAL_THREE_ARROWS_UP:
895 | accOffset = 3;
896 | break;
897 | case Accidental.NATURAL_TWO_ARROWS_UP:
898 | accOffset = 2;
899 | break;
900 | case Accidental.NATURAL_ARROW_UP:
901 | case Accidental.NATURAL_ONE_ARROW_UP:
902 | accOffset = 1;
903 | break;
904 | case Accidental.NATURAL_ARROW_DOWN:
905 | case Accidental.NATURAL_ONE_ARROW_DOWN:
906 | accOffset = -1;
907 | break;
908 | case Accidental.NATURAL_TWO_ARROWS_DOWN:
909 | accOffset = -2;
910 | break;
911 | case Accidental.NATURAL_THREE_ARROWS_DOWN:
912 | accOffset = -3;
913 | break;
914 | case Accidental.FLAT_THREE_ARROWS_UP:
915 | accOffset = -sharpValue + 3;
916 | break;
917 | case Accidental.FLAT_TWO_ARROWS_UP:
918 | accOffset = -sharpValue + 2;
919 | break;
920 | case Accidental.FLAT_ARROW_UP:
921 | case Accidental.FLAT_ONE_ARROW_UP:
922 | accOffset = -sharpValue + 1;
923 | break;
924 | case Accidental.FLAT_ARROW_DOWN:
925 | case Accidental.FLAT_ONE_ARROW_DOWN:
926 | accOffset = -sharpValue - 1;
927 | break;
928 | case Accidental.FLAT_TWO_ARROWS_DOWN:
929 | accOffset = -sharpValue - 2;
930 | break;
931 | case Accidental.FLAT_THREE_ARROWS_DOWN:
932 | accOffset = -sharpValue - 3;
933 | break;
934 | case Accidental.DOUBLE_FLAT_THREE_ARROWS_UP:
935 | accOffset = -2*sharpValue + 3;
936 | break;
937 | case Accidental.DOUBLE_FLAT_TWO_ARROWS_UP:
938 | accOffset = -2*sharpValue + 2;
939 | break;
940 | case Accidental.FLAT2_ARROW_UP:
941 | case Accidental.DOUBLE_FLAT_ONE_ARROW_UP:
942 | accOffset = -2*sharpValue + 1;
943 | break;
944 | case Accidental.FLAT2_ARROW_DOWN:
945 | case Accidental.DOUBLE_FLAT_ONE_ARROW_DOWN:
946 | accOffset = -2*sharpValue - 1;
947 | break;
948 | case Accidental.DOUBLE_FLAT_TWO_ARROWS_DOWN:
949 | accOffset = -2*sharpValue - 2;
950 | break;
951 | case Accidental.DOUBLE_FLAT_THREE_ARROWS_DOWN:
952 | accOffset = -2*sharpValue - 3;
953 | break;
954 |
955 | // Addon
956 | case Accidental.RAISE_ONE_SEPTIMAL_COMMA: // ^4
957 | accOffset = 4;
958 | break;
959 | case Accidental.LOWER_ONE_SEPTIMAL_COMMA: // v4
960 | accOffset = -4;
961 | break;
962 | case Accidental.SHARP_SLASH2: // #^4
963 | accOffset = sharpValue + 4;
964 | break;
965 | case Accidental.RAISE_ONE_TRIDECIMAL_QUARTERTONE: // #v4
966 | accOffset = sharpValue - 4;
967 | break;
968 | case Accidental.FOUR_TWELFTH_FLAT: // b^4
969 | accOffset = -sharpValue + 4;
970 | break;
971 | case Accidental.THREE_TWELFTH_FLAT: // bv4
972 | accOffset = -sharpValue - 4;
973 | break;
974 | case Accidental.DOUBLE_SHARP_EQUAL_TEMPERED: // x^4
975 | accOffset = 2*sharpValue + 4;
976 | break;
977 | case Accidental.SAGITTAL_SHARP25SD: // xv4
978 | accOffset = 2*sharpValue - 4;
979 | break;
980 | case Accidental.TEN_TWELFTH_FLAT: // bb^4
981 | accOffset = -2*sharpValue + 4;
982 | break;
983 | case Accidental.NINE_TWELFTH_FLAT: // bbv4
984 | accOffset = -2*sharpValue - 4;
985 | break;
986 | }
987 |
988 | if (accOffset !== null) {
989 | registerAccidental(note.line, segment.tick, accOffset, parms);
990 | }
991 | }
992 |
993 | // Check for prev accidentals first, will be null if not present
994 | var stepsFromBaseNote = accOffset !== null ? accOffset : getAccidental(note.line, segment.tick, parms);
995 | console.log('steps bef KeySig: ' + stepsFromBaseNote);
996 | if (stepsFromBaseNote === null) {
997 | // No accidentals - check key signature.
998 | stepsFromBaseNote = parms.currKeySig[baseNote];
999 | console.log('steps on KeySig: ' + stepsFromBaseNote);
1000 | }
1001 |
1002 | console.log("Base Note: " + baseNote + ", steps: " + stepsFromBaseNote + ", tick: " + note.parent.parent.tick);
1003 | var isConcert = note.tpc == note.tpc1;
1004 | note.tuning = getCentOffset(baseNote, stepsFromBaseNote, 0, parms.currEdo, parms.currCenter, isConcert ? 0 : parms.currTranspose);
1005 | return;
1006 | }
1007 |
1008 | onRun: {
1009 | console.log("hello n-edo");
1010 |
1011 | if (typeof curScore === 'undefined')
1012 | Qt.quit();
1013 |
1014 | var parms = {};
1015 |
1016 | /*
1017 | key signature as denoted by the TextFields.
1018 |
1019 | NOTE: parms.keySig has been deprecated, it now serves as a placeholder
1020 | for the natural key signature.
1021 |
1022 | THIS SHOULD BE READONLY!
1023 | */
1024 | parms.keySig = {
1025 | 'c': 0,
1026 | 'd': 0,
1027 | 'e': 0,
1028 | 'f': 0,
1029 | 'g': 0,
1030 | 'a': 0,
1031 | 'b': 0
1032 | };
1033 |
1034 | /*
1035 | Used for StaffText declared custom key signature.
1036 | No worries about handling system text vs staff text as
1037 | the annotation automatically applies appropriately.
1038 |
1039 | Will be reset to the original TextField denoted key signature
1040 | at the start of each staff, although using both TextField
1041 | and StaffText(22)/SystemText(21) methods of custom key sig
1042 | entry is STRONGLY DISCOURAGED due to extreme unpredicatability.
1043 | */
1044 | parms.currKeySig = parms.keySig
1045 |
1046 | parms.accidentals = {};
1047 |
1048 | applyToNotesInSelection(tuneNote, parms);
1049 | Qt.quit();
1050 | }
1051 | }
1052 |
--------------------------------------------------------------------------------