Code Monkey home page Code Monkey logo

music21's People

Contributors

almogcohen avatar bhadley avatar bhouge avatar clian1 avatar crantila avatar dnagler avatar doctor-schmidt avatar dvdrndlph avatar eflynch avatar flexatone avatar fzalkow avatar gregchapman-dev avatar jacobtylerwalls avatar jordibartolome avatar josecu avatar josiah-wolf-oberholtzer avatar lbigo avatar lrsjohnson avatar malcolmsailor avatar markgotham avatar maurachur avatar metalmike avatar mjwalter avatar mscuthbert avatar napulen avatar nsparikh avatar rogotherogue avatar sandroluck avatar shimpe avatar timfelixbeyer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

music21's Issues

Integrating notes not in measures w/ notes in measures

Reported by christopher.ariza, Jan 9, 2010
Eventually: should object.show(‘musicxml’) place notes that are outside of
measures in measures even if there are measures in the stream? I think that
that might make sense. This would require extracting unmeasured sections
into temporary Streams, running makeMeasures() on them, then extracting
those measures out and putting them back into the new stream. Doesn’t
seem a very high priority, but it’d be nice if the “emptyMeasure.append()”
step weren’t necessary. (Must be extremely fast in the simple case when there are no notes outside of measures)

Braille: Excess music hyphen before and space after measure with voices

What steps will reproduce the problem?

  1. Run the following python script:

from music21.note import WholeNote;
from music21.stream import Part, Voice;
v1 = Voice()
v1.append(WholeNote('C4'))
v2 = Voice()
v2.append(WholeNote('G4'))
p = Part()
p.insert(0, v1)
p.insert(0, v2)
p.makeMeasures().measure(1).show('braille')

(Extract a specific measure to shorten the result string for clarity.
The mentioned excess hyphen and space are present in normal p.show('braille')
as well.)

What is the expected output?

⠼⠙⠲⠀⠐⠽⠣⠜⠐⠷⠣⠅

What do you see instead?

⠼⠙⠲⠀⠐⠀⠐⠽⠣⠜⠐⠷⠀⠣⠅

Please provide any additional information below.

A measure with full-measure in-accord voices is normally just separated by ⠣⠜.
I do not see any reason why the transcription should add a leading music hyphen
(⠐) to a measure which contains full-measure in-accord. Nor do I think
there should be a space after the measure and between the final barline sign.

This only seems to occur if there are multiple voices in a measure.

Looking at the code, I think some of the logic for figuring out
addSpace and addHyphen probably needs an overhaul to not fire in the situation
provided in this test case.

Separate "Scratch" Directories for Different Purposes

TL;DR: I'd like to be able to choose different locations for the different types of files stored in the music21 "scratch" directory.

The "scratch" directory is used for two very different things:

  • Creating temporary files while preparing output.
  • Storing pickled versions of previously-imported output.

The first of these is the definition of "temporary" files, and they could be removed virtually right away after they're created. Certainly they should be removed periodically.

The second of these is not at all temporary, since it's only useful if the files are not removed periodically (certainly at much longer periods than the temporary files).

Because music21 puts these in the same place, it's more difficult to manage the different roles these files play. For a desktop user, it's not a big deal. For deployment on a server, I want to put some of these files in /tmp and some of them in /var/cache, and they require different (SELinux) security labels.

For these reasons, I'd like to be able to set different directories for the different types of files.

(Note this is indeed low priority).

hashing for Chord object

I'm not sure if this was planned, but the ChordSymbol object has different hashes:
import music21
music21.harmony.
dict_har = {}
chord_a = music21.harmony.ChordSymbol('C7')
chord_b = music21.harmony.ChordSymbol('C7')
dict_har[chord_a] = chord_a
dict_har[chord_b]
KeyError Traceback (most recent call last)

Use __slots__ for simple objects that are used often

The slots feature takes some of the power and flexibility away from Python objects, but instead greatly lowers their memory requirements, adding some speed along the way. Basic music21 functionality, such as DurationUnits, etc., to be reimplemented with slots.

  • Duration/DurationUnit
  • Sites
  • base.Groups
  • Beam / Beams
  • editorial.Editorial / editorial.Comment (possibly to be removed or at least only instantiated on first use...)
  • meter.MeterSequence
  • meter.MeterTerminal
  • note.Lyric
  • stream.Derivation
  • stream.StreamStatus
  • stream.SpannerStorage
  • pitch.Microtone
  • pitch.Accidental
  • tie.Tie
  • volume.Volume

Not to be done (at least yet): Music21Object or its subclasses (Note, Stream, Chord, etc. (flexibility is important))

Tracking Bug: Get LilyPond Version from User's System

TODO in lily.translate.py:L167 ("this should be obtained from user and/or user's system") referring to the installed LilyPond version. The hard-coded default version is 2.13, which doesn't make sense in any case, since that was the development series for 2.14, and everything that's different between 2.12 and 2.14 appeared gradually through the 2.13 series---but not all at once.

misleading pitches in cello Mozart + Beethoven string quartets

Cello music published before the 20th century often writes high notes in treble clef which is supposed to be played an octave lower. This is not notated with a _8vb; the cellist must simply figure out based on the context whether a particular score should be played at regular pitch or an octave lower. A summary of the issue is given here:
http://www.daisyfield.com/music/cm/FalseTreble.htm
(although I hadn't heard it called "false treble" before, it makes sense!)
This is particularly aggravating because the range of "false treble" is one note away from tenor clef, which is readily understood by moderately skilled cellists.

Unfortunately, many (perhaps all?) of the musescore files in music21 suffer from this problem, compounded by a lack of clef information (since they are stage1). For example, mozart/k421/movement1.zip 01/04 contains this:

measure 15
C3    4
C2    4
rest  8
measure 16
C5    8
E5    8

checking IMSLP shows that measure 16 goes into treble clef,
http://javanese.imslp.info/files/imglnks/usimg/1/12/IMSLP64149-PMLP05232-Mozart_Werke_Breitkopf_Serie_14_KV590.pdf
but speaking as a cellist with 25 years of experience, that is a "false treble". The actual pitches should be

measure 16
C4     8
E4     8

Unfortunately I can't think of any quick or easy solution. Adding a warning to the corpus documentation may be appropriate. Updating all the stage1 files to stage2 (as well as correcting the pitches to show the real pitches) would be ideal, but that is of course a very manpower-intensive task.

Sorry to be the bearer of bad news!

converter.py unit test fail : testParseURL

def testParseURL(self):
    urlA = 'http://kern.ccarh.org/cgi-bin/ksdata?l=users/craig/classical/schubert/piano/d0576&file=d0576-06.krn&f=xml'
    urlB = 'http://kern.ccarh.org/cgi-bin/ksdata?l=users/craig/classical/schubert/piano/d0576&file=d0576-06.krn&f=kern'
    urlC = 'http://kern.ccarh.org/cgi-bin/ksdata?l=users/craig/classical/bach/cello&file=bwv1007-01.krn&f=xml'
    for url in [urlA, urlB, urlC]:
        unused_post = parseURL(url)

shows the following error:

ERROR: testParseURL (music21.converter.TestExternal)

Traceback (most recent call last):
File "C:\Users\Michael\git\music21\music21\converter.py", line 1241, in testParseURL
unused_post = parseURL(url)
File "C:\Users\Michael\git\music21\music21\converter.py", line 1019, in parseURL
v.parseURL(url, format=format)
File "C:\Users\Michael\git\music21\music21\converter.py", line 937, in parseURL
self._converter.parseFile(fp, number=number)
File "C:\Users\Michael\git\music21\music21\converter.py", line 499, in parseFile
raise ConverterException('score from file path (%s) no parts defined' % fp)
ConverterException: score from file path (c:\users\michael\appdata\local\temp\music21\m21-79fede18c19af95328cb65b5421c20d3.xml) no parts defined

This was the problematic link (urlB and urlC work well):
urlA = 'http://kern.ccarh.org/cgi-bin/ksdata?l=users/craig/classical/schubert/piano/d0576&file=d0576-06.krn&f=xml'

Developer documentation: Update needed for iPython with Anaconda 1.8.0

The current version of Anaconda (1.8.0) does not support "conda pip" commands. Please let me know if you want me to add documentation for installation with Anaconda (1.8.0) and I will file a PR. Ultimately, it would be helpful to have music21 available through conda.

carol 10:21 PM -bash ~ ]conda pip music21
ERROR:
The "conda pip" command has been removed from conda (as of version 1.8) for
the following reasons:
  * users get the wrong impression that you *must* use conda pip (instead
    of simply pip) when using Anaconda
  * there should only be one preferred way to build packages, and that is
    the conda build command
  * the command did too many things at once, i.e. build a package and
    then also install it
  * the command is Python centric, whereas conda (from a package management
    perspective) is Python agnostic
  * packages created with conda pip are not robust, i.e. they will maybe
    not work on other people's systems

In short:
  * use "conda build" if you want to build a conda package
  * use "conda install" if you want to install something
  * use "pip" if you want to install something that is on PyPI for which there
    isn't a conda package.

carol 10:21 PM -bash ~ ]conda install music21
Error: No packages found matching: music21
carol 10:22 PM -bash ~ ]pip install music21

Support all MusicXML lyric types

Support all in and out of lyrics from MusicXML 3.0

Right now Finale can export lyrics with instead of text. These are lost on input. On output an empty is generated, which isn't valid MusicXML.

Bug in the harmony module

The following code:

>>> y = harmony.ChordSymbol('F')
>>> y.key = key.Key('C')
>>> y.romanNumeral

Produces the following TypeError:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\harmony.py", line 373, in fget
    self._roman = roman.romanNumeralFromChord(self)
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\roman.py", line 622, in romanNumeralFromChord
    chordObjSemiclosed = chordObj.semiClosedPosition(inPlace=False)
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\chord.py", line 2822, in semiClosedPosition
    c2 = self.closedPosition(forceOctave, inPlace, leaveRedundantPitches)
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\chord.py", line 920, in closedPosition
    returnObj = copy.deepcopy(self)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 174, in deepcopy
    y = copier(memo)
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\chord.py", line 277, in __deepcopy__
    new = note.NotRest.__deepcopy__(self, memo=memo)
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\note.py", line 599, in __deepcopy__
    new = GeneralNote.__deepcopy__(self, memo=memo)
  File "C:\Users\Eidan\Anaconda\lib\site-packages\music21\base.py", line 1679, in __deepcopy__
    newValue = copy.deepcopy(part, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 190, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 334, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 163, in deepcopy
    y = copier(x, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 257, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 190, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 334, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 163, in deepcopy
    y = copier(x, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 257, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 190, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 334, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 163, in deepcopy
    y = copier(x, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 257, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 163, in deepcopy
    y = copier(x, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 257, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 190, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "C:\Users\Eidan\Anaconda\lib\copy.py", line 329, in _reconstruct
    y = callable(*args)
  File "C:\Users\Eidan\Anaconda\lib\copy_reg.py", line 93, in __newobj__
    return cls.__new__(cls, *args)
TypeError: object.__new__(NotImplementedType) is not safe, use NotImplementedType.__new__()

reduceChords: support arpeggio collapse

The reduceChords algorithm should be able to identify and collapse arpeggios.

This would be a pre-processing step before running the full multi-part reduction algorithm.

Parsing MusicXML ignores repeat 'backward'

Hi!

I am trying to analyse a MusicXML file:

# input files
music_score_output_musicxml_page1 = "IMSLP5673-Bach-partita-flute-allemande_Seite_1.xml"

# load MusicXML using music21
score_object_page1 = converter.parse(music_score_output_musicxml_page1)

for page in layout.divideByPages(score_object_page1, fastMeasures = False).pages:

    print "Page", page

    for system in page.systems:
        for staff in system.staves:
            for measure in staff.getElementsByClass('Measure'):

                print "\t", measure

                for elem in measure._elements:
                    if type(elem) == Repeat:

                        print "\t\t", elem

Using this file:
http://www.ifs.tuwien.ac.at/~schindler/files/IMSLP5673-Bach-partita-flute-allemande_Seite_1.xml

It was first extracted from an image using Audiveris and then manually corrected using MuseScore. Finally I checked in the XML source if the and tags are set properly.

Applying the code on the file provides the following output:

Page <music21.layout.Page 369844296>
    <music21.stream.Measure 0 offset=0.0>
        <music21.bar.Repeat direction=start>
    <music21.stream.Measure 1 offset=3.625>
    <music21.stream.Measure 2 offset=7.625>
    <music21.stream.Measure 3 offset=11.625>
    <music21.stream.Measure 4 offset=15.625>
    <music21.stream.Measure 5 offset=19.375>
    <music21.stream.Measure 6 offset=23.0625>
    <music21.stream.Measure 7 offset=27.0625>
    <music21.stream.Measure 8 offset=31.0625>
    <music21.stream.Measure 9 offset=34.0625>
    <music21.stream.Measure 10 offset=37.8125>
    <music21.stream.Measure 11 offset=41.875>
    <music21.stream.Measure 12 offset=45.875>
    <music21.stream.Measure 13 offset=49.75>
    <music21.stream.Measure 14 offset=53.625>
    <music21.stream.Measure 15 offset=57.625>
    <music21.stream.Measure 16 offset=61.625>
    <music21.stream.Measure 17 offset=65.625>
    <music21.stream.Measure 18 offset=69.625>
    <music21.stream.Measure 19 offset=73.5>
    <music21.stream.Measure 20 offset=77.375>
        <music21.bar.Repeat direction=start>
    <music21.stream.Measure 21 offset=81.375>
    <music21.stream.Measure 22 offset=85.375>
    <music21.stream.Measure 23 offset=89.375>
    <music21.stream.Measure 24 offset=93.125>

Maybe there is something wrong with the MusicXML file or there seems to be a bug in music21's MusicXML parser.

reduceChords: support alignment by lyrics

The reduceChords should support aligning notes and chords in different voices if they share identical lyrics.

This would be a pre-processing step before running the multi-part chord reduction algorithm.

xmlHandler.py unit test fail : testOpen

ERROR: testOpen (music21.musicxml.xmlHandler.TestExternal)

Traceback (most recent call last):
File "C:\Users\Michael\git\music21\music21\musicxml\xmlHandler.py", line 1124, in testOpen
c.repr()
File "C:\Users\Michael\git\music21\music21\musicxml\xmlHandler.py", line 1082, in repr
self.reprTest()
File "C:\Users\Michael\git\music21\music21\musicxml\xmlHandler.py", line 1086, in reprTest
print('+'*20 + ' ' + self.getBestTitle())
TypeError: cannot concatenate 'str' and 'NoneType' objects

ChromaticInterval transposition looks at key signature context

exapand ChromatiInterval to adjust its diatonic representation based on context.

"So for instance, B.transpose(4) would be D#
usually, but if the context showed a key that had Eb in it, then Eb would be
returned. In the absence of key information, double and triple sharps, etc.
should be removed."

converter.py unit test fail : testFreezer

def testFreezer(self):
    from music21 import stream, note, corpus, freezeThaw
    s = stream.Stream()
    n = note.Note()
    s.append(n)

    s = corpus.parse('bach')

    aConverter = freezeThaw.StreamFreezer(s)
    fp = aConverter.write()

    aConverter.openPickle(fp)
    #aConverter.stream
    aConverter.stream.show()

shows the following error:

ERROR: testFreezer (music21.converter.TestExternal)

Traceback (most recent call last):
File "C:\Users\Michael\git\music21\music21\converter.py", line 1255, in testFreezer
aConverter.openPickle(fp)
AttributeError: 'StreamFreezer' object has no attribute 'openPickle'

Open a MIDI file with more than 16 tracks, read it, write it back -> no notes in file.

When I open a midi file with more than 16 tracks, it reads them all into one track (each track is considered a channel), and events from every track whose number was larger than 16 becomes channel=None, which I suspect is causing a MIDI reading/writing malfunction.

Shouldn't each track be their own MidiTrack, and event's channel should be according to MIDI channel (and not track)? This would probably solve the issue.

Here's the code I tested this with:

parsed_midi = music21.midi.MidiFile()
parsed_midi.open("file.mid", "rb")
parsed_midi.read()
parsed_midi.close()
parsed_midi.open("file.mid", "wb")
parsed_midi.write()
parsed_midi.close()

(works quite well with midi files with less than 16 tracks, doesn't work for midi files with more)

"musicxml.png" Output Format Shouldn't Exist

As reported here and here, music21 sometimes tries to use a perhaps-non-existent "musicxml.png" output format.

I would like to help work toward resolving this, but the lack of documentation and of developer feedback are real impediments in this case.

check sorting of concatenated elements found in _endElements

We need to store an additional flag in the location object to say that an object is an _endElement. Here's why: say we have two streams, the first contains a lot of notes and then in _endElements we put a keySignature and then a repeatBarline. Stream 2 begins with a clef change and then notes. If we create a new stream (S0) that contains S1 + S2 and then do S0.flat, the autosort will put the clef before the keySignature change (and probably also before the repeat sign). So I'd like it that elements in the _endElements list sort before elements in the following stream. I don't think it'd be too hard. One simple way is to add a huge negative number to the sort priority for all _endElements.

braille: multiple consecutive whole measure rests

What steps will reproduce the problem?

from music21 import *
p = stream.Part()
for _ in range(8):
r1 = note.Rest()
r1.duration.type='whole'
p.append(r1)
p.show('braille')

What is the expected output?

⠀⠀⠼⠙⠲⠀⠀⠀
⠼⠁⠀⠼⠓⠍⠣⠅

What do you see instead?

⠀⠀⠀⠀⠀⠀⠀⠀⠼⠙⠲⠀⠀⠀⠀⠀⠀⠀⠀⠀

⠼⠁⠀⠍⠀⠶⠀⠶⠀⠶⠀⠶⠀⠶⠀⠶⠀⠍⠣⠅

What version of the product are you using?

svn trunk

On what operating system?

Debian GNU/Linux

Please provide any additional information below.

Multiple consecutive whole measure rests can and should be transcribed
in a more concise way. Except for when we are doing bar-over-bar,
two consecutive whole measure rests should simply be written as ⠍⠍, and
more then two consecutive whole measure rests are written with a number
sign (⠼) followed by the number of rests (in our case ⠓ which means 8)
followed by the whole-rest sign (⠍).

This device is especially useful in music with several parts, or if a particular
instrument has a few measures rest. It is not possible to use in
bar-over-bar format of course, but that should not be used for a single
part like in our example above anyway.

Give Value Distinctions for ambiguous Braille

  1. from music21 import *
  2. ambiguous = converter.parse("tinynotation: 4/4 C2 D4.. C32 C")
  3. print braille.translate.objectToBraille(ambiguous)

What is the expected output?

⠀⠀⠀⠀⠼⠙⠲⠀⠀⠀⠀⠀
⠼⠁⠀⠸⠝⠱⠄⠄⠠⠣⠂⠝⠝⠣⠅

or

⠀⠀⠀⠀⠼⠙⠲⠀⠀⠀⠀⠀
⠼⠁⠀⠘⠣⠂⠸⠝⠱⠄⠄⠝⠝⠣⠅

What do you see instead?

⠀⠀⠀⠀⠼⠙⠲⠀⠀⠀⠀⠀
⠼⠁⠀⠸⠝⠱⠄⠄⠝⠝⠣⠅

Please provide any additional information below.

Braille music note and rest values are inherently ambiguous. The dot pattern
for a whole note can also mean a 16th note, a half note/rest can also mean a
32th note/rest and so on. When a measure contains values like half and 32th,
value distinction signs need to be added in appropriate places to make
the values of all notes/rests clear to the reader.

In our example above, currently, the reader has absolutely no idea which of
the three C notes is the half note, and which are the 32ths. The time signature
implies that one of them must be a half, but it is not possible to know which.

Note that there are possibly several solutions to a particular value ambiguity.
The shortest and most clear version should be choosen automatically.

bad durations from haydn musedata file

I noticed some "incomplete bars" in the Haydn op17no1 string quartet, including the first bar of the first violin. This is a zipped musescore file; the beginning of the violin part contains:

4 1
110 4 192 48
4 4 0 1 13
measure 0
rest168
G#4  24
measure 1

However, music21 is coming up with a duration of 17/12 for the first note. I tracked it down to music21/musedata/__init__.py , which around line 282 contains:

    if self.stage == 1:
        divisions = int(self.src[5:7])
    else:
        divisions = int(self.src[5:8])

It's taking the stage==1 option, thereby only getting "68" instead of "168" due to a (maybe?) missing space in "rest168". I'm not sufficiently familiar with musescore to judge the correct solution. Superficially, it appears to work if I change self.src[5:7] to self.src[4:7], but I'm not certain if that would break other stuff.

Personally, I'd be tempted to convert all the old formats to musicxml and junk the old files. But I think the philosophy of music21 might lean more towards making the converters work for all the different datatypes, in which case it would be better to tackle the case of stage1 musescore files containing 3-digit durations. (or, potentially, figuring out why this file isn't detected as stage2, if that's what it's supposed to be?)

PS: when testing any changes to the converter code, note that music21 caches input files. I deleted /tmp/music21/ between each time I added debug info to musescore/__init.py__

converter.py unit test fail : testMusicXMLConversion

def testMusicXMLConversion(self):
    from music21.musicxml import testFiles
    mxString = testFiles.ALL[1] # @UndefinedVariable
    a = ConverterMusicXML()
    a.parseData(mxString)

shows the following error:

ERROR: testMusicXMLConversion (music21.converter.TestExternal)

Traceback (most recent call last):
File "C:\Users\Michael\git\music21\music21\converter.py", line 1216, in testMusicXMLConversion
a = ConverterMusicXML()
TypeError: init() takes exactly 2 arguments (1 given)

Tracking Bug for "the lilypondFormat is not yet consulted"

As of svn revision 3647...

The TODO in base.py:L3439 ("the lilypondFormat is not yet consulted").

This is a tracking bug, to help interested parties know when the task is finished, or to encourage community members to contribute a fix.

Instrument Context gives better implicit octaves.

defaultOctave eventually should be able to get its value from context -- so clefs and/or instruments might have defaultOctaves (so that piccoloPart.append(Chord([3,4,5]) would append different implicitOctaves as tubaPart.append(Chord([3,4,5])) -- it's a long way off, but something to think about).

Remove Note subclasses QuarterNote, HalfNote, etc. OR exempt from full docs.

these were useful for testing and documenting in early stages because we did not have the ability to do:

n = note.Note('C4', type='half')

I love the way that this looks:

n = note.HalfNote('C4')

but realistically, they clutter the documentation, occasionally make conversions fail, and don't fit well with our model for objects as well. I'd also be okay with just exempting them from documentation and putting them in a single explanation in the docs.

No information how to run the tests

I couldn't find any info on how to run the tests in the repository. It would be helpful to mention this in the toplevel README file. Alternatively (or even better in addition) this could be mentioned in the Developer Reference section of the documentation. It may also be useful to have some quick guidelines in that section on how to write new tests and where they should be added.

Crash when loading an MXL file with a percussion track

Migrated from GoogleCode

Reported by stefaan.himpe, Jan 2, 2013
What steps will reproduce the problem?
load the file from attachment using converter.parse

What is the expected output? What do you see instead?
I get a crash with the following backtrace:
File "MusicTransforms.py", line 88, in
s = converter.parse('styles/basic/major.mxl')
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/converter.py", line 1076, in parse
return parseFile(value, number=number, format=m21Format, forceSource=forceSource)
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/converter.py", line 977, in parseFile
v.parseFile(fp, number=number, format=format, forceSource=forceSource)
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/converter.py", line 803, in parseFile
self._converter.parseFile(fp, number=number)
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/converter.py", line 502, in parseFile
self.load()
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/converter.py", line 399, in load
fromMxObjects.mxToScore(self._mxScore, inputM21 = self._stream)
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/musicxml/fromMxObjects.py", line 2570, in mxToScore
spannerBundle=spannerBundle, inputM21=s)
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/musicxml/fromMxObjects.py", line 2331, in mxToStreamPart
mxPart = mxScore.getPart(partId)
File "/usr/local/lib/python2.7/dist-packages/music21-1.3.0-py2.7.egg/music21/musicxml/base.py", line 852, in getPart
raise MusicXMLException('could not find id %s in Score' % partId)
music21.musicxml.base.MusicXMLException: could not find id P4 in Score

What version of the product are you using? On what operating system?
latest SVN on debian sid

Please provide any additional information below.
As far as I can tell, the problem is caused by an unsupported tag in the musicxml file (this tag is not defined anywhere in music21/musicxml/base.py). This causes c.score to contain only information about parts P1-P3. The mxl file was created in MuseScore.

MusicXML PNG: explanation of Environment Keys

When outputting to PNG, I get the EnvironmentException raised in environment.py:L685. It's because there's no environmentKey set for "musicxml.png". That's easy to solve by inserting an "elif" clause around line 648.

For that matter, I'm not clear why there's a "musicxml.png" format at all, and especially why LilyPond outputs to that format. A few comments around common.fileExtensions (lines 32 to 57) would be helpful for that reason. Maybe a brief description of how music21 uses each format.

I wondered which environment setting it should use---probably graphicsPath? Maybe, but I have graphicsPath set to "gimp" so maybe at some point something said it should be a graphics editing application? The environment module's documentation doesn't say what any of the settings are for, so it's hard to know.

windowed display on large windows

Analysis.discrete and windowed:

Very large scores, when used for windowed displayed, create useless output.

We can set a maximum windows size scale to make such diagrams useful. 200 windows seems like a good max.

Improved Filetype Detection

I suspect we can offer more robust and reliable filetype detection in music21. This work falls out of my efforts with the MEI-importing module, but it requires changes to the Converter class, so I'm filing it separately. Note that any decision here does not affect the viability of the MEI module.

My goals are two-fold: firstly to provide a consistent and helpful error message when a file's type cannot be detected; secondly to reduce the attack surface available to maliciously-constructed files, for those of us who use music21 on public Web servers. Currently, trying to import a MusicXML file that ends with ".krn" (for example) results in a puzzling error message.

I uploaded a proof-of-concept to the "dev_converter" branch of the ELVIS fork of music21: ELVIS-Project/music21@1ea9970. This solution accomplishes my two goals, except for people using music21 on a Windows-based Web server. On the other hand, this solution relies on a shell program (undesirable but not a show-stopper), works significantly less well on Windows (likewise undesirable but not a show-stopper), and does not take advantage of the filename extensions that are registered by SubConverter modules.

Ideally, I'd like to use the SubConverter-registered file extensions, add SubConverter-registered MIME-types, and use a built-in Python strategy for MIME-type detection. I'm particularly unsure how to solve the last problem.

I welcome all comments or criticism, including if this is actually an undesirable change. Thank you!

Import/Export as MEI

MEI is, or at least should be, the future of symbolic music notation file formats. MEI import/export in music21 would be a "big win" both for MEI and music21.

Though admittedly difficult because of the extensive features the format offers, MEI files would probably be able to save all the data music21 might attach to a Score.

We'll need to use the Python bindings for libmei:
https://github.com/DDMAL/libmei

runThroughLilyPond() Uses Hardcoded Backend

In lily.translate:L2320, the createPNG() method uses a hardcoded "eps" backend, which doesn't make sense to me, since the LilyPond documentationhttp://lilypond.org/doc/v2.16/Documentation/usage/command_002dline-usage#advanced-command-line-options-for-lilypondsays "png" output format implies "ps" backend, which makes that seem like a default.[1] Looks like that's because you append all the systems in a single, large image file, but (A) it's unexpected for there to be only one page and for you to change the inter-system spacing, so an admonition in the documentation would be helpful. Also, what about users who prefer the default PNG-format output from LilyPond? This should be the default behaviour, and music21 should optionally append all systems into one file---behaviour that is indeed useful in many situations.

All the calls to runThroughLilyPond() (lines 2298, 2329, 2385) should use the "lilypondBackend" environment setting rather than hardcoded "backend" arguments. If "lilypondBackend" is ignored for some of the output formats (like "png in one file"), this should be noted in the documentation.

Allow measures to be inside voices in addition to the current vice-versa

Support conversions, or display warnings, for Voices defined outside of Measures, instead of the expected (reversed) arrangement.

Explanation -- it's musically logical to think of a part with a voice and then that voice is divided by measures rather than the music21 default of part -> measure -> voice. Support an easy conversion between one and another. Important for extracting say Trombone 2 from a part. etc.

Not a high priority since musicxml does not support this and conversion in other formats (humdrum, etc.) is easy. But it's important for music21 to allow for most conceptually logical arrangements or at least provide a way to converting from them before showing.

Humdrum metadata not appearing as music21 metadata

Reported by craigsapp, Apr 2, 2013
What steps will reproduce the problem?

from music21 import *
jos0303e = converter.parse('http://jrp.ccarh.org/cgi-bin/jrp?a=humdrum&f=Jos0303e', format='humdrum')
jos0303e.show()

What is the expected output? What do you see instead?

I expect to see the title of a work when it is exported via MusicXML into Finale. Instead, I see Music21 Fragment" as the title. Also I expect to see the composer's name on the right-hand side of the first system, but I instead see "Music21".

What version of the product are you using? On what operating system?

Using OS X 10.8.3; Python 2.7.2; Music21 v. 1.5.0; Finale 2012c.r13

Please provide any additional information below.

It would be useful to display the composer and title of a work when displayed in Finale via MusicXML output from Music21. Currently the title is set to "Music21 Fragment" and the composer is set to "Music21". See the attached PNG image for the visual display of the example work Jos0303e.krn.

More preferable would be to preserve the title and composer information within the converted data structure, and this information would be inserted into the appropriate location in the MusicXML file being sent to Finale for display. The MusicXML output from Music21 has this sort of title:

Music21 Fragment

In the Humdrum file, the title has this form:
!!!OTL: Title goes here
Where the line starts with !!!OTL: and is followed by the text for the title (no linebreaks). The title can be displayed in multiple languages. In that case choose the first OTL entry in the file as the title to display. For example in this Bach chorale:

http://kern.humdrum.org/data?l=371chorales&f=chor001.krn

There are two titles:

!!!OTL@@de: Aus meines Herzens Grunde
!!!OTL@EN: From the Depths of My Heart

The one which should be displayed is "Aus meines Herzens Grunde" since it is first. It is also the in the primary language due to the two @ signs, but this should not be the reason to choose it as the title.

Also, I use HTML entity encoding for accented characters in Humdrum reference records, so it would be useful to parse these to get the correct accented characters. For example the work:

http://kern.ccarh.org/ksdata?l=371chorales&file=chor172.krn

Has the title reference record:
!!!OTL@@de: Sei gegrüßet, Jesu gütig
which should be rendered as:
Sei gegrüßet, Jesu gütig

Another consideration is that there are two levels of title information in Humdrum:

!!!OPR: title of the parent work
!!!OTL: title of the work

Just displaying the OTL entry is fine, but maybe a more advanced system would display two lines for the title. When both OPR and OTL are present in the data, then display OPR on a line followed by OTL underneath it.

Currently the composer field in the MusicXML export from Music21 is:

 <identification>
    <creator type="composer">Music21</creator>
  </identification>

For the composer in Humdrum files, there is a reference record in this form:
!!!COM: composer's name
If there is a comma in the composer's name, then the display of the name should be flipped at that comma. For example:
!!!COM: Bach, Johann Sebastian
should be displayed as
Johann Sebastian Bach
or for a more parsimonious display, perhaps:
J.S. Bach

There is also an attributed composer:
!!!COA: An attributed composer's name
This should be used if there is no !!!COM: reference record. If there are both COM and COA entries, then display only the first one. There may be two or more COM/COA entries:
!!!COM1: Composer one's name
!!!COM2: composer two's name
In this case the !!!COM1: composer should be displayed.

For even fancier display, the catalog or opus number of a work could be displayed underneath the composer's name. For example Bach BWV numbers can be extracted from the !!!SCT: reference record:

!!!COM: Bach, Johann Sebastian
!!!SCT: BWV 410

Which would be displayed on the right side of the first system as:
J.S. Bach
BWV 410

(I don't know if this can be done in MusicXML/Finale without much hacking -- perhaps by putting a newline in the composer entry).

If there is no scholarly catalog number in an !!!SCT: reference record, then it would be useful of the Opus were displayed underneath the composer. The opus number is stored in an !!!OPS: record, while the sub-opus number is stored in !!!ONM:

For example:
!!!OPS: op. 59
!!!ONM: no. 3
would be displayed underneath the composer as
op. 59, no. 3
If the OPS or ONM contains only a number with no text for "op." or "no.", then it would be useful to add it.

I have not tested the following yet, but the copyright notice at the bottom of the page in Finale display should display the contents of a !!!YEC: reference record in the Humdrum file if it is present in the original data.
screen shot 2013-04-02 at 7 37 27 pm

Suspended Chord in MusicXML

Reported by Alex.Bluk, Jul 25, 2013
What steps will reproduce the problem?

  1. Create a sus add 9 symbolic chord

f = harmony.ChordSymbol('Fsus add 9')

  1. write it

f.show()

Returns a error:

Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/IPython/core/interactiveshell.py", line 2731, in run_code
exec code_obj in self.user_global_ns, self.user_ns
File "", line 1, in
f.show()
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/base.py", line 3432, in show
returnedFilePath = self.write(fileFormat)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/base.py", line 3269, in write
dataStr = m21ToString.fromMusic21Object(self)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/m21ToString.py", line 56, in fromMusic21Object
return fromGeneralNote(m21Object)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/m21ToString.py", line 280, in fromGeneralNote
return fromMusic21Object(out)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/m21ToString.py", line 54, in fromMusic21Object
return fromStream(m21Object)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/m21ToString.py", line 81, in fromStream
mxScore = toMxObjects.streamToMx(post)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/toMxObjects.py", line 2305, in streamToMx
spannerBundle=spannerBundle)
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/toMxObjects.py", line 2164, in streamPartToMx
mxTranspose=mxTranspose))
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/toMxObjects.py", line 1950, in measureToMx
mxMeasure.componentList.append(chordSymbolToMx(obj))
File "/Library/Python/2.7/site-packages/music21-1.5.0-py2.7.egg/music21/musicxml/toMxObjects.py", line 954, in chordSymbolToMx
mxDegreeType.set('charData', hd.type)
AttributeError: 'ChordStepModification' object has no attribute 'type'

What version of the product are you using? On what operating system?

SVN version revision 3518

References to grace notes in Slurs are incomplete

Reported by bret.aarden, Jun 25, 2012

Hello,

I just stumbled upon an interesting behavior: references to grace notes in slurs seem to be incomplete. In "mozart/k458/movement3.mxl", for instance, m. 53 has slurs from grace notes to eighth notes. In the slur spanners the eighth notes have intact DefinedContexts, but the grace notes have lost the references to their containing measures. The copies in the slurs also no longer think they're grace notes. Regular notes in the same slur have no such problem. (I first spotted this in the first movement, which has slurs between two grace notes, and in that case both grace notes are afflicted.)

s=corpus.parse('mozart/k458/movement3.mxl')
s[1][167]
<music21.stream.Measure 53 offset=208.0>
s[1][167][1]
<music21.note.Note G>
s[1][167][1].isGrace
True
s[1][167][1].getSites()
[None, <music21.stream.SpannerStorage 4344967056>, <music21.stream.Measure 53 offset=208.0>]
s[1][112]
<music21.spanner.Slur <music21.note.Note G><music21.note.Note F>>
s[1][112][0].isGrace
False
s[1][112][0].getSites()
[None, <music21.stream.SpannerStorage 4344967056>]
s[1][112][1].getSites()
[None, <music21.stream.SpannerStorage 4344967056>, <music21.stream.Measure 53 offset=208.0>]

I'm using v.1.0 on MacOS 10.7 with Python 2.7.

No big problem, now that I know to check for this behavior, but I wanted to bring it to your attention.

Cheers,
-Bret.

LilyPond Backend Selection Doesn't Work

I'm having problems with backend selection. In lily.translate:L182, there's a note: "I had a note that said 2.12 and > should use self.backendString = '--formats=' but doesn't seem true." Indeed that's not true, because output format and backend are distinct. For the if/else statements just above (lines 175--81), the "if self.minorVersion >= 11" statement doesn't make sense because 2.11 was the development series for 2.12, meaning (A) there are probably some 2.11 releases with the old behaviour, and (B) nobody should be using 2.11.x in a production environment anyway.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.