private static bool CanJoin(Beat b1, Beat b2)
{
// is this a voice we can join with?
if (b1 == null || b2 == null || b1.IsRest || b2.IsRest || b1.GraceType != GraceType.None || b2.GraceType != GraceType.None)
{
return false;
}
var m1 = b1.Voice.Bar;
var m2 = b1.Voice.Bar;
// only join on same measure
if (m1 != m2) return false;
// get times of those voices and check if the times
// are in the same division
var start1 = b1.Start;
var start2 = b2.Start;
// we can only join 8th, 16th, 32th and 64th voices
if (!CanJoinDuration(b1.Duration) || !CanJoinDuration(b2.Duration))
{
return start1 == start2;
}
// TODO: create more rules for automatic beaming
var divisionLength = MidiUtils.QuarterTime;
switch (m1.MasterBar.TimeSignatureDenominator)
{
case 8:
if (m1.MasterBar.TimeSignatureNumerator % 3 == 0)
{
divisionLength += MidiUtils.QuarterTime / 2;
}
break;
}
// check if they are on the same division
var division1 = ((divisionLength + start1) / divisionLength) | 0;
var division2 = ((divisionLength + start2) / divisionLength) | 0;
return division1 == division2;
}