Search code examples
pythonjuliapython-importmusic21

Julia PyCall difficulties in running modules of Music21


I am a beginner having difficulties using Julia's PyCall to interface with the MIT Python music module music21.

According to Music21’s website, in order to display a short melody in musical notation one would type this in Python:

converter.parse("tinynotation: 3/4 c4 d8 f g16 a g f#").show()

Here is what I did to try and execute this code in Julia:

I first initialized music21, which seemed to work:

@pyimport music21
music21: Certain music21 functions might need these optional packages: matplotlib, scipy; if you run into errors, install them by following the instructions at http://mit.edu/music21/doc/installing/installAdditional.html

Then I tried to recreate the above Python example in Julia by typing:

converter.parse("tinynotation: 3/4 c4 d8 f g16 a g f#").show()

I received this error:
ERROR: UndefVarError: converter not defined
Stacktrace:
 [1] eval(::Module, ::Any) at ./boot.jl:235

UPDATE 1 According to rickhg12hs's suggestion, I attempted music21.converter.parse("tinynotation: 3/4 c4 d8 f g16 a g f#").show().

Now I am getting this error message on 'Parse': ERROR: type PyObject has no field parse Stacktrace: 1 eval(::Module, ::Any) at ./boot.jl:235

It seems like an improvement as it is now crashing a little later in the code chain, at 'Parse' instead of 'Converter'.

UPDATE 2 - FIXED This issue has to do with dot overloading. Based on this link, I tried modifying my code to look like this:

music21.converter[:parse]("tinynotation: 3/4 c4 d8 f g16 a g f#")[:show]()

but now I get this error

FSPathMakeRef(/Applications/MuseScore 2.app/Contents/MacOS/mscore) failed with error -43.

I discovered that the last thing I had to do was to download MuseScore and now the problem is fixed!

See @crstnbr's answer for more context on the ugliness of this solution and imminent fixes.

Many thanks! Nakul


Solution

  • I don't have the package installed (I'll test it in a second) but the following should work:

    @pyimport music21 as m
    m.converter[:parse]("tinynotation: 3/4 c4 d8 f g16 a g f#")[:show]() 
    

    Note that the arguably ugly (but systematic) [:fieldname] access will go away sometime soon in Julia 1.0 after my Pull request here gets merged. The reason for this syntax is that Julia didn't allow to override the . access functionality. This, fortunately, changed in Julia 1.0.