Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all notes example from the README not working #256

Closed
Phibonacci opened this issue May 13, 2023 · 9 comments
Closed

Remove all notes example from the README not working #256

Phibonacci opened this issue May 13, 2023 · 9 comments
Labels
bug Bug in the library in-prerelease API changes are in prerelease package for the milestone
Projects
Milestone

Comments

@Phibonacci
Copy link

Phibonacci commented May 13, 2023

I am looking to remove all the notes from each chords but the first one, for each track. To get started I tried the following example from the README that is supposed to remove absolutely all notes from the midi.

using Melanchall.DryWetMidi.Core;
using Melanchall.DryWetMidi.Interaction;

var midiFile = MidiFile.Read("myfile.mid");
foreach (var trackChunk in midiFile.GetTrackChunks())
{
    using (var notesManager = trackChunk.ManageNotes())
    {
        notesManager.Notes.RemoveAll(n => n.NoteName == NoteName.CSharp);
    }
}

notesManager.Notes does not exist.

error CS1061: 'TimedObjectsManager' does not contain a definition for 'Notes' and no accessible extension method 'Notes' accepting a first argument of type 'TimedObjectsManager' could be found (are you missing a using directive or an assembly reference?)

@melanchall
Copy link
Owner

Hi,

Thank you, I'll fix the example. You just need to use notesManager.Objects.

@Phibonacci
Copy link
Author

Thanks for your quick answer.

I looked at the ManageNotes extension but then I get an IEnumerable that cannot be modified.

@melanchall
Copy link
Owner

I looked at the ManageNotes extension but then I get an IEnumerable that cannot be modified.

Where? What code? Please provide details.

@melanchall melanchall added the question Just question about the library label May 13, 2023
@melanchall melanchall added this to To do in DryWetMIDI via automation May 13, 2023
@melanchall melanchall added this to the 7.0.0 milestone May 13, 2023
@Phibonacci
Copy link
Author

Phibonacci commented May 14, 2023

After going through the library I found a method to update the chords. I thought this would allow me to remove all notes from each chord but the first one, on all tracks.

using Melanchall.DryWetMidi.Core;
using Melanchall.DryWetMidi.Interaction;

var midiFile = MidiFile.Read("in.mid");
foreach (var trackChunk in midiFile.GetTrackChunks())
{
    trackChunk.ProcessChords(TrimChord);
}
midiFile.Write("out.mid");

void TrimChord(Chord chord)
{
    chord.Notes.RemoveAll(x => x != chord.Notes.First());
}

But the output file is identical to the input one.

I'm guessing the ProcessChords is making copies of the chords. How can I edit them instead?

@Phibonacci
Copy link
Author

Phibonacci commented May 14, 2023

This worked.

using Melanchall.DryWetMidi.Core;
using Melanchall.DryWetMidi.Interaction;

var midiFile = MidiFile.Read("in.mid");
foreach (var trackChunk in midiFile.GetTrackChunks())
{
    var newChords = new List<Chord>();
    foreach (var chord in trackChunk.GetChords())
    {
        var higherNote = FindHigherNote(chord.Notes);
        chord.Notes.RemoveAll(x => x != higherNote);
        newChords.Add(chord);
    }
    trackChunk.RemoveChords();
    trackChunk.AddObjects(newChords);
}

Note? FindHigherNote(TimedObjectsCollection<Note> notes)
{
    var higherNote = notes.First();
    foreach (var note in notes)
    {
        if (higherNote.GetMusicTheoryNote().CompareTo(note.GetMusicTheoryNote()) < 0)
        {
            higherNote = note;
        }
    }
    return higherNote;
}

midiFile.Write("out.mid");

@melanchall
Copy link
Owner

I'm guessing the ProcessChords is making copies of the chords. How can I edit them instead?

That's correct. But the file should be updated. Hmm, it's probably a bug in the library. I'll check it. Please don't close the issue.

@melanchall melanchall added the unconfirmed bug Possible bug in the library, can't check label May 14, 2023
@melanchall melanchall moved this from To do to In progress in DryWetMIDI May 14, 2023
@melanchall
Copy link
Owner

melanchall commented May 15, 2023

Yes, that's the bug. I'll think how to support chord's notes collection changes within ProcessChords methods.

@melanchall melanchall added bug Bug in the library and removed unconfirmed bug Possible bug in the library, can't check question Just question about the library labels May 15, 2023
melanchall added a commit that referenced this issue May 20, 2023
@melanchall
Copy link
Owner

I've released DryWetMIDI 7.0.0-prerelease2 which introduces ChordProcessingHint parameter in ProcessChords methods. So now for your task you can use this code:

midiFile.ProcessChords(
    chord => 
    {
        var higherNote = FindHigherNote(chord.Notes);
        chord.Notes.RemoveAll(x => x != higherNote);
    },
    hint: ChordProcessingHint.NotesCollectionCanBeChanged);

Thanks for the issue!

@melanchall melanchall added the in-prerelease API changes are in prerelease package for the milestone label May 20, 2023
@melanchall
Copy link
Owner

🚀 7.0.0 version is released now!

Prerelease NuGet packages will be unlisted soon, so please update the package references to the new version.

DryWetMIDI automation moved this from In progress to Done Jun 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug in the library in-prerelease API changes are in prerelease package for the milestone
Projects
DryWetMIDI
  
Done
Development

No branches or pull requests

2 participants