basic-pitch icon indicating copy to clipboard operation
basic-pitch copied to clipboard

Output of one Piano cover is a MIDI with 62 instruments in MuseScore

Open kevinlinxc opened this issue 2 years ago • 11 comments

Hi, I input a cover of a piano song into the Python library, and opened the resulting MIDI file in MuseScore. This was the result: image Essentially, there were a few notes played by 62 different pianos, despite the original performance being played on 1.

Is this expected behaviour from basic-pitch? ~~Is it because I don't have the CUDA dependencies?~~ Installed CUDA and cuDNN.

If it is expected behaviour, I'm looking for some angles to attack this problem from on the MuseScore side and the Basic-Pitch side. Any help would be appreciated.

kevinlinxc avatar Jun 07 '22 02:06 kevinlinxc

Tried all of the following, unsuccessfully:

  1. Merging with Tools->Implode in Musescore (Does ~~nothing~~ barely anything): https://musescore.org/en/node/332630
  2. This Python script: https://github.com/m13253/midi-track-merge (Converted to 16 tracks, still not what I wanted, repeated uses leads to errors)
  3. Miditocsv, edit first column, csvtomidi: https://www.fourmilab.ch/webtools/midicsv (Didn't change anything, strangely)
  4. My own script to turn Basic Pitch's csv into a MIDI. Sounds decent, but timing is obviously off and I'm not sure how to calculate the proper time in beats from the given time in seconds. https://streamable.com/vkmahx
  5. This library and this code (does nothing)
  6. Pretty midi doesn't even seem to mention track anywhere

kevinlinxc avatar Jun 07 '22 06:06 kevinlinxc

I ended up getting to merge by modifying mido, the package behind pretty midi - still didn't look pretty, but it was on one track at least.

import os
import mido

mid = mido.MidiFile(os.path.join("outputs", "bakamitai_basic_pitch.mid"))
merged_track = mido.merge_tracks(mid.tracks)
new_midi= mido.MidiFile()
new_midi.tracks=[merged_track]
new_midi.save("merged.mid")

mido/midifiles/tracks.py:

def _to_abstime(messages):
    """Convert messages to absolute time."""
    now = 0
    for msg in messages:
        now += msg.time
        try:
            msg.channel = 1
        except:
            pass
        yield msg.copy(time=now)

The remaining problem is that MIDI -> sheet music has not come far enough yet. Not really anything can be done about that, unless I do grad school for machine learning. For this issue though, I'm still curious about if/how basic pitch could yield 1track.

kevinlinxc avatar Jun 07 '22 07:06 kevinlinxc

Hi @kevinlinxc ,

The short answer - on master the generated MIDI will be one single track, but we haven't pushed a new version to PyPi yet. We should have a new release in the next couple of days, but in the meantime, running the code from master should solve your problem.

The longer answer - basic pitch supports pitch bends per note, however MIDI 1.0 does not. We originally purposely generated midi with one "track" per unique frequency transcribed, so that each track could get note-level MIDI. However, as you've seen it's not very convenient for use in a DAW, so we've updated the default behavior to put all the MIDI in a single track, with an aggregated per-track pitch bend over time, rather than a per-note pitch bend. There's instead now an option to still export the note-level pitch bend data.

Hope this clears things up!

rabitt avatar Jun 09 '22 10:06 rabitt

Hi, I just tried using main (no master branch). I downloaded the zip, unzipped it, and then called my venv/Scripts/python setup.py install to install it. The output is still the same. The version number also still seems to be 0.0.1. Am I doing anything wrong?

kevinlinxc avatar Jun 11 '22 17:06 kevinlinxc

Thanks for this information, update and everyone's work on basic pitch. I had come to ask about the same topic and found this thread. Your web based version at spotify produced a very accurate sounding single track, while the command line version split the same audio sample out to about 30 tracks. I manually combined all those in to one within my daw, but the result didn't sound as accurate as the web based tool . I considered trying the repository, but in reading kevinglinxc's last message, I think I'll just look forward to the next version on PyPi if it will be coming soon.

Misfire2 avatar Jun 15 '22 23:06 Misfire2

I tried installing directly from GitHub and I'm facing the same issue. Dragging and dropping the MIDI file into Ableton Live creates a lot of MIDI tracks. MIDI output of the webapp only creates one track. When calling predict_and_save, I pass multiple_pitch_bends = False, melodia_trick = True. I assume that multiple_pitch_bends = False should avoid creating multiple tracks: https://github.com/spotify/basic-pitch/commit/cf15da3f7b8abeceeb00b5b82d7b985f07dd1bff#diff-ce098c38843d8c4c8ad03c2ce0105ed308a6a88dc4c505dff0de6ef4a40e9e24R221

neo-anderson avatar Jun 17 '22 00:06 neo-anderson

This eve I took a look at the repository diffs and pulled down the latest versions of inference, note_creation, and predict. I directly replaced those files in my module folder and now I'm now generating the same single track midi files that the webtool was providing. yay

Misfire2 avatar Jun 17 '22 23:06 Misfire2

@Misfire2 I followed your method, but I'm still getting multiple tracks in the output MIDI. I diffed the files and they're the same as the ones in the repo. Can you please share your command/function call? I noticed something just now. If I run basic-pitch via the terminal with command basic-pitch output_folder input.wav, I get a MIDI file with a single track. However, if I import and call the predict_and_save function in a python script, I get a MIDI file back with multiple tracks. I compared the arguments and they are the same and mostly just the defaults. Any clue?

neo-anderson avatar Jun 29 '22 01:06 neo-anderson

I'm working from a windows box and have only been using the command line option ... />basic-pitch output-folder input-file . From the start, even command line was giving me multiple tracks. Once I replaced the 3 files, command line produced just the single track. My setup might be slightly different than your because I originally installed the package from https://pypi.org/project/basic-pitch/ I didn't use the entire repository version, I only replace those 3 files while leaving the rest of the pypi package in place. I'm just a C++ guy and haven't delved deeper in to the code since I was getting the basic function I needed from command line.

Misfire2 avatar Jun 29 '22 17:06 Misfire2

Thanks. This is what worked for me. I deleted the conda environment, cleaned the cache, installed the package directly from Github with pip. Then, I called predict_and_save with multiple_pitch_bends = False and received a MIDI file with a single track 👍

neo-anderson avatar Jun 30 '22 00:06 neo-anderson

Just a quick update - we've updated the version on pypi, and starting from version 0.1.0 this problem should be solved.

rabitt avatar Jul 20 '22 15:07 rabitt