- Added file
/resources/minimal.mei
which is used by constructormeico.mei.Mei.Mei()
to instantiate an empty Mei object. The object now contains an MEI with no meaningful content, but when writing it to a file it is valid now. Using this constructor will now require exception handling!
- Conversion of MEI to MusicXML implemented. Thanks to Matthias Nowakowski.
meiHead
nearly completely.music
most of the note-related data.- See
MEI2MusixXml_Coverage_Documentation.md
for more detail.
- Conversion of MEI to MusicXML has been added to the commandline interface of meicoApp.
- Added new methods
getAllMdivs()
to classmeico.mei.Mei
to retrieve allmdiv
elements in the MEI'smusic
environment. However, in case of nestedmdiv
elements, only the leaf ones are returned. I.e., the returned list will only containmdiv
elements that do not contain othermdiv
elements. - Added new methods
getAllVariantEncodings()
to classmeico.mei.Mei
to retrieve allapp
andchoice
elements from the MEI.
- Expansion of search for the title in method
meico.mei.Mei.getTitle()
, so it supports MEI 3.0 (workDesc
) and MEI 4.0+ (workList
).
- Some minor preparations in class
meico.mei.Mei2MusicXmlConverter
for MEI to MusicXML conversion.
- Added basic MusicXML integration to meico and meicoApp. Both MusicXML file formats, raw (
.musicxml
,.xml
) and compressed (.mxl
) are supported for reading and writing. - While the ProxyMusic framework does not support marshalling and demarshalling of MusicXML
score-timewise
, classmeico.musicxml.MusicXml
supports conversion ofscore-timewise
toscore-partwise
and vice versa. - Integration of MusicXML basic functionality in meicoApp.
- New class
meico.mei.Mei2MsmMpmConverter
has been added to implement a better modularization of different conversion options. All conversion functionality from MEI to MSM and MPM moved frommeico.mei.MEI
andmeico.mei.Helper
into this class. Classmeico.mei.Helper
still holds all static methods, as these are useful also outside of this particular conversion. - Slight changes in methods
convert()
andmakeMovement()
of classmeico.mei.Mei2MsmMpmConverter
. TherelatedResources
entries in the MPM are now only with filenames and no longer with the absloute path on the local machine. - Added MusicXML Coverage Documentation.
- XOM update to v1.3.8.
- Enhancement in
meico.xml.XmlBase.XmlBase(String xml)
constructor. The added exceptions may require some applications to extend their exception handling also for other classes that are based onXmlBase
. - Added new class
meico.supplementary.InputStream2StringConverter
. - Verovio update to v3.15.0-5abc7c0 and fix (due to broken backward compatibility).
- Added new methods
meico.midi.Midi.getMinimalPPQ()
that computes the minimal integer timing resolution (in pulses per quarter note) necessary for an accurate representation of a MIDI sequence. - The eponymous method in class
meico.msm.Msm
has been updated with the same algorithm. - Another addition is method
meico.midi.Midi.convertPPQ()
that allows to convert the timing basis of a MIDI sequence, similar to the eponymous method in classmeico.msm.Msm
.
- Potential bus fix in method
meico.mpm.elements.maps.TempoMap.getTempoAt()
that ensures that the exponent attribute of aTempoData
object is present. - New methods were added to class
meico.mpm.elements.maps.TempoMap
that reduces (monotonous) series of successive tempo instructions to one instruction. - MeicoApp now imports MIDI files with extension
.mid
(as before) and.midi
(this is new).
- Private method
meico.mpm.elements.maps.TempoMap.renderTempoToMap(double date, int ppq, TempoData tempoData)
has been madepublic
and refactored tocomputeDiffTiming()
to better describe its function. - Class
meico.mpm.elements.maps.GenericMap
has new methods:contains()
to check whether a given XML element is an entry in this map.getElementIndexOf()
to determine the index of a given element.
- Bugfix in method
meico.mpm.elements.Performance.getAllMsmPartsAffectedByGlobalMap()
which caused some global performance features not being applied correctly to all affected maps.
- Bugfix in
meico.mpm.elements.maps.OrnamentationMap
methodsrenderAllNonmillisecondsModifiersToMap()
andrenderMillisecondsModifiersToMap()
. Temporary attributes from thetemporalSpread
modifier were processed incorrectly.
- Bugfix in class
meico.mpm.elements.styles.defs.OrnamentDef
, the attributetime.units
of elementtemporalSpread
is renamed totime.unit
(without "s") in accordance to the MPM shema definition.
- Added all necessary functionality to handle IDs in MPM elements
temporalSpread
anddynamicsGradient
.
- Added missing namespace to the creation of a element
relatedResources
in constructormeico.elements.metadata.Metadata.Metadata(Author author, Comment comment, Collection<RelatedResource> relatedResources)
. - JavaDoc update.
- Update of MPM ornamentation-related code in correspondence with MPM version 2.0.3.
- The following methods have been made
public
, so applications can request corresponding data from the classes.meico.mpm.elements.maps.ArticulationMap.getArticulationDataOf()
,meico.mpm.elements.maps.DynamicsMap.getDynamicsDataOf()
,meico.mpm.elements.maps.ImprecissionMap.getDistributionDataOf()
,meico.mpm.elements.maps.MetricalAccentuationMap.getMetricalAccentuationDataOf()
,meico.mpm.elements.maps.OrnamentationMap.getOrnamentationDataOf()
,meico.mpm.elements.maps.RubatoMap.getRubatoDataOf()
, andmeico.mpm.elements.maps.TempoMap.getTempoDataOf()
.
- Update of meicoApp's internal Verovio to v3.11.0-e2d6db8.
- Classes
meico.mpm.elements.styles.defs.OrnamentDef.DynamicsGradient
andmeico.mpm.elements.styles.defs.OrnamentDef.TemporalSpread
have been extended with references to their XML representations. - JavaFX externals have been removed from meicoApp as they do not help with Java versions 11+.
- New method
meico.mpm.Mpm.isInNamespace()
. to check whether a given element name is in the MPM namespace. One of the constructors ofmeico.mpm.elements.map.GenericMap
uses this to apply the MPM namespace more properly - it can also be used to create maps that are not in MPM namespace, such asscore
orchannelVolumeMap
in MSM. - Methods
meico.mpm.elements.maps.AsynchronyMap.renderAsynchronyToMap()
andmeico.mpm.elements.maps.ImprecisionMap.addOffsetsToAttributes()
have been enhanced, so they do no longer produce negative timings, i.e. shift the timing of events to negative milliseconds dates.
- Bugfix in
meico.mpm.elements.Dated.addMap()
.
- Export of MEI to MSM and MPM will now keep the
staffDef
's ID as the ID of the MSM and MPMpart
. - Two addition to the instruments dictionary:
Piano Left Hand
andPiano Right Hand
.
- Added support for attribute
xml:id
on MPM maps in classmeico.mpm.elements.maps.GenericMap
. meico.mpm.elements.maps.GenericMap
constructor has now full support for MSMscore
.- Fixed data integrity of MPM maps that get processed by rubato transformation during performance rendering.
- Optimization of the performance rendering process.
- New method
meico.msm.Msm.getPart()
to retrieve a specificpart
element. - Ornamentation support added to MPM API.
- New classes are
meico.mpm.elements.styles.OrnamentationStyle
,meico.mpm.elements.styles.defs.OrnamentDef
,meico.mpm.elements.styles.defs.OrnamentDef.DynamicsGradient
,meico.mpm.elements.styles.defs.OrnamentDef.TemporalSpread
,meico.mpm.elements.maps.OrnamentationMap
, andmeico.mpm.elements.maps.data.OrnamentData
. - Added MEI export for element
arpeg
to MPM ornamentation. New methodmeico.mei.Mei.processArpeg()
and additions tomeico.mei.Mei.makeMovement()
and classmeico.mei.Helper
. - Ornamentation has been added to the performance rendering in
meico.mpm.elements.Performance.perform()
.
- New classes are
- Enhancement of method
meico.mei.Helper.computeControlEventTiming()
; in search for the timing of an MEI control event, it will now also look at the first reference in attributeplist
. - Deleted package
meico.midi.legacy
.
- New method
meico.midi.Midi.exportAudio(Soundbank soundbank)
to convert MIDI to audio with a soundfont that is already loaded, so its correspondingFile
is no longer required.
- Enhancement/reimplementation of method
meico.mpm.elements.maps.ArticulationMap.renderArticulationToMap_millisecondModifiers()
to allow more extreme delays and duration changes.
- Reimplementation of method
meico.mpm.elements.maps.AsynchronyMap.renderAsynchronyToMap()
. The previous version did handle some note offsets incorrectly. This is fixed in the new version.
- New method
meico.midi.Midi.addOffset()
to add a timing offset (in ticks) to all events in a MIDI sequence. - In method
meico.audio.Audio.convertWaveform2Image()
a dark gray center line is added to the image rendering. - Added another variant of method
meico.audio.Audio.convertWaveform2Image()
that uses an externally instantiated audio frame dispatcherpump
, so the application can also cancel its processing. - Generalized method
meico.audio.Audio.convertDoubleArray2ByteArray()
to allow more than just 16 bit sample size. - Another generalization of method
meico.audio.Audio.convertByteArray2DoubleArray()
that should now also accept audio formats other than mono and stereo.
- Bugfix in method
meico.audio.Audio.convertWaveform2Image()
that caused anIndexOutOfBoundsException
when the amplitude of the signal is at maximum.
- Minor fix in method
meico.supplementary.RandomNumberProvider.getValue(int index)
to ensure that only non-negative index values are processed.
- A little optimization in method
meico.audio.Audio.convertSpectrogramToImage()
. In addition, this method has been extended with a new argumentnormalize
to give applications the possibility to decide whether the spectrogram values should or should not be normalized for rendering. - Internal Verovio update to v3.7.0-dev-e93a13d.
- Minor fix in method
meico.audio.Audio.convertByteArray2DoubleArray()
so that it no longer prints an error message when there is no error. - New methods
meico.audio.Audio.exportWaveformImage()
andmeico.audio.Audio.convertWaveform2Image()
that renders the audio data to aBufferedImage
instance. The functionality was also added to the meicoApp GUI. However, the waveform image exported here is rather low-res by default. The methods allow larger pixel resolutions; applications can specify the image dimensions and the slice of audio to be rendered freely.
- New supplementary class
meico.supplementary.ColorCoding
that simplifies the mapping of one-dimensional values to colors. Meico uses these for spectrogram visualizations. - Advancements in method
meico.audio.Audio.convertSpectrogramToImage()
. It is now possible to create spectrogram images with one of several color codings. - Updated Ant build script.
- Updated internal Verovio distribution to v3.5.0-dev-7cfde60.
- Added package information to the documentation.
- Added Constant Q Transform spectrogram export to class
meico.audio.Audio
. The method isexportConstantQTransformSpectrogram()
.- Method
convertSpectrogramToImage()
makes it convenient to convert the spectrogram data to pixel data. - A new external has been added to the meico ecosystem. Jipes is an open source signal processing library by Hendrik Schreiber. It can be used to build any further audio analysis methods following the same pattern as the CQT export.
- MeicoApp has been extended accordingly with a new export option in the commandline application and in the graphical application.
- Method
- Fixed constructor
meico.midi.MidiPlayer.MidiPlayer(Midi midi)
. Now it assigns the MIDI data to its sequencer. - Added new method
meico.midi.MidiPlayer.setMidiOutputPort()
which allows setting an output port different from the internal Gervill synthesizer.- The internal
Synthesizer
instance is kept alife, so that any preloaded soundfonts are immediately available when switching back. - To switch back to Gervill is important not to provide a new instance but to use the original one, like this
midiPlayer.setMidiOutputPort(midiPlayer.getSynthesizer())
. A shortcut is thismidiPlayer.setMidiOutputPort(null)
that will automatically choose the internal synthesizer as default.
- The internal
- Verovio update in meicoApp.
- Bugfix in methods
meico.mpm.elements.maps.DynamicsMap.getDynamicsDataOf()
andmeico.mpm.elements.maps.RubatoMap.getRubatoDataOf()
.
- Little enhancement in methods
meico.mpm.elements.maps.ArticulationMap.addStyleSwitch()
that is now also able to handle argumentdefaultArticulation == null
. - Added constructors to classes
meico.mpm.elements.maps.data.ArticulationData
,MetricalAccentuationData
,RubatoData
,DynamicsData
,TempoData
, andDistributionData
so they can now be instantiated from a corresponding XML element. - Fix in method
meico.mpm.elements.maps.MetricalAccentuationMap.addAccentuationPattern(MetricalAccentuationData data)
. It has rejected input data that defined anaccentuationPatternDef
name but not the corresponding object itself. However, this is the usual situation when parsing an XML element. So this had to be fixed.- Same for method
meico.mpm.elements.maps.RubatoMap.addRubato(RubatoData data)
.
- Same for method
- Bugfix: corrected constant value
meico.mpm.Mpm.RUBATOR_STYLE = "RubatorStyles"
to"RubatoStyles"
. - Introduced some constants to class
meico.mpm.elements.maps.data.DistributionData
that provide the default strings for the type of the distribution. These are now used in classmeico.mpm.elements.maps.ImprecisionMap
instead of the hard-coded strings, so it will be easier to alter and extend those constants in future updates.
- In classes
meico.mpm.elements.maps.GenericMap
andmeico.mpm.elements.maps.ArticulationMap
a variant of methodaddStyleSwitch()
has been added that supports input of an ID string.
- Added new class
meico.mpm.elements.metadata.Comment
and incorporated it in all classes that handle MPM metadata comment elements. - In class
meico.mpm.elements.metadata.Metadata
some new methods have been added:removeAuthor()
andremoveComment()
. - Enhancement in method
meico.mpm.Mpm.addPerformance()
to cancel if the inputPerformance
object is null. It also got aboolean
return value to indicate the success of the action. - The same has been added to method
meico.mpm.elements.Performance.addPart()
. It returnsfalse
also if the part is already in the performance. - The same has been added to methods
meico.mpm.elements.metadata.Metadata.addAuthor()
,addComment()
andaddRelatedResource()
. Instead of an index they return-1
. - Bugfixes in methods
meico.mpm.elements.metadata.Author.setId()
andremoveAuthor()
. - Classes
meico.mpm.elements.Part
,Performance
have been extended to provide access also to the element'sxml:id
. - New methods
clear()
andrenameStyleDef()
in classmeico.mpm.elements.Header
to remove all content of from the respective MPM element. - New method
clear()
in classmeico.mpm.elements.Dated
to remove all content of from the respective MPM element. - Bugfix in method
meico.mpm.elements.Header.removeStyleType()
,removeStyleDef()
,addStyleType()
. - Lots of enhancement and refactoring of all classes in packages
meico.mpm.elements.styles
andmeico.mpm.elements.styles.defs
. - Correction of
rubatoDef
factory methodmeico.mpm.elements.styles.defs.RubatoDef.createRubatoDef(String name)
tocreateRubatoDef(String name, double frameLength)
. ArubatoDef
without aframeLangth
is invalid. Hence the factory could never create arubatoDef
. This is fixed. - Refactoring of method
meico.mpm.elements.styles.defs.AccentuationPatternDef.getSize()
tosize()
to follow the convention used in all other classes. - Added another method
addAccentuation()
to classmeico.mpm.elements.styles.defs.AccentuationPatternDef
that supports input of anid
string.
- Enhancement of class
meico.mpm.elements.metadata.Metadata
so it can be instatiated with related resources.
- Made class
meico.midi.InstrumentsDirectory
public, so it can be used outside of its package. - Extended method
meico.mei.Mei.makePart()
.- This addresses issue #23 where the staff label did not suffice to properly indicate which General MIDI instrument should be chosen during the MIDI export.
- Thus, support for MEI element
instrDef
has been added. It should be used as follows.Only one of the attributes<staffDef clef.line="2" clef.shape="G" lines="5" n="1" label="unhelpful label"> <instrDef midi.instrname="Violin" midi.instrnum="40"/> </staffDef>
midi.instrnum
(prioritized) andmidi.instrname
is required. The former should have values from 0 to 127 (not 1 to 128!). A list of General MIDI instrument names and numbers can be found on Wikipedia (here the numbers must be decreased by 1!). - Meico will add a
programChangeMap
to the MSM part during export and use this instead of the label to generate the corresponding MIDI messages during MIDI export. - The MEI Coverage Documentation has been updated accordingly and provides further information.
- Little tweak in method
meico.mpm.maps.DynamicsMap.renderDynamicsToMap()
: If adynamicsMap
does not have adynamics
element at date 0.0 but there arenotes
to be performed before the firstdynamics
instruction, they now get a default velocity value.
- Little tweak in method
meico.mei.Mei.processMeasure()
as it struggled to remove and insertingtimeSignature
elements fromtimeSignatureMap
when the measure does not comply with the given time signature. - Indexing correction in method
meico.mpm.elements.styles.defs.AccentuationPatternDef.addAccentuationToArrayList()
so accentuations are added in the correct order to patterns. - In method
meico.mei.Mei.processSyl()
attributewordpos
was mandatory (with valuesi
orm
) to process attribtecon
. This did not work for some cases. So,wordpos
is now being ignored andcon
will always be processed.
- Added method
meico.mei.Helper.addUUID()
which encapsulates the generation of uniquexml:id
attributes. The corresponding code in methodmeico.msm.Msm.addIds()
has been adapted. - Added another method
addAccentuationPattern()
to classmeico.mpm.elements.maps.MetricalAccentuationMap
which allows setting attributestickToMeasures
. - Minor fix in method
meico.mei.Mei.addArticulationToMap()
which generated anoteid
string fromnull
instead of setting the stringnull
. - After update 0.8.12, method
getCurrentTimeSignature()
in classmeico.mei.Helper
required more context as input to determine the time signature information. It has been updated accordingly. This required adaptations also in several other methods in classesmeico.mei.Helper
andmeico.mei.Mei
which have been done, too.
- Fix of the processing of
<accid>
elements where the parent<note>
has different graphical and gestural pitch, see issue #17.
- Enhancement of the processing of MEI
tie
element. - Bugfix in method
meico.mei.Mei.processBreath()
that generated a wrong default articulation. - Bugfix in method
meico.mpm.elements.maps.ArticulationMap.renderArticulationToMap_noMillisecondModifiers()
: NullPointerException in an error message. - Optimization of methods
meico.mei.Helper.getPreviousSiblingElement()
andgetNextSiblingElement()
. - An extensive overhaul of method
meico.mei.Mei.processMeasure()
which is now able to handle the situation that no global time signature is given (viascoreDef
) and only locally defined in thestaffDef
elements. - Some code polishing.
- Another bugfix: The
endid
of MEItie
elements was not properly resolved.
- Bugfix: If an MEI
space
element was in alayer
environment, it was falsely interpreted as textual gap. However, it is a musical gap and should be interpreted as rest.
- Updated MPM API to MPM v2.1.0. This update moved element
relatedResources
into elementmetadata
. - Added new class
meico.mpm.elements.metadata.RelatedResource
. - Bugfix: MEI to MPM conversion generated tempo style switches while there was no tempo style to switch to. This has been fixed.
- Added a getter to class
meico.mpm.Mpm
to provide access to the metadata:getMetadata()
. - Added support for MEI
verse
andsyl
elements, so they are converted to MSMlyrics
elements. - Added support for MEI
dynam
andtempo
elements that are positioned within averse
environment. - New method
processSpace()
for processing MEIspace
elements. These elements are usually interpreted as rests. However, this should not be done when they encode a textual space, e.g. in lyrics. That is what the method ensures.
- Enhancement in method
meico.msm.Msm.parseProgramChangeMap()
so MIDI program change events can also be generated after date 0.0. This makes it possible to switch instrument/timbre during the music.
- Another bugfix in method
meico.mpm.elements.styles.defs.ArticulationDef.articulateNote()
so style switches with no attributedefaultArticulation
(it is optional) are supported.
- New methods in class
meico.mei.Helper
:pulseDuration2decimal()
,decimalDuration2HtmlUnicode()
,durationRemainder2UnicodeDots()
,accidDecimal2unicodeString()
. These can beused to generate Unicode strings from note value and pitch information. - Bugfix in method
meico.mei.Mei.makeMovement()
. It checks for the file to be not null before accessing it. - Bugfix in method
meico.mpm.elements.styles.defs.ArticulationDef.articulateNote()
that cause articulation rendering running into an infinite loop whenabsoluteDurationChange
is checked to create only non-negative durations.
- Another bugfix in method
meico.mpm.elements.maps.DynamicsMap.renderDynamicsToMap()
. Seems like the previous update solved one bug and introduced another. - Enhancement in method
meico.mpm.elements.maps.DynamicsMap.getDynamicsDataOf()
. It is now possible to setsubNoteDynamics="true"
even in a constant dynamics segment. This can be useful after a continuous segment to avoid sudden steps of the MIDI channel volume controller.
- Added a new Output option to meicoApp. It is now possible during expressive MIDI rendering to also get an MSM that is enriched with performance data (milliseconds dates, velocities, etc.). This is mostly relevant for debugging purposes with no direct practical use for end users, yet.
- Changed method
meico.app.gui.StatusPanel.setMessage()
to write the output message not directly but from a JavaFX thread. This should eliminate some of the minor (non-blocking) exceptions that are thrown every now and then. - Bugfix in method
meico.mpm.elements.maps.RubatoMap.renderRubatoToMap()
that caused some end date computations to return NaN. - Bugfix in method
meico.mpm.elements.maps.data.DynamicsData.getSubNoteDynamicsSegment()
that cause decrescendi not being rendered with sub-note dynamics. - Optimizations in method
meico.mpm.elements.maps.DynamicsMap.renderDynamicsToMap()
. - New additions to class
meico.mpm.elements.maps.GenericMap
: methodsgetFirstElement()
,getLastElement()
andisEmpty()
.
- Bugfix in class
meico.msm.Msm
: If the MSM provided aprogramChangeMap
for eachpart
, only the first was correctly rendered to MIDI. This has been fixed.
- New functionality added to class
meico.msm.Msm
: methodaddIds()
addsxml:id
to eachnote
andrest
element that does not have one. MeicoApp has been updated accordingly.
- Reorganization of the meico programming library and application code as well as its release assets.
- Meico is basically a programming library. All content of package
meico.app
is example code for meico's usage in application projects. However, for the graphical meico application certain JavaFX dependencies had to be added to meico which complicated development for other applications that do not rely on JavaFX. Thus, we decided to split the meico code base into the core functionality and the example applications. - The release assets include
meico.jar
(the headless core functionality to be used by other development projects) andmeicoApp.jar
(the standalone runnablejar
with the commandline and graphical application, it includesmeico.jar
).
- The codebase has been reorganized accordingly.
- The
master
branch contains the headless meico, no application code or application-related dependencies. This is all you need to develop your own meico application. - The
meicoApp
branch contains themeico.app
package and all other demo applications (meicoPy and the REST demo).
- The
- Class
meico.Meico
has been stripped down. It no longer contains any launcher code, only meico's current version number. MeicoApp lanches from its own main classmeico.app.Main
. - Class
meico.supplementary.VerovioProvider
as been removed. Verovio cannot be part of the headless meico base. It works only with a browser environment and that is only present in meicoApp (which contains Verovio). - File
README.md
has been updated. Livenses are also a bit different for those who use the headless meico package as JavaFX, Verovio and Font Awesome are used only in meicoApp and not in the base package.
- Meico is basically a programming library. All content of package
- Class
meico.mpm.Mpm
, when instantiated, parses the XML data and generates an exception if no elementmetadata
was found. However, this is no encoding error and should not produce error messages. This has been fixed. - Local Verovio update to v2.7.0-dev-02b4f36.
- Added new class
meico.supplementary.VerovioProvider
to be used in other classes (Mei
,MusicXml
) as a convenient handle to get the Verovio Toolkit script.
- Method
meico.audio.Audio.convertByteArray2DoubleArray()
has been generalized to also work with sample sizes other than 16 bit. The method will no longer mix the two stereo channels into one, but returns an ArrayList with both channels, one double array each. - Replaced the Java LAME sources in package
meico.audio
by external filenet.sourceforge.lame-3.98.4.jar
. - In class
meico.audio.Audio
the new methoddecodeMp3ToPcm()
has been added. With this, MP3 files can be imported, are decoded to PCM audio and can be stored as WAV files. - Methods
writeAudio()
andwriteMp3()
in classmeico.audio.Audio
have been improved to make sure that a wave file is not stored with.mp3
extension and vice versa. - Some minor JavaDocs improvements and
README.md
update. - Changed
com.sun.media.sound.InvalidDataException
byException
for compatibility with newer Java versions.
- Added MPM metadata support to package
meico.mpm
. - The MPM metadata will also be generated during MEI-to-MPM export.
- Added a JavaDoc shield to
README.md
- Some refactoring in classes
meico.mpm.elements.maps.ImprecisionMap
andmeico.mpm.elements.maps.data.DistributionData
to avoid naming confusion with the MPM specification. - Added MPM validation to class
meico.app.gui.DataObject
. - In class
meico.mpm.Mpm
- Fix: No generation of an empty element
relatedResources
. - Extension: Methods for the deletion of elements from
relatedResources
have been added.
- Fix: No generation of an empty element
- Added support for attribute
seed
to the MPM distribution elements and imprecision maps.
- Some refactoring of MPM attributes to be compliant with the schema definition.
- In the GUI app, when an MPM is reloaded and its performances are displayed on the workspace, these performance objects do not update together with the MPM and, thus, are no longer consistent with their parent. This is confusing to the user. Hence, they are removed now and newly created from the updated data.
- Enhancement in method
meico.mei.Mei.processMeasure()
. If a measure does not comply with the underlying time signature meico needs to add anothertimeSignature
element in thetimeSignatureMap
. However, the subsequent measure may comply with the original time signature. Hence, at the end of the non-compliant measure meico should switch back to the original time signature. This is what it does now. - Minor stability fix in method
meico.mei.Mei.addDynamicsToMpm()
.
- MPM attributes
startStyle
anddefaultArticulation
have been removed from all...-Map
elements. Initial styles are indicated by style switches (e.g.<style date="0.0" name.ref="my initial style"/>
and for articulation maps<style date="0.0" name.ref="my initial style" defaultArticulation="nonlegato"/>
) at the beginning of of the map. The corresponding code changes are in classesmeico.mei.Mei
,meico.mpm.maps.ArticulationMap
,DynamicsMap
,GenericMap
,MetricalAccentuationMap
,RubatoMap
,TempoMap
. - In class
meico.mpm.Mpm
elementreferenceMusic
is renamed torelatedResources
and elementreference
has been renamed toresource
.
- Bugfix in
meico.mei.Mei.addArticulationToMap()
so it really generates articulations.
- Extended the comandline application
meico.app.Main
, added flag[-ex], [--expressive]
, so it does export expressive MIDI and audio.
- Updated XOM to version 1.3.2. Updated the Ant script
build.xml
accordingly. - New format added: Music Performance Markup (MPM):
- The corresponding package is
meico.mpm
. This package contains the full API to generate, edit, store and parse MPM data and render them to expressive MIDI sequences. - Added several overloaded methods
meico.mei.Mei.exportMsmMpm()
which return two lists, one with the MSMs, the other with the corresponding MPMs. - New methods in class
meico.mei.Mei
:processDynam()
andaddDynamicsToMpm()
are used for converting MEI elementsdynam
andhairpin
to MPM.processTempo()
andaddTempoToMpm()
are used for converting MEItempo
elements to MPM.processArtic()
andaddArticulationToMPM()
are used for converting MEI articulation data (in elementsartic
,note
andchord
) to MPM.processBreath()
is used for converting MEIbreath
elements to MPM.processSlur()
andmeico.mei.Helper.checkSlurs()
are used to convert MEIslur
elements to MEIslur
attributes and ultimately to MPM legato articulations.
- Meico's processing of MEI
note
andchord
elements has been extended to support articulation, i.e. attributesartic
andartic.ges
. - New additions in class
meico.mei.Helper
:mpmPostprocessing()
, listtstamp2s
,parseTempo()
,updateMpmNoteidsAfterResolvingRepetitions()
. - Added MPM to the graphical user interface via class
meico.app.gui.DataObject
. - In MEI tempo is mostly associated only to the staff where it is printed even though it applies to all parts. There are several ways to encode the association, e.g. by
part="%all"
. If such is not specified meico will create only a local MPMtempoMap
. The resulting performance will sound "surprising" as the parts become asynchronous. To cope with this in the way it might have been intended (all parts follow the sametempoMap
) the GUI representation of an MPM object offers the option to make all local tempi global, i.e. merge all local tempo maps into one global tempo map. - Resolving
sequencingMap
in the GUI is also applied to the sibling MPM object. - The commandline application in class
meico.app.Main
has been extended accordingly.
- The corresponding package is
- To preserve conformity between MSM and MPM the following MSM attributes have been renamed:
midi.date
intodate
,midi.duration
intoduration
,end
intodate.end
. - New additions to class
meico.msm.Msm
:renderMidi()
holds the actual algorithm that is invoked by theexportMidi()
method and is extended by methods for generating MIDI from expressive data (e.g., milliseconds dates that have been computed from classmeico.mpm.elements.Performance
).exportExpressiveMidi()
is used to generate and export expressive MIDI data.parseChannelVolumeMap()
is used to render a part'schannelVolumeMap
into a sequence of MIDI channelVolume control change messages. That map is generated during performance rendering in methodmeico.mpm.elements.Performance.perform()
and added to augmented MSM that it returns.parseProgramChangeMap()
, these maps can be used to add MIDI program change events and to keep consistency when the MSM is generated from a MIDI file; the method generates the corresponding MIDI events during MSM-to-MIDI export.convertPulsesPerQuarter()
/convertPPQ()
is used to match the timing basis of the MSM object with the timing basis of a performance. It can be used in other contexts as well to change an MSM's timing basis.fitVelocities()
,computeSemicircleCompression()
,computePartwiseCompression
are used when the range of velocity values goes beyond the MIDI specification [0, 127].
- Changed the method signature of
meico.mei.Mei.convert()
to void. The result of the conversion is accessed viameico.mei.Helper.movements
anyway. Methodmeico.mei.Mei.exportMsm()
has been adapted accordingly. - MEI preprocessing before conversion to MSM/MPM got an additional method
meico.mei.Mei.removeRendElements()
. This replaces allrend
elements by their contents which reduces on-the-fly processing effort. These elements are an optional intermediate layer and not relevant for this particular conversion. - Added class
AbstractXmlSubtree
to packagemeico.xml
. - Added package
meico.supplementary
for classes that are not specific to but useful across several other classes.- First addition to this package is class
KeyValue
that represents data tuplets. - Second addition is class
RandomNumberProvider
. It offers several distribution types: uniform, Gaussian, triangular, Brownian, Compensating Triangular, and distribution list. The provider generates a consistent series of pseudo random numbers that is accessed via an index. The index can be floating point, this returns a linear interpolation of the neighboring integer index positions. The randomization can be reseeded. The random number series can be exported asmeico.audio.Audio
object and, thus, stored to the file system as.wav
or.mp3
file.
- First addition to this package is class
- Moved activation and deactivation methods and flag from classes
meico.app.gui.Schema
,meico.app.gui.Soundbank
,meico.app.gui.XSLTransform
to classmeico.app.gui.DataObject
as they all do the same and non-activatable data objects can simply ignore this functionality. Respective code in classmeico.app.gui.Workspace
has been adapted. - Applied slide changes to the graphical user interface's color scheme of data objects (which is computed in
meico.app.gui.Settings.classToColor()
) for better discriminability of different types of data objects. - New additions to class
meico.mei.Helper
:indexNotesAndChords()
,getCurrentTimeSignature()
,tstampToTicks()
,computeControlEventTiming()
,parseTempo()
,reorderMeasureContent()
,isSameLayer()
,getStaff()
,getStaffId()
,checkSlurs()
,addSlurId()
. - Methods
meico.mei.Mei.reorderElements()
andresolveTieElements()
have been removed.- They did not take care of critical apparatus,
choice
, etc. The mechanism to reorder MEI control events according to attributestartid
has been integrated with methodmeico.mei.Mei.processMeasure
/meico.mei.Helper.reorderMeasureContent()
andmeico.mei.Helper.computeControlEventTiming()
. This solves the aforementioned problem and is more efficient than the preprocessing procedure was. - Processing of MEI
tie
elements has been redone with methodsmeico.mei.Mei.processTie()
,meico.mei.Helper.getTie()
andcheckTies()
and integrated with methodsmeico.mei.Mei.processNote()
andprocessChord()
.
- They did not take care of critical apparatus,
- Method
meico.mei.Helper.computeDuration()
has been made more flexible. So far, it refused to compute anything as long as the MEI element was not within astaff
environment. This, however, is only necessary if the element has nodur
attribute. If that attribute is present the duration can be computed even outside of thestaff
environment - as the method does now. - Enahncements in method
meico.mei.Helper.computePitch()
:- Bugfix: The end of transpositions included the first note after the transposition.
- Enhancement: For transpositions and octavings attribute
layer
is now taken into account, even if multiple layers are specified in it.
- The signature of methods
meico.mei.Helper.copyId()
has changed. They produce a return value which is the Attribute they generate. - Method
meico.mei.Mei.makeMovement()
has been extended. It will now keep a link to the correspondingwork
element inmeiHead/workList
. This is used during conversion to find time signature and tempo information if missing at the respective point in themusic
environment. After converting the contents of themdiv
methodmakeMovement()
checks the existence of a global initial tempo in MPM. If missing, it is generated from thework
'stempo
element (if there is one). - Methods
meico.mei.Mei.processPhrase()
,processPedal()
,processOctave()
,processTupletSpan()
have been redone. The processing of the corresponding MEI elements supports now attributeststamp.ges
,tstamp
,startid
,dur
,tstamp2.ges
,tstamp2
,endid
,part
andstaff
. - MEI elements
oLayer
andoStaff
have been added to the processing in methodmeico.mei.Mei.convert()
. They are processed by the same routines as MEIlayer
andstaff
elements. - Method
meico.msm.Msm.applySequencingMapToMap()
has been updated to update also attributesdate.end
. - New additions to class
meico.audio.Audio
:convertByteArray2DoubleArray()
makes analyses of audio data more convenient as it convertsAudio
object's byte array into an array of doubles between -1.0 and 1.0.convertDoubleArray2ByteArray()
converts an input double array into a byte array.
- Bugfix in method
meico.audio.Audio.convertByteArray2AudioInputStream()
: The computation of the length of theAudioInputStream
did not take the number of channels fromAudioFormat
into account. This is fixed. - Time consumption analysis and commandline/logfile output have been added to all export methods.
- Additions to the instruments dictionary:
Oboe d'amore
,Oboe da caccia
and all clarinet names with an appended" in"
so it matches better with, e.g.,Clarinet in E
and will not be confused withClarino in
. - Method
meico.mei.Mei.processMeasure()
has been extended. After processing its contents and if the measure's length does not confirm the underlying time signature, intermediatetimeSignature
entries are added to the global MSMtimeSignatureMap
so that it follows the measure's timing. - Method
meico.msm.resolveSequencingMaps()
did not expand global maps so far. This has been added. It will now also return a HashMap with thexml:id
strings that have been extended to avoid multiple IDs in one XML document. This HashMap is used to update thenoteid
attributes in MPMarticulationMap
s because the repetitions are also expanded in MPM (if there is one that is linked to the MSM). - Method
meico.mei.Helper.cloneElement()
does now also clone the namespace URI. - In method
meico.app.gui.DataObject.addSeveralChildren()
, which is executed whenever more than one data object is created, a slight spiral effect has been added so that the overlapping of circles is a bit reduced. - In class
meico.app.gui.DataObject
, methodreloadMei()
has been renamed toreload()
and extended so that it can also be used to reload MSM and MPM data. This functionality has also been added to the GUI, i.e. the radial menu of both object types. - New additions to class
meico.midi.EventMaker
:- method
createControlChange()
, - method
byteArrayToInt()
.
- method
- In class
meico.midiMidi2MsmConverter
in methodprocessShortEvent()
noteOn velocity has been added to the MSMnote
elements, so it can be further incorporated in MPM performance rendering (as far as it is not overwritten by adynamicsMap
). - New Addition to class
meico.midi.Midi
: methodgetTempoMap()
parses the MIDI sequence, collects all tempo events and generates an MPMtempoMap
from it. - In package
meico.app
a new class has been added, calledHumanizer
. It demos a little bit of the MPM functionality by generating some basic humanizing and applying it to a Midi object. It is also integrated in the graphical user interface, just import or create a MIDI object and to the click the new option "Humanize (experimental)" on the right part of its radial menu. - Added the full JavaDoc of meico to the repository.
- Verovio update to v2.4.0-dev-facbfa6.
- Fixed license information for Saxon in
README.md
. Thanks to Peter Stadler! - Made several classes in package
meico.app.gui
package-private as they will never be accessed from outside the package and are not intended to. - Made class
meico.msm.MsmBase
abstract and renamed it toAbstractMsm
. - Removed MSM's global header element
pulsesPerQuarter
. Instead an eponimous Attribute has been added to the root note of the MSM. - New additions to class
meico.xml.XmlBase
: MethodsremoveAllElements(String localName)
andremoveAllAttributes(String attributeName)
can be used for processing of all XML based formats.
- New conversion option: MIDI to MSM.
- New method
meico.midi.Midi.exportMsm()
implemented. - The actual conversion is implemented in class
meico.midi.Midi2MsmConverter
. To use it, instantiate it with its constructor, then invoke convert(), see methodmeico.midi.Midi.exportMsm()
for sample code. - Standard MIDI file formats 0, 1 and 2 are supported.
- Relevant MIDI events that are parsed into MSM data are: NOTE_OFF, NOTE_ON, PROGRAM_CHANGE, META_Track_Name, META_Instrument_Name, META_Marker, META_Midi_Channel_Prefix, META_Midi_Port, META_Time_Signature, META_Key_Signature. More may be added with future updates, e.g. META_Lyric.
- META_Track_Name and META_Instrument_Name events as well as PROGRAM_CHANGE events are incorporated to create meaningful MSM part names.
- New method
midi2PnameAndAccid()
in classmeico.mei.Helper
that converts a MIDI pitch to a pitch name string and an MSM-conform accidentals string. - Added methods
getInstrumentName()
and a String array with the GM standard instrument names to classmeico.midi.InstrumentsDictionary
. Given a program change number, it retruns the instrument's name, i.e. either the standard GM names or the first string that is associated with this program change number in the dictionary. - Made methods
meico.mei.Helper.msmCleanup()
public to be accessible from classmeico.midi.Midi
. - The conversion option for MIDI objects in the graphical user interface has been added in class
meico.app.gui.DataObject
.
- New method
- Updates in class
meico.msm.Msm
:- Class
meico.msm.Msm
got a static methodcreateMsm()
that creates a minimalMsm
instance with the basic xml markup. This simplifies the code in methodmeico.mei.Mei.makeMovement()
. - Moved method
meico.msm.MsmBase.getParts()
to classmeico.msm.Msm
as it is different in a future implementation of the format MPM (Music Performance Markup). - Added new methods to class
meico.msm.Msm
:addPart()
,makePart()
. The latter extends the eponimous methods in classMsmBase
with some Msm-specific map creations that will be different in MPM. Some adaptations in methodmeico.mei.Mei.makePart()
have been done in accordance to this. - The MIDI export in class
meico.msm.Msm
has been extended a little bit.
- Class
- New additions to the instruments dictionary: Superior, Superius, Contratenor, Clarino, Clarino in, Clarini, Clarini in, Ocarina, Gefäßflöte, and Kugelflöte. Many thanks to Richard Freedman for his suggestions.
- Bugfixes
- In method
meico.mei.Helper.computePitch()
the octave of preceding accidentals was not correctly recognized. accid
elements that occur in transposing staffs/layers are not assigned to the correct pitches and octaves due to the transposition context. This has been fixed in methodmeico.mei.Mei.processAccid()
by adopting the untransposed attributespname
andoct
(non-gestural) from the parentnote
.- In method
meico.mei.Mei.processDot()
an incorrect condition has been corrected. - In method
meico.msm.Msm.parseKeySignatureMap()
the computation of accidentals was corrected.
- In method
- Added some commandline/logfile output to all export methods for better readability.
- Added some missing MIDI meta messages to class
meico.midi.EventMaker
.
- Added support for MEI attribute
sameas
to classmeico.mei.Mei
in methodresolveCopyOfs()
. It is interpreted in the same way as attributecopyof
, i.e. all attributes and children of the referred element are copied over to the referring element.- Added method
meico.mei.Mei.resoveCopyofsAndSameas()
which ultimately just invokesresolveCopyOfs()
but has a more appropriate naming. - Classes
meico.app.Main
andmeico.app.gui.DataObject
as well as filesREADME.md
anddocumentation.md
have been adapted accordingly.
- Added method
- Added a new commandline option to meico
-n
/--ignore-repetitions
. This should be used to prevent the expansion of repetition marks. It should solve the situation when expansions and repetitions in MEI are used redundantly and meico (commandline) would do it twice. - Fixed bug on the settings window of the gui app (class
meico.app.gui.Settings
). JavaFx'sSpinner
class does not commit a value when changed via text input. Thus, whenever a value (e.g. the tempo) was changed this way, the user had to press ENTER to commit. To fix this an event listener has been added that forces the commit when the value changes even without the need to press ENTER. - The window for preferences settings is made resizable and scrollable. This will hopefully workaround the limited window size issue that some users experience on their machines.
- Reverted the JavaFX update from v0.6.7 to keep compatibility to OpenJDK 9.
- Reverted changes in
verovio.html
to v0.6.5 as this was more stable. Some experimental suff has been added that does not affect its performance. - A new package
meico.svg
with classes to hold SVG data has been added.- It is also integrated in the graphical user interface.
- However, there is no generic SVG export from MEI, yet, even with Verovio.
- JavaFX dependencies have been updated to version 12.0.1.
- Internal Verovio update to v2.1.0-dev-b010e32.
- Added configuration option
scoreFont
(default value isLeipzig
) to set Verovio's rendering font. To set another font, filemeico.cfg
must be edited. It is no yet built into the preferences page of the GUI.
- Minor revisions in
verovio.html
. - Updated internal Verovio to v2.1.0-dev-865f210.
- Added
measure
elements to theaddIds
functionality of classmeico.mei.Mei
.
.xml
import and type recognition now supported: Added methodmeico.app.gui.DataObject.readXmlFileToCorrectType()
. It is called when a.xml
file is loaded. So far, meico rejected to load such files as it was unclear which kind of data it holds. The new method loads it as anXmlBase
object and reads its root name to find out whether it is an MEI, MSM, MusicXML, or XSLT. An instance of the corresponding type is then created.- Added floating point support to time signatures in methods
meico.mei.Helper.getOneMeasureLength()
and in classmeico.mei.Mei
methodsprocessMeasure()
,makeTimeSignature()
,processBeatRpt()
,processMRpt2()
, andmakeMeasureRest()
.
- Bugfix in
meico.mei.Mei.processAccid()
. - Added error catching in methods
meico.mei.Helper.computePitch()
andmeico.mei Helper.computeDuration()
.
- Bugfix in commandline mode
meico.app.Main
. It forgot to make pitch and chroma export. - Enhancement in class
meico.mei.Mei
methodsprocessStaffDef()
,processStaff()
,processLayer()
to support nested structures (staffDef
withinstaff
etc.). - Updated internal Verovio to v2.1.0-dev-533442f.
- Updated internal Verovio to v2.0.0-dev-61da81a.
- Added package and class
meico.xml.XmlBase
as a base class for all XML-based classes in meico.- Refactored class
meico.msm.MsmBase
accordingly. - Class
meico.mei.Mei
has been refactored, too, to extendXmlBase
. - Disabled fetching of DTD in method
meico.xml.XmlBase.readFromFile()
as this causes problems in XOM preventing parsing XML files with a DOCTYPE declaration.
- Refactored class
- Added floating point support for transpositions in MEI.
- Added class
meico.musicxml.MusicXml
.- So far, it is just a dummy class that parses uncompressed MusicXML, writes to the file system, offers XSL transform, validation and access to the data ... standard XML functionality in meico. There are currently no export methods to convert to or from MusicXML.
.musicxml
files can be imported in the GUI app. XSL transform and validation are fully functional.- This will hopefully grow further in the future.
- Added new methods to class
meico.midi.Midi
:getPPQ()
,getTickLength()
andgetMicrosecondLength
. - Minor corrections in the constructor methods of classe
meico.midi.Midi
. - Added new method variant of
meico.mei.Helper.validateAgainstSchema()
that takes an input string instead of a file. With this validation does not require the data to be present in the file system. - Note: We did some experiments with XML schema files in XSD format. However, meico uses the Saxon 9 HE version which supports only RNG schema files for validation, in contrast to the EE version. Thus, XSD files should be converted to RNG format to be used in meico.
- Added new class
meico.msm.MsmBase
which forms the base class for MSM and (later on) MPM classes. Hence, classmeico.msm.Msm
is now refactored to extendMsmBase
.- Method
meico.mei.Mei.makePart()
has been edited to utilize themakePart()
functionality ofMsmBase
. - Added new method
meico.msm.MsmBase.validate()
to validate the MSM and MPM code against a specified schema. Though, at the moment there is no corresponding schema definition, at least for MSM.
- Method
- Added
System.setProperty("prism.order", "sw");
to methodmeico.app.gui.MeicoApp.init()
. This fixes a graphics glitch that occurs every now and then. - Meico's MIDI to audio renderer relies on the package
sun.com.media.sound
. However, since Java 9 this package is marked as deprecated. It was still accessible at runtime but is going to disappear from Oracle JDK in the near future. It seems to have disappeared from OpenJDK as well.- To solve this the Gervill Sound Synthesizer
gervill.jar
has been added to theexternals
. It provides the required package, so no code changes were necessary. - Since it is published under GNU GPL 2.0, we have to change meico's license model as well. The new license is GNU GPL 3.0.
- To solve this the Gervill Sound Synthesizer
- Some JavaFX 11 modules had to be added, too, as it is no longer included in any JDK (neither Oracle nor Open):
javafx.base.jar
,javafx.controls.jar
,javafx.graphics.jar
,javafx.media.jar
, andjavafx.web.jar
.- These are also licensed under GNU GPL 2.0.
- In GUI mode, JavaFX version number has been added to the log file/commandline output at startup.
- Because of incompatible licensing models we had to remove the MEI Common Music Notation Schema
mei-CMN.rng
from this project.- Instead, RNG files can now be imported and used in the same way as XSLTs and soundfonts, i.e. drag and drop it into the workspace, activate it and validate the MEI.
- Classes
meico.mei.Mei
,meico.app.gui.Settings
,meico.app.gui.Workspace
,meico.app.gui.DataObject
, andmeico.app.Main
had to be adapted. - New class
meico.app.gui.Schema
has been added. - It is possible to set a default schema that meico will remember with every restart. Once this is done, meico behaves in the same way users of previous versions are used to.
- Updated copyright notice in class
meico.midi.Midi2AudioRenderer
and the license information inREADME.md
.
- Added a welcome message in the workspace:
"Drop your files here: MEI, MSM, TXT, MIDI, WAV, XSL, SF2, DLS."
and a file drop icon. This should clarify the first step of meico's usage to every beginner and provides a list of file formats that can be imported. The whole thing is responsive to window height, i.e. resizing the window will adjust the scale of the message. It will disappear after successfully dropping/importing the first file. - In class
meico.app.gui.Settings
there were some InputStreams that have not been closed. This has been fixed. - Disabled the option to switch off the internal WebView. Not all information shown internally can be forwarded to an external browser.
- Verovio integration:
- The motivation behind adding the webview to the GUI was to show Verovio's score renderings in it. This is now finally implemented.
- Added a prototype HTML document
/resources/Verovio/verovio.html
. It contains a placeholder"MeiCode"
which will be replaced by actual MEI code. - The new class
meico.app.gui.VerovioGenerator
provides the necessary methods to generate an HTML code that calls Verovio and passes the MEI code to it. - Classes
meico.app.gui.DataObject
andmeico.app.gui.WebBrowser
have been adapted. - In class
meico.app.gui.Settings
a new flagoneLineScore
has been added. If true, the score rendering will print all music in one system. This can be specified by the user in the settings. - In the settings the user can decide whether to use the local version of Verovio that is packed into meico's jar or the latest online available version (requires internet connection, of course).
- Do not expect too much, Verovio works suboptimal in Java's JavaScript engine.
- Whenever something is shown in the WebView, i.e. when clicking on "Score Rendering" or "Show",
- the WebView window will expand automatically and
- its title string will change to express what is shown.
- If an MEI or MSM does not provide a title, its visual representation in the GUI will be an empty circle. This has been changed. If the title string is empty, the filename will be printed.
- Class
meico.app.gui.WebBrowser
has extendedVBox
which cased a problem when resizing the window. The render area did not resize. This has been fixed by extendingStackPane
instead ofVBox
. - Added two new methods
prettyXml()
andrepeatString()
to classmeico.mei.Helper
to generate a formatted XML string from an unformatted one, basically for printing MEI and MSM code in the WebView. The corresponding options have been added to their menues.
- Some tweaks in the Travis CI script
.travis.yml
. Because of bad OpenJFX support Travis CI reports build fails with OpenJDK. At the moment only the Oracle JDK builds can be trusted. - Finished the MEI Coverage Documentation
documentation.md
. - Some minor code revisions, nothing essential.
- Bugfix in method
meico.mei.Mei.readMeiFile()
: If argumentvalidate
is settrue
, it was trying to validate the MEI before it was actually loaded. - Generated an up-to-date Ant script
build.xml
and added<manifest> <attribute name="Main-Class" value="meico.app.Main"/> </manifest>
to ensure that there is a main manifest attribute. - Thanks to David Weigl for reporting these issues!
- So far, XSL transform functions of meico did support only XSLT 1.0 and 2.0. In some Java versions also 3.0 stylesheets worked but not in general. This issue has been solved.
- Update Saxon to version 9.8.0.14 HE.
- Due to signature issues the files
TE-050AC.RSA
andTE-050AC.SF
had to be removed from theMETA-INF
folder ofsaxon9he.jar
. - In class
meico.mei.Helper
all XSLTransform processing methods have been redone and new ones have been added in order to overcome the afformentioned issues. XOM and Java were accessing Saxon's old transformer functionality only which does not support XSLT 3.0. The reworked versions access Saxon directly now and use itsXslt30Transformer
for all stylesheets. Classesmeico.mei.Mei
,meico.msm.Msm
,meico.app.gui.XSLTransform
,meico.app.gui.Workspace
, andmeico.app.gui.DataObject
have beed adapted accordingly. - Some further optimizations to XSL transforms have been implemented, esp. in classes
meico.app.gui.Settings
andmeico.app.gui.DataObject
.
- Added a custom meico icon to the window titlebar. It replaces Java's default icon. This and further icon files have been added to
resources/figures
. - When closing objects in the workspace the garbage collector does not seem to free their allocated memory automatically. A call of
System.gc()
has been added to classmeico.app.gui.Workspace
methodclearAll()
to force the garbage collection. - When changing the settings for accordion animation and auto expansion of the player a restart is no longer necessary necessary.
- Added method
main()
to classmeico.app.gui.MeicoApp
so it can be compiled and run as self-contained JavaFX application.
- Bugfix: make logfile when checked in the settings.
- If a file drop fails, the exception message is sent to the statuspanel.
- The conversion option "Score Rendering" has been removed from MEI menu as long as Verovio integration is not yet functional.
- Updated
README.md
.
- New graphical user interface:
- The new desktop application is located in package
meico.app.gui
in classMeicoApp
. - Lots of new file formats are droppable. Here is an overview of all supported file extensions:
.mei
,.msm
,.mid
,.wav
,.txt
,.xsl
,.sf2
,.dls
. - In addition to these import formats there are the following export formats that cannot be imported:
.mp3
,.json
(encodes pitch/chroma information). - Radial menus provide access to all operations that can be applied to the different data types. As a convenience shortcut MIDI and audio playback can be triggered by doubleclick. Soundbanks and XSLTs can also be activated via doubleclick.
- The following stuff has been deleted from the project as they are no longer required:
- classe
meico.app.MeicoApp
has been removed, - class
meico.app.FileDrop
has been removed, - the layout manager MigLayout has been removed from
externals
, - all the graphics from the old GUI have been removed from the
resources/graphics
folder.
- classe
- Font Awesome has been added.
- Meico uses the default system font. Layouting reacts on different font measurements.
- Added keyboard input to trigger playback: SPACE (does not work on all systems), ENTER and the play/pause key (one of the extra media keys on some keyboards).
- All operations are now processed in seperate threads. This prevents interface freezing and allows to run several operations in parallel. While an operation is processed, a "computing/please wait" animation is shown on the corresponding data item.
- A separate window offers some preferences settings to customize meico a little bit and preload certain soundbanks and XSLTs. However, most of the settings will become active only after restarting meico. All settings are stored in a file
meico.cfg
when closing meico and restored at the next startup. The file will be generated if not yet existent.
- The new desktop application is located in package
- Class
meico.Meico
got two new static methodslaunch()
andlaunch(String windowTitle, String logFileName)
. Applications can conveniently launch meico's graphical user interface by calling one of these methods, e.g.Meico.launch()
orMeico.launch("My window title")
. - Some revisions to classes
meico.midi.MidiPlayer
andmeico.audio.AudioPlayer
to ensure data integrity and correct feedback on method callisPlaying()
(esp. inAudioPlayer
). ClassMidiPlayer
got also two further getter methodsgetMicrosecondLength()
andgetTickLength()
. - The output of method
meico.mei.Mei.validate()
has been changed fromboolean
toString
. Now it returns the whole validation report. To get aboolean
callvalidate()
and thenisValid()
. - Added lots of
synchronized
s so that meico should run more stable in multithreaded environments. - Up to now, the MEI data was altered during conversion rendering it invalid. It has no use except for debugging purposes. We now ensured, that the original version is reset in method
meico.mei.Mei.exportMsm(int ppq, boolean dontUseChannel10, boolean ignoreExpansions, boolean cleanup)
after the conversion process. The altered version is kept only if attribute cleanup is set false (debug mode). - XOM library has been updated to version 1.2.11.
- Known issue: Loading XSLTs does not work on several Java versions. The issue seems to originate from the XOM library. In tests with Java 1.8.0_172 everything works fine. So at the moment this is the recommended Java version for running meico, at least regarding the use of XSLTs. everything else works alo in later versions.
- Added
NullPointerException
to audio rendering Exception handling inmeico.app.MeicoApp
, subclassMidi4Gui
. - MIDI playback overhaul:
- Extracted all MIDI playback related parts from
meico.midi.Midi
to new classmeico.midi.MidiPlayer
. ClassMidi
holds the data and its processing methods, classMidiPlayer
provides playback and synthesis functionality. - Removed all MIDI playback methods from class
Midi
. Hence, this part is no longer backwards compatible. - Class
MidiPlayer
features lots of new getter, setter and play methods. - An application that wants to play MIDI data should do this:
MidiPlayer player = new MidiPlayer(); player.loadSoundbank(soundbank); // this is optional; soundbank is a File or URL object player.play(myMidi); // myMidi is an instance of Sequence or meico's Midi class ... music plays ... player.stop(); player.close(); // if not needed anymore, close it
- Soundbanks can now be loaded and applied to MIDI playback. In GUI mode, users do not have to render audio to get the "high-quality" sound output. Hence, setup of the soundbank has been shifted to the MIDI name (right click). Here users can select the
.sf2
or.dls
file to be used or switch back to Java's default soundbank. It is even possible to switch the soundbank during playback. - The corresponding parts of
meico.app.MeicoApp
have been adapted. There is no longer a player for each MIDI instance but only one global MidiPlayer instance that is fed with the MIDI data (either aSequence
object or aMidi
object) to be played back.
- Extracted all MIDI playback related parts from
- Audio playback overhaul:
- Extracted all audio playback related parts from
meico.audio.Audio
to new classmeico.audio.AudioPlayer
. ClassAudio
holds the data and its processing methods, classAudioPlayer
provides playback functionality. - Removed all audio playback methods from class
Audio
. Hence, this part is no longer backwards compatible. - Class
AudioPlayer
features lots of new getter, setter and play methods. - An application that wants to play audio data should do this:
AudioPlayer player = new AudioPlayer(); player.play(myAudio); // myAudio is an instance of meico's Audio class ... music plays ... player.stop();
- Extracted all audio playback related parts from
- Added method
exportAudio(URL soundbankUrl)
to classmeico.midi.Midi
so that soundbanks do not have to be local files and URLs do not have to be decoded to files by the application. - Slight revisions to class
meico.audio.Audio
to ensure data integrity after MP3 conversion. - A note concerning MIDI to audio rendering: Meico's MIDI to audio renderer relies on the package
sun.com.media.sound
. However, Java 9 and later versions do no longer provide access to this package at compile time. It is still accessible at runtime. Hence, meico should be compiled with Java 8 and can run with later versions (tested until Java 10). But at some point they will probably make this package inaccessible also at runtime. A workaround for this is using the Gervill Sound Synthesizer (searchgervill.jar
in the internet and add it toexternals
) that provides the required package, so no code changes are necessary. However, consider that Gervill is licensed under GNU GPL-2.0 while meico is under GNU LGPL-3.0!
- Never trust automated refactoring. Some strange side effects have been fixed.
- Added library JSON.simple v3.0.2
- Switched the output of class
meico.pitches.Pitches
to JSON format. The default output file extension will also be.json
from now on. - The whole data structure of pitch (and chroma) data has been revised. Some new classes have been added to package
meico.pitches
, namelyFeatureVector
andFeatureElement
. - To make the pitches data structure and output file as memory efficient as possible, the timing resolution is reduced to the minimum ppq necessary to preserve accurate rhythm and note durations. MSM's ppq remains unchanged!
- Previos function calls stay the same to ensure backwards compatibility. Hence, we do not increment the beta version number.
- New methods
getParts()
,getPPQ()
andgetMinimalPPQ()
in classmeico.msm.MSM
.
- Updated Saxon parser to version 9.8.0.11 HE.
- Made the v0.3.6 fix a bit safer.
- Fixed missing
accid.ges
support inmeico.mei.Helper.computePitch()
for precedingaccid
elements.
- Another bugfix: processing of
accid
elements preceding to anote
element has been fixed.
- Little bugfix in
meico.mei.Mei.processAccid()
. In case ofnote
elements withaccid
children that do not provite anoloc
attribute, theoctave
is read from thenote
. Now it is done correct.
- Updated
meico.mei.Mei.processNote()
so that first its child elements (accid
,dot
) are processed before processing thenote
itself. - Extended processing of
accid
elements to look for parent notes in case theoloc
orploc
attribute are missing. - New method added
meico.mei.Mei.processDot()
:dot
elements have been processed directly during the processing ofnote
andrest
elements which lead to not considering the critical apparatus elements and, hence, not recognizing dots within that environment. This should be fixed now.
- In window mode the checkbox "Do not resolve expansions" has been renamed to "Resolve expansions". This should be more intuitive than checking a negated statement.
- More documentation has been added.
- The root element of MSM documents has been renamed from
meta
tomsm
. - During MEI-to-MSM conversion, when resolving MEI elements
beatRpt
,halfmRpt
,mRpt
,mRpt2
, andmultiRpt
, elements with duplicate IDs were created. This is taken care of now. - Added a new method to class
meico.mei.Mei
that returns the title of the music,getTitle()
. - Method
meico.mei.Mei.makeMovement()
has been extended. It creates now also atitle
attribute in the MSM root elementmsm
. Thattitle
attribute is a concatenation of the work's title and themdiv
element's attributesn
andlabel
.
- Added class
meico.Meico
that holds the version number of meico. It can be accessed viaMeico.version
. - Added a new package
meico.pitches
with classesPitches
andKey
. - Added new methods to class
meico.msm.Msm
:getEndDate()
returns the date of the last note offset, i.e. the length of the music in MIDI ticks.exportChroma()
converts MSM to a sequence of chroma features with 12 semitones in equal temperament and A = 440 Hz.exportPitches()
converts MSM to a sequence of absolute pitch vectors with 12 semitones per octave in equal temperament and A = 440 Hz. This conforms with the MIDI standard, i.e. 0 is the lowest and 127 the highest possible pitch. This method is overloaded. The more general version of this method takes an instance ofmeico.pitches.Key
as parameter.
- Some adds to the commandline app:
- Added new option
-o
and--chroma
to get chroma export. - Added new option
-h
and--pitches
to get absolute pitches export. - Added the current version number to the output of option
-?
/--help
. - File
README.md
has been updated accordingly.
- Added new option
- Chroma/pitches export has also been added to the window mode gui, available via right click on an MSM object.
- File
README.md
has been updated with the new pitches/chroma functions. - Redirected several error messages to
System.err
instead ofSystem.out
. This makes output in the commandline and log file more consistent.
- Two new types of maps have been added to the MSM format,
sectionMap
andphraseMap
. Their contents derive fromsection
andphrase
elements in MEI. They indicate musical sections and phrases. The MEI-to-MSM conversion has been extended by the corresponding routines (meico.mei.Mei.processSection()
andmeico.mei.Mei.processPhrase()
). - Added a new method
meico.mei.Helper.getMidiTimeAsString()
which is useful to avoid unnecessary String-to-Double-to-String conversions. - Added support for MEI
expansion
elements.- New methods added to class
meico.mei.Mei
:resolveExpansions(Element root)
andresolveExpansions()
. The latter is public and can be called by applications to convert an MEI withexpansion
elements into a "through-composed" MEI withoutexpansion
elements. - A new parameter
ignoreExpansions
has been added to methodmeico.mei.Mei.exportMsm(int ppq, boolean dontUseChannel10, boolean ignoreExpansions, boolean msmCleanup)
. So meico can be forced to convert the MEI data either as it is or in its rearranged form as indicated byexpansion
elements. There is also a methodmeico.mei.Mei.exportMsm(int ppq, boolean dontUseChannel10, boolean ignoreExpansions)
, if you have used a previous version of meico be sure to check consistency with yourexportMsm()
calls as there is a slight backwards incompatibility at this point! - A new parameter (
-e
,--ignore-expansions
) has been added to the commandline app. - The Python demo
meicoPy.py
got the same parameter now. - In the window app a checkbox has been added to the MEI-to-MSM conversion options saying
Do not resolve expansion elements
. - The REST api has also been updated and features the new parameter
ignore_expansions
.
- New methods added to class
- The resolution of MSM
sequencingMaps
, i.e. repetitions in MEI, has been redone and should work properly now.- Method
meico.msm.Msm.applySequencingMapToMap()
has been rewritten. - Class
meico.msm.Goto
has a second constructor methodGoto(Element gt)
which is much safer and more convenient thanGoto(double date, double targetDate, String targetId, String activity, Element source)
. It features also an new methodisActive()
that is used during the
- Method
- MEI
staffDef
elements do not necessarily need to have an attributelabel
but could also have a child elementlabel
. Support for this latter type has been added to methodmeico.mei.Mei.makePart()
. Continuo
has been added to the instruments dictionary as an instance ofHarpsichord
.
- Added MEI
section
elements to methodmeico.mei.Mei.addIds()
, so sections without an id get one. - Added method
meico.mei.Mei.processSection()
to experiment with interpreting MEI sections as potential repetition starts. But sections cannot generally be interpreted this way. So this function has been commented out again. - Initiated an MEI Coverage Documentation in
documentation.md
. Detailed descriptions need to be added in the future.
- MSM
movement
ids had no namespace. Now they are in the xml namespace. - Repetitions started always at an
rptstart
or the beginning of the piece. End barlines where ignored, so far. Meico now interprets<measure left/right="end">
as a potential repetition start.
- Bugfix in
meico.mei.Mei.processApp()
. - Bugfix in
meico.mei.Mei.processLayer()
. - Added method
meico.mei.Helper.getFirstChildElement(Element ofThis, String localname)
. It is a workaround for the XOM methodgetFirstChildElement(String name)
which sometimes does not seem to work properly. - Enhancements in the processing of
choice
elements. - Added support for
restore
elements.- It negates all
del
children (by adding an Attributerestore-meico="true"
). So the deletions will be considered during conversion. - The processing of
del
elements has been enhanced, accordingly. - But be aware, in our implementation a
restore
does not overrule a parentdel
element! Hence, putting adel
around arestore
effectively deletes the restoration.
- It negates all
- Added support for critical apparatus, i.e. the elements
app
,lem
andrdg
.- This is part of the MEI-to-MSM conversion process in
meico.mei.Mei.convert()
and is implemented in functionmeico.mei.Mei.processApp()
. - If an
app
element occurs, meico chooses the first (and hopefully only)lem
element to process. All other child elements are ignored. If nolem
is inapp
, meico chooses the firstrdg
element. - If any other choice is desired, the user has to resolve this manually. A tool for generating "variant-free", unambiguous MEI code is the MEI Sequence Editor. This tool goes through all variants and lets the user make the decision. It then outputs the corresponding MEI file.
- This is part of the MEI-to-MSM conversion process in
- Added editorial element support, i.e. all the elements that can occur in the
choice
andsubst
environment.- The elements
sic
andcorr
are processed in both cases of occurence, as "standalone" (always processed) and in thechoice
environment assic
-corr
pair (corr
is chosen). - The same for
orig
andreg
. In thechoice
environmentreg
is favored.
- The elements
- Added also the elements
add
,expan
,supplied
,unclear
to the supported elements in MEI-to-MSM conversion. Thedel
element is also processed now, but basically ignored. - The
cert
attribute (certainty) is not taken into account so far. And also therestore
environment is not processed, yet.
- Some adds to the instruments dictionary.
- Bugfix in
Msm.applySequencingMapToMap()
.- Only the first repetition was rendered correctly. Now also the later repetitions are correclty processed.
- Issue with duplicate
xml:id
's is solved.
- Optimizations in
Msm.resolveSequencingMaps()
. - Bugfix in GUI layout when loading a
wav
file. - The library Java-String-Similarity has been updated to v1.0.0.
- Updated Ant script
build.xml
accordingly.
- Updated Ant script
- Removed OracleJDK 7 from Travis CI builds
.travis.yml
as it is no longer supported by Travis CI. Java 7 compatibility can still be checked with OpenJDK 7.
- Changed MP3 encoding in method
meico.audio.Audio.encodePcmToMp3()
toLame.QUALITY_HIGH
. - Little additions to all
README.md
files. - Added method
meico.midi.Midi.writeMidi(String filename)
. - The
write...
methods in classesmeico.midi.Midi
andmeico.audio.Audio
did not ensure that the file actually exists in the file system or is created if not. This has been fixed. - All
write...
methods in classesmeico.midi.Midi
andmeico.audio.Audio
return aboolean
on the success of the file writing. Exception throwing has been removed. Classesmeico.app.Main
,meico.app.MeicoApp
andmeicoPy.py
have been adapted accordingly. - Added a REST interface implementation (to be found in directory
rest
). Corresponding startup and usage documentation can be found in theREADME.md
file at this directory. - Added
requirements.txt
to meicoPy.
- Added MP3 export to
meicoPy.py
. - Added more constructor methods in
meico.mei.Mei
andmeico.msm.Msm
to instantiate also from a Java InputStream.
- Added method
getDocument()
to classmeico.mei.Mei
andtoXML()
to classesmeico.mei.Mei
andmeico.msm.Msm
. - Bugfix in methods
meico.mei.Mei.exportMei()
,meico.mei.Mei.exportMsm()
andmeico.msm.Msm.exportMidi()
: create filname only if source file name is given, otherwise create export object withnull
as filename. - Added new constructors to classes
meico.mei.Mei
andmeico.msm.Msm
that take the input code as Java String. - Added
openjdk8
,openjdk7
, andoraclejdk9
to the TravisCI tests.
- In preparation of further application modes for meico package
meico.app
has been restructured.- Entry point is class
meico.app.Main
methodmain()
. The class also implements the commandline mode. - The window mode (GUI) is implemented in class
meico.app.MeicoApp
. Note the slight change fromMeiCoApp
toMeicoApp
! MANIFEST.MF
was updated accordingly.
- Entry point is class
- Added MP3 export of PCM encoded audio data.
- Added Java LAME sources to package
meico.audio
. Meico is 3.98.4. License is LGPL 3.0. - Added new methods to class
meico.audio.Audio
:public byte[] encodePcmToMp3(byte[] pcm, AudioFormat format)
,public byte[] getAudioAsMp3()
,public void writeMp3()
,public void writeMp3(String filename)
, andpublic void writeMp3(File file)
.
- Commandline mode has been extended accordingly. The new option is
-3
or--mp3
to get audio export as MP3. - Window mode has been extended, too. Left click on the audio save button will output an MP3 file. Via right click, the user can specify an arbitrary filename. If the extension is
.mp3
or.wav
, audio will be stored in the corresponding format. In all other cases, the output is a Wave file, by default, but with the specified extension.
- Added Java LAME sources to package
- Method
meico.msm.Goto.toXML()
has been renamed totoElement()
as it returns a XOM Element instance.
- The generated ids in method
meico.mei.Helper.barline2SequencingCommand()
could start numerical which is not XML conform. This is fixed. - Added methods to class
meico.msm.Msm
:public Document xslTransformToDocument(File xslt)
public String xslTransformToString(File xslt)
- Updated Ant build script.
- The XSLT-based new conversions from v0.2.12 were redone and generalized for several reasons.
- Licensing for the stylesheets is unclear/undefined. So they were removed from this repository. They can be obtained from the official MEI Encoding Tools GitHub page.
- Packages
data
,mods
,marc
, andmup
where removed from this repository including all contained classes. - The new export methods from v0.2.12 (see table) were replaced by two new, more generic methods in
meico.mei.Mei
:public Document xslTransformToDocument(File xslt)
andpublic String xslTransformToString(File xslt)
. This allows users to apply any XSLT stylesheets and obtain the result either as XOM Document instance or Java String. This should be a more flexible, less restrictive solution. For conversion of an Mei instancemyMei
to MusicXML, the user obtains the filemei2musicxml.xsl
and callsmyMei.xsltTransformToDocument("path\\to\\mei2musicxml.xsl")
. This returns the resulting Document that can be processed further or written to the file system.
- New method
writeStringToFile(String string, String filename)
inmeico.mei.Helper
.
-
Bugfix in commandline mode.
-
Reworked filename generation. New method
meico.mei.Helper.getFilenameWithoutExtension(String filename)
. -
Added Saxon v9.7.0.15 HE to the externals to process XSLT Stylesheets from the Music Encoding Initiative.
-
Added further conversions. These are using the Music Encoding Initiative's XSLT stylesheets from the MEI Encoding Tools GitHub page. However, they are a bit buggy sometimes ... and slow!
Conversion implemented in method comment MEI to MusicXML meico.mei.Mei.exportMusicXml()
buggy MusicXML to MEI (v3.0.0) meico.data.MusicXml.exportMei()
not functional, yet, because of XSLT syntax error MEI to MARC meico.mei.Mei.exportMarc()
requires more testing MEI to MODS meico.mei.Mei.exportMods()
requires more testing MEI to MUP (v1.0.3) meico.mei.Mei.exportMup()
requires more testing -
A series of new Classes has been added accordingly:
meico.data.MusicXml
,meico.marc.Marc
,meico.mods.Mods
, andmeico.mup.Mup
. -
Two new helper methods have been added to
meico.mei.Helper
:public static Document xslTransformToDocument(Document input, Document stylesheet)
andpublic static String xslTransformToString(Document input, Document stylesheet)
.
-
These adds are not part of the window mode and meicoPy, yet, butt will be integrated in a future draw.
- Bugfix in
meico.msm.Msm.resolveSequencingMaps()
. - Added meicoPy, a Python demo script. This demonstrates the usage of meico within Python. It is a reimplementation of meico's command line mode in Python.
- Some adds to the instruments dictionary.
- When creating MSM
goto
elements from endings, the elements get a temporal attributen
(derives from the respective MEIending
element which also has ann
attribute). In MSM this attribute is only required for the conversion and should not be present in the final output MSM. MethodHelper.msmCleanup()
has been extended accordingly. - If an MEI
ending
has no attributen
, meico now checks for attributelabel
and takes this to search for numbering information. However, in case that both attributes are present, attributen
is preferred.
- Added method
Msm.deleteEmptyMaps()
. It removes all empty maps, i.e. all elements with a substring"Map"
in the local-name (timeSignatureMap
,keySignatureMap
,markerMap
,sequencingMap
etc.), from the XML tree. This is to make the MSM file a bit smaller and less cluttered. - Added methods
getElementAtAfter()
andgetElementBeforeAt()
to classMsm
, helper methods for navigation within maps. - Repetition support implemented in meico, see the following lines for details.
- Added local and global
sequencingMap
elements to MSM. These hold information about the arrangement, i.e. repetitions, jumps etc. These will be encoded via elementsmarker
(same as in themarkerMap
but with a UUID) andgoto
(uses themarker
UUIDs to indicate jump target).-
The
marker
attributemessage
describes the meaning of the marker:
<marker midi.date="..." message="..." xml:id="..."/>
message=
description "fine"
the end mark of the piece; it is generated from MEI measure
attributesleft/right="end"
"repetition start"
indicates a possible jump target; it is generated from MEI measure
attributesleft/right="rptstart"
orleft/right="rptboth"
"ending ..."
this marker derives from an MEI ending
element which starts at this position; then
orlabel
of the ending are also given here -
If an MEI
measure
's attributeleft
orright
has the value"rptend"
or"rptboth"
, an MSMgoto
element is generated and added to thesequencingMap
. The format of thegoto
element is as follows:
<goto midi.date="..." activity="..." target.date="..." target.id="..."/>
Attribute Description midi.date
the position of the jump mark on the midi ticks timeline activity
documents in a bit sequence when the goto
is active and when it is inactive; e.g.,"1001"
would mean that the first time the playback reaches thegoto
it is active (do the jump), the next two times inactive (ignore it), then once more active, and from then on always inactive; for standard repetitions in musicactivity="1"
; the attribute is optional; if it is missing it is assumed asactivity="1"
by defaulttarget.date
the midi ticks position to jump to target.id
the xml:id
of the marker to jump to (the marker'smidi.date
should be equal totarget.date
) -
Class
meico.msm.Msm
implements methodresolveSequencingMaps()
which the user can call to expand all other maps and the parts' scores according to the global and local sequencing information. This will delete allsequencingMap
elements from the MSM tree as they no longer apply to the data. In case of a localsequencingMap
a part ignores the global one. MEI-to-MSM conversion, however, generates only a globalsequencingMap
.- Private method
Msm.applySequencingMapToMap()
has been added. - Class
meico.msm.Goto
has been added to representgoto
elements from thesequencingMap
and make processing more convenient. Application developers cann ignore this class as it is only of relevance for meico's internal processing.
- Private method
-
MSM tool to resolve
sequencingMap
elements has been added to window mode (MSM option "Expand Repetitions") and command line mode (here, it is done automatically). -
If elements that have an
xml:id
are repeated/copied, the id is changed to[original id] + "_repetition"
.
-
- Extended processing of MEI
measure
elements in methodMei.processMeasure()
.- Attribute
metcon
is now taken into account if a measure is underfull. Ifmetcon == "false"
, the measure can be shorter than what is defined by the time signature. An underfull measure with nometcon
attribute ormetcon != "false"
will be filled up with rests. Overfull measures, however, will always be extended. - Barlines of measures are encoded in attributes
left
andright
. If these have sequencing-related information (rptstart
,rptend
,rptboth
, orend
) the respective information in the global MSMsequencingMap
are generated. Therefore, the new methodHelper.barline2SequencingCommand()
has been added which is called fromMei.processMeasure()
.
- Attribute
- Processing of MEI
ending
elements added via methodMei.processEnding()
.- If there is only one ending, playback will skip it at repetition by default.
- Meico tries to realize the order of the endings according to the numbering in the endings'
n
attribute. This attribute should contain an integer substring (e.g.,"1"
,"1."
,"2nd"
,"Play this at the 3rd time!"
, but not"first"
or"Play this at the third time!"
). (Sub-)String"fine"
/"Fine"
/"FINE"
will also be recognized. Strings such as"1-3"
will be recognized as"1"
, this means that more complex instructions will not be recognized correctly due to the lack of unambiguous, binding formalization (meico is no "guessing machine"). If meico fails to find ann
attribute or extract a meaningful numbering from it, the endings are played in order of appearance in the MEI source. Meico does not analyse attributelabel
; so the editor should always encode the numbering in attributen
. - We tried to cover a variety of repetition and ending constellations but it is virtually impossible to cover all the crude situations that MEI allows (e.g., nested repetitions, repetitions within endings). So be not disappointed if some unorthodox situation from your special music encoding project does not work as expected.
- In MEI, global (score-wise) and local (staff-wise and layer-wise) key signatures can be mixed. Rule of thumb is, the latest key signature before a
note
is the one that has to be considered. So far, meico ignored global data if there was a local entry once. This lead to some wrong results if global entries come after local (e.g., at the beginning it may be encoded instaffDef
elements but later inscoreDef
elements; see, for instance,Hummel_Concerto_for_trumpet.mei
in the sample encodings). This issue is now fixed. If local and global key signature information deviate from each other meico trys to add global data to the localkeySignatureMap
in MPM where necessary. However, this is done ad hoc in methodHelper.computePitch()
in a very local context. Hence, it is not 100% perfect. This means, if the necessity for local copies occurs somewhere within the piece, pastkeySignature
elements will be missing until this point. - New method
Helper.addToMap()
. This is from now on used to insert new child elements into maps (sequential lists with elements that have an attributemidi.date
) and ensure the timely order of the elements. All relevant methods in classesHelper
andMei
have been adapted accordingly.
- Slight enhancements of
Midi.play()
andMidi.stop()
. - Some code polishing in classes
meico.mei.Mei
andmeico.mei.Helper
. - Better support of MEI
layer
elements during MEI-to-MSM conversion.- New
Helper
methods:getLayer()
,getLayerId()
, andaddLayerAttribute()
. - Affected methods have been revised. All MEI-to-MSM conversion methods that generate
note
,rest
,timeSignature
,keySignature
,transposition
,dur.default
, andoct.default
elements in MSM add a temporary layer attribute that is deleted duringHelper.msmCleanup()
. - Method
Mei.processRepeat()
considers layers, i.e., if a repetition takes place within alayer
environment (e.g., beatRpt), then only those elements are repeated that belong to this layer. - Method
Mei.processStaffDef()
has been extended. So far, its child elements were ignored. Now, they are processed.
- New
- Bugfix in
Helper.computePitch()
. Partly (not always) wrong conversion of accidental string to numeric value has been fixed.
- Added method
Helper.midi2pname()
. - Extended method
Helper.pname2midi()
. - Changes to MSM accidental elements:
- Renamed attribute
pitch
intomidi.pitch
. - Added attribute
pitchname
for better readability. - Both attributes can be used equivalently. Method
Helper.computePitch()
checks for both, preferringmidi.pitch
overpitchname
.
- Renamed attribute
- Removed files
MidiDataInputStream.java
,MidiDataOutputStream.java
,MidiFileReader.java
,MidiFileWriter.java
, andExtendedMidiFileFormat.java
from packagemeico.midi
. These were elements of the GNU Classpath project by Free Software Foundation. Since we dropped Java 6 compatibility these resources were no longer necessary. The corresponding methodsreadMidi()
andwriteMidi()
have been redone. - Added exit codes for errors in command line mode.
- Updated
README.md
.
- Added audio playback methods
play()
andstop()
to classmeico.audio.Audio
. - Added audio playback button to the window mode graphical user interface.
- Ensured that all playback is exclusive, i.e. starting one playback will stop any other currently running playback both for midi and audio.
- Ensured that the playback of a Midi or audio instance stops when the instance is deleted or overridden.
- Java 7 conform code polishing.
- Added Soundbank support for Midi-to-audio rendering.
- Instead of Java's default sounds the user can now freely choose a
.dls
or.sf2
file from the file system and use this for the synthesis of audio files. - A corresponding conversion option has been added to the window mode. Just right click the Midi-to-audio conversion button and click the
Choose soundbank
option, then select a corresponding file from the file system. I recommend testing these SoundFonts. - A command line option has been added:
[-s "C:\mySoundfonts\mySoundfont.sf2"]
or[--soundbank "C:\mySoundfonts\mySoundfont.sf2"]
to choose a specific.sf2
or.dls
file for higher quality sounds rendering.
- Instead of Java's default sounds the user can now freely choose a
- Deleted method
Midi2AudioRenderer.renderMidi2Audio(File soundbankFile, int[] patches, Sequence sequence)
. - Bugfix in class
meico.midi.Midi
: thesequencer
has been opened in the constructor but was never closed. Now it is opened when methodstart()
is called and closed when methodstop()
is called. Thus, it is only open during Midi playback. - Added Ant build script
build.xml
, thanks to Simon Waloschek. - Added Travis CI continuous integration system
.travic.yml
, thanks to Simon Waloschek. - Updated
README.md
. - Added
Violoncello
to the instruments dictionary.
- Fixed Midi-to-Audio conversion. Export of wave files works now.
- Updated
README.md
.
- Fixed delay and "hiccup" in Midi playback when initializing and starting a sequencer of a
Midi
object for the first time. - Added content to method
Audio.writeAudio(File file)
(so far it was empty). - Added format data to class
Audio
. New getter methods have been added. - In class
Audio
audio data are no longer represented asAudioInputStream
but as byte array. Constructors have been adapted. ClassMeicoApp
has also been adapted in subclassAudio4Gui
. - Deactivated methods
Audio.writeAudio()
until byte-array-to-AudioInputStream conversion works properly. - Fixed issues with the playback buttons in window mode.
- Updated
README.md
.
- Added subpackage
graphics
toresources
and moved all graphics resources into it. - Added audio export in Wave format.
- Added new command line options (
[-w]
or[--wav]
) to trigger wave export in command line mode. - Modified
Midi.exportAudio()
(formerMidi.exportWav()
) to create and return an instance ofmeico.audio.Audio
. - Added several methods to class
Audio
. Audio data is now represented in anAudioInputStream
and can be written into a file. - Modified method
meico.midi.Midi2AudioRenderer
. Its rendering methods return anAudioInputStream
object instead of directly writing a file into the file system. - Extended the window mode graphical user interface to include the new functionalities.
- Updated
README.md
.
- Added new command line options (
- Instead of using one global midi sequencer for Midi playback in class
meico.app.MeicoApp
(window mode) I switched to the built-in local sequencers in classmeico.midi.Midi
. - Added tooltips in window mode for better user guidance.
- Introduced some layouting variables in class
meico.app.MeicoApp
for better editing of the window mode graphical user interface via global variables.
- Added basic audio export to midi package (
meico.midi.Midi2AudioRenderer.java
). - Added
UnsupportedSoundbankException.java
to packagemeico.midi
. - Added test audio output to command line mode.
- Renamed the
element
elements in the MSM format. In thetimeSignatureMap
they are calledtimeSignature
, inkeySignatureMap
they are calledkeySignature
and in themarkerMap
they are now calledmarker
. - Method
Helper.computePitchOld()
deleted. - Added method
Mei.processAccid()
, soaccid
elements are now processed not only as children ofnote
elements (as until now) but also when they are siblings tonote
elements and the like. However, the attributesploc
andoloc
are required to associate the accidental with a pitch. - Ids generated by meico (UUIDs) did not validate. This issue is fixed. Generated ids start with
"meico_"
. - Added support for multiple
body
elements in an MEImusic
element. This is no valid MEI, though, but meico won't crash if it occurs anyway. - Added processing of
incip
,parts
, andpart
elements. - Little bugfix with
halfmRpt
. - Added method
Helper.pname2midi()
as this functionality is used at several occasions. - Key signature processing (
scoreDef
,staffDef
,keySig
) in methodMei.makeKeySignature()
has been redone.- More cases and unorthodox/mixed key signatures are now covered, also in the MSM representation.
- Nonetheless,
keyAccid
elements require thepname
attribute so that meico can associate the accidental with a pitch class. - If not indicated by
keyAccid
elements,scoreDef
,staffDef
, andkeySig
require at least thekey.sig
orsig
attribute to denote a key signature. - Attribute
key.sig.mixed
orsig.mixed
are also supported. - The octave position of the key signature accidentals is ignored. It is not clearly defined if an accidental affects only this one octave or all octaves of that pitch class. In meico we decided to interpret it in the latter way.
- Modified method
Helper.computePitch()
to consider key signature accidentals.
- The processing of
chord
elements (bTrem
andfTrem
are processed similarly) has been redone. If achord
element has no duration data in its attributes (dur
,dots
) and does not inherit it from a parent element, its duration is now specified by the longest child element. - Added
Prinzipal
,Soprano
,Baritone
,Euphonium
,Chant
to the instruments dictionary. - Bugfix in
Mei.reorderElements()
, relevant in the case that astartid
attribute refers to an element within the element. - Minor corrections in
MeicoApp.commandLineMode()
.
- Bugfix in command line mode: missing path when writing
"-debug.mei"
and the file has been loaded via relative path. - Added
S.
,A.
,T.
,B.
to the instrument dictionary for ChoirOhs. - Method
InstrumentsDictionary.getProgramChange()
outputs its string matching results to the command line or log file, resp. - Missing
accid.ges
attribute processing inHelper.computePitch()
added.
- Renamed the
dur
attribute in MSM notes and rests intomidi.duration
. - Further renamings:
date
intomidi.date
,pitch
intomidi.pitch
,channel.midi
intomidi.channel
, andport.midi
intomidi.port
. - Added
Bassus
,Cantus
,Singstimme
,Singstimmen
,Pianoforte
,Trumpet in
,Trompete in
to the instruments dictionary. - Added a flag to the window mode constructor method
MeicoApp(String title, boolean makeLogFile)
. The redirection of console output into a log file is done only whenmakeLogFile
is set true. - Bugfixing in
Mei.processStaff()
andHelper.getPart()
. tie
elements are now processed (new methodMei.resolveTieElements()
); they are resolved intotie
attributes ofnote
elements during the preprocessing. Hence, meico now supports the use oftie
elements and is no longer restricted totie
attributes only. However, users should not mixtie
andslur
elements; the latter are not and will not be processed as ties!- Method
Mei.resolveCopyOfs()
rewritten. It is not only faster now. It might happen (and does happen in the MEI sample library) that a placeholder element (the one with thecopyof
attribute) copies elements that again contain placeholders; it requires multiple runs to resolve this. The new implementation can handle circular referencing (cannot be resolved and would otherwise lead to infinite loops). Furthermore, if the placeholder element has anxml:id
this id is no longer overwritten by the newly generated ids. - Method
Mei.reorderElements()
(part of the MEI preprocessing) has been rewritter and is much faster now.
- Moved unused code in the
meico.midi
package into thelegacy
sub-package. - Added validation of MEI files against
mei-CMN.rng
version 3.0.0 (August 2016).- The file
mei-CMN.rng
from MEI GitHub repository was added to the resources. - The
Jing
library (version 20091111) was added to the externals (notice thecopyright.txt
in filejing-20091111.jar
). - The method
validateAgainstSchema()
is implemented in classHelper
and called byvalidate()
throughreadMeiFile()
in classMei
. - New addition to command line mode:
[-v]
or[--validate]
: to activate validation of mei files loaded. - In window mode files are read without validation by default. Right click on the MEI file loaded to trigger validation and get a popup message on the success.
- Applications may call method
isValid()
in classMei
after the file was read to check validity. If the file has been loaded without validation it remainsfalse
by default. To do the validation afterwards, callvalidate()
.
- The file
- In window mode all command line outputs (
System.out
andSystem.err
) are now redirected into a log filemeico.log
. - Added
Bratsche
to the instruments dictionary. - Replaced the
:
in the id generation for copyOf resolution into_
.
- Added flag to the mei-to-msm conversion to avoid the midi drum channel, added it to the window mode and command line options
[-c]
or[--dont-use-channel-10]
: the flag says whether channel 10 (midi drum channel) shall be used or not; it is already done at mei-to-msm convertion, because the msm should align with the midi file later on
- Changed id generation for copyOf resolution into a combined id:
source id + ":" + generated id
; hence, applications can now trace them back to the source element - Minor bugfix of command line option
[--no--program-changes]
to[--no-program-changes]
- Minor ui corrections for window mode
- Adding new attributes,
date.midi
anddur.midi
, to mei note and rest elements during conversion. This is only for debugging purpose and appears only in the-debug.mei
file when running the command line mode with--debug
flag. - Also a
pnum
is added to the meinote
elements in the debug version which holds the calculated midi pitch value.
- Added
Canto
,Quinto
andTenore
to theVoiceOhs
in the instruments dictionary. - In
MeicoApp
'scommandLineMode()
a relative path can be used; the absolute path is derived automatically. Hence, users do not have to write down whole paths in the command line from now on. - Fixed bug in the processing of note accidentals when
accid
elements are used instead ofaccid
attributes. - Fixed bug in
Helper.getNextSiblingElement(Element ofThis)
. - Method
exportMidi()
inMsm.java
now has a flag to suppress the generation of program change events (useful in some applications). The flag is also supported in command line mode (add[--no-program-changes]
to your call) and window mode (right click on the msm to midi conversion button). - Added an optional tempo parameter to the command line mode
[-t argument]
or[--tempo argument]
. - Changed the format of the command line parameters to follow POSIX standard.
[-?]
or[--help]
: for this command line help text. If you use this, any other arguments are skipped.[-a]
or[--add-ids]
: to add xml:ids to note, rest and chord elements in mei, as far as they do not have an id; meico will output a revised mei file[-r]
or[--resolve-copy-ofs]
: mei elements with acopyOf
attribute are resolved into selfcontained elements with an ownxml:id
; meico will output a revised mei file[-m]
or[--msm]
: converts mei to msm; meico will write an msm file to the path of the mei[-i]
or[--midi]
: converts mei to msm to midi; meico will output a midi file to the path of the mei[-p]
or[--no-program-changes]
: call this to suppress the generation of program change events in midi[-t argument]
or[--tempo argument]
: this sets the tempo of the midi file; the argument must be a floating point number; if this is not used the tempo is always 120 bpm[-d]
or[--debug]
: to write debug versions of mei and msm- Path tho the mei file (e.g.,
"D:\Arbeit\Software\Java\MEI Converter\test files\Hummel_Concerto_for_trumpet.mei"
), this should always be the last parameter - always in quotes!
Bugs fixed in Mei.java
that were introduced by rewriting convert()
for Java 1.6 compatibility.
Java 1.6+ compatibility
instrument dictionary extended (church organ
: upper
, lower
, pedal
)
So far, msm part names were the staffDef
labels. Now, they are created from an eventually existing parent staffGrp
label and the staffDef
label ("staffGrp label" + " " + "staffDef label"
).
Java 7+ compatibility
first release (requires Java 8+)