Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions Sourcecode/include/mx/api/PitchData.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,55 @@ namespace mx

struct PitchData
{
// default construction is middle c (c4)
PitchData();

// the note name. i.e. c, d, e, f, g, a, b
Step step;

// the alteration (number of semitones of pitch distance) from the step. for example, if step is 'c' and
// alter is 1, then the sounding pitch is c#. if step is 'd' and alter is -2, then the sounding pitch is
// 'c' (i.e. d double flat). alter only affects the sounding pitch of the note. accidentals are applied
// independently. alter is always required to produce the correct sounding pitch, regardless of key
// signature or accidentals.
int alter;

// additional alteration to the sounding pitch (in hundredths of a semitone). the MusicXML alter value is
// a floating point number to facilitate microtonal music. however for mx::api we wanted the simplicity of
// dealing with integrals for the more common case on non-microtonal music. in order to still support
// microtones without resording to a floating-point alter value, we break out microtonal adjustments to a
// separate 'cents' field, which will be addeded to the alter integral:
// <alter> = (double)alter + (cents / 100.0)
double cents;

// in MusicXML, the accidental is completely independent of the sounding pitch and is only present when you
// actually want to show the accidental in the notated music. i.e. accidental is purely visual. for example,
// if you have a measure consisting of repeated c# notes, you would typically notate this with an accidental
// on the first note only. the rest of the notes of the measure would be 'sharped' by virtue of the first
// note's sharp. in MusicXML, the first note should have an accidental of 'sharp' and an alter of '1', and
// the remaining notes of the measure should have an accidental of 'none' and an alter of '1'.
Accidental accidental;
bool isAccidentalParenthetical;
bool isAccidentalCautionary;
bool isAccidentalEditorial;
bool isAccidentalBracketed;

// which octave the note is located in. middle c is in octave 4.
int octave;

// automatically set the Accidental enum value by
// parsing the alter value
// automatically set the Accidental enum value by parsing the alter value (does not consider the value of
// cents). this is a convenience function that simply adds the correct accidental given the current value
// of alter. for example, if alter is 1, then showAccidental will set the accidental field to 'sharp'.
void showAccidental();

// set the accidental value to 'none' and clear out the
// other accidental-related values
// set the accidental value to 'none' and clear out the other accidental-related values
void hideAccidental();
};

MXAPI_EQUALS_BEGIN( PitchData )
MXAPI_EQUALS_MEMBER( step )
MXAPI_EQUALS_MEMBER( alter )
MXAPI_DOUBLES_EQUALS_MEMBER( cents )
MXAPI_EQUALS_MEMBER( accidental )
MXAPI_EQUALS_MEMBER( isAccidentalParenthetical )
MXAPI_EQUALS_MEMBER( isAccidentalCautionary )
Expand Down
1 change: 1 addition & 0 deletions Sourcecode/private/mx/api/PitchData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace mx
PitchData::PitchData()
: step{ Step::c }
, alter{ 0 }
, cents{ 0.0 }
, accidental{Accidental::none}
, isAccidentalParenthetical{ false }
, isAccidentalCautionary{ false }
Expand Down
1 change: 1 addition & 0 deletions Sourcecode/private/mx/impl/NoteFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ namespace mx
auto converter = Converter{};
myOutNoteData.pitchData.step = converter.convert( reader.getStep() );
myOutNoteData.pitchData.alter = reader.getAlter();
myOutNoteData.pitchData.cents = reader.getCents();

myOutNoteData.pitchData.accidental = api::Accidental::none;

Expand Down
14 changes: 13 additions & 1 deletion Sourcecode/private/mx/impl/NoteReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "mx/utility/StringToInt.h"

#include <map>
#include "mx/api/PitchData.h"

namespace mx
{
Expand All @@ -64,6 +65,7 @@ namespace mx
, myDurationValue( 0.0L )
, myStep( core::StepEnum::c )
, myAlter( 0 )
, myCents( 0.0 )
, myOctave( 4 )
, myStaffNumber( 0 )
, myVoiceNumber( 0 )
Expand Down Expand Up @@ -212,7 +214,17 @@ namespace mx
const auto& pitch = *fullNoteTypeChoice.getPitch();
myStep = pitch.getStep()->getValue();
myOctave = pitch.getOctave()->getValue().getValue();
myAlter = static_cast<int>( std::ceil( pitch.getAlter()->getValue().getValue() - 0.5 ) );
const auto xmlAlter = pitch.getAlter()->getValue().getValue();
const auto intAlter = static_cast<int>( xmlAlter );
myAlter = intAlter;
const auto micro = xmlAlter - static_cast<mx::core::DecimalType> ( intAlter );
const auto microDistance = std::abs( micro );
if( microDistance >= 0.000000000001 )
{
const auto theCents = micro * 100.0;
const auto theNarrowCents = static_cast<decltype(mx::api::PitchData::cents)>( theCents );
myCents = theNarrowCents;
}
break;
}

Expand Down
2 changes: 2 additions & 0 deletions Sourcecode/private/mx/impl/NoteReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace mx
inline long double getDurationValue() const { return myDurationValue; }
inline core::StepEnum getStep() const { return myStep; }
inline int getAlter() const { return myAlter; }
inline double getCents() const { return myCents; }
inline int getOctave() const { return myOctave; }
inline int getStaffNumber() const { return myStaffNumber; }
inline int getVoiceNumber() const { return myVoiceNumber; }
Expand Down Expand Up @@ -89,6 +90,7 @@ namespace mx
long double myDurationValue;
core::StepEnum myStep;
int myAlter;
double myCents;
int myOctave;
int myStaffNumber;
int myVoiceNumber;
Expand Down
7 changes: 6 additions & 1 deletion Sourcecode/private/mx/impl/NoteWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,13 @@ namespace mx
pitch->getStep()->setValue( myConverter.convert( myNoteData.pitchData.step ) );
if( myNoteData.pitchData.alter != 0 )
{
core::DecimalType microtones = 0.0;
if( myNoteData.pitchData.cents != 0.0 ) {
microtones = static_cast<core::DecimalType>( myNoteData.pitchData.cents / 100.0 );
}
const auto alter = static_cast<core::DecimalType>( myNoteData.pitchData.alter ) + microtones;
pitch->setHasAlter( true );
pitch->getAlter()->setValue( core::Semitones{ static_cast<core::DecimalType>( myNoteData.pitchData.alter ) } );
pitch->getAlter()->setValue( core::Semitones{ alter } );
}
pitch->getOctave()->setValue( core::OctaveValue{ myNoteData.pitchData.octave } );
}
Expand Down
Loading