Philosophiz

Documenting my mind

為什麼不再孤單?

自那時候起
一個人再不孤單

因為一個人的時候
我可以躲在自己的世界裏
觀察一個不屬於自己的世界

有緣總比無緣好

幸運的人,會遇到幾個真的懂自己的人
緣起,你讓她明白過你自己
緣滅,你再不出現於她的生活裏

至少,世上還有懂你的人

星巴克的味道

最近迷上了星巴克的一種味道,一種從前不察覺的味道。這種味道像Mocha,雖然有甜有苦,但兩者在味蕾上交加時卻只剩下甜。

每天喝Mocha會太膩,偶爾一次剛好。

“In programming, as in everything else, to be in error is to be reborn.”
– Alan J. Perlis

Comparing MMA with Musescore

This post is taken from a documentation written when I was doing my final year project as a computer science student at HKUST. If there will be any changes or updates to the following text, I may not update this post accordingly. So please kindly refer to http://tinyurl.com/comparing-mma-and-musescore for updates or to comment on it.

This documentation is based on Musescore version 1.2 and the Melisma Music Analyzer 2003 release. (May contain errors.)


How Musescore converts MIDI to MusicXML

Musescore imports midi into its own internal model and then converts this internal model into MusicXML. According to Musescore developer Nicolas Froment#, Musescore does not handle tuplets, and ties are always favoured instead of dotted notes without considering the beats.


While importing a midi file from using the GUI, Musescore allows the user to select the shortest note. If the import is done using the command line, the shortest note is set to 30#. Once Musescore knows the shortest note, it will start converting the midi file into its internal model in the following steps:

  1. Separate different midi channels into tracks

  2. For each midi track

    1. Merge note-on and note-off events into a note event with tick duration

    2. Extract system exclusive events and determine the midi type

    3. Extract time signatures and build a time signature list

  3. Change the division of the midi file and each midi track

  4. For each midi track

    1. Determine the maximum pitch

    2. Determine the minimum pitch

    3. Determine the med pitch (sum of all pitches in this track divided by the total number of events in this track)

  5. For each midi track

    1. Find out the instrument

    2. Create a part for this instrument

    3. Create a staff for this instrument

    4. If this track is piano, assume that the current track and the next track form a piano part

  6. Remove empty measures at the beginning

  7. Count the number of measures in each track

  8. Create measures

  9. For each track,

    1. Quantize each event

    2. Remove overlapping events

    3. Remove events that have a duration less than or equal to zero

  10. For each midi track

    1. Process meta events

    2. If this track has a part, set the track name, midi channel, and midi program

    3. If this track is not an empty track, convert track


While processing meta events in each track, Musescore converts each track into its internal structure:

  1. Find keys using the CBMS algorithm

  2. Find chords

  3. Separate voices

  4. Get the staff

  5. Get the list of events

  6. Get information about drumset

  7. Get the list of keys

  8. For each voice

    1. Initialise an empty list of notes (let’s call it notes)

    2. For each event

      1. While notes is not empty

        1. Split notes on measure boundary

        2. Add chord to segment

        3. For each note in notes

          1. add note to chord

          2. Remove this note from notes

      2. Check for gaps and fill with rests

      3. Collect all notes on current tick position (append to notes)

    3. While notes is not empty

      1. add chord to segment

      2. Split notes on measure boundary

      3. For each note in notes

        1. Add note to chord

        2. Remove this note from notes

    4. Check for gaps and fill with rests

  9. If this track doesn’t have a key and this track is not a drum track, create a key signature event and add it to the first element in the key list

  10. For each key in the key list

    1. Create a key signature

    2. Add this key signature to the segment of the corresponding measure (identified by tick)


Chord finding

Both MMA and Musescore find chords. Although two programs do it a bit differently, their underlying assumptions are almost identical, that is, all the notes in a chord have the same onset time, offset time, and duration.


MMA finds chords by comparing the onset time and duration, while Musescore finds chords by comparing the onset time and offset time. Mathematically, these two ways of finding chords are equivalent. The difference between the two programs is that MMA simplifies the comparison of two notes by shifting the note onset and note offset to the nearest previous beat, whereas Musescore allows a tolerance or 3 MIDI ticks between the ontimes or offtimes of two notes.


Key finding

MMA allows users to choose from one of four algorithms for key finding, namely, the Krumhansl-Schmickler algorithm (Krumhansl 1990), the CBMS algorithm (Temperley 2001), a variant of CBMS (not recommended by the authors), and a Bayesian key-finding algorithm (see Temperly, “A Bayesian Key-Finding Algorithm:, in Music and Artificial Intelligence, Springer, 2002).


Like MMA, Musescore makes use of the CBMS algorithm, the Bayesian key finding algorithm, and Krumhansl’s algorithm. As documented by Musescore developers,  Musescore uses code from the Melisma Music Analyzer project to implement its key-finding functions. Musescore uses only the CBMS algorithm. When importing a midi file, Musescore looks at the key meta events in the file, and add the keys to a list. If there are no key events, Musescore uses the CBMS algorithm to determines the key.


Meter finding

Upon importing a midi file, Musescore extracts time signatures from the file by looking at the time signature events, and stores them in a list. If there are no time signature events, Musescore sets the time signature for the whole file to 4/4.


Tempo

Musescore extracts tempos from the tempo meta events in the midi file and add them to a tempo map. If no tempo events are present, Musescore ignores this information.


Instrumentation

Musescore extracts the program (instrument/patch) of each midi channel (track) from the midi file and adds this information to each event in the track.


Dynamics

Here dynamics corresponds to the velocity of each note on event in a midi file. Musescore keeps the velocity in each note (except for rest notes). In MusicXML, the dynamics attribute of a note element corresponds to MIDI 1.0’s note on velocity. The conversion of dynamics from MIDI to MusicXML is therefore trivial.


Rhythm

Rhythm here means percussion. Musescore identifies the 10th channel as percussion (General MIDI standard) and sets it as a drum track or unpitched instrument in MusicXML. In our data corpus, however, most of the midi files that have percussion parts do not make use of the 10th channel. As a result, Musescore treats these percussion parts as pitched instruments with percussion clefs. So one can identify find the percussion parts by looking at the clef, although this is not a desirable way to do so.


Melody

Melody extraction and segmentation is still an open-research area in computing. In fact, while there have been many algorithms proposed to do so, no one algorithm has been proven to be most efficient. In our project we have mostly relied on good MIDI data that has manually separated the melody line, which can be clearly read by Musescore. While we have tried to use the MMA for this extraction, the MMA has clearly documented that it does not extract melody lines per se. It extracts only what it calls “streams”, which are not melody lines but are rather moving part lines that may have some form of cohesion. The MMA (Grouper Program) is only capable of segmenting the melody line into smaller parts if the melody line is already given, i.e. if it is a monophonic line.


Midi Toolbox (version 1.01) from the University of Jyvaskyla is one tool that extracts melodic segmentation, but this tool has to run on Matlab. Although Matlab is proprietary software and a legal license of Matlab is required, the Midi Toolbox is available free of charge under the GNU General Public License. Three melodic segmentation algorithms are available in the toolbox: Gestalt-based algorithm (Tenney & Polansky, 1980), Melodic Segmentation algorithm (Bod, 2002), and Local Boundary Model (Cambouropoulos, 1997). Without a legal license of Matlab, we will instead use code from the toolbox to implement the melody extractor if time permits.

To Mary by John Clare

To Mary
John Clare

I sleep with thee, and wake with thee,
And yet thou art not there;
I fill my arms with thoughts of thee,
And press the common air.
Thy eyes are gazing upon mine,
When thou art out of sight;
My lips are always touching thine,
At morning, noon, and night.

I think and speak of other things
To keep my mind at rest:
But still to thee my memory clings
Like love in woman’s breast.
I hide it from the world’s wide eye
And think and speak contrary;
But soft the wind comes from the sky,
And whispers tales of Mary.

The night wind whispers in my ear,
The moon shines in my face;
A burden still of chilling fear
I find in every place.
The breeze is whispering in the bush,
And the dews fall from the tree,
All, sighing on, and will not hush
Some pleasant tales of thee.

Eight features Windows 8 borrowed from Linux

Eight features Windows 8 borrowed from Linux.