2012-05-26 14:49:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
|
|
|
// Linux Music Score Editor
|
|
|
|
// $Id: importmidi.cpp 2721 2010-02-15 19:41:28Z wschweer $
|
|
|
|
//
|
|
|
|
// Copyright (C) 2002-2011 Werner Schweer and others
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "importpdf.h"
|
|
|
|
#include "libmscore/score.h"
|
|
|
|
#include "omr/omr.h"
|
|
|
|
#include "libmscore/part.h"
|
|
|
|
#include "libmscore/staff.h"
|
|
|
|
#include "libmscore/measure.h"
|
|
|
|
#include "libmscore/rest.h"
|
|
|
|
#include "omr/omrpage.h"
|
|
|
|
#include "libmscore/segment.h"
|
|
|
|
#include "libmscore/layoutbreak.h"
|
|
|
|
#include "libmscore/page.h"
|
|
|
|
#include "libmscore/clef.h"
|
|
|
|
#include "libmscore/bracket.h"
|
|
|
|
#include "libmscore/mscore.h"
|
|
|
|
#include "libmscore/chord.h"
|
|
|
|
#include "libmscore/note.h"
|
|
|
|
#include "libmscore/utils.h"
|
2013-05-21 09:44:08 +02:00
|
|
|
#include "libmscore/timesig.h"
|
|
|
|
#include "libmscore/keysig.h"
|
2016-05-24 05:15:15 +02:00
|
|
|
#include "libmscore/spacer.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
namespace Ms {
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
2013-05-21 09:44:08 +02:00
|
|
|
// OmrState
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-05-21 09:44:08 +02:00
|
|
|
class OmrState {
|
|
|
|
public:
|
|
|
|
Score* score = 0;
|
|
|
|
Fraction timesig { 4, 4};
|
|
|
|
int tick = 0;
|
|
|
|
|
2016-05-24 05:15:15 +02:00
|
|
|
void importPdfPage(OmrPage* omrPage, int top);
|
2015-11-12 16:20:17 +01:00
|
|
|
int importPdfSystem(OmrSystem* omrSystem);
|
2013-05-21 09:44:08 +02:00
|
|
|
void importPdfMeasure(OmrMeasure* m, const OmrSystem* omrSystem);
|
|
|
|
};
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// importPdfMeasure
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-05-21 09:44:08 +02:00
|
|
|
void OmrState::importPdfMeasure(OmrMeasure* m, const OmrSystem* omrSystem)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2016-05-24 05:15:15 +02:00
|
|
|
Measure* measure = new Measure(score);
|
|
|
|
measure->setTick(tick);
|
|
|
|
if (m->timesig()) {
|
|
|
|
timesig = m->timesig()->timesig;
|
|
|
|
score->sigmap()->add(tick, SigEvent(timesig));
|
|
|
|
}
|
|
|
|
measure->setTimesig(timesig);
|
|
|
|
measure->setLen(timesig);
|
|
|
|
TDuration d(TDuration::DurationType::V_MEASURE);
|
|
|
|
Rest* rest;
|
|
|
|
Segment* s = measure->getSegment(Segment::Type::ChordRest, tick);
|
|
|
|
for (int staffIdx = 0; staffIdx < omrSystem->staves().size(); ++staffIdx) {
|
|
|
|
rest = new Rest(score, d);
|
|
|
|
rest->setDuration(timesig);
|
|
|
|
rest->setTrack(staffIdx*4);
|
|
|
|
s->add(rest);
|
|
|
|
}
|
2015-11-12 16:20:17 +01:00
|
|
|
#if 0
|
2013-05-21 09:44:08 +02:00
|
|
|
for (int staffIdx = 0; staffIdx < omrSystem->staves().size(); ++staffIdx) {
|
|
|
|
if (tick == 0) {
|
|
|
|
const OmrStaff& omrStaff = omrSystem->staves()[staffIdx];
|
|
|
|
int keySigType = omrStaff.keySig().type;
|
|
|
|
KeySig* ks = new KeySig(score);
|
2015-11-12 16:20:17 +01:00
|
|
|
//ks->setSig(keySigType, keySigType);
|
2013-05-21 09:44:08 +02:00
|
|
|
ks->setTrack(staffIdx * VOICES);
|
2015-11-12 16:20:17 +01:00
|
|
|
Segment* s = measure->getSegment(Segment::Type::KeySig, 0);
|
2013-05-21 09:44:08 +02:00
|
|
|
s->add(ks);
|
2015-11-12 16:20:17 +01:00
|
|
|
//score->staff(staffIdx)->setKey(0, keySigType);
|
2013-05-21 09:44:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (m->timesig()) {
|
|
|
|
TimeSig* ts = new TimeSig(score);
|
2015-11-12 16:20:17 +01:00
|
|
|
Segment* s = measure->getSegment(Segment::Type::TimeSig, tick);
|
2013-05-21 09:44:08 +02:00
|
|
|
ts->setSig(timesig);
|
|
|
|
ts->setTrack(staffIdx * VOICES);
|
|
|
|
s->add(ts);
|
|
|
|
}
|
|
|
|
Fraction nl;
|
|
|
|
QList<OmrChord>& chords = m->chords()[staffIdx];
|
|
|
|
if (timesig == Fraction(3,8)) {
|
|
|
|
if (chords.size() == 1) {
|
|
|
|
chords[0].duration = TDuration(timesig);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2013-05-21 09:44:08 +02:00
|
|
|
else if (chords.size() == 3) {
|
|
|
|
int i = 0;
|
|
|
|
for (;i < 3; ++i) {
|
|
|
|
if (chords[i].duration.fraction() != Fraction(1,4))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == 3) {
|
|
|
|
for (i = 0;i < 3; ++i) {
|
|
|
|
chords[i].duration = TDuration(Fraction(1, 8));
|
|
|
|
}
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2013-05-21 09:44:08 +02:00
|
|
|
}
|
|
|
|
foreach(const OmrChord& omrChord, chords) {
|
|
|
|
nl += omrChord.duration.fraction();
|
|
|
|
}
|
|
|
|
bool notesOk = nl == timesig;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2013-05-21 09:44:08 +02:00
|
|
|
if (notesOk) {
|
|
|
|
int ltick = 0;
|
|
|
|
foreach(const OmrChord& omrChord, chords) {
|
|
|
|
Chord* chord = new Chord(score);
|
|
|
|
chord->setDurationType(omrChord.duration);
|
|
|
|
chord->setDuration(omrChord.duration.fraction());
|
|
|
|
chord->setTrack(staffIdx * VOICES);
|
2015-11-12 16:20:17 +01:00
|
|
|
Segment* s = measure->getSegment(Segment::Type::ChordRest, tick + ltick);
|
2013-05-21 09:44:08 +02:00
|
|
|
s->add(chord);
|
2015-11-12 16:20:17 +01:00
|
|
|
//int keyType = score->staff(staffIdx)->key(tick + ltick).accidentalType();
|
2013-05-21 09:44:08 +02:00
|
|
|
|
|
|
|
foreach (OmrNote* omrNote, omrChord.notes) {
|
|
|
|
Note* note = new Note(score);
|
2015-11-12 16:20:17 +01:00
|
|
|
//ClefType clef = score->staff(staffIdx)->initialClef()._concertClef;
|
|
|
|
//int pitch = line2pitch(omrNote->line, clef, keyType);
|
|
|
|
//note->setPitch(pitch);
|
2013-05-21 09:44:08 +02:00
|
|
|
note->setTpcFromPitch();
|
|
|
|
chord->add(note);
|
|
|
|
}
|
|
|
|
ltick += omrChord.duration.ticks();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2015-11-12 16:20:17 +01:00
|
|
|
TDuration d(TDuration::DurationType::V_MEASURE);
|
|
|
|
Segment* s = measure->getSegment(Segment::Type::ChordRest, measure->tick());
|
2013-05-21 09:44:08 +02:00
|
|
|
Rest* rest = new Rest(score, d);
|
|
|
|
rest->setDuration(timesig);
|
|
|
|
rest->setTrack(staffIdx * VOICES);
|
|
|
|
s->add(rest);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
}
|
2015-11-12 16:20:17 +01:00
|
|
|
#endif
|
2013-05-21 09:44:08 +02:00
|
|
|
|
|
|
|
score->measures()->add(measure);
|
|
|
|
tick += measure->timesig().ticks();
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// importPdfSystem
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2015-11-12 16:20:17 +01:00
|
|
|
int OmrState::importPdfSystem(OmrSystem* omrSystem)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2013-05-21 09:44:08 +02:00
|
|
|
for (int i = 0; i < omrSystem->measures().size(); ++i) {
|
|
|
|
OmrMeasure* m = &omrSystem->measures()[i];
|
|
|
|
importPdfMeasure(m, omrSystem);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2016-05-24 05:15:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
if(score->lastMeasure()){
|
|
|
|
LayoutBreak* b = new LayoutBreak(score);
|
|
|
|
b->setLayoutBreakType(LayoutBreak::Type::LINE);
|
|
|
|
score->lastMeasure()->add(b);
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
return tick;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// importPdfPage
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-05-24 05:15:15 +02:00
|
|
|
void OmrState::importPdfPage(OmrPage* omrPage, int top)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
2015-11-12 16:20:17 +01:00
|
|
|
TDuration d(TDuration::DurationType::V_MEASURE);
|
2016-05-24 05:15:15 +02:00
|
|
|
int tick = 0;
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
int nsystems = omrPage->systems().size();
|
2016-05-24 05:15:15 +02:00
|
|
|
if(nsystems == 0) return;
|
|
|
|
|
|
|
|
//int n = nsystems == 0 ? 1 : nsystems;
|
|
|
|
for (int k = 0; k < nsystems; ++k) {
|
2012-05-26 14:49:10 +02:00
|
|
|
int numMeasures = 1;
|
|
|
|
if (k < nsystems) {
|
2015-11-12 16:20:17 +01:00
|
|
|
tick = importPdfSystem(omrPage->system(k));
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
Measure* measure;
|
|
|
|
for (int i = 0; i < numMeasures; ++i) {
|
|
|
|
measure = new Measure(score);
|
|
|
|
measure->setTick(tick);
|
2016-05-24 05:15:15 +02:00
|
|
|
|
2015-11-12 16:20:17 +01:00
|
|
|
Rest* rest = new Rest(score, d);
|
2012-05-26 14:49:10 +02:00
|
|
|
rest->setDuration(Fraction(4,4));
|
|
|
|
rest->setTrack(0);
|
2015-11-12 16:20:17 +01:00
|
|
|
Segment* s = measure->getSegment(Segment::Type::ChordRest, tick);
|
|
|
|
s->add(rest);
|
|
|
|
rest = new Rest(score, d);
|
2012-05-26 14:49:10 +02:00
|
|
|
rest->setDuration(Fraction(4,4));
|
|
|
|
rest->setTrack(4);
|
2015-11-12 16:20:17 +01:00
|
|
|
s->add(rest);
|
2012-05-26 14:49:10 +02:00
|
|
|
score->measures()->add(measure);
|
|
|
|
tick += MScore::division * 4;
|
|
|
|
}
|
|
|
|
if (k < (nsystems-1)) {
|
|
|
|
LayoutBreak* b = new LayoutBreak(score);
|
2016-05-24 05:15:15 +02:00
|
|
|
b->setLayoutBreakType(LayoutBreak::Type::LINE);
|
2012-05-26 14:49:10 +02:00
|
|
|
measure->add(b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-05-24 05:15:15 +02:00
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
Measure* measure = score->lastMeasure();
|
|
|
|
if (measure) {
|
|
|
|
LayoutBreak* b = new LayoutBreak(score);
|
2016-05-24 05:15:15 +02:00
|
|
|
b->setLayoutBreakType(LayoutBreak::Type::PAGE);
|
2012-05-26 14:49:10 +02:00
|
|
|
measure->add(b);
|
|
|
|
}
|
2016-05-24 05:15:15 +02:00
|
|
|
|
|
|
|
measure = score->firstMeasure();
|
|
|
|
if (measure) {
|
|
|
|
MStaff *ms = measure->mstaves()[0];
|
|
|
|
if (!ms->_vspacerUp){
|
|
|
|
Spacer* spacer = new Spacer(score);
|
|
|
|
spacer->setSpacerType(SpacerType::UP);
|
|
|
|
spacer->setTrack(0);
|
|
|
|
measure->add(spacer);
|
|
|
|
}
|
|
|
|
Spacer* sp = ms->_vspacerUp;
|
|
|
|
sp->layout();
|
|
|
|
sp->setPos(sp->rxpos(), top);
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2016-05-24 05:15:15 +02:00
|
|
|
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// importPdf
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2015-11-12 16:20:17 +01:00
|
|
|
Score::FileError importPdf(MasterScore* score, const QString& path)
|
2012-05-26 14:49:10 +02:00
|
|
|
{
|
|
|
|
Omr* omr = new Omr(path, score);
|
|
|
|
if (!omr->readPdf()) {
|
|
|
|
delete omr;
|
2015-11-12 16:20:17 +01:00
|
|
|
return Score::FileError::FILE_BAD_FORMAT;
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2013-05-21 09:44:08 +02:00
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
score->setOmr(omr);
|
|
|
|
qreal sp = omr->spatiumMM();
|
|
|
|
if (sp == 0.0)
|
|
|
|
sp = 1.5;
|
2015-11-12 16:20:17 +01:00
|
|
|
score->setSpatium(sp * DPMM);
|
|
|
|
score->style()->set(StyleIdx::lastSystemFillLimit, 0.0);
|
|
|
|
score->style()->set(StyleIdx::staffLowerBorder, 0.0);
|
|
|
|
score->style()->set(StyleIdx::measureSpacing, 1.0);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2012-12-16 17:38:15 +01:00
|
|
|
PageFormat pF;
|
|
|
|
pF.copy(*score->pageFormat());
|
2015-11-12 16:20:17 +01:00
|
|
|
pF.setEvenLeftMargin(5.0 * DPMM / DPI);
|
2012-05-26 14:49:10 +02:00
|
|
|
pF.setEvenTopMargin(0);
|
|
|
|
pF.setEvenBottomMargin(0);
|
2015-11-12 16:20:17 +01:00
|
|
|
pF.setOddLeftMargin(5.0 * DPMM / DPI);
|
2012-05-26 14:49:10 +02:00
|
|
|
pF.setOddTopMargin(0);
|
|
|
|
pF.setOddBottomMargin(0);
|
|
|
|
score->setPageFormat(pF);
|
|
|
|
|
2015-11-12 16:20:17 +01:00
|
|
|
score->style()->set(StyleIdx::minSystemDistance, Spatium(omr->systemDistance()));
|
|
|
|
score->style()->set(StyleIdx::maxSystemDistance, Spatium(omr->systemDistance()));
|
|
|
|
score->style()->set(StyleIdx::akkoladeDistance, Spatium(omr->staffDistance()));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2015-11-12 16:20:17 +01:00
|
|
|
//incomplete implementation for musescore skeletion creation
|
2012-05-26 14:49:10 +02:00
|
|
|
Part* part = new Part(score);
|
2013-05-21 09:44:08 +02:00
|
|
|
OmrPage* omrPage = omr->pages().front();
|
2016-05-24 05:15:15 +02:00
|
|
|
|
|
|
|
//may need to identify maximal number of staff per system and then high some of those
|
|
|
|
if (omrPage->systems().size() > 0) {
|
|
|
|
for (int i = 0; i < omrPage->systems().front().staves().size(); i++) {
|
2015-11-12 16:20:17 +01:00
|
|
|
Staff* staff = new Staff(score);
|
|
|
|
staff->setPart(part);
|
|
|
|
part->insertStaff(staff, -1);
|
|
|
|
score->staves().append(staff);
|
2016-05-24 05:15:15 +02:00
|
|
|
}
|
|
|
|
}
|
2015-11-12 16:20:17 +01:00
|
|
|
score->appendPart(part);
|
2013-05-21 09:44:08 +02:00
|
|
|
|
|
|
|
OmrState state;
|
|
|
|
state.score = score;
|
2016-05-24 05:15:15 +02:00
|
|
|
foreach (OmrPage* omrPage, omr->pages()) {
|
|
|
|
OmrStaff staff = omrPage->systems().last().staves().first();
|
|
|
|
int top = staff.top();
|
|
|
|
state.importPdfPage(omrPage, top);
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
|
|
//---create bracket
|
|
|
|
|
2015-11-12 16:20:17 +01:00
|
|
|
//score->staff(0)->setBracket(0, BracketType::BRACE);
|
|
|
|
//score->staff(0)->setBracketSpan(0, 2);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
|
|
score->setShowOmr(true);
|
|
|
|
omr->page(0)->readHeader(score);
|
|
|
|
score->rebuildMidiMapping();
|
2015-11-12 16:20:17 +01:00
|
|
|
return Score::FileError::FILE_NO_ERROR;
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2013-05-13 18:49:17 +02:00
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|