Implement slurs, modernize C++

This commit is contained in:
Matthias Neeracher 2018-02-19 01:59:23 +01:00
parent a0e47688a4
commit 136d66fecc
24 changed files with 1684 additions and 7383 deletions

BIN
.DS_Store vendored

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -575,22 +575,15 @@ def _score
return score return score
end end
NEW_REXML = REXML::VERSION > "3.1.7"
xml = REXML::Document.new xml = REXML::Document.new
xml.add REXML::XMLDecl.new('1.0', 'UTF-8') xml.add REXML::XMLDecl.new('1.0', 'UTF-8')
xml.add REXML::DocType.new(['score-partwise', 'PUBLIC', xml.add REXML::DocType.new(['score-partwise', 'PUBLIC',
'"-//Recordare//DTD MusicXML 1.1 Partwise//EN"', '-//Recordare//DTD MusicXML 1.1 Partwise//EN',
NEW_REXML ? 'http://www.musicxml.org/dtds/partwise.dtd' : 'http://www.musicxml.org/dtds/partwise.dtd'])
'"http://www.musicxml.org/dtds/partwise.dtd"'])
xml.add_element(_score) xml.add_element(_score)
if NEW_REXML formatter = REXML::Formatters::Pretty.new(2)
formatter = REXML::Formatters::Pretty.new(2) formatter.compact = true
formatter.compact = true formatter.write(xml, $stdout)
formatter.write(xml, $stdout)
else
xml.write($stdout, 0)
end
# Local Variables: # Local Variables:
# mode:ruby # mode:ruby

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2011 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#import "VLDocument.h" #import "VLDocument.h"
@ -470,7 +470,7 @@
NewMusicSequence(&musicSequence); NewMusicSequence(&musicSequence);
MusicSequenceFileLoad(musicSequence, (CFURLRef)[self fileURLWithExtension:@"mid"], MusicSequenceFileLoad(musicSequence, (CFURLRef)[self fileURLWithExtension:@"mid"],
0, 0); kMusicSequenceFile_MIDIType, 0);
size_t countIn = 0; size_t countIn = 0;
if (playElements & kVLPlayCountIn) if (playElements & kVLPlayCountIn)

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2007-2011 Matthias Neeracher // Copyright © 2007-2018 Matthias Neeracher
// //
#include "VLLilypondWriter.h" #include "VLLilypondWriter.h"
@ -41,7 +41,7 @@ void VLLilypondWriter::Visit(VLSong & song)
fMelody += fSeenEnding ? "}}\n" : "}\n"; fMelody += fSeenEnding ? "}}\n" : "}\n";
} }
void VLLilypondWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas) void VLLilypondWriter::VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas)
{ {
char measNo[8]; char measNo[8];
if (!(m % 4)) if (!(m % 4))
@ -166,8 +166,10 @@ void VLLilypondWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas
fAccum.erase(trip, 15); fAccum.erase(trip, 15);
while ((trip = fAccum.find(" ~ } \\times 2/3 { ")) != std::string::npos) while ((trip = fAccum.find(" ~ } \\times 2/3 { ")) != std::string::npos)
fAccum.erase(trip+2, 17); fAccum.erase(trip+2, 17);
while ((trip = fAccum.find(" ~.")) != std::string::npos) while ((trip = fAccum.find("~.")) != std::string::npos)
fAccum.erase(trip, 2); fAccum.erase(trip, 1);
while ((trip = fAccum.find("~(.")) != std::string::npos)
fAccum.replace(trip, 3, ".(");
if (fSong->fGoToCoda == m+1) if (fSong->fGoToCoda == m+1)
fAccum += "\n" fAccum += "\n"
@ -257,25 +259,43 @@ void VLLilypondWriter::VisitNote(VLLyricsNote & n)
nm = "s"; nm = "s";
} }
const char * space = fAccum.size() ? " " : ""; const char * space = fAccum.size() ? " " : "";
const char * tie = n.fTied & VLNote::kTiedWithNext ? " ~" : ""; const char * tie;
switch (n.fTied & (VLNote::kTiedWithNext|VLNote::kSlurWithNext|VLNote::kStartSlur|VLNote::kEndSlur)) {
case VLNote::kTiedWithNext|VLNote::kSlurWithNext|VLNote::kStartSlur:
tie = "(";
break;
case VLNote::kTiedWithNext|VLNote::kStartSlur:
tie = "~(";
break;
case VLNote::kTiedWithNext:
tie = "~";
break;
case VLNote::kEndSlur:
tie = ")";
break;
case VLNote::kTiedWithNext|VLNote::kSlurWithNext:
default:
tie = "";
break;
}
char duration[32]; char duration[32];
if (n.fTied == VLNote::kTiedWithPrev && n.fVisual == fPrevNote.fVisual+1 if ((n.fTied & VLNote::kTiedWithPrev) && n.fVisual == fPrevNote.fVisual+1
&& n.fPitch == fPrevNote.fPitch && n.fPitch == fPrevNote.fPitch
) ) {
strcpy(duration, "."); strcpy(duration, ".");
else if (n.fVisual & VLNote::kTupletMask) } else if (n.fVisual & VLNote::kTupletMask) {
sprintf(duration, "%s\\times %d/%d { %s%d%s }", sprintf(duration, "%s\\times %d/%d { %s%d%s }",
space, VLNote::TupletDenom(n.fVisual), VLNote::TupletNum(n.fVisual), space, VLNote::TupletDenom(n.fVisual), VLNote::TupletNum(n.fVisual),
nm.c_str(), kValue[n.fVisual & VLNote::kNoteHeadMask], tie); nm.c_str(), kValue[n.fVisual & VLNote::kNoteHeadMask], tie);
else } else {
sprintf(duration, "%s%s%d%s", sprintf(duration, "%s%s%d%s",
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHeadMask], tie); space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHeadMask], tie);
}
fAccum += duration;
fPrevNote = n;
fAccum += duration; if (n.fPitch != VLNote::kNoPitch && !(n.fTied & VLNote::kTiedWithPrev)) {
fPrevNote= n; for (size_t i=0; i<fL.size(); ++i) {
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]) { if (n.fLyrics.size() <= i || !n.fLyrics[i]) {
fL[i] += " \\skip1"; fL[i] += " \\skip1";
} else { } else {
@ -283,6 +303,8 @@ void VLLilypondWriter::VisitNote(VLLyricsNote & n)
if (n.fLyrics[i].fKind & VLSyllable::kHasNext) if (n.fLyrics[i].fKind & VLSyllable::kHasNext)
fL[i] += " --"; fL[i] += " --";
} }
}
}
} }
static const char * kLilypondStepNames[] = { static const char * kLilypondStepNames[] = {

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2007 Matthias Neeracher // Copyright © 2007-2018 Matthias Neeracher
// //
#include "VLModel.h" #include "VLModel.h"
@ -14,10 +14,10 @@ class VLLilypondWriter: public VLSongVisitor {
public: public:
VLLilypondWriter() {} VLLilypondWriter() {}
virtual void Visit(VLSong & song); void Visit(VLSong & song) override;
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas); void VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas) override;
virtual void VisitNote(VLLyricsNote & n); void VisitNote(VLLyricsNote & n) override;
virtual void VisitChord(VLChord & c); void VisitChord(VLChord & c) override;
const std::string & Chords() const { return fChords; } const std::string & Chords() const { return fChords; }
const std::string & Melody() const { return fMelody; } const std::string & Melody() const { return fMelody; }
@ -30,9 +30,12 @@ private:
VLSong * fSong; VLSong * fSong;
bool fUseSharps; bool fUseSharps;
bool fInPickup; bool fInPickup;
bool fInSlur;
bool fAutomaticLayout; bool fAutomaticLayout;
int fPrevBreak; int fPrevBreak;
size_t fSeenEnding; size_t fSeenEnding;
size_t fPrevTie;
size_t fStartTie;
int fNumEndings; int fNumEndings;
VLNote fPrevNote; VLNote fPrevNote;
std::string fAccum; std::string fAccum;

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2008-2011 Matthias Neeracher // Copyright © 2008-2018 Matthias Neeracher
// //
#include "VLMIDIWriter.h" #include "VLMIDIWriter.h"
@ -77,7 +77,7 @@ void VLMIDIWriter::Visit(VLSong & song)
VisitMeasures(song, true); VisitMeasures(song, true);
} }
void VLMIDIWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas) void VLMIDIWriter::VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas)
{ {
const VLLocation kStartOfMeasure = {m, VLFraction(0)}; const VLLocation kStartOfMeasure = {m, VLFraction(0)};
if (fVolta.size() <= m) if (fVolta.size() <= m)
@ -98,7 +98,7 @@ void VLMIDIWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
void VLMIDIWriter::VisitNote(VLLyricsNote & n) void VLMIDIWriter::VisitNote(VLLyricsNote & n)
{ {
if (!(n.fTied & VLNote::kTiedWithPrev)) { if (!(n.fTied & VLNote::kTiedWithPrev)) {
VLMIDIUserEvent event = {12, n.fPitch, fStanza, n.fVisual, fAt}; VLMIDIUserEvent event = {12, n.fPitch, static_cast<uint8_t>(fStanza), n.fVisual, fAt};
MusicTrackNewUserEvent(fTrack, fNoteTime, MusicTrackNewUserEvent(fTrack, fNoteTime,
reinterpret_cast<const MusicEventUserData *>(&event)); reinterpret_cast<const MusicEventUserData *>(&event));
} }
@ -109,7 +109,7 @@ void VLMIDIWriter::VisitNote(VLLyricsNote & n)
void VLMIDIWriter::VisitChord(VLChord & c) void VLMIDIWriter::VisitChord(VLChord & c)
{ {
if (c.fPitch != VLNote::kNoPitch) { if (c.fPitch != VLNote::kNoPitch) {
VLMIDIUserEvent event = {12, 0, fStanza, 0, fAt}; VLMIDIUserEvent event = {12, 0, static_cast<uint8_t>(fStanza), 0, fAt};
MusicTrackNewUserEvent(fTrack, fChordTime, MusicTrackNewUserEvent(fTrack, fChordTime,
reinterpret_cast<const MusicEventUserData *>(&event)); reinterpret_cast<const MusicEventUserData *>(&event));
} }

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2008-2011 Matthias Neeracher // Copyright © 2008-2018 Matthias Neeracher
// //
#include "VLModel.h" #include "VLModel.h"
@ -35,10 +35,10 @@ public:
VLMIDIWriter(MusicSequence music, size_t countIn) VLMIDIWriter(MusicSequence music, size_t countIn)
: fMusic(music), fCountIn(countIn) {} : fMusic(music), fCountIn(countIn) {}
virtual void Visit(VLSong & song); void Visit(VLSong & song) override;
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas); void VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas) override;
virtual void VisitNote(VLLyricsNote & n); void VisitNote(VLLyricsNote & n) override;
virtual void VisitChord(VLChord & c); void VisitChord(VLChord & c) override;
private: private:
MusicSequence fMusic; MusicSequence fMusic;
size_t fCountIn; size_t fCountIn;

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2007 Matthias Neeracher // Copyright © 2007-2018 Matthias Neeracher
// //
#include "VLMMAWriter.h" #include "VLMMAWriter.h"
@ -22,7 +22,7 @@ void VLMMAWriter::Visit(VLSong & song)
VisitMeasures(song, true); VisitMeasures(song, true);
} }
void VLMMAWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas) void VLMMAWriter::VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas)
{ {
if (fPreview) if (fPreview)
if (meas.fPropIdx < fBeginSection || meas.fPropIdx >= fEndSection) if (meas.fPropIdx < fBeginSection || meas.fPropIdx >= fEndSection)

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2007 Matthias Neeracher // Copyright © 2007-2018 Matthias Neeracher
// //
#include "VLModel.h" #include "VLModel.h"
@ -16,10 +16,10 @@ public:
: fPreview(preview), fBeginSection(beginSection), fEndSection(endSection) : fPreview(preview), fBeginSection(beginSection), fEndSection(endSection)
{} {}
virtual void Visit(VLSong & song); void Visit(VLSong & song) override;
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas); void VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas) override;
virtual void VisitNote(VLLyricsNote & n); void VisitNote(VLLyricsNote & n) override;
virtual void VisitChord(VLChord & c); void VisitChord(VLChord & c) override;
const std::string & Measures() const { return fMeasures; } const std::string & Measures() const { return fMeasures; }
private: private:

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2017 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#include "VLModel.h" #include "VLModel.h"
@ -107,11 +107,13 @@ VLNote::VLNote(VLFraction dur, int pitch, uint16_t visual)
std::string VLNote::Name(uint16_t accidental) const std::string VLNote::Name(uint16_t accidental) const
{ {
if (uint16_t acc = (fVisual & kAccidentalsMask)) if (uint16_t acc = (fVisual & kAccidentalsMask)) {
if (acc == kWantNatural) if (acc == kWantNatural) {
accidental |= acc; accidental |= acc;
else } else {
accidental = acc; accidental = acc;
}
}
return VLPitchName(fPitch, accidental); return VLPitchName(fPitch, accidental);
} }
@ -603,6 +605,57 @@ void VLSong::DelChord(VLLocation at)
fMeasures.pop_back(); fMeasures.pop_back();
} }
VLSong::note_iterator::note_iterator(const VLMeasureList::iterator &meas, const VLNoteList::iterator &note)
: fMeasIter(meas), fNoteIter(note)
{
}
VLSong::note_iterator &
VLSong::note_iterator::operator--()
{
if (fNoteIter == fMeasIter->fMelody.begin()) {
--fMeasIter;
fNoteIter = fMeasIter->fMelody.end();
}
--fNoteIter;
return *this;
}
VLSong::note_iterator &
VLSong::note_iterator::operator++()
{
++fNoteIter;
if (fNoteIter == fMeasIter->fMelody.end()) {
++fMeasIter;
fNoteIter = fMeasIter->fMelody.begin();
}
return *this;
}
bool
VLSong::note_iterator::operator==(const note_iterator &other)
{
return fMeasIter == other.fMeasIter && fNoteIter == other.fNoteIter;
}
VLSong::note_iterator
VLSong::begin_note(size_t measure)
{
return note_iterator(fMeasures.begin()+measure, fMeasures[measure].fMelody.begin());
}
VLSong::note_iterator
VLSong::end_note(size_t measure)
{
return note_iterator(fMeasures.begin()+measure, fMeasures[measure].fMelody.end());
}
VLSong::note_iterator
VLSong::end_note()
{
return end_note(fMeasures.size()-1);
}
VLLyricsNote VLSong::FindNote(VLLocation at) VLLyricsNote VLSong::FindNote(VLLocation at)
{ {
VLNoteList::iterator i = fMeasures[at.fMeasure].fMelody.begin(); VLNoteList::iterator i = fMeasures[at.fMeasure].fMelody.begin();
@ -781,15 +834,19 @@ void VLSong::AddNote(VLLyricsNote note, VLLocation at)
++i; ++i;
} }
i->fTied = 0; i->fTied = 0;
if (note.fTied & VLNote::kTiedWithPrev) // kTiedWithNext is NEVER user set if (note.fTied & VLNote::kTiedWithPrev) {// kTiedWithNext is NEVER user set
if (at.fMeasure && i == fMeasures[at.fMeasure].fMelody.begin()) { auto j = i;
VLNoteList::iterator j = fMeasures[at.fMeasure-1].fMelody.end(); if (at.fAt != VLFraction(0) || at.fMeasure) {
--j; if (at.fAt == VLFraction(0)) {
if (j->fPitch == i->fPitch) { j = fMeasures[at.fMeasure-1].fMelody.end();
j->fTied |= VLNote::kTiedWithNext; }
i->fTied |= VLNote::kTiedWithPrev; --j;
} if (note.fPitch != VLNote::kNoPitch && j->fPitch != VLNote::kNoPitch) {
} j->fTied |= VLNote::kTiedWithNext;
i->fTied |= VLNote::kTiedWithPrev;
}
}
}
} }
void VLSong::DelNote(VLLocation at) void VLSong::DelNote(VLLocation at)
@ -906,6 +963,97 @@ VLNote VLSong::ExtendNote(VLLocation at)
return *i; return *i;
} }
VLLocation VLSong::TieNote(VLLocation at, bool tieWithPrev)
{
VLNoteList::iterator i = fMeasures[at.fMeasure].fMelody.begin();
VLNoteList::iterator end= fMeasures[at.fMeasure].fMelody.end();
if (i==end)
return VLLocation(); // Empty song, do nothing
for (VLFraction t(0); i != end && t+i->fDuration <= at.fAt; ++i)
t += i->fDuration;
if (i == end)
--i;
if (i->fPitch == VLNote::kNoPitch)
return VLLocation(); // Don't tie rests
VLNoteList::iterator j=i;
auto startMeasure = at.fMeasure;
if (tieWithPrev) {
if (j != fMeasures[at.fMeasure].fMelody.begin()) {
--j;
//
// Extend across next note/rest
//
if (i->fPitch == j->fPitch) {
// Consolidate identical pitches
j->fDuration += i->fDuration;
fMeasures[at.fMeasure].fMelody.erase(i);
i = j;
} else {
i->fTied |= VLNote::kTiedWithPrev;
j->fTied |= VLNote::kTiedWithNext;
i->fLyrics.clear();
}
} else if (at.fMeasure-- > 0) {
//
// Extend into previous measure
//
j = fMeasures[at.fMeasure].fMelody.end();
--j;
if (j->fPitch != VLNote::kNoPitch) { // Don't tie with rests
i->fTied |= VLNote::kTiedWithPrev;
j->fTied |= VLNote::kTiedWithNext;
i->fLyrics.clear();
}
}
} else {
++j;
if (j != fMeasures[at.fMeasure].fMelody.end()) {
//
// Extend across next note/rest
//
if (i->fPitch == j->fPitch) {
// Consolidate identical pitches
i->fDuration += j->fDuration;
fMeasures[at.fMeasure].fMelody.erase(j);
} else {
i->fTied |= VLNote::kTiedWithNext;
j->fTied |= VLNote::kTiedWithPrev;
j->fLyrics.clear();
}
} else if (++at.fMeasure < fMeasures.size()) {
//
// Extend into next measure
//
j = fMeasures[at.fMeasure].fMelody.begin();
if (j->fPitch != VLNote::kNoPitch) { // Don't tie with rests
i->fTied |= VLNote::kTiedWithNext;
j->fTied |= VLNote::kTiedWithPrev;
j->fLyrics.clear();
}
}
}
while (i->fTied & VLNote::kTiedWithPrev) {
if (i == fMeasures[startMeasure].fMelody.begin()) {
if (startMeasure) {
i = fMeasures[--startMeasure].fMelody.end();
} else {
break;
}
}
--i;
}
at.fMeasure = startMeasure;
at.fAt = VLFraction();
for (j = fMeasures[startMeasure].fMelody.begin(); j != i; ++j) {
at.fAt = at.fAt+j->fDuration;
}
return at;
}
bool VLSong::IsNonEmpty() const bool VLSong::IsNonEmpty() const
{ {
for (size_t measure=0; measure<fMeasures.size(); ++measure) { for (size_t measure=0; measure<fMeasures.size(); ++measure) {
@ -1346,7 +1494,6 @@ bool VLSong::PrevWord(size_t stanza, VLLocation & at)
do { do {
VLMeasure & meas = fMeasures[at.fMeasure]; VLMeasure & meas = fMeasures[at.fMeasure];
VLNoteList::iterator note = fMeasures[at.fMeasure].fMelody.begin(); VLNoteList::iterator note = fMeasures[at.fMeasure].fMelody.begin();
VLNoteList::iterator end = fMeasures[at.fMeasure].fMelody.end();
bool hasWord = false; bool hasWord = false;
VLFraction word(0); VLFraction word(0);
VLFraction now(0); VLFraction now(0);
@ -1384,7 +1531,6 @@ bool VLSong::NextWord(size_t stanza, VLLocation & at)
do { do {
VLMeasure & meas = fMeasures[at.fMeasure]; VLMeasure & meas = fMeasures[at.fMeasure];
VLNoteList::iterator note = fMeasures[at.fMeasure].fMelody.begin(); VLNoteList::iterator note = fMeasures[at.fMeasure].fMelody.begin();
VLNoteList::iterator end = fMeasures[at.fMeasure].fMelody.end();
VLFraction now(0); VLFraction now(0);
while (note != meas.fMelody.end()) { while (note != meas.fMelody.end()) {
@ -1459,7 +1605,6 @@ void VLSong::SetWord(size_t stanza, VLLocation at, std::string word, VLLocation
do { do {
VLMeasure & meas = fMeasures[at.fMeasure]; VLMeasure & meas = fMeasures[at.fMeasure];
VLNoteList::iterator note = fMeasures[at.fMeasure].fMelody.begin(); VLNoteList::iterator note = fMeasures[at.fMeasure].fMelody.begin();
VLNoteList::iterator end = fMeasures[at.fMeasure].fMelody.end();
VLFraction now(0); VLFraction now(0);
while (note != meas.fMelody.end()) { while (note != meas.fMelody.end()) {
@ -1550,7 +1695,7 @@ void VLSong::AddRepeat(size_t beginMeasure, size_t endMeasure, int times)
VLRepeat & rp = fRepeats[r]; VLRepeat & rp = fRepeats[r];
if (rp.fEndings[0].fBegin == beginMeasure if (rp.fEndings[0].fBegin == beginMeasure
&& rp.fEndings[0].fEnd >= endMeasure && rp.fEndings[0].fEnd >= endMeasure
) ) {
if (rp.fEndings[0].fEnd == endMeasure) { if (rp.fEndings[0].fEnd == endMeasure) {
// //
// Exact match, just change times // Exact match, just change times
@ -1569,6 +1714,7 @@ void VLSong::AddRepeat(size_t beginMeasure, size_t endMeasure, int times)
break; break;
} }
}
} }
VLRepeat rep; VLRepeat rep;
@ -1795,13 +1941,15 @@ bool VLSong::DoesBeginEnding(size_t measure, bool * repeat, size_t * volta) cons
size_t v = (1<<rp.fTimes)-1; size_t v = (1<<rp.fTimes)-1;
for (size_t e=1; e<rp.fEndings.size(); ++e) for (size_t e=1; e<rp.fEndings.size(); ++e)
if (rp.fEndings[e].fBegin == measure) { if (rp.fEndings[e].fBegin == measure) {
if (repeat) if (repeat) {
if (e == rp.fEndings.size()-1 if (e == rp.fEndings.size()-1
&& rp.fEndings[e].fVolta == v && rp.fEndings[e].fVolta == v
) ) {
*repeat = false; // Not after last alternative *repeat = false; // Not after last alternative
else } else {
*repeat = true; *repeat = true;
}
}
if (volta) if (volta)
*volta = rp.fEndings[e].fVolta; *volta = rp.fEndings[e].fVolta;
@ -2279,6 +2427,7 @@ VLSongVisitor::~VLSongVisitor()
void VLSongVisitor::VisitMeasures(VLSong & song, bool performanceOrder) void VLSongVisitor::VisitMeasures(VLSong & song, bool performanceOrder)
{ {
fSong = &song;
if (performanceOrder) { if (performanceOrder) {
VLSong::iterator e = song.end(); VLSong::iterator e = song.end();
@ -2309,6 +2458,75 @@ void VLSongVisitor::VisitNotes(VLMeasure & measure, const VLProperties & prop,
if (decomposed) { if (decomposed) {
measure.DecomposeNotes(prop, decomp); measure.DecomposeNotes(prop, decomp);
// Set slur flags
bool inSlur = false;
bool inTie = false;
uint8_t prevPitch = 0;
if ((decomp.front().fTied & VLNote::kTiedWithPrev)) {
inTie = true;
prevPitch = decomp.front().fPitch;
auto predecessor = fSong->begin_note(&measure-&fSong->fMeasures[0]);
bool seenNote = false;
do {
--predecessor;
if (predecessor->fPitch != decomp.front().fPitch) {
inSlur = true;
if (!seenNote) {
decomp.front().fTied |= VLNote::kSlurWithPrev;
}
break;
}
seenNote = true;
} while (predecessor->fTied & VLNote::kTiedWithPrev);
}
VLLyricsNote *firstInTie = nullptr;
VLLyricsNote *prevInTie = nullptr;
for (auto &note: decomp) {
if ((note.fTied & VLNote::kTiedWithPrev) && note.fPitch != prevPitch) {
if (prevInTie) {
prevInTie->fTied |= VLNote::kSlurWithNext;
}
note.fTied |= VLNote::kSlurWithPrev;
inSlur = true;
}
if (note.fTied & VLNote::kTiedWithNext) {
if (!inTie) {
firstInTie = &note;
inTie = true;
}
prevInTie = &note;
prevPitch = note.fPitch;
} else {
if (inSlur) {
if (firstInTie) {
firstInTie->fTied |= VLNote::kStartSlur;
}
note.fTied |= VLNote::kEndSlur;
}
inSlur = false;
inTie = false;
}
}
if (inTie) {
// Find out if measure-final tie contains slur
auto successor = fSong->begin_note(&measure-&fSong->fMeasures[0]+1);
if (successor->fPitch != prevPitch) {
prevInTie->fTied |= VLNote::kSlurWithNext;
}
while (!inSlur) {
if (successor->fPitch != prevPitch) {
inSlur = true;
} else if (!(successor->fTied & VLNote::kTiedWithNext)) {
break;
} else {
++successor;
}
}
}
if (inSlur && firstInTie) {
firstInTie->fTied |= VLNote::kStartSlur;
}
n = decomp.begin(); n = decomp.begin();
e = decomp.end(); e = decomp.end();
} else { } else {

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2011 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#include <list> #include <list>
@ -159,14 +159,18 @@ struct VLNote {
kOctave = 12 kOctave = 12
}; };
// //
// We only allow ties BETWEEN measures. Within measures, we just store // We only allow ties BETWEEN measures or different pitches. Within measures, we
// a combined note length. // just store a combined note length.
// //
uint8_t fTied; // Tied with note in adjacent measure uint8_t fTied; // Tied with adjacent note
enum { enum {
kNotTied = 0, kNotTied = 0,
kTiedWithNext = 1, kTiedWithNext = 1,
kTiedWithPrev = 2, kTiedWithPrev = 2,
kSlurWithNext = 4,
kSlurWithPrev = 8,
kStartSlur = 16,
kEndSlur = 32,
}; };
// //
// Hint at visual representation (Computed in DecomposeNotes) // Hint at visual representation (Computed in DecomposeNotes)
@ -198,8 +202,8 @@ struct VLNote {
kTupletMask = 0xFF00 kTupletMask = 0xFF00
}; };
static int TupletNum(uint16_t visual) { return visual >> 12; } static uint16_t TupletNum(uint16_t visual) { return visual >> 12; }
static int TupletDenom(uint16_t visual) { return (visual >> 8) & 0x0F; } static uint16_t TupletDenom(uint16_t visual) { return (visual >> 8) & 0x0F; }
static uint16_t Tuplet(int num, int denom) { return (num << 12) | (denom << 8); } static uint16_t Tuplet(int num, int denom) { return (num << 12) | (denom << 8); }
VLNote(VLFraction dur=0, int pitch=kNoPitch, uint16_t visual=0); VLNote(VLFraction dur=0, int pitch=kNoPitch, uint16_t visual=0);
VLNote(std::string name); VLNote(std::string name);
@ -342,6 +346,8 @@ struct VLMeasure {
bool IsEmpty() const; bool IsEmpty() const;
bool NoChords() const; bool NoChords() const;
bool CanSkipRests() const; bool CanSkipRests() const;
bool SlurAtStart() const;
bool SlurAtEnd() const;
void DecomposeNotes(const VLProperties & prop, VLNoteList & decomposed) const; void DecomposeNotes(const VLProperties & prop, VLNoteList & decomposed) const;
}; };
@ -420,6 +426,26 @@ public:
iterator begin() { return iterator(*this, false); } iterator begin() { return iterator(*this, false); }
iterator end() { return iterator(*this, true); } iterator end() { return iterator(*this, true); }
// Iterate over all notes in song
class note_iterator {
public:
note_iterator(const VLMeasureList::iterator &meas, const VLNoteList::iterator &note);
VLLyricsNote &operator*() { return *fNoteIter; }
VLLyricsNote *operator->() { return &*fNoteIter; }
note_iterator &operator--();
note_iterator &operator++();
bool operator==(const note_iterator &other);
bool operator!=(const note_iterator &other) { return !(*this == other); }
private:
VLNoteList::iterator fNoteIter;
VLMeasureList::iterator fMeasIter;
};
note_iterator begin_note(size_t measure=0);
note_iterator end_note(size_t measure);
note_iterator end_note();
VLLyricsNote FindNote(VLLocation at); VLLyricsNote FindNote(VLLocation at);
bool PrevNote(VLLocation & at); bool PrevNote(VLLocation & at);
bool NextNote(VLLocation & at); bool NextNote(VLLocation & at);
@ -428,6 +454,7 @@ public:
void DelChord(VLLocation at); void DelChord(VLLocation at);
void DelNote(VLLocation at); void DelNote(VLLocation at);
VLNote ExtendNote(VLLocation at); VLNote ExtendNote(VLLocation at);
VLLocation TieNote(VLLocation at, bool tieWithPrev);
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);
@ -493,10 +520,10 @@ class VLSongVisitor {
public: public:
virtual ~VLSongVisitor(); virtual ~VLSongVisitor();
virtual void Visit(VLSong & song) {} virtual void Visit(VLSong & song) {}
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas) {} virtual void VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas) {}
virtual void VisitNote(VLLyricsNote & n) {} virtual void VisitNote(VLLyricsNote & n) {}
virtual void VisitChord(VLChord & c) {} virtual void VisitChord(VLChord & c) {}
protected: protected:
VLSongVisitor() {} VLSongVisitor() {}
@ -504,6 +531,8 @@ protected:
void VisitNotes(VLMeasure & measure, const VLProperties & prop, void VisitNotes(VLMeasure & measure, const VLProperties & prop,
bool decomposed); bool decomposed);
void VisitChords(VLMeasure & measure); void VisitChords(VLMeasure & measure);
private:
VLSong *fSong;
}; };
#endif #endif

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2007 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#import "VLPDFView.h" #import "VLPDFView.h"
@ -45,14 +45,14 @@
{ {
// Display single page mode. // Display single page mode.
if ([self displayMode] > kPDFDisplaySinglePageContinuous) if ([self displayMode] > kPDFDisplaySinglePageContinuous)
[self setDisplayMode: [self displayMode] - 2]; [self setDisplayMode: static_cast<PDFDisplayMode>([self displayMode] - 2)];
} }
- (IBAction) displayTwoUp: (id) sender - (IBAction) displayTwoUp: (id) sender
{ {
// Display two-up. // Display two-up.
if ([self displayMode] < kPDFDisplayTwoUp) if ([self displayMode] < kPDFDisplayTwoUp)
[self setDisplayMode: [self displayMode] + 2]; [self setDisplayMode: static_cast<PDFDisplayMode>([self displayMode] + 2)];
} }
- (IBAction) zoomToFit: (id) sender - (IBAction) zoomToFit: (id) sender

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2007-2011 Matthias Neeracher // Copyright © 2007-2018 Matthias Neeracher
// //
#import "VLPListDocument.h" #import "VLPListDocument.h"
@ -26,11 +26,11 @@ public:
VLPlistVisitor(NSMutableDictionary * plist, bool performanceOrder) VLPlistVisitor(NSMutableDictionary * plist, bool performanceOrder)
: fPlist(plist), fPerfOrder(performanceOrder) {} : fPlist(plist), fPerfOrder(performanceOrder) {}
virtual void Visit(VLSong & song); void Visit(VLSong & song) override;
protected: protected:
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas); void VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas) override;
virtual void VisitNote(VLLyricsNote & n); void VisitNote(VLLyricsNote & n) override;
virtual void VisitChord(VLChord & c); void VisitChord(VLChord & c) override;
NSArray * EncodeProperties(const std::vector<VLProperties> & properties); NSArray * EncodeProperties(const std::vector<VLProperties> & properties);
NSDictionary * EncodeProperties(const VLProperties & properties); NSDictionary * EncodeProperties(const VLProperties & properties);
@ -82,7 +82,7 @@ void VLPlistVisitor::Visit(VLSong & song)
[fPlist setObject:fMeasures forKey:@"measures"]; [fPlist setObject:fMeasures forKey:@"measures"];
} }
void VLPlistVisitor::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas) void VLPlistVisitor::VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas)
{ {
fNotes = [NSMutableArray arrayWithCapacity:1]; fNotes = [NSMutableArray arrayWithCapacity:1];
fChords= [NSMutableArray arrayWithCapacity:1]; fChords= [NSMutableArray arrayWithCapacity:1];
@ -303,7 +303,7 @@ enum {
kPotentialSwing16th kPotentialSwing16th
}; };
- (void)readMelody:(NSArray *)melody inMeasure:(size_t)measNo onsets:(int *)onsets lyrics:(uint8_t *)prevKind - (void)readMelody:(NSArray *)melody inMeasure:(uint32_t)measNo onsets:(int *)onsets lyrics:(uint8_t *)prevKind
{ {
VLLocation at = {measNo, VLFraction(0)}; VLLocation at = {measNo, VLFraction(0)};
int lastOnset = 0; int lastOnset = 0;
@ -328,7 +328,7 @@ enum {
[[ndict objectForKey:@"normalNotes"] intValue]); [[ndict objectForKey:@"normalNotes"] intValue]);
if ([[ndict objectForKey:@"tied"] intValue] & VLNote::kTiedWithPrev) { if ([[ndict objectForKey:@"tied"] intValue] & VLNote::kTiedWithPrev) {
if (at.fAt != VLFraction(0)) { if (at.fAt != VLFraction(0) && note.fPitch == tiedNote.fPitch) {
// //
// Extend preceding note // Extend preceding note
// //
@ -339,9 +339,9 @@ enum {
goto advanceAt; goto advanceAt;
} else { } else {
// //
// Extend previous measure // Slur or extend previous measure
// //
note.fTied |= VLNote::kTiedWithPrev; note.fTied |= VLNote::kTiedWithPrev;
} }
} else { } else {
for (NSEnumerator * le = [[ndict objectForKey:@"lyrics"] objectEnumerator]; for (NSEnumerator * le = [[ndict objectForKey:@"lyrics"] objectEnumerator];
@ -402,7 +402,7 @@ advanceAt:
} }
} }
- (void)readChords:(NSArray *)chords inMeasure:(size_t)measNo - (void)readChords:(NSArray *)chords inMeasure:(uint32_t)measNo
{ {
VLLocation at = {measNo, VLFraction(0)}; VLLocation at = {measNo, VLFraction(0)};

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2012 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -109,6 +109,7 @@ const uint32_t kNoMeasure = (uint32_t)-1;
IBOutlet id fKeyMenu; IBOutlet id fKeyMenu;
IBOutlet id fTimeMenu; IBOutlet id fTimeMenu;
IBOutlet id fDivisionMenu; IBOutlet id fDivisionMenu;
IBOutlet NSMenu *fNoteActionMenu;
} }
@property (nonatomic) int numTopLedgers; @property (nonatomic) int numTopLedgers;

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2008 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#import "VLSheetView.h" #import "VLSheetView.h"
@ -804,6 +804,11 @@ const float kSemiFloor = -1.0f*kLineH;
if ([event modifierFlags] & NSAlphaShiftKeyMask) if ([event modifierFlags] & NSAlphaShiftKeyMask)
return; // Keyboard mode, ignore mouse return; // Keyboard mode, ignore mouse
if ([event modifierFlags] & NSControlKeyMask) {
[[NSCursor contextualMenuCursor] set];
} else {
[[NSCursor arrowCursor] set];
}
bool hadCursor = fCursorRegion == kRegionNote; bool hadCursor = fCursorRegion == kRegionNote;
[self findRegionForEvent:event]; [self findRegionForEvent:event];
bool hasCursor = fCursorRegion == kRegionNote; bool hasCursor = fCursorRegion == kRegionNote;
@ -830,17 +835,36 @@ const float kSemiFloor = -1.0f*kLineH;
fCursorRegion = kRegionNowhere; fCursorRegion = kRegionNowhere;
[[self window] setAcceptsMouseMovedEvents:NO]; [[self window] setAcceptsMouseMovedEvents:NO];
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
[[NSCursor arrowCursor] set];
}
- (void) rightMouseDown:(NSEvent *)event
{
[[self document] endSong];
VLRegion region = [self findRegionForEvent:event];
switch (region) {
case kRegionNote:
[NSMenu popUpContextMenu:fNoteActionMenu withEvent:event forView:self];
break;
default:
break;
}
} }
- (void) mouseDown:(NSEvent *)event - (void) mouseDown:(NSEvent *)event
{ {
if ([event modifierFlags] & NSControlKeyMask) {
[self rightMouseDown:event];
return;
}
[[self document] endSong]; [[self document] endSong];
BOOL extend = ([event modifierFlags] & NSShiftKeyMask) != 0; BOOL extend = ([event modifierFlags] & NSShiftKeyMask) != 0;
VLRegion region = [self findRegionForEvent:event]; VLRegion region = [self findRegionForEvent:event];
if (extend && [[self editTarget] canExtendSelection:region]) if (extend && [[self editTarget] canExtendSelection:region])
[[self editTarget] extendSelection:fCursorLocation]; [[self editTarget] extendSelection:fCursorLocation];
else else
switch (region) { switch (region) {
case kRegionNote: case kRegionNote:
[self setEditTarget:nil]; [self setEditTarget:nil];

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2006-2017 Matthias Neeracher // Copyright © 2006-2018 Matthias Neeracher
// //
#import "VLSheetView.h" #import "VLSheetView.h"
@ -224,7 +224,7 @@ std::string NormalizeName(NSString* rawName)
// Build new list // Build new list
// //
for (int m = 0; m<kLayout.NumMeasures(); ++m) { for (int m = 0; m<kLayout.NumMeasures(); ++m) {
int measIdx = m+kFirstMeas; uint32_t measIdx = m+kFirstMeas;
if (measIdx >= song->CountMeasures()) if (measIdx >= song->CountMeasures())
break; break;
const VLMeasure measure = song->fMeasures[measIdx]; const VLMeasure measure = song->fMeasures[measIdx];

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2006-2007 Matthias Neeracher // Copyright © 2006-2018 Matthias Neeracher
// //
#import "VLSheetView.h" #import "VLSheetView.h"
@ -211,7 +211,7 @@ float VLCocoaFontHandler::Width(const char * utf8Text)
// Build new list // Build new list
// //
for (int m = 0; m<kLayout.NumMeasures(); ++m) { for (int m = 0; m<kLayout.NumMeasures(); ++m) {
int measIdx = m+kFirstMeas; uint32_t measIdx = m+kFirstMeas;
if (measIdx >= song->CountMeasures()) if (measIdx >= song->CountMeasures())
break; break;
const VLMeasure measure = song->fMeasures[measIdx]; const VLMeasure measure = song->fMeasures[measIdx];

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2011 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -19,6 +19,11 @@
- (void) moveCursorToNextNote; - (void) moveCursorToNextNote;
- (void) moveCursorToPrevNote; - (void) moveCursorToPrevNote;
- (IBAction) tieNoteWithPrev:(id)sender;
- (IBAction) tieNoteWithNext:(id)sender;
- (IBAction) addRest:(id)sender;
- (IBAction) deleteNote:(id)sender;
@end @end
// Local Variables: // Local Variables:

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2011 Matthias Neeracher // Copyright © 2005-2018 Matthias Neeracher
// //
#import "VLSheetView.h" #import "VLSheetView.h"
@ -19,6 +19,43 @@
@implementation VLSheetView (Notes) @implementation VLSheetView (Notes)
- (IBAction)tieNoteWithPrev:(id)sender
{
if (fCursorLocation.fMeasure != kNoMeasure) {
[[self document] willChangeSong];
[self song]->TieNote(fCursorLocation, true);
[[self document] didChangeSong];
}
}
- (IBAction)tieNoteWithNext:(id)sender
{
if (fCursorLocation.fMeasure != kNoMeasure) {
[[self document] willChangeSong];
[self song]->TieNote(fCursorLocation, false);
[[self document] didChangeSong];
}
}
- (IBAction)addRest:(id)sender
{
if (fCursorLocation.fMeasure != kNoMeasure) {
VLLyricsNote note;
[[self document] willChangeSong];
[self song]->AddNote(note, fCursorLocation);
[[self document] didChangeSong];
}
}
- (IBAction)deleteNote:(id)sender
{
if (fCursorLocation.fMeasure != kNoMeasure) {
[[self document] willChangeSong];
[self song]->DelNote(fCursorLocation);
[[self document] didChangeSong];
}
}
- (void) addNoteAtCursor - (void) addNoteAtCursor
{ {
if (fCursorLocation.fMeasure != kNoMeasure && fCursorVertPos != kCursorNoPitch) { if (fCursorLocation.fMeasure != kNoMeasure && fCursorVertPos != kCursorNoPitch) {
@ -349,7 +386,7 @@
for (int m = 0; m<kLayout.NumMeasures(); ++m) { for (int m = 0; m<kLayout.NumMeasures(); ++m) {
VLVisualFilter filterVisuals(kProp.fKey); VLVisualFilter filterVisuals(kProp.fKey);
int measIdx = m+kFirstMeas; uint32_t measIdx = m+kFirstMeas;
if (measIdx >= song->CountMeasures()) if (measIdx >= song->CountMeasures())
break; break;
const VLMeasure & measure = song->fMeasures[measIdx]; const VLMeasure & measure = song->fMeasures[measIdx];

View File

@ -132,8 +132,8 @@ void VLSoundScheduler::Schedule(VLSoundEvent * what, float when)
what->Perform(); what->Perform();
} }
static std::auto_ptr<VLSoundOut> sSoundOut; static std::unique_ptr<VLSoundOut> sSoundOut;
static std::auto_ptr<VLSoundScheduler> sSoundScheduler; static std::unique_ptr<VLSoundScheduler> sSoundScheduler;
VLSoundOut * VLSoundOut::Instance() VLSoundOut * VLSoundOut::Instance()
{ {
@ -160,7 +160,7 @@ void VLSoundOut::PlayFile(CFDataRef file)
MusicSequence music; MusicSequence music;
NewMusicSequence(&music); NewMusicSequence(&music);
MusicSequenceFileLoadData(music, file, 0, 0); MusicSequenceFileLoadData(music, file, kMusicSequenceFile_MIDIType, 0);
PlaySequence(music); PlaySequence(music);
} }
@ -517,7 +517,7 @@ void VLAUSoundOut::Play(const int8_t * note, size_t numNotes)
const int8_t kNoteVelocity = 127; const int8_t kNoteVelocity = 127;
for (int i=0; i<numNotes; ++i) { for (int i=0; i<numNotes; ++i) {
MIDINoteMessage n = {0, note[i], kNoteVelocity, 0, 1.0}; MIDINoteMessage n = {0, static_cast<UInt8>(note[i]), kNoteVelocity, 0, 1.0};
MusicTrackNewMIDINoteEvent(track, 0.0, &n); MusicTrackNewMIDINoteEvent(track, 0.0, &n);
} }

BIN
TestData/.DS_Store vendored

Binary file not shown.

View File

@ -1642,6 +1642,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)"; ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
@ -1665,6 +1667,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)"; ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
@ -1686,6 +1690,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)"; ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Sources/VocalEasel_Prefix.pch; GCC_PREFIX_HEADER = Sources/VocalEasel_Prefix.pch;

View File

@ -22,8 +22,8 @@
</BuildActionEntries> </BuildActionEntries>
</BuildAction> </BuildAction>
<TestAction <TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES" shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Development"> buildConfiguration = "Development">
<Testables> <Testables>