3

I am struggling to understand why the below code is throwing an error when it ran seamlessly about a year back. The code snippet is from a popular Coursera course. Does the Music21 package has some recent changes around stream.Voice?

data_fn = 'data/original_metheny.mid'
midi_data = converter.parse(data_fn)
melody_stream = midi_data[5] # For Metheny piece, Melody is Part #5.
melody1, melody2 = melody_stream.getElementsByClass(stream.Voice)

The error thrown is ValueError: not enough values to unpack (expected 2, got 0), which means there is no output for stream.Voice class when previously there were outputs for the same data (midi file). melody_stream.getElementsByClass('Measure') does show outputs.

Can you guide how to debug this?

maamli
  • 65
  • 6

2 Answers2

4

What worked for me was downgrading music21 package to a version older than 7.x. So if you already have a newer version of music21 package installed, remove it using pip uninstall music21, Then install the 6.7.0 version using pip install music21==6.7.0.

Amir Zare
  • 453
  • 1
  • 4
  • 15
3

Yes, one of the improvements in music21 v.7 is that files imported from MIDI now have a similar representation to files imported from MusicXML and other formats. Specifically, Parts now have Measures, which may or may not have Voices, rather than Parts directly containing Voices. Code should not depend on finding Voices directly contained in Parts, which is what this example was doing.

Instead, use this code to find all the measure-voices:

melody_stream.recurse().getElementsByClass(stream.Voice)

Or, equivalently, use the shortcut syntax in v.7:

melody_stream[stream.Voice]

Or, if you don't want the measures at all, call flatten() or chordify() depending on your use case.

Jacob Walls
  • 873
  • 3
  • 15
  • I'm playing with the same example and made change as per your comment ---> 31 melody1, melody2 = melody_stream[stream.Voice]; 32 for j in melody2: 33 melody1.insert(j.offset, j) ValueError: too many values to unpack (expected 2) – Aditya Mittal Sep 02 '22 at 11:34
  • Line 29 in this file https://github.com/amanchadha/coursera-deep-learning-specialization/blob/master/C5%20-%20Sequence%20Models/Week%201/Jazz%20improvisation%20with%20LSTM/preprocess.py – Aditya Mittal Sep 02 '22 at 11:38
  • Ah, but you omitted the `.recurse()`. If you're not sure when to use `recurse()`, here's a mailing list post with a gentle introduction to nested streams and how to access them: https://groups.google.com/g/music21list/c/4zjsrZXkc2w/m/TjeTy1N1AQAJ – Jacob Walls Sep 03 '22 at 13:38