Comments (9)
That feature has not been added to the mx::api
structs. It should be easy to add it. As a workaround, it is also possible to obtain the mx::core
representation and manipulate it.
This requires using the 'private' includes, e.g. #include "mx/core/Document.h"
and dealing with the unwieldy interface to the elements themselves.
I will add this feature to mx::api
as soon as possible (unfortunately that might be 2-3 weeks from now due to some circumstances). You can try adding it to mx::api
before then if you wish. I should be able to respond within 24-hours to questions.
from mx.
I will have a go at seeing if I can add it to mx::api
but it will take me a while to get my head around the mx::core
stuff. After a preliminary look, it looks like I'd have to do something similar to how divisions is handled. Will probably have real questions later.
from mx.
I started looking at this and wrote the following thinking that transposition would be an attribute of a Part
A new struct, e.g. TranspositionData
added to this file before PartData
:
mx/Sourcecode/include/mx/api/PartData.h
Line 96 in 03a9b32
An optional instance of that struct added to PartData
, e.g. std::optional<TranspositionData> transposition
.
There's a macro pattern to remember: https://github.com/webern/mx/blob/03a9b3254b853c04fb069cacc79281800215a0d4/Sourcecode/include/mx/api/PartData.h#L169..L210
During 'serialization', functionality has to be added to PartWriter.cpp
to 'serialize' the mx::api
version into mx::core
version, probably in this function:
During deserialization
, functionality has to be added to
However, not as simple as that
Your original statement says that transposition exists in the attributes of the first measure. Uh oh, this is more complicated. If mx::api
should support the changing of transpositions in arbitrary locations throughout the music, then it adds more complexity to mx::api
than I like. i.e. if mx::api
supported all features of MusicXML then it would just be MusicXML and not an 'API'!
Anyway, if we stick with the idea of placing the transposition in the part, such that one can only specify the transposition once, at the beginning, then we could still create the struct and add it to PartData.h
like I suggested above, but we would need to write it to the first measure of music, and detect it in the first measure of music instead of what I showed above.
There are precedents for this, anyway it will be these files:
Unfortunately much of the code in mx::impl
is really stupidly written and painful for me to look at... I mean it works, but this was one of my first projects. Anyway, I hope these links help a little.
Testing
If we go with putting this in PartData.h
then probably clone a test file, e.g. https://github.com/webern/mx/blob/master/Sourcecode/private/mxtest/api/DirectionDataTest.cpp and name the copy of it PartDataTest.cpp
as the starting point.
from mx.
My only experience of musicxml is as something that can be read and written by musescore (i.e., I am definitely no expert on the intricacies of musicxml!). In musescore, each staff is a part in partwise musicxml and has an associated instrument, e.g., Flute, Clarinet, Trumpet, etc. Part of the details of each instrument includes its transposition. When the score is exported to musicxml, some of the instrument information ends up in the <part-list>
specification (in <part-name>
, <score-instrument>
, <midi-instrument>
, etc.) but the transposition information ends up as a <transpose>
element in the <attributes>
of the first <measure>
of the <part>
.
I don't know if there is any other valid use case where there could be a <transpose>
later in a <part>
(oops! seems like there is - see below). The description of <transpose>
at https://usermanuals.musicxml.com/MusicXML/Content/EL-MusicXML-transpose.htm says
If the part is being encoded for a transposing instrument in written vs. concert pitch, the transposition must be encoded in the transpose element using the transpose type.
which makes it sound like it is envisaged to be used as part of the description of the instrument that should be the same for the entire part. In a saner world, maybe <transpose>
should have been part of the instrument description in <part-list>
.
But, to counter that view, the description of the <semitones>
element of <transpose>
at https://usermanuals.musicxml.com/MusicXML/Content/EL-MusicXML-chromatic.htm has an example where transposition changes mid-part.
The question is, do you want mx::api
to accommodate such uses?
I would argue not to. As it is, mx::api::PartData
holds an InstrumentData
attribute. To me, this implies that the entire part represents a particular instrument (as does the presence of <score-instrument>
etc., in <part-list>
). Part of the description of that instrument should surely be its transposition.
Rather than create a new struct TranspositionData
, why not just add an int chromaticTranspose
attribute to the InstrumentData
struct? The <chromatic>
element is then chromaticTranspose % 12
while <octave-change>
is chromaticTranspose / 12
. I am not a musician so don't really understand the significance of the <diatonic>
element. Can it be computed from <chromatic>
?
The situation seems similar to <divisions>
. Does mx::api
allow changing <divisions>
in the middle of a score or is it always set in the first measure of each part from the ScoreData.ticksPerQuarter
?
from mx.
I would argue not to. As it is, mx::api::PartData holds an InstrumentData attribute. To me, this implies that the entire part represents a particular instrument (as does the presence of etc., in ). Part of the description of that instrument should surely be its transposition.
I agree, if someone needs to change transposition later in a piece, then a different feature could be added for that more advanced use-case.
The example you provided
<transpose>
<diatonic>-1</diatonic>
<chromatic>-2</chromatic>
</transpose>
Does seem non-ambiguous, but I'm thinking there are probably some ambiguous cases where the ability to set both diatonic
and chromatic
might be necessary. I asked a question about it just now: w3c/musicxml#333
from mx.
My problem is I don't know much musical theory and assume all one needs to know about music is that frequency is proportional to 2**(n/12)!
The purpose of <transpose>
is to define the interval from written pitch to sounding pitch and is usually expressed as the note that sounds when a C4 is written. Hence a Bb clarinet, etc.
I gather the <diatonic>
term part of <transpose>
is the change in the base note name ignoring sharps or flats. So C
to F#
has diatonic=3
while C
to Gb
has diatonic=4
but both have chromatic=6
. But if I look at Wikipedia's list of transposing instruments https://en.wikipedia.org/wiki/List_of_transposing_instruments I notice that, where necessary, the sound of written C4 is always expressed as a flat, never a sharp. I assume this is some sort of convention.
So, if we associate int chromaticTranspose
with an instrument, then on reading we set chromaticTranspose
from the <chromatic>
element (and <octave-change>
if present) and ignore <diatonic>
while on writing we lookup <diatonic>
from chromaticTranspose
using a table like
Note | C | Db | D | Eb | E | F | Gb | G | Ab | A | Bb | B |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Chromatic | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Diatonic | 0 | 1 | 1 | 2 | 2 | 3 | 4 | 4 | 5 | 5 | 6 | 6 |
from mx.
I think I've changed my mind. Mostly because of this quote from wikipedia
The transposition is not a property of the instrument, but rather a convention of musical notation. Instruments whose music is typically notated in this way are called transposing instruments.
This makes sense with the way musicxml places <transpose>
in the <attributes>
of a <measure>
. So I'm creating a new type TransposeData
used in a similar way as the keys
attribute of MeasureData
that should handle a <transpose>
wherever it occurs.
from mx.
Yeah that's fine. I think it's disappointing for the user to have to interact with transposition in that way (when the most common use-case is to set it once at the beginning of the piece when setting the instrument), but your approach will work and will support additional use cases.
from mx.
I've started working on this. Let me know if you want me to get it done or if you want to collaborate in some way...
from mx.
Related Issues (20)
- Revive DocumentManagerTest.cpp
- Fix AppearanceData TODO in LayoutFunctions.cpp
- MeasureNumbering might be dead code
- How exactly am I supposed to setup and use mx in a project? HOT 2
- build-with-apple.sh is broken because ios simulator architectures have changed HOT 3
- in Xcode LLVM C++ standard library with c++11 support HOT 3
- PathRoot.h not found with Xcode MXTest Project HOT 3
- use mx in iOS app, get problem HOT 10
- Help building the library HOT 2
- Timing information of individual notes ? HOT 1
- Expand repeats ? HOT 1
- Implement segno reading HOT 2
- Add reading and writing of arpeggiate HOT 2
- Question about ordering of starts and stops for e.g. slurs HOT 2
- Any Benchmark on musicxml parsing?
- NonTraditional key : C key HOT 6
- Use RAII for the DocumentManager
- Add Encoding Supports Hints to ScoreData
- Use the typesystem to help with Tenths
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mx.