Support for fret diagrams in the GPX format
This commit is contained in:
parent
3fce939333
commit
539d11edb5
5 changed files with 184 additions and 194 deletions
|
@ -651,7 +651,18 @@ void GuitarPro1::read(QFile* fp)
|
|||
Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
|
||||
if (beatBits & 0x2) {
|
||||
int numStrings = score->staff(staffIdx)->part()->instr()->stringData()->strings();
|
||||
readChord(segment, staffIdx * VOICES, numStrings);
|
||||
int header = readUChar();
|
||||
QString name;
|
||||
if ((header & 1) == 0) {
|
||||
name = readDelphiString();
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, false);
|
||||
}
|
||||
else {
|
||||
skip(25);
|
||||
name = readPascalString(34);
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, true);
|
||||
skip(36);
|
||||
}
|
||||
}
|
||||
Lyrics* lyrics = 0;
|
||||
if (beatBits & 0x4) {
|
||||
|
@ -731,6 +742,46 @@ void GuitarPro::setTempo(int tempo, Measure* measure)
|
|||
score->setTempo(measure->tick(), tt->tempo());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readChord
|
||||
//---------------------------------------------------------
|
||||
|
||||
void GuitarPro::readChord(Segment* seg, int track, int numStrings, QString name, bool gpHeader)
|
||||
{
|
||||
FretDiagram* fret = new FretDiagram(score);
|
||||
fret->setTrack(track);
|
||||
fret->setStrings(numStrings);
|
||||
|
||||
int firstFret = readInt();
|
||||
fret->setOffset(firstFret-1);
|
||||
if (firstFret != 0 || gpHeader) {
|
||||
for (int i = 0; i < (gpHeader ? 7 : 6); ++i) {
|
||||
int currentFret = readInt();
|
||||
// read the frets and add them to the fretboard
|
||||
// substract 1 extra from numStrings as we count from 0
|
||||
if (i > numStrings - 1) {}
|
||||
else if (currentFret > 0) {
|
||||
fret->setDot(numStrings - 1 - i, currentFret-firstFret+1);
|
||||
}
|
||||
else if (currentFret == 0) {
|
||||
fret->setDot(numStrings - 1 - i, 0);
|
||||
fret->setMarker(numStrings - 1 - i, '0');
|
||||
}
|
||||
else if (currentFret == -1) {
|
||||
fret->setDot(numStrings - 1 - i, 0);
|
||||
fret->setMarker(numStrings - 1 - i, 'X');
|
||||
}
|
||||
}
|
||||
}
|
||||
seg->add(fret);
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
Harmony* harmony = new Harmony(seg->score());
|
||||
harmony->setHarmony(name);
|
||||
harmony->setTrack(track);
|
||||
seg->add(harmony);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// read
|
||||
//---------------------------------------------------------
|
||||
|
@ -948,7 +999,18 @@ qDebug("BeginRepeat=============================================");
|
|||
Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
|
||||
if (beatBits & 0x2) {
|
||||
int numStrings = score->staff(staffIdx)->part()->instr()->stringData()->strings();
|
||||
readChord(segment, staffIdx * VOICES, numStrings);
|
||||
int header = readUChar();
|
||||
QString name;
|
||||
if ((header & 1) == 0) {
|
||||
name = readDelphiString();
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, false);
|
||||
}
|
||||
else {
|
||||
skip(25);
|
||||
name = readPascalString(34);
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, true);
|
||||
skip(36);
|
||||
}
|
||||
}
|
||||
Lyrics* lyrics = 0;
|
||||
if (beatBits & 0x4) {
|
||||
|
@ -1262,77 +1324,6 @@ int GuitarPro1::readBeatEffects(int, Segment*)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readChord
|
||||
//---------------------------------------------------------
|
||||
|
||||
void GuitarPro1::readChord(Segment* seg, int track, int numStrings)
|
||||
{
|
||||
FretDiagram* fret = new FretDiagram(score);
|
||||
fret->setTrack(track);
|
||||
fret->setStrings(numStrings);
|
||||
|
||||
int header = readUChar();
|
||||
|
||||
QString name;
|
||||
if ((header & 1) == 0) {
|
||||
name = readDelphiString();
|
||||
int firstFret = readInt();
|
||||
fret->setOffset(firstFret-1);
|
||||
if (firstFret) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
int currentFret = readInt();
|
||||
// read the frets and add them to the fretboard
|
||||
// substract 1 extra from numStrings as we count from 0
|
||||
if (i > numStrings-1) {}
|
||||
else if (currentFret > 0) {
|
||||
fret->setDot(numStrings-1-i, currentFret-firstFret+1);
|
||||
}
|
||||
else if (currentFret == 0) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, '0');
|
||||
}
|
||||
else if (currentFret == -1) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, 'X');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
skip(25);
|
||||
name = readPascalString(34);
|
||||
int firstFret = readInt();
|
||||
fret->setOffset(firstFret-1);
|
||||
// even if the guitar has 6 (or fewer) strings we must read 7 digits
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
int currentFret = readInt();
|
||||
// read the frets and add them to the fretboard
|
||||
// substract 1 extra from numStrings as we count from 0
|
||||
if (i > numStrings-1) {}
|
||||
else if (currentFret > 0) {
|
||||
fret->setDot(numStrings-1-i, currentFret-firstFret+1);
|
||||
}
|
||||
else if (currentFret == 0) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, '0');
|
||||
}
|
||||
else if (currentFret == -1) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, 'X');
|
||||
}
|
||||
}
|
||||
skip(36);
|
||||
}
|
||||
seg->add(fret);
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
Harmony* harmony = new Harmony(seg->score());
|
||||
harmony->setHarmony(name);
|
||||
harmony->setTrack(track);
|
||||
seg->add(harmony);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// read
|
||||
//---------------------------------------------------------
|
||||
|
@ -1588,7 +1579,18 @@ void GuitarPro3::read(QFile* fp)
|
|||
Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
|
||||
if (beatBits & 0x2) {
|
||||
int numStrings = score->staff(staffIdx)->part()->instr()->stringData()->strings();
|
||||
readChord(segment, staffIdx * VOICES, numStrings);
|
||||
int header = readUChar();
|
||||
QString name;
|
||||
if ((header & 1) == 0) {
|
||||
name = readDelphiString();
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, false);
|
||||
}
|
||||
else {
|
||||
skip(25);
|
||||
name = readPascalString(34);
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, true);
|
||||
skip(36);
|
||||
}
|
||||
}
|
||||
Lyrics* lyrics = 0;
|
||||
if (beatBits & 0x4) {
|
||||
|
@ -2071,78 +2073,6 @@ void GuitarPro4::readInfo()
|
|||
comments.append(readDelphiString());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readChord
|
||||
//---------------------------------------------------------
|
||||
|
||||
void GuitarPro4::readChord(Segment* seg, int track, int numStrings)
|
||||
{
|
||||
FretDiagram* fret = new FretDiagram(score);
|
||||
fret->setTrack(track);
|
||||
fret->setStrings(numStrings);
|
||||
|
||||
int header = readUChar();
|
||||
|
||||
QString name;
|
||||
|
||||
if ((header & 1) == 0) {
|
||||
name = readDelphiString();
|
||||
int firstFret = readInt();
|
||||
fret->setOffset(firstFret-1);
|
||||
if (firstFret != 0) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
int currentFret = readInt();
|
||||
// read the frets and add them to the fretboard
|
||||
// substract 1 extra from numStrings as we count from 0
|
||||
if (i > numStrings-1) {}
|
||||
else if (currentFret > 0) {
|
||||
fret->setDot(numStrings-1-i, currentFret-firstFret+1);
|
||||
}
|
||||
else if (currentFret == 0) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, '0');
|
||||
}
|
||||
else if (currentFret == -1) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, 'X');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
skip(16);
|
||||
name = readPascalString(21);
|
||||
skip(4);
|
||||
int firstFret = readInt();
|
||||
fret->setOffset(firstFret-1);
|
||||
// even if the guitar has 6 (or fewer) strings we must read 7 digits
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
int currentFret = readInt();
|
||||
// read the frets and add them to the fretboard
|
||||
// substract 1 extra from numStrings as we count from 0
|
||||
if (i > numStrings-1) {}
|
||||
else if (currentFret > 0) {
|
||||
fret->setDot(numStrings-1-i, currentFret-firstFret+1);
|
||||
}
|
||||
else if (currentFret == 0) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, '0');
|
||||
}
|
||||
else if (currentFret == -1) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, 'X');
|
||||
}
|
||||
}
|
||||
skip(32);
|
||||
}
|
||||
seg->add(fret);
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
Harmony* harmony = new Harmony(seg->score());
|
||||
harmony->setHarmony(name);
|
||||
harmony->setTrack(track);
|
||||
seg->add(harmony);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// read
|
||||
|
@ -2331,7 +2261,19 @@ void GuitarPro4::read(QFile* fp)
|
|||
Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
|
||||
if (beatBits & 0x2){
|
||||
int numStrings = score->staff(staffIdx)->part()->instr()->stringData()->strings();
|
||||
readChord(segment, staffIdx * VOICES, numStrings);
|
||||
int header = readUChar();
|
||||
QString name;
|
||||
if ((header & 1) == 0) {
|
||||
name = readDelphiString();
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, false);
|
||||
}
|
||||
else {
|
||||
skip(16);
|
||||
name = readPascalString(21);
|
||||
skip(4);
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, true);
|
||||
skip(32);
|
||||
}
|
||||
}
|
||||
Lyrics* lyrics = 0;
|
||||
if (beatBits & 0x4) {
|
||||
|
@ -2870,7 +2812,12 @@ int GuitarPro5::readBeat(int tick, int voice, Measure* measure, int staffIdx, Tu
|
|||
Segment* segment = measure->getSegment(SegmentType::ChordRest, tick);
|
||||
if (beatBits & 0x2) {
|
||||
int numStrings = score->staff(staffIdx)->part()->instr()->stringData()->strings();
|
||||
readChord(segment, staffIdx * VOICES, numStrings);
|
||||
skip(17);
|
||||
QString name = readPascalString(21);
|
||||
skip(4);
|
||||
// no header to be read in the GP5 format - default to true.
|
||||
readChord(segment, staffIdx * VOICES, numStrings, name, true);
|
||||
skip(32);
|
||||
}
|
||||
Lyrics* lyrics = 0;
|
||||
if (beatBits & 0x4) {
|
||||
|
@ -3035,48 +2982,6 @@ void GuitarPro5::readMixChange(Measure* measure)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readChord
|
||||
//---------------------------------------------------------
|
||||
|
||||
void GuitarPro5::readChord(Segment* seg, int track, int numStrings)
|
||||
{
|
||||
FretDiagram* fret = new FretDiagram(score);
|
||||
fret->setTrack(track);
|
||||
fret->setStrings(numStrings);
|
||||
|
||||
skip(17);
|
||||
QString name = readPascalString(21);
|
||||
skip(4);
|
||||
int firstFret = readInt();
|
||||
fret->setOffset(firstFret-1);
|
||||
// even if the guitar has 6 (or fewer) strings we must read 7 digits
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
int currentFret = readInt();
|
||||
// read the frets and add them to the fretboard
|
||||
// substract 1 extra from numStrings as we count from 0
|
||||
if (i > numStrings-1) {}
|
||||
else if (currentFret > 0) {
|
||||
fret->setDot(numStrings-1-i, currentFret-firstFret+1);
|
||||
}
|
||||
else if (currentFret == 0) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, '0');
|
||||
}
|
||||
else if (currentFret == -1) {
|
||||
fret->setDot(numStrings-1-i, 0);
|
||||
fret->setMarker(numStrings-1-i, 'X');
|
||||
}
|
||||
}
|
||||
skip(32);
|
||||
seg->add(fret);
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
Harmony* harmony = new Harmony(seg->score());
|
||||
harmony->setHarmony(name);
|
||||
harmony->setTrack(track);
|
||||
seg->add(harmony);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readTracks
|
||||
|
@ -3466,6 +3371,10 @@ void GuitarPro6::parseFile(char* filename, QByteArray* data)
|
|||
{
|
||||
// test to check if we are dealing with the score
|
||||
if (!strcmp(filename, "score.gpif")) {
|
||||
QFile file("/tmp/score.gpif");
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(*data);
|
||||
file.close();
|
||||
readGpif(data);
|
||||
}
|
||||
}
|
||||
|
@ -3532,6 +3441,69 @@ void GuitarPro6::readMasterTracks(QDomNode* masterTrack)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readChord
|
||||
//---------------------------------------------------------
|
||||
|
||||
void GuitarPro6::readChord(QDomNode* diagram, int track)
|
||||
{
|
||||
// initialise a new fret diagram for our current track
|
||||
FretDiagram* fretDiagram = new FretDiagram(score);
|
||||
fretDiagram->setTrack(track);
|
||||
|
||||
// get the identifier to set as the domain in the map
|
||||
int id = diagram->attributes().namedItem("id").toAttr().value().toInt();
|
||||
QDomNode diagramNode = diagram->firstChild();
|
||||
|
||||
// set the number of strings on this part
|
||||
int stringCount = diagramNode.attributes().namedItem("stringCount").toAttr().value().toInt();
|
||||
fretDiagram->setStrings(stringCount);
|
||||
|
||||
// set the fret offset
|
||||
int baseFret = diagramNode.attributes().namedItem("baseFret").toAttr().value().toInt();
|
||||
fretDiagram->setOffset(baseFret);
|
||||
|
||||
QDomNode diagramEntity = diagramNode.firstChild();
|
||||
int counter = 0;
|
||||
while (!diagramEntity.isNull()) {
|
||||
QString nodeName = diagramEntity.nodeName();
|
||||
// new fret
|
||||
if (!nodeName.compare("Fret")) {
|
||||
// get the string and fret numbers from the arguments to the node as integers
|
||||
int string = diagramEntity.attributes().namedItem("string").toAttr().value().toInt();
|
||||
int fret = diagramEntity.attributes().namedItem("fret").toAttr().value().toInt();
|
||||
|
||||
// if there are unspecified string values, add the X marker to that string
|
||||
while (counter < string) {
|
||||
fretDiagram->setMarker(counter, 'X');
|
||||
counter++;
|
||||
}
|
||||
|
||||
// look at the specified string/fret and add to diagram
|
||||
if (fret == 0) {
|
||||
fretDiagram->setMarker(string, '0');
|
||||
counter++;
|
||||
}
|
||||
else {
|
||||
qDebug("Setting fret (string=%d,fret=%d)", string, fret-baseFret);
|
||||
fretDiagram->setDot(string, fret);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
// move to the next string/fret specification
|
||||
diagramEntity = diagramEntity.nextSibling();
|
||||
}
|
||||
|
||||
// mark any missing strings as 'X'
|
||||
while (counter < stringCount) {
|
||||
fretDiagram->setMarker(counter, 'X');
|
||||
counter++;
|
||||
}
|
||||
|
||||
// insert the fret diagram into the map of diagrams
|
||||
fretDiagrams.insert(id, fretDiagram);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// readTracks
|
||||
//---------------------------------------------------------
|
||||
|
@ -3553,7 +3525,8 @@ void GuitarPro6::readTracks(QDomNode* track)
|
|||
else if (nodeName == "Properties") {
|
||||
QDomNode currentProperty = currentNode.firstChild();
|
||||
while (!currentProperty.isNull()) {
|
||||
if (currentProperty.attributes().namedItem("name").toAttr().value() == "Tuning") {
|
||||
QString propertyName = currentProperty.attributes().namedItem("name").toAttr().value();
|
||||
if (!propertyName.compare("Tuning")) {
|
||||
// set up the tuning for the part
|
||||
QString tuningString = currentProperty.firstChild().toElement().text();
|
||||
QStringList tuningStringList = tuningString.split(" ");
|
||||
|
@ -3569,6 +3542,14 @@ void GuitarPro6::readTracks(QDomNode* track)
|
|||
Instrument* instr = part->instr();
|
||||
instr->setStringData(*stringData);
|
||||
}
|
||||
else if (!propertyName.compare("DiagramCollection")) {
|
||||
QDomNode items = currentProperty.firstChild();
|
||||
QDomNode currentItem = items.firstChild();
|
||||
while (!currentItem.isNull()) {
|
||||
readChord(¤tItem, trackCounter);
|
||||
currentItem = currentItem.nextSibling();
|
||||
}
|
||||
}
|
||||
else
|
||||
unhandledNode(nodeName);
|
||||
currentProperty = currentProperty.nextSibling();
|
||||
|
@ -3845,6 +3826,10 @@ void GuitarPro6::readMasterBars(GPPartInfo* partInfo)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (!currentNode.nodeName().compare("Chord")) {
|
||||
int key = currentNode.toElement().text().toInt();
|
||||
segment->add(fretDiagrams[key]);
|
||||
}
|
||||
else if (currentNode.nodeName() == "Rhythm") {
|
||||
// we have found a rhythm
|
||||
QString refString = currentNode.attributes().namedItem("ref").toAttr().value();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "libmscore/mscore.h"
|
||||
#include "libmscore/fraction.h"
|
||||
#include "libmscore/fret.h"
|
||||
|
||||
namespace Ms {
|
||||
|
||||
|
@ -111,6 +112,7 @@ class GuitarPro {
|
|||
void createMeasures();
|
||||
void applyBeatEffects(Chord*, int beatEffects);
|
||||
void readTremoloBar(int track, Segment*);
|
||||
void readChord(Segment* seg, int track, int numStrings, QString name, bool gpHeader);
|
||||
|
||||
public:
|
||||
QString title, subtitle, artist, album, composer;
|
||||
|
@ -138,7 +140,6 @@ class GuitarPro {
|
|||
class GuitarPro1 : public GuitarPro {
|
||||
|
||||
protected:
|
||||
virtual void readChord(Segment*, int track, int numStrings);
|
||||
void readNote(int string, Note* note);
|
||||
virtual int readBeatEffects(int track, Segment*);
|
||||
|
||||
|
@ -178,7 +179,6 @@ class GuitarPro4 : public GuitarPro {
|
|||
|
||||
void readInfo();
|
||||
void readNote(int string, Note* note, GpNote*);
|
||||
virtual void readChord(Segment*, int track, int numStrings);
|
||||
virtual int readBeatEffects(int track, Segment* segment);
|
||||
virtual void readMixChange(Measure* measure);
|
||||
|
||||
|
@ -198,7 +198,6 @@ class GuitarPro5 : public GuitarPro {
|
|||
virtual int readBeatEffects(int track, Segment* segment);
|
||||
void readNote(int string, Note* note);
|
||||
virtual void readMixChange(Measure* measure);
|
||||
virtual void readChord(Segment*, int track, int numStrings);
|
||||
void readMeasure(Measure* measure, int staffIdx, Tuplet*[]);
|
||||
void readArtificialHarmonic();
|
||||
void readTracks();
|
||||
|
@ -235,6 +234,8 @@ class GuitarPro6 : public GuitarPro {
|
|||
QDomNode notes;
|
||||
QDomNode rhythms;
|
||||
};
|
||||
// a mapping from identifiers to fret diagrams
|
||||
QMap<int, FretDiagram*> fretDiagrams;
|
||||
void parseFile(char* filename, QByteArray* data);
|
||||
int readBit();
|
||||
QByteArray getBytes(QByteArray* buffer, int offset, int length);
|
||||
|
@ -245,6 +246,7 @@ class GuitarPro6 : public GuitarPro {
|
|||
int readBitsReversed(int bitsToRead);
|
||||
void readGpif(QByteArray* data);
|
||||
void readScore(QDomNode* metadata);
|
||||
void readChord(QDomNode* diagram, int track);
|
||||
int findNumMeasures(GPPartInfo* partInfo);
|
||||
void readMasterTracks(QDomNode* masterTrack);
|
||||
void readTracks(QDomNode* tracks);
|
||||
|
|
BIN
mtest/guitarpro/fret-diagram.gpx
Normal file
BIN
mtest/guitarpro/fret-diagram.gpx
Normal file
Binary file not shown.
|
@ -61,6 +61,7 @@ private slots:
|
|||
void gpDottedTuplets() { gpReadTest("dotted-tuplets", "gp5"); }
|
||||
void gpTupletSlur() { gpReadTest("tuplet-with-slur", "gp4"); }
|
||||
void gpBeamsStemsLL() { gpReadTest("beams-stems-ledger-lines", "gp5"); }
|
||||
void gpxFretDiagram() { gpReadTest("fret-diagram", "gpx"); }
|
||||
void gp5FretDiagram() { gpReadTest("fret-diagram", "gp5"); }
|
||||
void gp4FretDiagram() { gpReadTest("fret-diagram", "gp4"); }
|
||||
};
|
||||
|
|
|
@ -30,5 +30,7 @@ cp $MSCORE/keysig.gp4.mscx keysig.gp4-ref.mscx
|
|||
cp $MSCORE/dotted-tuplets.gp5.mscx dotted-tuplets.gp5-ref.mscx
|
||||
cp $MSCORE/tuplet-with-slur.gp4.mscx tuplet-with-slur.gp4-ref.mscx
|
||||
cp $MSCORE/beams-stems-ledger-lines.gp5.mscx beams-stems-ledger-lines.gp5-ref.mscx
|
||||
cp $MSCORE/fret-diagram.gpx.mscx fret-diagram.gpx-ref.mscx
|
||||
cp $MSCORE/fret-diagram.gp5.mscx fret-diagram.gp5-ref.mscx
|
||||
cp $MSCORE/fret-diagram.gp4.mscx fret-diagram.gp4-ref.mscx
|
||||
|
||||
|
|
Loading…
Reference in a new issue