mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
VLSongVisitor; generate Lilypond through VLLilypondWriter
This commit is contained in:
parent
559781ce3d
commit
6779d727e7
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "VLLilypondDocument.h"
|
#import "VLLilypondDocument.h"
|
||||||
|
#import "VLLilypondWriter.h"
|
||||||
|
|
||||||
@interface NSMutableString (VLLilypond)
|
@interface NSMutableString (VLLilypond)
|
||||||
|
|
||||||
|
@ -115,6 +116,8 @@ static const char * sKeyNames[] = {
|
||||||
- (NSData *)lilypondDataWithError:(NSError **)outError
|
- (NSData *)lilypondDataWithError:(NSError **)outError
|
||||||
{
|
{
|
||||||
const VLProperties & prop = song->fProperties.front();
|
const VLProperties & prop = song->fProperties.front();
|
||||||
|
VLLilypondWriter writer;
|
||||||
|
writer.Visit(*song);
|
||||||
NSBundle * bndl = [NSBundle mainBundle];
|
NSBundle * bndl = [NSBundle mainBundle];
|
||||||
NSString * tmpl =
|
NSString * tmpl =
|
||||||
[bndl pathForResource:lilypondTemplate
|
[bndl pathForResource:lilypondTemplate
|
||||||
|
@ -130,12 +133,10 @@ static const char * sKeyNames[] = {
|
||||||
[bndl objectForInfoDictionaryKey:@"CFBundleVersion"]];
|
[bndl objectForInfoDictionaryKey:@"CFBundleVersion"]];
|
||||||
[ly substituteMacro:@"PAPERSIZE" withValue:@"letter"];
|
[ly substituteMacro:@"PAPERSIZE" withValue:@"letter"];
|
||||||
[ly substituteMacro:@"FORMATTING" withValue:@"ragged-last-bottom = ##f"];
|
[ly substituteMacro:@"FORMATTING" withValue:@"ragged-last-bottom = ##f"];
|
||||||
std::string lys;
|
|
||||||
song->LilypondChords(lys);
|
|
||||||
[ly substituteMacro:@"VLVERSION" withValue:
|
[ly substituteMacro:@"VLVERSION" withValue:
|
||||||
[bndl objectForInfoDictionaryKey:@"CFBundleVersion"]];
|
[bndl objectForInfoDictionaryKey:@"CFBundleVersion"]];
|
||||||
[ly substituteMacro:@"CHORDS" withValue:
|
[ly substituteMacro:@"CHORDS" withValue:
|
||||||
[NSString stringWithUTF8String:lys.c_str()]];
|
[NSString stringWithUTF8String:writer.Chords().c_str()]];
|
||||||
[ly substituteMacro:@"TIME" withValue:
|
[ly substituteMacro:@"TIME" withValue:
|
||||||
[NSString stringWithFormat:@"%d/%d",
|
[NSString stringWithFormat:@"%d/%d",
|
||||||
prop.fTime.fNum, prop.fTime.fDenom]];
|
prop.fTime.fNum, prop.fTime.fDenom]];
|
||||||
|
@ -144,14 +145,12 @@ static const char * sKeyNames[] = {
|
||||||
sKeyNames[prop.fKey+kMajorOffset]]
|
sKeyNames[prop.fKey+kMajorOffset]]
|
||||||
: [NSString stringWithFormat:@"%s \\minor",
|
: [NSString stringWithFormat:@"%s \\minor",
|
||||||
sKeyNames[prop.fKey+kMinorOffset]]];
|
sKeyNames[prop.fKey+kMinorOffset]]];
|
||||||
song->LilypondNotes(lys);
|
|
||||||
[ly substituteMacro:@"NOTES" withValue:
|
[ly substituteMacro:@"NOTES" withValue:
|
||||||
[NSString stringWithUTF8String:lys.c_str()]];
|
[NSString stringWithUTF8String:writer.Melody().c_str()]];
|
||||||
if (size_t stanzas = song->CountStanzas())
|
if (size_t stanzas = song->CountStanzas())
|
||||||
for (size_t s=0; s++<stanzas; ) {
|
for (size_t s=0; s<stanzas; ++s) {
|
||||||
song->LilypondStanza(lys, s);
|
|
||||||
[ly substituteMacro:@"LYRICS" withValue:
|
[ly substituteMacro:@"LYRICS" withValue:
|
||||||
[NSString stringWithUTF8String:lys.c_str()]
|
[NSString stringWithUTF8String:writer.Lyrics(s).c_str()]
|
||||||
repeat: s<stanzas];
|
repeat: s<stanzas];
|
||||||
}
|
}
|
||||||
[ly purgeMacros];
|
[ly purgeMacros];
|
||||||
|
|
297
Sources/VLLilypondWriter.cpp
Normal file
297
Sources/VLLilypondWriter.cpp
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
//
|
||||||
|
// File: VLLilypondWriter.h
|
||||||
|
//
|
||||||
|
// Author(s):
|
||||||
|
//
|
||||||
|
// (MN) Matthias Neeracher
|
||||||
|
//
|
||||||
|
// Copyright © 2007 Matthias Neeracher
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "VLLilypondWriter.h"
|
||||||
|
|
||||||
|
void VLLilypondWriter::Visit(VLSong & song)
|
||||||
|
{
|
||||||
|
fSong = &song;
|
||||||
|
fChords.clear();
|
||||||
|
fMelody.clear();
|
||||||
|
fLyrics.clear();
|
||||||
|
fLyrics.resize(song.CountStanzas());
|
||||||
|
fL = fLyrics;
|
||||||
|
fInPickup = true;
|
||||||
|
fIndent.clear();
|
||||||
|
fSeenEnding = 0;
|
||||||
|
fNumEndings = 0;
|
||||||
|
|
||||||
|
VisitMeasures(song, false);
|
||||||
|
//
|
||||||
|
// Terminate melody
|
||||||
|
//
|
||||||
|
if (fIndent.size())
|
||||||
|
fMelody += fSeenEnding ? "}}\n" : "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLLilypondWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
|
||||||
|
{
|
||||||
|
char measNo[8];
|
||||||
|
if (!(m % 4))
|
||||||
|
sprintf(measNo, " %% %d", m+1);
|
||||||
|
else
|
||||||
|
measNo[0] = 0;
|
||||||
|
|
||||||
|
fUseSharps = p.fKey >= 0;
|
||||||
|
fInPickup = fInPickup && !m && meas.NoChords();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate chords
|
||||||
|
//
|
||||||
|
fAccum.clear();
|
||||||
|
VisitChords(meas);
|
||||||
|
fAccum += measNo;
|
||||||
|
fChords+= fAccum + '\n';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate structure elements
|
||||||
|
//
|
||||||
|
int times;
|
||||||
|
size_t volta;
|
||||||
|
bool repeat;
|
||||||
|
|
||||||
|
fAccum.clear();
|
||||||
|
if (fSong->DoesEndRepeat(m)) {
|
||||||
|
fAccum += "}\n";
|
||||||
|
fIndent = "";
|
||||||
|
}
|
||||||
|
if (fSong->DoesBeginEnding(m, &repeat, &volta)) {
|
||||||
|
fAccum += fSeenEnding ? "}{\n" : "} \\alternative {{\n";
|
||||||
|
fAccum += " \\set Score.repeatCommands = #'((volta \"";
|
||||||
|
const char * comma = "";
|
||||||
|
for (int r=0; r<8; ++r)
|
||||||
|
if (volta & (1<<r)) {
|
||||||
|
char volta[8];
|
||||||
|
sprintf(volta, "%s%d.", comma, r+1);
|
||||||
|
comma = ", ";
|
||||||
|
fAccum += volta;
|
||||||
|
}
|
||||||
|
fAccum += "\")" + std::string(repeat ? "" : " end-repeat") + ")\n";
|
||||||
|
fSeenEnding |= volta;
|
||||||
|
++fNumEndings;
|
||||||
|
} else if (fSong->DoesEndEnding(m)) {
|
||||||
|
fAccum += "}}\n";
|
||||||
|
fIndent = "";
|
||||||
|
}
|
||||||
|
if (fSong->DoesBeginRepeat(m, ×)) {
|
||||||
|
char volta[8];
|
||||||
|
sprintf(volta, "%d", times);
|
||||||
|
fAccum = fAccum + "\\repeat volta "+volta+" {\n";
|
||||||
|
fIndent = " ";
|
||||||
|
fSeenEnding = 0;
|
||||||
|
fNumEndings = 0;
|
||||||
|
}
|
||||||
|
fAccum += fIndent;
|
||||||
|
if (fSong->fCoda == m)
|
||||||
|
fAccum += "\\break \\mark \\markup { \\musicglyph #\"scripts.coda\" }\n"
|
||||||
|
+ fIndent;
|
||||||
|
fMelody += fAccum;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate melody & lyrics
|
||||||
|
//
|
||||||
|
fAccum.clear();
|
||||||
|
for (size_t stanza=0; stanza<fL.size(); ++stanza)
|
||||||
|
fL[stanza].clear();
|
||||||
|
fPrevNote.fPitch = VLNote::kNoPitch;
|
||||||
|
VisitNotes(meas, p, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Consolidate triplets and dots
|
||||||
|
//
|
||||||
|
size_t trip;
|
||||||
|
while ((trip = fAccum.find("} \\times 2/3 { ")) != std::string::npos)
|
||||||
|
fAccum.erase(trip, 15);
|
||||||
|
while ((trip = fAccum.find(" ~ } \\times 2/3 { ")) != std::string::npos)
|
||||||
|
fAccum.erase(trip+2, 17);
|
||||||
|
while ((trip = fAccum.find(" ~.")) != std::string::npos)
|
||||||
|
fAccum.erase(trip, 2);
|
||||||
|
|
||||||
|
if (fSong->fGoToCoda == m+1)
|
||||||
|
fAccum += "\n"
|
||||||
|
+ fIndent
|
||||||
|
+ "\\mark \\markup { \\musicglyph #\"scripts.coda\" } |";
|
||||||
|
else
|
||||||
|
fAccum += " |";
|
||||||
|
fMelody += fAccum + measNo + '\n';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Accumulate lyrics
|
||||||
|
//
|
||||||
|
const char * nuline = m%4 ? "" : "\n";
|
||||||
|
for (size_t stanza=0; stanza<fLyrics.size(); ++stanza)
|
||||||
|
fLyrics[stanza] += fL[stanza] + nuline;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char kScale[] = "c d ef g a b";
|
||||||
|
static const char kValue[] = {
|
||||||
|
1, 2, 4, 8, 16, 32
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string LilypondPitchName(int8_t pitch, bool useSharps)
|
||||||
|
{
|
||||||
|
if (pitch == VLNote::kNoPitch)
|
||||||
|
return "r";
|
||||||
|
pitch %= 12;
|
||||||
|
if (kScale[pitch] != ' ')
|
||||||
|
return kScale[pitch] + std::string();
|
||||||
|
else if (useSharps)
|
||||||
|
return kScale[pitch-1] + std::string("is");
|
||||||
|
else
|
||||||
|
return kScale[pitch+1] + std::string("es");
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLLilypondWriter::VisitNote(VLLyricsNote & n)
|
||||||
|
{
|
||||||
|
std::string nm = LilypondPitchName(n.fPitch, fUseSharps);
|
||||||
|
if (n.fPitch != VLNote::kNoPitch) {
|
||||||
|
int ref = VLNote::kMiddleC-VLNote::kOctave;
|
||||||
|
for (int ticks = (n.fPitch-ref)/VLNote::kOctave; ticks>0; --ticks)
|
||||||
|
nm += '\'';
|
||||||
|
for (int commas = (ref-n.fPitch)/VLNote::kOctave; commas>0; --commas)
|
||||||
|
nm += ',';
|
||||||
|
fInPickup = false;
|
||||||
|
} else if (fInPickup) {
|
||||||
|
nm = "s";
|
||||||
|
}
|
||||||
|
const char * space = fAccum.size() ? " " : "";
|
||||||
|
const char * tie = n.fTied & VLNote::kTiedWithNext ? " ~" : "";
|
||||||
|
char duration[32];
|
||||||
|
if (n.fTied == VLNote::kTiedWithPrev && n.fVisual == fPrevNote.fVisual+1
|
||||||
|
&& n.fPitch == fPrevNote.fPitch
|
||||||
|
)
|
||||||
|
strcpy(duration, ".");
|
||||||
|
else if (n.fVisual & VLNote::kTriplet)
|
||||||
|
sprintf(duration, "%s\\times 2/3 { %s%d%s }",
|
||||||
|
space, nm.c_str(), kValue[n.fVisual], tie);
|
||||||
|
else
|
||||||
|
sprintf(duration, "%s%s%d%s", space, nm.c_str(), kValue[n.fVisual], tie);
|
||||||
|
|
||||||
|
fAccum += duration;
|
||||||
|
fPrevNote= n;
|
||||||
|
|
||||||
|
if (n.fPitch != VLNote::kNoPitch && !(n.fTied & VLNote::kTiedWithPrev))
|
||||||
|
for (size_t i=0; i<fL.size(); ++i)
|
||||||
|
if (n.fLyrics.size() <= i || !n.fLyrics[i]) {
|
||||||
|
fL[i] += " \\skip1";
|
||||||
|
} else {
|
||||||
|
fL[i] += ' ' + n.fLyrics[i].fText;
|
||||||
|
if (n.fLyrics[i].fKind & VLSyllable::kHasNext)
|
||||||
|
fL[i] += " --";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * kLilypondStepNames[] = {
|
||||||
|
"", "", "sus2", "", "", "sus", "5-", "", "5+", "6", "7", "7+", "",
|
||||||
|
"9-", "9", "9+", "", "11", "11+", "", "13-", "13"
|
||||||
|
};
|
||||||
|
|
||||||
|
void VLLilypondWriter::VisitChord(VLChord & c)
|
||||||
|
{
|
||||||
|
std::string name = LilypondPitchName(c.fPitch, fUseSharps);
|
||||||
|
char duration[16];
|
||||||
|
if (c.fDuration.fNum == 1 && !(c.fDuration.fDenom & (c.fDuration.fDenom-1))) // Power of two
|
||||||
|
sprintf(duration, "%d", c.fDuration.fDenom);
|
||||||
|
else
|
||||||
|
sprintf(duration, "1*%d/%d", c.fDuration.fNum, c.fDuration.fDenom);
|
||||||
|
name += std::string(duration);
|
||||||
|
std::string ext;
|
||||||
|
uint32_t steps = c.fSteps;
|
||||||
|
if (c.fPitch == VLNote::kNoPitch)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
//
|
||||||
|
// m / dim
|
||||||
|
//
|
||||||
|
if (steps & VLChord::kmMin3rd)
|
||||||
|
if (steps & (VLChord::kmDim5th|VLChord::kmDim7th)
|
||||||
|
&& !(steps & (VLChord::km5th|VLChord::kmMin7th|VLChord::kmMaj7th|VLChord::kmMin9th|VLChord::kmMaj9th|VLChord::km11th|VLChord::kmAug11th|VLChord::kmMin13th|VLChord::kmMaj13th))
|
||||||
|
) {
|
||||||
|
ext = "dim";
|
||||||
|
steps|= (steps & VLChord::kmDim7th) << 1;
|
||||||
|
steps&= ~(VLChord::kmMin3rd|VLChord::kmDim5th|VLChord::kmDim7th);
|
||||||
|
} else {
|
||||||
|
ext = "m";
|
||||||
|
steps&= ~VLChord::kmMin3rd;
|
||||||
|
}
|
||||||
|
steps &= ~(VLChord::kmUnison | VLChord::km5th);
|
||||||
|
//
|
||||||
|
// Maj
|
||||||
|
//
|
||||||
|
if (steps & VLChord::kmMaj7th) {
|
||||||
|
if (ext.size())
|
||||||
|
ext += '.';
|
||||||
|
ext += "maj";
|
||||||
|
if (steps & VLChord::kmMaj9th) {
|
||||||
|
ext += "9";
|
||||||
|
steps &= ~VLChord::kmMaj9th;
|
||||||
|
} else
|
||||||
|
ext += "7";
|
||||||
|
steps&= ~VLChord::kmMaj7th;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Sus
|
||||||
|
//
|
||||||
|
if (steps & (VLChord::kmMaj2nd|VLChord::km4th)) {
|
||||||
|
if (ext.size())
|
||||||
|
ext += '.';
|
||||||
|
ext += "sus";
|
||||||
|
if (steps & VLChord::kmMaj2nd)
|
||||||
|
ext += "2";
|
||||||
|
else
|
||||||
|
ext += "4";
|
||||||
|
steps&= ~(VLChord::kmMaj2nd|VLChord::km4th);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// 6/9
|
||||||
|
//
|
||||||
|
if ((steps & (VLChord::kmDim7th|VLChord::kmMaj9th)) == (VLChord::kmDim7th|VLChord::kmMaj9th)) {
|
||||||
|
if (ext.size() && !isalpha(ext[ext.size()-1]))
|
||||||
|
ext += '.';
|
||||||
|
ext += "6.9";
|
||||||
|
steps&= ~(VLChord::kmDim7th|VLChord::kmMaj9th);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Other extensions. Only the highest unaltered extension is listed.
|
||||||
|
//
|
||||||
|
if (uint32_t unaltered = steps & (VLChord::kmMin7th|VLChord::kmMaj9th|VLChord::km11th|VLChord::kmMaj13th)) {
|
||||||
|
steps &= ~unaltered;
|
||||||
|
|
||||||
|
for (int step = VLChord::kMaj13th; step > VLChord::kDim7th; --step)
|
||||||
|
if (unaltered & (1 << step)) {
|
||||||
|
std::string sn = kLilypondStepNames[step];
|
||||||
|
if (ext.size() && !isalpha(ext[ext.size()-1]) && sn.size())
|
||||||
|
ext += '.';
|
||||||
|
ext += sn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int step = VLChord::kMin2nd; steps; ++step)
|
||||||
|
if (steps & (1 << step)) {
|
||||||
|
std::string sn = kLilypondStepNames[step];
|
||||||
|
if (ext.size() && !isalpha(ext[ext.size()-1]) && sn.size())
|
||||||
|
ext += '.';
|
||||||
|
ext += sn;
|
||||||
|
steps &= ~(1 << step);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext.size())
|
||||||
|
name += ':' + ext;
|
||||||
|
//
|
||||||
|
// Root
|
||||||
|
//
|
||||||
|
if (c.fRootPitch != VLNote::kNoPitch)
|
||||||
|
name += "/+" + LilypondPitchName(c.fRootPitch, fUseSharps);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (fAccum.size())
|
||||||
|
fAccum += ' ';
|
||||||
|
fAccum += name;
|
||||||
|
}
|
43
Sources/VLLilypondWriter.h
Normal file
43
Sources/VLLilypondWriter.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// File: VLLilypondWriter.h
|
||||||
|
//
|
||||||
|
// Author(s):
|
||||||
|
//
|
||||||
|
// (MN) Matthias Neeracher
|
||||||
|
//
|
||||||
|
// Copyright © 2007 Matthias Neeracher
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "VLModel.h"
|
||||||
|
|
||||||
|
class VLLilypondWriter: public VLSongVisitor {
|
||||||
|
public:
|
||||||
|
VLLilypondWriter() {}
|
||||||
|
|
||||||
|
virtual void Visit(VLSong & song);
|
||||||
|
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas);
|
||||||
|
virtual void VisitNote(VLLyricsNote & n);
|
||||||
|
virtual void VisitChord(VLChord & c);
|
||||||
|
|
||||||
|
const std::string & Chords() const { return fChords; }
|
||||||
|
const std::string & Melody() const { return fMelody; }
|
||||||
|
const std::string & Lyrics(size_t stanza) const { return fLyrics[stanza]; }
|
||||||
|
private:
|
||||||
|
std::string fChords;
|
||||||
|
std::string fMelody;
|
||||||
|
std::vector<std::string> fLyrics;
|
||||||
|
|
||||||
|
VLSong * fSong;
|
||||||
|
bool fUseSharps;
|
||||||
|
bool fInPickup;
|
||||||
|
size_t fSeenEnding;
|
||||||
|
int fNumEndings;
|
||||||
|
VLNote fPrevNote;
|
||||||
|
std::string fAccum;
|
||||||
|
std::string fIndent;
|
||||||
|
std::vector<std::string> fL;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode:C++
|
||||||
|
// End:
|
|
@ -92,19 +92,6 @@ static std::string PitchName(int8_t pitch, bool useSharps)
|
||||||
+ std::string(kVLFlatStr);
|
+ std::string(kVLFlatStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string LilypondPitchName(int8_t pitch, bool useSharps)
|
|
||||||
{
|
|
||||||
if (pitch == VLNote::kNoPitch)
|
|
||||||
return "r";
|
|
||||||
pitch %= 12;
|
|
||||||
if (kScale[pitch] != ' ')
|
|
||||||
return kScale[pitch] + std::string();
|
|
||||||
else if (useSharps)
|
|
||||||
return kScale[pitch-1] + std::string("is");
|
|
||||||
else
|
|
||||||
return kScale[pitch+1] + std::string("es");
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string MMAPitchName(int8_t pitch, bool useSharps)
|
static std::string MMAPitchName(int8_t pitch, bool useSharps)
|
||||||
{
|
{
|
||||||
if (pitch == VLNote::kNoPitch)
|
if (pitch == VLNote::kNoPitch)
|
||||||
|
@ -164,50 +151,6 @@ void VLNote::Name(std::string & name, bool useSharps) const
|
||||||
name = PitchName(fPitch, useSharps);
|
name = PitchName(fPitch, useSharps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VLNote::LilypondName(std::string & name, VLFraction at, VLFraction prevDur, VLFraction nextDur, bool & triplet, bool & pickup, const VLProperties & prop) const
|
|
||||||
{
|
|
||||||
std::string n = LilypondPitchName(fPitch, prop.fKey >= 0);
|
|
||||||
if (fPitch != kNoPitch) {
|
|
||||||
for (int ticks = (fPitch-kMiddleC+kOctave)/kOctave; ticks>0; --ticks)
|
|
||||||
n += '\'';
|
|
||||||
for (int commas = (kMiddleC-kOctave-fPitch)/kOctave; commas>0; --commas)
|
|
||||||
n += ',';
|
|
||||||
pickup = false;
|
|
||||||
} else if (pickup) {
|
|
||||||
n = "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> durations;
|
|
||||||
VLFraction prevPart(0);
|
|
||||||
for (VLFraction dur = fDuration; dur.fNum; ) {
|
|
||||||
char duration[32];
|
|
||||||
VLFraction part, visual;
|
|
||||||
bool grouped = dur==nextDur ||
|
|
||||||
(prevPart!=0 ? dur==prevPart : dur==prevDur);
|
|
||||||
prop.PartialNote(at, dur, grouped, &part);
|
|
||||||
prop.VisualNote(at, part, triplet, &visual, &triplet);
|
|
||||||
if (!triplet && fPitch != kNoPitch && part == dur && 2*visual == prevPart) {
|
|
||||||
durations.pop_back();
|
|
||||||
sprintf(duration, "%s%d.", n.c_str(), visual.fDenom/2);
|
|
||||||
} else if (triplet) {
|
|
||||||
sprintf(duration, "\\times 2/3 { %s%d }", n.c_str(), visual.fDenom);
|
|
||||||
} else {
|
|
||||||
sprintf(duration, "%s%d", n.c_str(), visual.fDenom);
|
|
||||||
}
|
|
||||||
durations.push_back(duration);
|
|
||||||
prevPart = part;
|
|
||||||
at += part;
|
|
||||||
dur -= part;
|
|
||||||
}
|
|
||||||
for (size_t i=0; i<durations.size(); ++i) {
|
|
||||||
if (i && fPitch != kNoPitch)
|
|
||||||
name += " ~ ";
|
|
||||||
name += durations[i];
|
|
||||||
}
|
|
||||||
if (fTied & kTiedWithNext)
|
|
||||||
name += " ~";
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
VLFract fVal;
|
VLFract fVal;
|
||||||
const char * fName;
|
const char * fName;
|
||||||
|
@ -530,109 +473,6 @@ void VLChord::Name(std::string & base, std::string & ext, std::string & root, bo
|
||||||
root = PitchName(fRootPitch, useSharps);
|
root = PitchName(fRootPitch, useSharps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * kLilypondStepNames[] = {
|
|
||||||
"", "", "sus2", "", "", "sus", "5-", "", "5+", "6", "7", "7+", "",
|
|
||||||
"9-", "9", "9+", "", "11", "11+", "", "13-", "13"
|
|
||||||
};
|
|
||||||
|
|
||||||
void VLChord::LilypondName(std::string & name, bool useSharps) const
|
|
||||||
{
|
|
||||||
name = LilypondPitchName(fPitch, useSharps);
|
|
||||||
char duration[16];
|
|
||||||
if (fDuration.fNum == 1 && !(fDuration.fDenom & (fDuration.fDenom-1))) // Power of two
|
|
||||||
sprintf(duration, "%d", fDuration.fDenom);
|
|
||||||
else
|
|
||||||
sprintf(duration, "1*%d/%d", fDuration.fNum, fDuration.fDenom);
|
|
||||||
name += std::string(duration);
|
|
||||||
if (fPitch == kNoPitch)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string ext;
|
|
||||||
uint32_t steps = fSteps;
|
|
||||||
//
|
|
||||||
// m / dim
|
|
||||||
//
|
|
||||||
if (steps & kmMin3rd)
|
|
||||||
if (steps & (kmDim5th|kmDim7th)
|
|
||||||
&& !(steps & (km5th|kmMin7th|kmMaj7th|kmMin9th|kmMaj9th|km11th|kmAug11th|kmMin13th|kmMaj13th))
|
|
||||||
) {
|
|
||||||
ext = "dim";
|
|
||||||
steps|= (steps & kmDim7th) << 1;
|
|
||||||
steps&= ~(kmMin3rd|kmDim5th|kmDim7th);
|
|
||||||
} else {
|
|
||||||
ext = "m";
|
|
||||||
steps&= ~kmMin3rd;
|
|
||||||
}
|
|
||||||
steps &= ~(kmUnison | km5th);
|
|
||||||
//
|
|
||||||
// Maj
|
|
||||||
//
|
|
||||||
if (steps & kmMaj7th) {
|
|
||||||
if (ext.size())
|
|
||||||
ext += '.';
|
|
||||||
ext += "maj";
|
|
||||||
if (steps & kmMaj9th) {
|
|
||||||
ext += "9";
|
|
||||||
steps &= ~kmMaj9th;
|
|
||||||
} else
|
|
||||||
ext += "7";
|
|
||||||
steps&= ~kmMaj7th;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Sus
|
|
||||||
//
|
|
||||||
if (steps & (kmMaj2nd|km4th)) {
|
|
||||||
if (ext.size())
|
|
||||||
ext += '.';
|
|
||||||
ext += "sus";
|
|
||||||
if (steps & kmMaj2nd)
|
|
||||||
ext += "2";
|
|
||||||
else
|
|
||||||
ext += "4";
|
|
||||||
steps&= ~(kmMaj2nd|km4th);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// 6/9
|
|
||||||
//
|
|
||||||
if ((steps & (kmDim7th|kmMaj9th)) == (kmDim7th|kmMaj9th)) {
|
|
||||||
if (ext.size() && !isalpha(ext[ext.size()-1]))
|
|
||||||
ext += '.';
|
|
||||||
ext += "6.9";
|
|
||||||
steps&= ~(kmDim7th|kmMaj9th);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Other extensions. Only the highest unaltered extension is listed.
|
|
||||||
//
|
|
||||||
if (uint32_t unaltered = steps & (kmMin7th | kmMaj9th | km11th | kmMaj13th)) {
|
|
||||||
steps &= ~unaltered;
|
|
||||||
|
|
||||||
for (int step = kMaj13th; step > kDim7th; --step)
|
|
||||||
if (unaltered & (1 << step)) {
|
|
||||||
std::string sn = kLilypondStepNames[step];
|
|
||||||
if (ext.size() && !isalpha(ext[ext.size()-1]) && sn.size())
|
|
||||||
ext += '.';
|
|
||||||
ext += sn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int step = kMin2nd; steps; ++step)
|
|
||||||
if (steps & (1 << step)) {
|
|
||||||
std::string sn = kLilypondStepNames[step];
|
|
||||||
if (ext.size() && !isalpha(ext[ext.size()-1]) && sn.size())
|
|
||||||
ext += '.';
|
|
||||||
ext += sn;
|
|
||||||
steps &= ~(1 << step);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ext.size())
|
|
||||||
name += ':' + ext;
|
|
||||||
//
|
|
||||||
// Root
|
|
||||||
//
|
|
||||||
if (fRootPitch != kNoPitch)
|
|
||||||
name += "/+" + LilypondPitchName(fRootPitch, useSharps);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// MMA supports a large but finite list of chords
|
// MMA supports a large but finite list of chords
|
||||||
//
|
//
|
||||||
|
@ -1678,152 +1518,6 @@ size_t VLSong::CountBotLedgers() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VLSong::LilypondNotes(std::string & notes) const
|
|
||||||
{
|
|
||||||
notes = "";
|
|
||||||
std::string indent = "";
|
|
||||||
size_t seenEnding = 0;
|
|
||||||
int numEndings = 0;
|
|
||||||
size_t endMeasure = fMeasures.size()-EmptyEnding();
|
|
||||||
bool pickup = fMeasures[0].NoChords();
|
|
||||||
for (size_t measure=0; measure<endMeasure; ++measure) {
|
|
||||||
VLNoteList::const_iterator i = fMeasures[measure].fMelody.begin();
|
|
||||||
VLNoteList::const_iterator e = fMeasures[measure].fMelody.end();
|
|
||||||
VLFraction at(0);
|
|
||||||
|
|
||||||
int times;
|
|
||||||
size_t volta;
|
|
||||||
bool repeat;
|
|
||||||
|
|
||||||
if (DoesBeginRepeat(measure, ×)) {
|
|
||||||
char volta[8];
|
|
||||||
sprintf(volta, "%d", times);
|
|
||||||
notes = notes + "\\repeat volta "+volta+" {\n";
|
|
||||||
indent = " ";
|
|
||||||
seenEnding = 0;
|
|
||||||
numEndings = 0;
|
|
||||||
}
|
|
||||||
if (DoesEndRepeat(measure)) {
|
|
||||||
notes += "}\n";
|
|
||||||
indent = "";
|
|
||||||
}
|
|
||||||
if (DoesBeginEnding(measure, &repeat, &volta)) {
|
|
||||||
notes += seenEnding ? "}{\n" : "} \\alternative {{\n";
|
|
||||||
notes += " \\set Score.repeatCommands = #'((volta \"";
|
|
||||||
const char * comma = "";
|
|
||||||
for (int r=0; r<8; ++r)
|
|
||||||
if (volta & (1<<r)) {
|
|
||||||
char volta[8];
|
|
||||||
sprintf(volta, "%s%d.", comma, r+1);
|
|
||||||
comma = ", ";
|
|
||||||
notes += volta;
|
|
||||||
}
|
|
||||||
notes = notes + "\")" + (repeat ? "" : " end-repeat") + ")\n";
|
|
||||||
seenEnding |= volta;
|
|
||||||
++numEndings;
|
|
||||||
} else if (DoesEndEnding(measure)) {
|
|
||||||
notes += "}}\n";
|
|
||||||
indent = "";
|
|
||||||
}
|
|
||||||
notes += indent;
|
|
||||||
if (fCoda == measure)
|
|
||||||
notes += "\\break \\mark \\markup { \\musicglyph #\"scripts.coda\" }\n"
|
|
||||||
+ indent;
|
|
||||||
VLFraction prevDur(0);
|
|
||||||
bool triplet = false;
|
|
||||||
for (; i!=e; ++i) {
|
|
||||||
std::string note;
|
|
||||||
VLNoteList::const_iterator n = i;
|
|
||||||
VLFraction nextDur(0);
|
|
||||||
if (++n != e)
|
|
||||||
nextDur = n->fDuration;
|
|
||||||
i->LilypondName(note, at, prevDur, nextDur, triplet, pickup, fProperties[fMeasures[measure].fPropIdx]);
|
|
||||||
prevDur = i->fDuration;
|
|
||||||
at += i->fDuration;
|
|
||||||
notes += note+" ";
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Consolidate triplets
|
|
||||||
//
|
|
||||||
size_t trip;
|
|
||||||
while ((trip = notes.find("} \\times 2/3 { ")) != std::string::npos)
|
|
||||||
notes.erase(trip, 15);
|
|
||||||
while ((trip = notes.find("} ~ \\times 2/3 { ")) != std::string::npos)
|
|
||||||
notes.replace(trip, 17, "~ ", 2);
|
|
||||||
//
|
|
||||||
// Swap ties into correct order
|
|
||||||
//
|
|
||||||
while ((trip = notes.find("} ~")) != std::string::npos)
|
|
||||||
notes.replace(trip, 3, "~ } ", 4);
|
|
||||||
|
|
||||||
if (fGoToCoda == measure+1)
|
|
||||||
notes += "\n"
|
|
||||||
+ indent
|
|
||||||
+ "\\mark \\markup { \\musicglyph #\"scripts.coda\" } |";
|
|
||||||
else
|
|
||||||
notes += '|';
|
|
||||||
if (!(measure % 4)) {
|
|
||||||
char measNo[8];
|
|
||||||
sprintf(measNo, " %% %d", measure+1);
|
|
||||||
notes += measNo;
|
|
||||||
}
|
|
||||||
if (measure < fMeasures.size()-1)
|
|
||||||
notes += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VLSong::LilypondChords(std::string & chords) const
|
|
||||||
{
|
|
||||||
chords = "";
|
|
||||||
for (size_t measure=0; measure<fMeasures.size(); ++measure) {
|
|
||||||
bool useSharps = fProperties[fMeasures[measure].fPropIdx].fKey>=0;
|
|
||||||
VLChordList::const_iterator i = fMeasures[measure].fChords.begin();
|
|
||||||
VLChordList::const_iterator e = fMeasures[measure].fChords.end();
|
|
||||||
|
|
||||||
for (; i!=e; ++i) {
|
|
||||||
std::string chord;
|
|
||||||
i->LilypondName(chord, useSharps);
|
|
||||||
chords += chord+" ";
|
|
||||||
}
|
|
||||||
if (!(measure % 4)) {
|
|
||||||
char measNo[8];
|
|
||||||
sprintf(measNo, " %% %d", measure+1);
|
|
||||||
chords += measNo;
|
|
||||||
}
|
|
||||||
if (measure < fMeasures.size()-1)
|
|
||||||
chords += '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VLSong::LilypondStanza(std::string & lyrics, size_t stanza) const
|
|
||||||
{
|
|
||||||
lyrics = "";
|
|
||||||
std::string sep;
|
|
||||||
for (size_t measure=0; measure<fMeasures.size(); ++measure) {
|
|
||||||
VLNoteList::const_iterator i = fMeasures[measure].fMelody.begin();
|
|
||||||
VLNoteList::const_iterator e = fMeasures[measure].fMelody.end();
|
|
||||||
VLFraction at(0);
|
|
||||||
|
|
||||||
for (; i!=e; ++i) {
|
|
||||||
if (i->fPitch == VLNote::kNoPitch
|
|
||||||
|| (i->fTied & VLNote::kTiedWithPrev)
|
|
||||||
) {
|
|
||||||
continue; // Rest or continuation note, skip
|
|
||||||
} else if (i->fLyrics.size() < stanza || !i->fLyrics[stanza-1]) {
|
|
||||||
lyrics += sep + "\\skip1";
|
|
||||||
} else {
|
|
||||||
lyrics += sep + i->fLyrics[stanza-1].fText;
|
|
||||||
if (i->fLyrics[stanza-1].fKind & VLSyllable::kHasNext)
|
|
||||||
lyrics += " --";
|
|
||||||
}
|
|
||||||
sep = " ";
|
|
||||||
}
|
|
||||||
if ((measure % 4) == 3) {
|
|
||||||
sep = "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VLSong::FindWord(size_t stanza, size_t & measure, VLFraction & at)
|
bool VLSong::FindWord(size_t stanza, size_t & measure, VLFraction & at)
|
||||||
{
|
{
|
||||||
at += VLFraction(1,64);
|
at += VLFraction(1,64);
|
||||||
|
@ -2534,3 +2228,58 @@ VLFract VLSong::TiedDuration(size_t measure)
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VLSongVisitor::~VLSongVisitor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLSongVisitor::VisitMeasures(VLSong & song, bool performanceOrder)
|
||||||
|
{
|
||||||
|
if (performanceOrder) {
|
||||||
|
VLSong::iterator e = song.end();
|
||||||
|
|
||||||
|
for (VLSong::iterator m=song.begin(); m!=e; ++m) {
|
||||||
|
VLMeasure & meas = song.fMeasures[*m];
|
||||||
|
VLProperties& prop = song.fProperties[meas.fPropIdx];
|
||||||
|
VisitMeasure(*m, prop, meas);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t e = song.CountMeasures() - song.EmptyEnding();
|
||||||
|
|
||||||
|
for (size_t m=0; m!=e; ++m) {
|
||||||
|
VLMeasure & meas = song.fMeasures[m];
|
||||||
|
VLProperties& prop = song.fProperties[meas.fPropIdx];
|
||||||
|
VisitMeasure(m, prop, meas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLSongVisitor::VisitNotes(VLMeasure & measure, const VLProperties & prop,
|
||||||
|
bool decomposed)
|
||||||
|
{
|
||||||
|
VLNoteList decomp;
|
||||||
|
VLNoteList::iterator n;
|
||||||
|
VLNoteList::iterator e;
|
||||||
|
|
||||||
|
if (decomposed) {
|
||||||
|
measure.DecomposeNotes(prop, decomp);
|
||||||
|
n = decomp.begin();
|
||||||
|
e = decomp.end();
|
||||||
|
} else {
|
||||||
|
n = measure.fMelody.begin();
|
||||||
|
e = measure.fMelody.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; n!=e; ++n)
|
||||||
|
VisitNote(*n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLSongVisitor::VisitChords(VLMeasure & measure)
|
||||||
|
{
|
||||||
|
VLChordList::iterator c = measure.fChords.begin();
|
||||||
|
VLChordList::iterator e = measure.fChords.end();
|
||||||
|
|
||||||
|
for (; c!=e; ++c)
|
||||||
|
VisitChord(*c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,6 @@ struct VLNote {
|
||||||
VLNote(VLFraction dur=0, int pitch=kNoPitch);
|
VLNote(VLFraction dur=0, int pitch=kNoPitch);
|
||||||
VLNote(std::string name);
|
VLNote(std::string name);
|
||||||
void Name(std::string & name, bool useSharps = false) const;
|
void Name(std::string & name, bool useSharps = false) const;
|
||||||
void LilypondName(std::string & name, VLFraction at, VLFraction prevDur, VLFraction nextDur, bool & triplet, bool & pickup, const VLProperties & prop) const;
|
|
||||||
void MMAName(std::string & name, VLFraction at, VLFraction dur, VLFraction prevDur, VLFraction nextDur, const VLProperties & prop) const;
|
void MMAName(std::string & name, VLFraction at, VLFraction dur, VLFraction prevDur, VLFraction nextDur, const VLProperties & prop) const;
|
||||||
void MakeRepresentable();
|
void MakeRepresentable();
|
||||||
void AlignToGrid(VLFraction at, VLFraction grid);
|
void AlignToGrid(VLFraction at, VLFraction grid);
|
||||||
|
@ -210,7 +209,6 @@ struct VLChord : VLNote {
|
||||||
VLChord(VLFraction dur=0, int pitch=kNoPitch, int rootPitch=kNoPitch);
|
VLChord(VLFraction dur=0, int pitch=kNoPitch, int rootPitch=kNoPitch);
|
||||||
VLChord(std::string name);
|
VLChord(std::string name);
|
||||||
void Name(std::string & base, std::string & ext, std::string & root, bool useSharps = false) const;
|
void Name(std::string & base, std::string & ext, std::string & root, bool useSharps = false) const;
|
||||||
void LilypondName(std::string & name, bool useSharps = false) const;
|
|
||||||
bool MMAName(std::string & name, bool useSharps, bool initial) const;
|
bool MMAName(std::string & name, bool useSharps, bool initial) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,7 +272,8 @@ struct VLRepeat {
|
||||||
std::vector<Ending> fEndings;
|
std::vector<Ending> fEndings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VLSong {
|
class VLSong {
|
||||||
|
public:
|
||||||
VLSong(bool initialize = true);
|
VLSong(bool initialize = true);
|
||||||
void swap(VLSong & other);
|
void swap(VLSong & other);
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -368,14 +367,28 @@ struct VLSong {
|
||||||
size_t CountStanzas() const;
|
size_t CountStanzas() const;
|
||||||
size_t CountTopLedgers() const;
|
size_t CountTopLedgers() const;
|
||||||
size_t CountBotLedgers() const;
|
size_t CountBotLedgers() const;
|
||||||
void LilypondNotes(std::string & notes) const;
|
|
||||||
void LilypondChords(std::string & chords) const;
|
|
||||||
void LilypondStanza(std::string & lyrics, size_t stanza) const;
|
|
||||||
VLFract TiedDuration(size_t measure);
|
VLFract TiedDuration(size_t measure);
|
||||||
private:
|
private:
|
||||||
void AddMeasure();
|
void AddMeasure();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VLSongVisitor {
|
||||||
|
public:
|
||||||
|
virtual ~VLSongVisitor();
|
||||||
|
|
||||||
|
virtual void Visit(VLSong & song) {}
|
||||||
|
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas) {}
|
||||||
|
virtual void VisitNote(VLLyricsNote & n) {}
|
||||||
|
virtual void VisitChord(VLChord & c) {}
|
||||||
|
protected:
|
||||||
|
VLSongVisitor() {}
|
||||||
|
|
||||||
|
void VisitMeasures(VLSong & song, bool performanceOrder);
|
||||||
|
void VisitNotes(VLMeasure & measure, const VLProperties & prop,
|
||||||
|
bool decomposed);
|
||||||
|
void VisitChords(VLMeasure & measure);
|
||||||
|
};
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode:C++
|
// mode:C++
|
||||||
// End:
|
// End:
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
954DD4E60B44E67F0056C504 /* VLSheetViewSelection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 954DD4E50B44E67F0056C504 /* VLSheetViewSelection.mm */; };
|
954DD4E60B44E67F0056C504 /* VLSheetViewSelection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 954DD4E50B44E67F0056C504 /* VLSheetViewSelection.mm */; };
|
||||||
954F20310BFABD96006CAE0E /* VLMirrorWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 954F20300BFABD96006CAE0E /* VLMirrorWindow.nib */; };
|
954F20310BFABD96006CAE0E /* VLMirrorWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 954F20300BFABD96006CAE0E /* VLMirrorWindow.nib */; };
|
||||||
955CBA4F0B2366DD001CF4A1 /* VLKeyValueUndo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 955CBA4D0B2366DD001CF4A1 /* VLKeyValueUndo.mm */; };
|
955CBA4F0B2366DD001CF4A1 /* VLKeyValueUndo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 955CBA4D0B2366DD001CF4A1 /* VLKeyValueUndo.mm */; };
|
||||||
|
955DA2960C0551EC008F73B8 /* VLLilypondWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955DA2940C0551EC008F73B8 /* VLLilypondWriter.cpp */; };
|
||||||
955E58E5095658AB0045FDA5 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
|
955E58E5095658AB0045FDA5 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
|
||||||
955E59610957C1400045FDA5 /* TVLChord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E59600957C1400045FDA5 /* TVLChord.cpp */; };
|
955E59610957C1400045FDA5 /* TVLChord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E59600957C1400045FDA5 /* TVLChord.cpp */; };
|
||||||
955E59640957C15A0045FDA5 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
|
955E59640957C15A0045FDA5 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
|
||||||
|
@ -178,6 +179,8 @@
|
||||||
954F20300BFABD96006CAE0E /* VLMirrorWindow.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = VLMirrorWindow.nib; path = English.lproj/VLMirrorWindow.nib; sourceTree = "<group>"; };
|
954F20300BFABD96006CAE0E /* VLMirrorWindow.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = VLMirrorWindow.nib; path = English.lproj/VLMirrorWindow.nib; sourceTree = "<group>"; };
|
||||||
955CBA4C0B2366DD001CF4A1 /* VLKeyValueUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLKeyValueUndo.h; path = Sources/VLKeyValueUndo.h; sourceTree = "<group>"; };
|
955CBA4C0B2366DD001CF4A1 /* VLKeyValueUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLKeyValueUndo.h; path = Sources/VLKeyValueUndo.h; sourceTree = "<group>"; };
|
||||||
955CBA4D0B2366DD001CF4A1 /* VLKeyValueUndo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLKeyValueUndo.mm; path = Sources/VLKeyValueUndo.mm; sourceTree = "<group>"; };
|
955CBA4D0B2366DD001CF4A1 /* VLKeyValueUndo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLKeyValueUndo.mm; path = Sources/VLKeyValueUndo.mm; sourceTree = "<group>"; };
|
||||||
|
955DA2940C0551EC008F73B8 /* VLLilypondWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = VLLilypondWriter.cpp; path = Sources/VLLilypondWriter.cpp; sourceTree = "<group>"; };
|
||||||
|
955DA2950C0551EC008F73B8 /* VLLilypondWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLLilypondWriter.h; path = Sources/VLLilypondWriter.h; sourceTree = "<group>"; };
|
||||||
955E58E3095658AB0045FDA5 /* VLModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLModel.h; path = Sources/VLModel.h; sourceTree = "<group>"; };
|
955E58E3095658AB0045FDA5 /* VLModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLModel.h; path = Sources/VLModel.h; sourceTree = "<group>"; };
|
||||||
955E58E4095658AB0045FDA5 /* VLModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VLModel.cpp; path = Sources/VLModel.cpp; sourceTree = "<group>"; };
|
955E58E4095658AB0045FDA5 /* VLModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VLModel.cpp; path = Sources/VLModel.cpp; sourceTree = "<group>"; };
|
||||||
955E595C0957C0FC0045FDA5 /* TVLChord */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLChord; sourceTree = BUILT_PRODUCTS_DIR; };
|
955E595C0957C0FC0045FDA5 /* TVLChord */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLChord; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -339,6 +342,8 @@
|
||||||
2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
|
2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
955DA2940C0551EC008F73B8 /* VLLilypondWriter.cpp */,
|
||||||
|
955DA2950C0551EC008F73B8 /* VLLilypondWriter.h */,
|
||||||
95A55C520BD5E5760068A203 /* VLPDFDocument.h */,
|
95A55C520BD5E5760068A203 /* VLPDFDocument.h */,
|
||||||
95A55C530BD5E5770068A203 /* VLPDFDocument.mm */,
|
95A55C530BD5E5770068A203 /* VLPDFDocument.mm */,
|
||||||
95EDA5A80B06DE46004D8D6E /* VLMIDIDocument.h */,
|
95EDA5A80B06DE46004D8D6E /* VLMIDIDocument.h */,
|
||||||
|
@ -682,6 +687,7 @@
|
||||||
9599ED9D0B731CC500A6A2F7 /* VLGrooveController.mm in Sources */,
|
9599ED9D0B731CC500A6A2F7 /* VLGrooveController.mm in Sources */,
|
||||||
95A55C540BD5E5770068A203 /* VLPDFDocument.mm in Sources */,
|
95A55C540BD5E5770068A203 /* VLPDFDocument.mm in Sources */,
|
||||||
95784D870BFAD795009ABEA4 /* VLMirrorWindow.mm in Sources */,
|
95784D870BFAD795009ABEA4 /* VLMirrorWindow.mm in Sources */,
|
||||||
|
955DA2960C0551EC008F73B8 /* VLLilypondWriter.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user