mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14: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)
|
static void TransposePinned(int8_t & pitch, int semi)
|
||||||
{
|
{
|
||||||
if (pitch == VLNote::kNoPitch)
|
if (pitch == VLNote::kNoPitch)
|
||||||
|
|
|
@ -315,6 +315,7 @@ struct VLSong {
|
||||||
void AddNote(VLLyricsNote note, size_t measure, VLFraction at);
|
void AddNote(VLLyricsNote note, size_t measure, VLFraction at);
|
||||||
void DelChord(size_t measure, VLFraction at);
|
void DelChord(size_t measure, VLFraction at);
|
||||||
void DelNote(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 AddRepeat(size_t beginMeasure, size_t endMeasure, int times);
|
||||||
void DelRepeat(size_t beginMeasure, size_t endMeasure);
|
void DelRepeat(size_t beginMeasure, size_t endMeasure);
|
||||||
void AddEnding(size_t beginMeasure, size_t endMeasure, size_t volta);
|
void AddEnding(size_t beginMeasure, size_t endMeasure, size_t volta);
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum VLMusicElement {
|
||||||
kMusicNaturalCursor,
|
kMusicNaturalCursor,
|
||||||
kMusicRestCursor,
|
kMusicRestCursor,
|
||||||
kMusicKillCursor,
|
kMusicKillCursor,
|
||||||
|
kMusicExtendCursor,
|
||||||
kMusicCoda,
|
kMusicCoda,
|
||||||
kMusicElements
|
kMusicElements
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,6 +44,7 @@ static NSString * sElementNames[kMusicElements] = {
|
||||||
@"naturalcursor",
|
@"naturalcursor",
|
||||||
@"restcursor",
|
@"restcursor",
|
||||||
@"killcursor",
|
@"killcursor",
|
||||||
|
@"extendcursor",
|
||||||
@"coda"
|
@"coda"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -654,9 +655,17 @@ static int8_t sSharpAcc[] = {
|
||||||
|
|
||||||
- (void) accidentalFromEvent:(NSEvent *)event
|
- (void) accidentalFromEvent:(NSEvent *)event
|
||||||
{
|
{
|
||||||
|
fCursorAccidental = (VLMusicElement)0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extension
|
||||||
|
//
|
||||||
|
if ([event modifierFlags] & NSShiftKeyMask) {
|
||||||
|
fCursorAccidental = kMusicExtendCursor;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const VLProperties & prop = [self song]->fProperties.front();
|
const VLProperties & prop = [self song]->fProperties.front();
|
||||||
|
|
||||||
fCursorAccidental = (VLMusicElement)0;
|
|
||||||
if (prop.fKey >= 0) {
|
if (prop.fKey >= 0) {
|
||||||
if (prop.fKey >= sSharpAcc[fCursorPitch % 12]) { // Sharp in Key
|
if (prop.fKey >= sSharpAcc[fCursorPitch % 12]) { // Sharp in Key
|
||||||
switch ([event modifierFlags] & (NSAlternateKeyMask|NSCommandKeyMask)) {
|
switch ([event modifierFlags] & (NSAlternateKeyMask|NSCommandKeyMask)) {
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
VLNote newNote(1, fClickMode==' ' ? fCursorActualPitch : VLNote::kNoPitch);
|
VLNote newNote(1, fClickMode==' ' ? fCursorActualPitch : VLNote::kNoPitch);
|
||||||
|
|
||||||
[[self document] willChangeSong];
|
[[self document] willChangeSong];
|
||||||
if (fClickMode == 'k')
|
if (fCursorAccidental == kMusicExtendCursor)
|
||||||
|
[self song]->ExtendNote(fCursorMeasure, fCursorAt);
|
||||||
|
else if (fClickMode == 'k')
|
||||||
[self song]->DelNote(fCursorMeasure, fCursorAt);
|
[self song]->DelNote(fCursorMeasure, fCursorAt);
|
||||||
else
|
else
|
||||||
[self song]->AddNote(VLLyricsNote(newNote), fCursorMeasure, fCursorAt);
|
[self song]->AddNote(VLLyricsNote(newNote), fCursorMeasure, fCursorAt);
|
||||||
|
@ -75,37 +77,40 @@
|
||||||
VLMusicElement cursorElt;
|
VLMusicElement cursorElt;
|
||||||
|
|
||||||
cursorX = [self noteXInMeasure:fCursorMeasure at:fCursorAt];
|
cursorX = [self noteXInMeasure:fCursorMeasure at:fCursorAt];
|
||||||
switch (fClickMode) {
|
if (fCursorAccidental == kMusicExtendCursor) {
|
||||||
default:
|
|
||||||
cursorY =
|
cursorY =
|
||||||
[self noteYInMeasure:fCursorMeasure
|
[self noteYInMeasure:fCursorMeasure
|
||||||
withPitch:fCursorPitch
|
withPitch:fCursorPitch
|
||||||
accidental:&accidental]
|
accidental:&accidental];
|
||||||
-kNoteY;
|
cursorElt = fCursorAccidental;
|
||||||
[self drawLedgerLinesWithPitch:fCursorPitch
|
} else
|
||||||
at:NSMakePoint(cursorX,
|
switch (fClickMode) {
|
||||||
[self systemY:fCursorMeasure/fMeasPerSystem])];
|
default:
|
||||||
cursorElt = kMusicNoteCursor;
|
cursorY =
|
||||||
break;
|
[self noteYInMeasure:fCursorMeasure
|
||||||
case 'r':
|
withPitch:fCursorPitch accidental:&accidental] - kNoteY;
|
||||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
[self drawLedgerLinesWithPitch:fCursorPitch
|
||||||
withPitch:65
|
at:NSMakePoint(cursorX,
|
||||||
accidental:&accidental];
|
[self systemY:fCursorMeasure/fMeasPerSystem])];
|
||||||
cursorElt = kMusicRestCursor;
|
cursorElt = kMusicNoteCursor;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'r':
|
||||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||||
withPitch:fCursorPitch
|
withPitch:65 accidental:&accidental];
|
||||||
accidental:&accidental];
|
cursorElt = kMusicRestCursor;
|
||||||
cursorElt = kMusicKillCursor;
|
break;
|
||||||
break;
|
case 'k':
|
||||||
}
|
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||||
|
withPitch:fCursorPitch accidental:&accidental];
|
||||||
|
cursorElt = kMusicKillCursor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
NSPoint at = NSMakePoint(cursorX-kNoteX, cursorY);
|
NSPoint at = NSMakePoint(cursorX-kNoteX, cursorY);
|
||||||
[[self musicElement:cursorElt]
|
[[self musicElement:cursorElt]
|
||||||
compositeToPoint:at
|
compositeToPoint:at
|
||||||
operation: NSCompositeSourceOver];
|
operation: NSCompositeSourceOver];
|
||||||
if (fCursorAccidental) {
|
if (fCursorAccidental && fCursorAccidental != kMusicExtendCursor) {
|
||||||
at.y += kNoteY;
|
at.y += kNoteY;
|
||||||
switch (cursorElt= fCursorAccidental) {
|
switch (cursorElt= fCursorAccidental) {
|
||||||
case kMusicFlatCursor:
|
case kMusicFlatCursor:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user