-
-
Notifications
You must be signed in to change notification settings - Fork 110
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
[wip] Supporting more midi messages in MidiDrop plugin #1399
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
#include <Midi/MidiNote.hpp> | ||
#include <Process/Drop/ProcessDropHandler.hpp> | ||
#include <Process/TimeValue.hpp> | ||
#include <mpark/variant.hpp> | ||
namespace Midi | ||
{ | ||
|
||
|
@@ -18,12 +19,113 @@ class DropHandler final : public Process::ProcessDropHandler | |
const score::DocumentContext& ctx) const noexcept override; | ||
}; | ||
|
||
struct PitchbendData{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MAybe all of these could go into a more general Midi.hpp ... or, I wonder if it wouldn't be best in libremidi, and then try to consume those directly ? not sure... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the suggestion, I'll start moving it soon then, please let me know what makes most sense. I was going with MidiTrackEvent as type name (which is the core object along MidiNote which has "pointers" to optional? pair), and considering a "domain" folder: /domain/MidiNote.hpp moving the current one Do you like this? |
||
int16_t bend; | ||
}; | ||
struct ControllerData { | ||
midi_size_t channel; | ||
midi_size_t number; | ||
midi_size_t value; | ||
static ControllerData make_cc(const midi_size_t channel, const midi_size_t controller, const midi_size_t value) | ||
{ | ||
SCORE_ASSERT(channel >= 0 && channel < 16); | ||
return ControllerData{channel, controller, value}; | ||
} | ||
}; | ||
|
||
struct NoteOnData { | ||
midi_size_t channel; | ||
midi_size_t note; | ||
midi_size_t velocity; | ||
}; | ||
struct NoteOffData { | ||
midi_size_t channel; | ||
midi_size_t note; | ||
midi_size_t velocity; | ||
}; | ||
struct MidiTrackEvent { | ||
static MidiTrackEvent make_note_off(const double start, const midi_size_t ch, const midi_size_t n, const midi_size_t v){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these functions look a lot like the ones in libremidi, maybe it should go there ? |
||
return MidiTrackEvent{.m_start = start, .m_message = Midi::NoteOffData{.channel = ch, .note = n, .velocity = v}}; | ||
} | ||
static MidiTrackEvent make_note_on(const double start, const midi_size_t ch, const midi_size_t n, const midi_size_t v){ | ||
return MidiTrackEvent{.m_start = start, .m_message = Midi::NoteOnData{.channel = ch, .note = n, .velocity = v}}; | ||
} | ||
double m_start{}; | ||
|
||
void setStart(const double start){ m_start = start; } | ||
const double start(){return m_start; } | ||
mpark::variant<Midi::NoteOnData, Midi::NoteOffData, Midi::ControllerData,Midi::PitchbendData> m_message; | ||
}; | ||
|
||
struct MidiTrackEvents { | ||
void push_back(double delta, int tick, double total, Midi::ControllerData c){ | ||
smoothdeveloper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const double start = delta * (tick / total); | ||
trackEvents.push_back(MidiTrackEvent{.m_start = start, .m_message = c}); | ||
} | ||
|
||
void push_back(double delta, int tick, double total, Midi::NoteOnData n){ | ||
const double start = delta * (tick / total); | ||
trackEvents.push_back(MidiTrackEvent{.m_start = start, .m_message = n}); | ||
} | ||
|
||
void push_back(double delta, int tick, double total, Midi::NoteOffData n){ | ||
const double start = delta * (tick / total); | ||
trackEvents.push_back(MidiTrackEvent{.m_start = start, .m_message = n}); | ||
} | ||
|
||
void apply_scale_ratio(const double ratio){ | ||
for (auto& event : trackEvents) | ||
{ | ||
event.setStart(ratio * event.start()); | ||
} | ||
} | ||
auto size() const { return trackEvents.size(); } | ||
std::vector<Midi::MidiTrackEvent> trackEvents; | ||
}; | ||
|
||
struct MidiTrackNotes { | ||
using pitch = int; | ||
std::vector<Midi::NoteData> notes; | ||
pitch min{127}, max{0}; | ||
pitch minimum_pitch_noticed() const { return min; } | ||
pitch maximum_pitch_noticed() const { return max; } | ||
void append(Midi::NoteData note){ | ||
notes.push_back(note); | ||
} | ||
|
||
void notice_pitch(int pitch){ | ||
if (pitch < min) { | ||
min = pitch; | ||
} | ||
else if (pitch > max) { | ||
max = pitch; | ||
} | ||
} | ||
auto begin() { return notes.begin(); } | ||
auto end() { return notes.end(); } | ||
auto cbegin() const { return notes.begin(); } | ||
auto cend() const { return notes.end(); } | ||
auto begin() const { return notes.begin(); } | ||
auto end() const { return notes.end(); } | ||
|
||
auto size() const { return notes.size(); } | ||
auto empty() const { return notes.empty(); } | ||
void apply_scale_ratio(const double ratio){ | ||
for (auto& note : notes) | ||
{ | ||
note.setStart(ratio * note.start()); | ||
note.setDuration(ratio * note.duration()); | ||
} | ||
} | ||
}; | ||
|
||
|
||
struct MidiTrack | ||
{ | ||
QString name; | ||
|
||
std::vector<Midi::NoteData> notes; | ||
int min{127}, max{0}; | ||
MidiTrackNotes notes; | ||
MidiTrackEvents trackEvents; | ||
|
||
struct MidiSong | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍