// // 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<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; stanzafGoToCoda == 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; stanza0; --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 & VLNote::kNoteHead], 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 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; }