mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 03:04:00 +00:00
Implement note extensions
This commit is contained in:
parent
920abba112
commit
1d3fc9e22b
97
Resources/Music/extendcursor.eps
Normal file
97
Resources/Music/extendcursor.eps
Normal file
|
@ -0,0 +1,97 @@
|
|||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%BoundingBox: -1 -215.5 566.742 180
|
||||
%%Pages: 0
|
||||
%%Title: noteheads.s0triangle from feta26
|
||||
%%Creator: FontForge
|
||||
%%Author: Matthias Neeracher
|
||||
%%CreationDate: 19:50 21-4-2007
|
||||
%%EndComments
|
||||
%%BeginPreview: 73 51 4 51
|
||||
%0027ADC6000000000000000000000000000000000000000000000000000000000000000000
|
||||
%07FFFFFFD50000000000000000000000000000000000000000000000000000000000000000
|
||||
%1FFFFFFFFFC500000000000000000000000000000000000000000000000000000000000000
|
||||
%1FFFFFFFFFFFD6000000000000000000000000000000000000000000000000000000000000
|
||||
%06FFFFFFFFFFFFE81000000000000000000000000000000000000000000000000000000000
|
||||
%007FFFFFFFFFFFFFFA40000000000000000000000000000000000000000000000000000000
|
||||
%0009FFFFFFFFFFFFFFFD710000000000000000000000000000000000000000000000000000
|
||||
%0000CFFFFFFFFFFFFFFFFFA500000000000000000000000000000000000000000000000000
|
||||
%00002EFFFFFFFFFFFFFFFFFFE9400000000000000000000000000000000000000000000000
|
||||
%000006FFFFFFFFFFFFFFFFFFFFFEA510000000000000000000000000000000000000000000
|
||||
%000000BFFFFFFFFFFFFFFFFFFFFFFFFB730000000000000000000000000000000000000000
|
||||
%0000002FFFFFFFFFFFFFFFFFFFFFFFFFFFEA62000000000000000000000000000000000000
|
||||
%00000008FFFFFFFFF9DFFFFFFFFFFFFFFFFFFFEB7410000000000000000000000000000000
|
||||
%00000001EFFFFFFFF7038DFFFFFFFFFFFFFFFFFFFFFDA85310000000000000000000000000
|
||||
%000000007FFFFFFFFD000038DFFFFFFFFFFFFFFFFFFFFFFFFDB97542000000000000000000
|
||||
%000000001EFFFFFFFF600000027BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDCBA998877653000
|
||||
%0000000008FFFFFFFFD000000000149CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC20
|
||||
%0000000001FFFFFFFFF4000000000000159CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
|
||||
%0000000000AFFFFFFFFA0000000000000000148BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
|
||||
%00000000005FFFFFFFFF100000000000000000000257ADFFFFFFFFFFFFFFFFFFFFFFFFFFA0
|
||||
%00000000000EFFFFFFFF600000000000000000000000000257DFFFFFFFFFFFFFFFFFFFF910
|
||||
%000000000009FFFFFFFFB0000000000000000000000000028DFFFFFFFFFFFFFFFFFFB61000
|
||||
%000000000005FFFFFFFFF1000000000000000000000003AFFFFFFFFFFFFFFFFFC840000000
|
||||
%000000000001FFFFFFFFF40000000000000000000005CFFFFFFFFFFFFFFFFB620000000000
|
||||
%000000000000BFFFFFFFF800000000000000000005CFFFFFFFFFFFFFFFB610000000000000
|
||||
%0000000000007FFFFFFFFB000000000000000005CFFFFFFFFFFFFFFD720000000000000000
|
||||
%0000000000004FFFFFFFFE0000000000000003CFFFFFFFFFFFFFFA40000000000000000000
|
||||
%0000000000001FFFFFFFFF10000000000002AFFFFFFFFFFFFFE81000000000000000000000
|
||||
%0000000000000DFFFFFFFF3000000000007EFFFFFFFFFFFFD6100000000000000000000000
|
||||
%0000000000000BFFFFFFFF50000000003DFFFFFFFFFFFFD600000000000000000000000000
|
||||
%00000000000009FFFFFFFF7000000019FFFFFFFFFFFFE60000000000000000000000000000
|
||||
%00000000000007FFFFFFFF80000003DFFFFFFFFFFFE7100000000000000000000000000000
|
||||
%00000000000006FFFFFFFF8000008FFFFFFFFFFFFA20000000000000000000000000000000
|
||||
%00000000000005FFFFFFFF90001BFFFFFFFFFFFC3000000000000000000000000000000000
|
||||
%00000000000004FFFFFFFF9003DFFFFFFFFFFF700000000000000000000000000000000000
|
||||
%00000000000003FFFFFFFF906FFFFFFFFFFFC2000000000000000000000000000000000000
|
||||
%00000000000003FFFFFFFFA9FFFFFFFFFFF700000000000000000000000000000000000000
|
||||
%00000000000003FFFFFFFFFFFFFFFFFFFD3000000000000000000000000000000000000000
|
||||
%00000000000004FFFFFFFFFFFFFFFFFF910000000000000000000000000000000000000000
|
||||
%00000000000004FFFFFFFFFFFFFFFFE6000000000000000000000000000000000000000000
|
||||
%00000000000005FFFFFFFFFFFFFFFD30000000000000000000000000000000000000000000
|
||||
%00000000000007FFFFFFFFFFFFFFB100000000000000000000000000000000000000000000
|
||||
%00000000000008FFFFFFFFFFFFF90000000000000000000000000000000000000000000000
|
||||
%0000000000000AFFFFFFFFFFFF700000000000000000000000000000000000000000000000
|
||||
%0000000000000DFFFFFFFFFFF5000000000000000000000000000000000000000000000000
|
||||
%0000000000001FFFFFFFFFFE40000000000000000000000000000000000000000000000000
|
||||
%0000000000003FFFFFFFFFE300000000000000000000000000000000000000000000000000
|
||||
%0000000000005FFFFFFFFE3000000000000000000000000000000000000000000000000000
|
||||
%0000000000002EFFFFFFD20000000000000000000000000000000000000000000000000000
|
||||
%00000000000003CFFFFC200000000000000000000000000000000000000000000000000000
|
||||
%00000000000000014551000000000000000000000000000000000000000000000000000000
|
||||
%%EndPreview
|
||||
%%EndProlog
|
||||
%%Page "noteheads.s0triangle" 1
|
||||
gsave newpath
|
||||
25 178 moveto
|
||||
28 179 34 180 38 180 curveto
|
||||
43 180 45 180 59 172 curveto
|
||||
164 118 279 83 396 68 curveto
|
||||
434 63 466 60 512 59 curveto
|
||||
542 58 545 58 550 56 curveto
|
||||
564 51 570 39 565 28 curveto
|
||||
561 20 553 16 524 8 curveto
|
||||
386 -27 266 -95 164 -195 curveto
|
||||
153 -205 144 -214 142 -214 curveto
|
||||
137 -216 131 -216 119 -214 curveto
|
||||
108 -213 99 -208 95 -203 curveto
|
||||
91 -198 91 -193 94 -178 curveto
|
||||
103 -136 103 -82 94 -35 curveto
|
||||
87 1 74 39 58 70 curveto
|
||||
43 98 23 127 8 142 curveto
|
||||
1 149 -1 153 -1 158 curveto
|
||||
-1 162 1 167 4 170 curveto
|
||||
8 173 17 177 25 178 curveto
|
||||
closepath
|
||||
155 74 moveto
|
||||
140 79 128 83 127 84 curveto
|
||||
126 84 127 80 132 69 curveto
|
||||
158 19 170 -33 170 -88 curveto
|
||||
170 -108 171 -111 172 -110 curveto
|
||||
179 -104 197 -90 208 -81 curveto
|
||||
259 -43 317 -11 377 13 curveto
|
||||
385 16 391 19 391 19 curveto
|
||||
389 19 354 24 344 26 curveto
|
||||
280 37 218 53 155 74 curveto
|
||||
closepath
|
||||
1 0 0 setrgbcolor fill grestore
|
||||
%%EOF
|
|
@ -999,6 +999,67 @@ void VLSong::DelNote(size_t measure, VLFraction at)
|
|||
}
|
||||
}
|
||||
|
||||
void VLSong::ExtendNote(size_t measure, VLFraction at)
|
||||
{
|
||||
VLNoteList::iterator i = fMeasures[measure].fMelody.begin();
|
||||
VLFraction t(0);
|
||||
|
||||
for (;;) {
|
||||
if (t == at) {
|
||||
if (i->fPitch == VLNote::kNoPitch)
|
||||
return; // Don't extend rests
|
||||
do {
|
||||
VLNoteList::iterator j=i;
|
||||
++j;
|
||||
if (j != fMeasures[measure].fMelody.end()) {
|
||||
//
|
||||
// Extend across next note/rest
|
||||
//
|
||||
i->fDuration += j->fDuration;
|
||||
fMeasures[measure].fMelody.erase(j);
|
||||
} else if (++measure < fMeasures.size()) {
|
||||
//
|
||||
// Extend into next measure
|
||||
//
|
||||
VLNoteList::iterator k = fMeasures[measure].fMelody.begin();
|
||||
if (k->fTied & VLNote::kTiedWithPrev) {
|
||||
//
|
||||
// Already extended, extend further
|
||||
//
|
||||
i = k;
|
||||
continue; // Go for another spin
|
||||
} else {
|
||||
bool wasTied = k->fTied & VLNote::kTiedWithNext;
|
||||
//
|
||||
// Extend previous note
|
||||
//
|
||||
k->fPitch = i->fPitch;
|
||||
k->fTied = VLNote::kTiedWithPrev;
|
||||
i->fTied != VLNote::kTiedWithNext;
|
||||
k->fLyrics.clear();
|
||||
if (wasTied) {
|
||||
//
|
||||
// Extend further
|
||||
//
|
||||
i = k;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
//
|
||||
// Finished extending
|
||||
//
|
||||
return;
|
||||
}
|
||||
VLFraction tEnd = t+i->fDuration;
|
||||
if (tEnd > at)
|
||||
break; // Past the point, quit
|
||||
t = tEnd;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static void TransposePinned(int8_t & pitch, int semi)
|
||||
{
|
||||
if (pitch == VLNote::kNoPitch)
|
||||
|
|
|
@ -315,6 +315,7 @@ struct VLSong {
|
|||
void AddNote(VLLyricsNote note, size_t measure, VLFraction at);
|
||||
void DelChord(size_t measure, VLFraction at);
|
||||
void DelNote(size_t measure, VLFraction at);
|
||||
void ExtendNote(size_t measure, VLFraction at);
|
||||
void AddRepeat(size_t beginMeasure, size_t endMeasure, int times);
|
||||
void DelRepeat(size_t beginMeasure, size_t endMeasure);
|
||||
void AddEnding(size_t beginMeasure, size_t endMeasure, size_t volta);
|
||||
|
|
|
@ -36,6 +36,7 @@ enum VLMusicElement {
|
|||
kMusicNaturalCursor,
|
||||
kMusicRestCursor,
|
||||
kMusicKillCursor,
|
||||
kMusicExtendCursor,
|
||||
kMusicCoda,
|
||||
kMusicElements
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@ static NSString * sElementNames[kMusicElements] = {
|
|||
@"naturalcursor",
|
||||
@"restcursor",
|
||||
@"killcursor",
|
||||
@"extendcursor",
|
||||
@"coda"
|
||||
};
|
||||
|
||||
|
@ -654,9 +655,17 @@ static int8_t sSharpAcc[] = {
|
|||
|
||||
- (void) accidentalFromEvent:(NSEvent *)event
|
||||
{
|
||||
fCursorAccidental = (VLMusicElement)0;
|
||||
|
||||
//
|
||||
// Extension
|
||||
//
|
||||
if ([event modifierFlags] & NSShiftKeyMask) {
|
||||
fCursorAccidental = kMusicExtendCursor;
|
||||
return;
|
||||
}
|
||||
const VLProperties & prop = [self song]->fProperties.front();
|
||||
|
||||
fCursorAccidental = (VLMusicElement)0;
|
||||
if (prop.fKey >= 0) {
|
||||
if (prop.fKey >= sSharpAcc[fCursorPitch % 12]) { // Sharp in Key
|
||||
switch ([event modifierFlags] & (NSAlternateKeyMask|NSCommandKeyMask)) {
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
VLNote newNote(1, fClickMode==' ' ? fCursorActualPitch : VLNote::kNoPitch);
|
||||
|
||||
[[self document] willChangeSong];
|
||||
if (fClickMode == 'k')
|
||||
if (fCursorAccidental == kMusicExtendCursor)
|
||||
[self song]->ExtendNote(fCursorMeasure, fCursorAt);
|
||||
else if (fClickMode == 'k')
|
||||
[self song]->DelNote(fCursorMeasure, fCursorAt);
|
||||
else
|
||||
[self song]->AddNote(VLLyricsNote(newNote), fCursorMeasure, fCursorAt);
|
||||
|
@ -75,37 +77,40 @@
|
|||
VLMusicElement cursorElt;
|
||||
|
||||
cursorX = [self noteXInMeasure:fCursorMeasure at:fCursorAt];
|
||||
switch (fClickMode) {
|
||||
default:
|
||||
if (fCursorAccidental == kMusicExtendCursor) {
|
||||
cursorY =
|
||||
[self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch
|
||||
accidental:&accidental]
|
||||
-kNoteY;
|
||||
[self drawLedgerLinesWithPitch:fCursorPitch
|
||||
at:NSMakePoint(cursorX,
|
||||
[self systemY:fCursorMeasure/fMeasPerSystem])];
|
||||
cursorElt = kMusicNoteCursor;
|
||||
break;
|
||||
case 'r':
|
||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||
withPitch:65
|
||||
accidental:&accidental];
|
||||
cursorElt = kMusicRestCursor;
|
||||
break;
|
||||
case 'k':
|
||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch
|
||||
accidental:&accidental];
|
||||
cursorElt = kMusicKillCursor;
|
||||
break;
|
||||
}
|
||||
accidental:&accidental];
|
||||
cursorElt = fCursorAccidental;
|
||||
} else
|
||||
switch (fClickMode) {
|
||||
default:
|
||||
cursorY =
|
||||
[self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch accidental:&accidental] - kNoteY;
|
||||
[self drawLedgerLinesWithPitch:fCursorPitch
|
||||
at:NSMakePoint(cursorX,
|
||||
[self systemY:fCursorMeasure/fMeasPerSystem])];
|
||||
cursorElt = kMusicNoteCursor;
|
||||
break;
|
||||
case 'r':
|
||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||
withPitch:65 accidental:&accidental];
|
||||
cursorElt = kMusicRestCursor;
|
||||
break;
|
||||
case 'k':
|
||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch accidental:&accidental];
|
||||
cursorElt = kMusicKillCursor;
|
||||
break;
|
||||
}
|
||||
|
||||
NSPoint at = NSMakePoint(cursorX-kNoteX, cursorY);
|
||||
[[self musicElement:cursorElt]
|
||||
compositeToPoint:at
|
||||
operation: NSCompositeSourceOver];
|
||||
if (fCursorAccidental) {
|
||||
if (fCursorAccidental && fCursorAccidental != kMusicExtendCursor) {
|
||||
at.y += kNoteY;
|
||||
switch (cursorElt= fCursorAccidental) {
|
||||
case kMusicFlatCursor:
|
||||
|
|
Loading…
Reference in New Issue
Block a user