Music21 Midi Error: type object '_io.StringIO' has no attribute 'StringIO'. How to fix it?

9.9k views Asked by At

So, I've followed this question in order to get some sound playing with Music21, and here's the code:

from music21 import *
import random

def main():

#  Set up a detuned piano 
#  (where each key has a random 
#  but consistent detuning from 30 cents flat to sharp)
#  and play a Bach Chorale on it in real time.


    keyDetune = []
    for i in range(0, 127):
        keyDetune.append(random.randint(-30, 30))

    b = corpus.parse('bach/bwv66.6')
    for n in b.flat.notes:
        n.microtone = keyDetune[n.midi]
    sp = midi.realtime.StreamPlayer(b)
    sp.play()

    return 0

if __name__ == '__main__':

    main()

And here's the traceback:

Traceback (most recent call last):
  File "main.py", line 49, in <module>
    main()
  File "main.py", line 44, in main
    sp.play()
  File "G:\Development\Python Development\Anaconda3\lib\site-packages\music21\mi
di\realtime.py", line 104, in play
    streamStringIOFile = self.getStringIOFile()
  File "G:\Development\Python Development\Anaconda3\lib\site-packages\music21\mi
di\realtime.py", line 110, in getStringIOFile
    return stringIOModule.StringIO(streamMidiWritten)
AttributeError: type object '_io.StringIO' has no attribute 'StringIO'
Press any key to continue . . .

I'm running Python 3.4 x86 (Anaconda Distribution) on Windows 7 x64. I have no idea on how to fix this (But probably is some obscure Python 2.x to Python 3.x incompatibility issue, as always)

EDIT:

I've edited the import as suggested in the answer, and now I got a TypeError:

enter image description here

What would you recommend me to do as an alternative to "play some audio" with Music21? (Fluidsynth or whatever, anything).

2

There are 2 answers

4
SiHa On BEST ANSWER

You may be right... I think the error may actually be in Music21, with the way it handles importing StringIO

Python 2 has StringIO.StringIO, whereas

Python 3 has io.StringIO

..but if you look at the import statement in music21\midi\realtime.py

try:
    import cStringIO as stringIOModule
except ImportError:
    try:
        import StringIO as stringIOModule
    except ImportError:
        from io import StringIO as stringIOModule

The last line is importing io.StringIO, and so later on the call to stringIOModule.StringIO() fails because it's actually calling io.StringIO.StringIO.

I would try to edit the import statement to:

    except ImportError:
        import io as stringIOModule

And see if that fixes it.

0
Cool J On

return stringIOModule.StringIO(streamMidiWritten) AttributeError: type object '_io.StringIO' has no attribute 'StringIO' Press any key to continue . . .

Please @Ericsson, just remove the StringIO from the return value and you are good to go.

It will now be: return stringIOModule(streamMidiWritten)