Closed mo-krautsalat closed 4 years ago
Hi,
Thanks for using the library!
Initially pattern API was designed as "construction-only". Can you clarify your case. Do you create a pattern and then want remove a note from it?
I have a project where the user can press buttons on a GUI to create something like a pattern. In the best-case it should work like a step sequencer. My pattern is one bar long with 16 beats in it. If the user presses a button, a note should be added to the pattern and the button toggles it state to "active". If the user presses an already "active" button again, the note related to the button should be removed from the pattern.
I also tried out the tracks API but couldn't mange to get it work properly. Maybe I should have a look at it again.
Thanks for the quick answer!
OK, I got it. I'll try to provide corresponding API as soon as possible. I suppose I'll implement it tomorrow (15 Feb).
I've added SetNotesState
extension method for Pattern
:
void SetNotesState(this Pattern pattern, NoteSelection noteSelection, PatternActionState state, bool recursive = true)
noteSelection
defines predicate to select notes to set state for. All required info about note (including note index) is passed. state
can be one of the following values:
Name | Description |
---|---|
Enabled |
Note will be exported |
Disabled |
Note will not be exported; rest of the same length will be exported |
Excluded |
Note will not be exported at all |
In your case I suppose you should select note by its index and use Enabled
/Disabled
state.
New API is in develop branch so if you want to try it right now please download sources and build the library by yourself. Waiting for your feedback :)
Wow, thank you very much for your effort! I will try it tomorrow and get back to you :)
I tried implementing it, by couldn't get the predicate thing for the note selection working. Somehow I can't wrap my head around it. Maybe you could help me (again)? Also I found no way to define the note index directly?
Here is the part of my code with the add/remove note functionality:
public void AddNote(int message)
{
var note = new Melanchall.DryWetMidi.Interaction.Note((SevenBitNumber)message);
patternBuilder.SetNoteLength(new BarBeatTicksTimeSpan(0, 1, 0));
patternBuilder.SetVelocity((SevenBitNumber)127);
patternBuilder.Note(note.GetMusicTheoryNote());
if (playback != null)
{
lastTime = playback.GetCurrentTime(TimeSpanType.BarBeatTicks);
playback.Dispose();
}
Playback();
}
public void RemoveNote(int message, long bar, long beat)
{
SevenBitNumber nNumber = (SevenBitNumber)message;
NoteDescriptor noteDesc = new NoteDescriptor(new Melanchall.DryWetMidi.Interaction.Note(nNumber).GetMusicTheoryNote(), (SevenBitNumber)127, new BarBeatTicksTimeSpan(0, 1, 0));
NoteSelection noteSelection = new NoteSelection(2, noteDesc);
patternBuilder.Build().SetNotesState(noteSelection, PatternActionState.Disabled);
if (playback != null)
{
playback.Dispose();
}
Playback();
}
Thanks!
Hi,
This line contains issues:
patternBuilder.Build().SetNotesState(noteSelection, PatternActionState.Disabled);
First of all, you don't need to create NoteDescriptor
. NoteSelection
is predicate, all values are passed to it by SetNotesState
, and you then decide whether note should be processed or not:
// Disable note with index 2
SetNotesState((index, descriptor) => index == 2, PatternActionState.Disabled);
Also there is another big problem. You call Build
and then SetNotesState
, but you don't save changed pattern! After you called Build
, you should save new pattern and use it for playback, and for calling SetNotesState
. I suppose Playback
method calls Build
again on patternBuilder
, but Build
creates new instance of Pattern
every time you call it so changes made with SetNotesState
are lost.
Also this code
var note = new Melanchall.DryWetMidi.Interaction.Note((SevenBitNumber)message);
patternBuilder.SetNoteLength(new BarBeatTicksTimeSpan(0, 1, 0));
patternBuilder.SetVelocity((SevenBitNumber)127);
patternBuilder.Note(note.GetMusicTheoryNote());
can be simplified.
You can get MusicTheory.Note
with this call:
Note.Get((SevenBitNumber)message)
without creating Interaction.Note
.
SetNoteLength
and SetVelocity
are global things. There is no need to call them again for every single note. Just call them once where you create PatternBuilder
. If you want to override these values for some notes, just use .Note
overloads with length
and velocity
parameters.
@mo-krautsalat Any news?
Ups, sorry. Yes I got it working the way I wanted!
Thank you very much for your help and effort :)
Hello, is there a way to remove a note from a pattern? Looked at the Docs and API but didn't find a solution.
Other than that I really enjoy working with your library.
Thanks in advance, Mo