Skip to content

Commit

Permalink
Merge pull request #25080 from alexpavlov96/guitarbend_midi
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpavlov96 authored Oct 29, 2024
2 parents e881cf3 + ba73fb1 commit 8eb42bd
Show file tree
Hide file tree
Showing 57 changed files with 3,110 additions and 67 deletions.
59 changes: 45 additions & 14 deletions src/engraving/compat/midi/compatmidirender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "dom/navigate.h"

namespace mu::engraving {
static int slideTicks(const Chord* chord);
static int graceBendTicks(const Chord* chord);

void CompatMidiRender::renderScore(Score* score, EventsHolder& events, const CompatMidiRendererInternal::Context& ctx, bool expandRepeats)
{
score->masterScore()->setExpandRepeats(expandRepeats);
Expand Down Expand Up @@ -495,8 +498,8 @@ void CompatMidiRender::updateGateTime(const Instrument* instrument, int& gateTim

void CompatMidiRender::createGraceNotesPlayEvents(const Score* score, const Fraction& tick, Chord* chord, int& ontime, int& trailtime)
{
std::vector<Chord*> gnb = chord->graceNotesBefore();
std::vector<Chord*> gna = chord->graceNotesAfter();
std::vector<Chord*> gnb = chord->graceNotesBefore(true);
std::vector<Chord*> gna = chord->graceNotesAfter(true);
int nb = int(gnb.size());
int na = int(gna.size());
if (0 == nb + na) {
Expand Down Expand Up @@ -534,8 +537,12 @@ void CompatMidiRender::createGraceNotesPlayEvents(const Score* score, const Frac
// - the grace note duration as notated does not matter
//
Chord* graceChord = gnb[0];
const auto& graceNotes = graceChord->notes();
bool graceBend = std::any_of(graceNotes.begin(), graceNotes.end(), [](Note* note) {
return note->isGraceBendStart();
});

if (graceChord->noteType() == NoteType::ACCIACCATURA) {
if (graceChord->noteType() == NoteType::ACCIACCATURA || graceBend) {
ontime = 0;
graceDuration = 0;
weighta = 1.0;
Expand Down Expand Up @@ -932,7 +939,7 @@ void CompatMidiRender::createSlideOutNotePlayEvents(Note* note, NoteEventList* e
int slideOn = NoteEvent::NOTE_LENGTH - totalSlideDuration;
double velocity = !note->ghost() ? NoteEvent::DEFAULT_VELOCITY_MULTIPLIER : NoteEvent::GHOST_VELOCITY_MULTIPLIER;
if (!hasTremolo) {
el->push_back(NoteEvent(0, onTime, slideOn, velocity, !note->tieBack()));
el->push_back(NoteEvent(0, onTime, slideOn - onTime, velocity, !note->tieBack()));
}

int pitch = 0;
Expand Down Expand Up @@ -992,10 +999,19 @@ int CompatMidiRender::adjustTrailtime(int trailtime, Chord* currentChord, Chord*

const std::vector<Chord*>& graceBeforeChords = nextChord->graceNotesBefore();
std::vector<Chord*> graceNotesBeforeBar;
std::copy_if(graceBeforeChords.begin(), graceBeforeChords.end(), std::back_inserter(graceNotesBeforeBar), [](Chord* ch) {
return ch->noteType() == NoteType::ACCIACCATURA;

bool hasGraceBend = std::any_of(graceBeforeChords.begin(), graceBeforeChords.end(), [](Chord* ch) {
return std::any_of(ch->notes().begin(), ch->notes().end(), [](Note* n) {
return n->isGraceBendStart();
});
});

if (!hasGraceBend) {
std::copy_if(graceBeforeChords.begin(), graceBeforeChords.end(), std::back_inserter(graceNotesBeforeBar), [](Chord* ch) {
return ch->noteType() == NoteType::ACCIACCATURA;
});
}

const int currentTicks = currentChord->ticks().ticks();
IF_ASSERT_FAILED(currentTicks > 0) {
return trailtime;
Expand All @@ -1004,14 +1020,19 @@ int CompatMidiRender::adjustTrailtime(int trailtime, Chord* currentChord, Chord*
int reducedTicks = 0;

const auto& notes = nextChord->notes();
bool anySlidesIn = std::any_of(notes.begin(), notes.end(), [](const Note* note) {
return note->slideToType() == Note::SlideType::DownToNote || (note->slideToType() == Note::SlideType::UpToNote && note->fret() > 1);
});

if (!graceNotesBeforeBar.empty()) {
if (hasGraceBend) {
reducedTicks = graceBendTicks(currentChord);
} else if (!graceNotesBeforeBar.empty()) {
reducedTicks = std::min(graceNotesBeforeBar[0]->ticks().ticks(), currentTicks / 2);
} else if (anySlidesIn) {
reducedTicks = CompatMidiRender::slideTicks(currentChord);
} else {
bool anySlidesIn = std::any_of(notes.begin(), notes.end(), [](const Note* note) {
return note->slideToType() == Note::SlideType::DownToNote
|| (note->slideToType() == Note::SlideType::UpToNote && note->fret() > 1);
});

if (anySlidesIn) {
reducedTicks = slideTicks(currentChord);
}
}

trailtime += reducedTicks / (double)currentTicks * NoteEvent::NOTE_LENGTH;
Expand Down Expand Up @@ -1145,7 +1166,7 @@ int CompatMidiRender::totalTiedNoteTicks(Note* note)
return total.ticks();
}

int CompatMidiRender::slideTicks(Chord* chord)
static int slideTicks(const Chord* chord)
{
const int currentTicks = chord->ticks().ticks();
if (currentTicks <= SLIDE_DURATION) {
Expand All @@ -1155,6 +1176,16 @@ int CompatMidiRender::slideTicks(Chord* chord)
return SLIDE_DURATION;
}

static int graceBendTicks(const Chord* chord)
{
const int currentTicks = chord->ticks().ticks();
if (currentTicks / 2 <= GRACE_BEND_DURATION) {
return currentTicks / 2;
}

return GRACE_BEND_DURATION;
}

int CompatMidiRender::tick(const CompatMidiRendererInternal::Context& ctx, int tick)
{
return ctx.applyCaesuras ? ctx.pauseMap->tickWithPauses(tick) : tick;
Expand Down
1 change: 0 additions & 1 deletion src/engraving/compat/midi/compatmidirender.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ class CompatMidiRender
static bool isGlissandoValid(Glissando* glissando);
static const Drumset* getDrumset(const Chord* chord);
static int totalTiedNoteTicks(Note* note);
static int slideTicks(Chord* chord);
};
}

Expand Down
Loading

0 comments on commit 8eb42bd

Please sign in to comment.