diff options
| author | Florian Jung <flo@windfisch.org> | 2011-04-17 15:46:34 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-04-17 15:46:34 +0000 | 
| commit | a166bf3113c24a02c154bcd94f5f4291d6e675fe (patch) | |
| tree | 4d8f5a2d6a6b675e976c764b91aa8b62cbb19f2b /muse2/muse | |
| parent | 47a10173ea203de2036dd00791fe5c24fb673135 (diff) | |
| parent | aab05a914e357938f0ccb3d592186320e0646366 (diff) | |
a mastertrack keymap editor has been inserted and used
merged with current trunk, removed attic/
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | muse2/muse/arranger/pcanvas.cpp | 19 | ||||
| -rw-r--r-- | muse2/muse/dssihost.cpp | 10 | ||||
| -rw-r--r-- | muse2/muse/keyevent.cpp | 291 | ||||
| -rw-r--r-- | muse2/muse/keyevent.h | 109 | ||||
| -rw-r--r-- | muse2/muse/master/lmaster.cpp | 320 | ||||
| -rw-r--r-- | muse2/muse/master/lmaster.h | 30 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 101 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 69 | ||||
| -rw-r--r-- | muse2/muse/osc.cpp | 4 | ||||
| -rw-r--r-- | muse2/muse/shortcuts.cpp | 5 | ||||
| -rw-r--r-- | muse2/muse/shortcuts.h | 3 | ||||
| -rw-r--r-- | muse2/muse/song.cpp | 14 | ||||
| -rw-r--r-- | muse2/muse/song.h | 1 | ||||
| -rw-r--r-- | muse2/muse/songfile.cpp | 5 | ||||
| -rw-r--r-- | muse2/muse/tempo.cpp | 6 | ||||
| -rw-r--r-- | muse2/muse/tempo.h | 1 | 
17 files changed, 802 insertions, 187 deletions
| diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt index 0877d025..2a630f84 100644 --- a/muse2/muse/CMakeLists.txt +++ b/muse2/muse/CMakeLists.txt @@ -94,6 +94,7 @@ file (GLOB core_source_files        helper.cpp        importmidi.cpp         key.cpp +      keyevent.cpp        memory.cpp         midi.cpp        midictrl.cpp diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index ca2a16b0..e2c2b32d 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -1610,15 +1610,20 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)              // draw name              // FN: Set text color depending on part color (black / white)              int part_r, part_g, part_b, brightness; -            config.partColors[i].getRgb(&part_r, &part_g, &part_b); +            //config.partColors[i].getRgb(&part_r, &part_g, &part_b); +            // Since we'll draw the text on the bottom (to accommodate drum 'slivers'), +            //  get the lowest colour in the gradient used to draw the part. +            QRect rr = map(r); +            rr.setX(rr.x() + 3); +            gGradientFromQColor(config.partColors[i], rr.topLeft(), rr.bottomLeft()).stops().last().second.getRgb(&part_r, &part_g, &part_b);              brightness =  part_r*29 + part_g*59 + part_b*12;              //if (brightness < 12000 || part->selected())              //  p.setPen(Qt::white);   /* too dark: use white for text color */              //else              //  p.setPen(Qt::black);  /* otherwise use black */              bool rev = brightness < 12000 || part->selected(); -            QRect rr = map(r); -            rr.setX(rr.x() + 3); +            //QRect rr = map(r); +            //rr.setX(rr.x() + 3);              p.save();              p.setFont(config.fonts[1]);              p.setWorldMatrixEnabled(false); @@ -1626,12 +1631,12 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)                p.setPen(Qt::black);                 else                p.setPen(Qt::white);  -            p.drawText(rr.translated(1, 1), Qt::AlignTop|Qt::AlignLeft, part->name()); +            p.drawText(rr.translated(1, 1), Qt::AlignBottom|Qt::AlignLeft, part->name());              if (rev)                p.setPen(Qt::white);                 else                p.setPen(Qt::black);   -            p.drawText(rr, Qt::AlignTop|Qt::AlignLeft, part->name()); +            p.drawText(rr, Qt::AlignBottom|Qt::AlignLeft, part->name());              p.restore();              }        } @@ -1719,6 +1724,7 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect& bb, EventList* events, M        iEvent ito(events->lower_bound(to));        //printf("PartCanvas::drawItem pTick:%d from:%d to:%d\n", pTick, from, to); +      bool isdrum = (mt->type() == Track::DRUM);        for (iEvent i = events->begin(); i != ito; ++i) {              int t  = i->first + pTick;              int te = t + i->second.lenTick(); @@ -1741,7 +1747,8 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect& bb, EventList* events, M                    int pitch = i->second.pitch();                    int th = int(mt->height() * 0.75); // only draw on three quarters                    int hoffset = (mt->height() - th ) / 2; // offset from bottom -                  int y     =  hoffset + (r.y() + th - (pitch * (th) / 127)); +                  //int y     =  hoffset + (r.y() + th - (pitch * (th) / 127)); +                  int y     =  hoffset + r.y() + th - (isdrum?127-pitch:pitch) * th / 127;                    p.drawLine(t, y, te, y);              }        } diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index aa18025d..f2e94dae 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -1104,11 +1104,11 @@ bool DssiSynthIF::init(DssiSynth* s)            }            else if (LADSPA_IS_PORT_OUTPUT(pd))            { -            controlsOut[cop].idx = k;     -            controls[cop].val    = 0.0; -            controls[cop].tmpVal = 0.0; -            controls[cop].enCtrl  = false; -            controls[cop].en2Ctrl = false; +            controlsOut[cop].idx = k; +            controlsOut[cop].val    = 0.0; +            controlsOut[cop].tmpVal = 0.0; +            controlsOut[cop].enCtrl  = false; +            controlsOut[cop].en2Ctrl = false;              #ifdef DSSI_DEBUG               printf("DssiSynthIF::init control output port:%d port idx:%d name:%s\n", cop, k, ld->PortNames[k]); diff --git a/muse2/muse/keyevent.cpp b/muse2/muse/keyevent.cpp new file mode 100644 index 00000000..865aef01 --- /dev/null +++ b/muse2/muse/keyevent.cpp @@ -0,0 +1,291 @@ +//========================================================= +//  MusE +//  Linux Music Editor +//  $Id: key.cpp,v 1.7.2.7 2008/05/21 00:28:52 terminator356 Exp $ +// +//  (C) Copyright 1999/2000 Werner Schweer (ws@seh.de) +//========================================================= + +#include <stdio.h> +#include <errno.h> +#include <cmath> + +#include "key.h" +#include "globals.h" +#include "gconfig.h" +#include "xml.h" +#include "keyevent.h" + +KeyList keymap; + +//--------------------------------------------------------- +//   KeyList +//--------------------------------------------------------- + +KeyList::KeyList() +      { +      _key   = KEY_C; +      insert(std::pair<const unsigned, KeyEvent> (MAX_TICK+1, KeyEvent(_key, 0))); +      useList      = true; +      } + +//--------------------------------------------------------- +//   add +//--------------------------------------------------------- + +void KeyList::add(unsigned tick, key_enum key) +      { +      if (tick > MAX_TICK) +            tick = MAX_TICK; +      iKeyEvent e = upper_bound(tick); + +      if (tick == e->second.tick) +            e->second.key = key; +      else { +            KeyEvent& ne = e->second; +            KeyEvent ev = KeyEvent(ne.key, ne.tick); +            ne.key  = key; +            ne.tick   = tick; +            insert(std::pair<const unsigned, KeyEvent> (tick, ev)); +            } +      } + +//--------------------------------------------------------- +//   KeyList::dump +//--------------------------------------------------------- + +void KeyList::dump() const +      { +      printf("\nKeyList:\n"); +      for (ciKeyEvent i = begin(); i != end(); ++i) { +            printf("%6d %06d key %6d\n", +               i->first, i->second.tick, i->second.key); +            } +      } + + +//--------------------------------------------------------- +//   clear +//--------------------------------------------------------- + +void KeyList::clear() +      { +      KEYLIST::clear(); +      insert(std::pair<const unsigned, KeyEvent> (MAX_TICK+1, KeyEvent(_key, 0))); +      } + +//--------------------------------------------------------- +//   keyAtTick +//--------------------------------------------------------- + +key_enum KeyList::keyAtTick(unsigned tick) const +      { +      if (useList) { +            ciKeyEvent i = upper_bound(tick); +            if (i == end()) { +                  printf("no key at tick %d,0x%x\n", tick, tick); +                  return _key; +                  } +            return i->second.key; +            } +      else +            return _key; +      } + +//--------------------------------------------------------- +//   del +//--------------------------------------------------------- + +void KeyList::del(unsigned tick) +      { +      iKeyEvent e = find(tick); +      if (e == end()) { +            printf("KeyList::del(%d): not found\n", tick); +            return; +            } +      del(e); +      } + +void KeyList::del(iKeyEvent e) +      { +      iKeyEvent ne = e; +      ++ne; +      if (ne == end()) { +            printf("KeyList::del() HALLO\n"); +            return; +            } +      ne->second.key = e->second.key; +      ne->second.tick  = e->second.tick; +      erase(e); +      } + +//--------------------------------------------------------- +//   change +//--------------------------------------------------------- + +void KeyList::change(unsigned tick, key_enum newkey) +      { +      iKeyEvent e = find(tick); +      e->second.key = newkey; +      } + +//--------------------------------------------------------- +//   setKey +//    called from transport window +//    & slave mode key changes +//--------------------------------------------------------- + +//void KeyList::setKey(unsigned tick, int newkey) +//      { +//      if (useList) +//            add(tick, newkey); +//      else +//            _key = newkey; +//      ++_keySN; +//      } + +//--------------------------------------------------------- +//   addKey +//--------------------------------------------------------- + +void KeyList::addKey(unsigned t, key_enum key) +      { +      add(t, key); +      } + +//--------------------------------------------------------- +//   delKey +//--------------------------------------------------------- + +void KeyList::delKey(unsigned tick) +      { +      del(tick); +      } + +//--------------------------------------------------------- +//   changeKey +//--------------------------------------------------------- + +//void KeyList::changeKey(unsigned tick, int newkey) +//      { +//      change(tick, newkey); +//      ++_keySN; +//      } + +//--------------------------------------------------------- +//   setMasterFlag +//--------------------------------------------------------- + +bool KeyList::setMasterFlag(unsigned /*tick*/, bool val) +      { +      if (useList != val) { +            useList = val; +            return true; +            } +      return false; +      } + + + +//--------------------------------------------------------- +//   KeyList::write +//--------------------------------------------------------- + +void KeyList::write(int level, Xml& xml) const +      { +      xml.put(level++, "<keylist fix=\"%d\">", _key); +      for (ciKeyEvent i = begin(); i != end(); ++i) +            i->second.write(level, xml, i->first); +      xml.tag(level, "/keylist"); +      } + +//--------------------------------------------------------- +//   KeyList::read +//--------------------------------------------------------- + +void KeyList::read(Xml& xml) +      { +      for (;;) { +            Xml::Token token = xml.parse(); +            const QString& tag = xml.s1(); +            switch (token) { +                  case Xml::Error: +                  case Xml::End: +                        return; +                  case Xml::TagStart: +                        if (tag == "key") { +                              KeyEvent t; +                              unsigned tick = t.read(xml); +                              iKeyEvent pos = find(tick); +                              if (pos != end()) +                                    erase(pos); +                              insert(std::pair<const int, KeyEvent> (tick, t)); +                              } +                        else +                              xml.unknown("keyList"); +                        break; +                  case Xml::Attribut: +                        if (tag == "fix") +                              _key = key_enum(xml.s2().toInt()); +                        break; +                  case Xml::TagEnd: +                        if (tag == "keylist") { +                              return; +                              } +                  default: +                        break; +                  } +            } +      } + +//--------------------------------------------------------- +//   KeyEvent::write +//--------------------------------------------------------- + +void KeyEvent::write(int level, Xml& xml, int at) const +      { +      xml.tag(level++, "key at=\"%d\"", at); +      xml.intTag(level, "tick", tick); +      xml.intTag(level, "val", key); +      xml.tag(level, "/key"); +      } + +//--------------------------------------------------------- +//   KeyEvent::read +//--------------------------------------------------------- + +int KeyEvent::read(Xml& xml) +      { +      int at = 0; +      for (;;) { +            Xml::Token token = xml.parse(); +            const QString& tag = xml.s1(); +            switch (token) { +                  case Xml::Error: +                  case Xml::End: +                        return 0; +                  case Xml::TagStart: +                        if (tag == "tick") +                              tick = xml.parseInt(); +                        else if (tag == "val") +                              key = key_enum(xml.parseInt()); +                        else +                              xml.unknown("KeyEvent"); +                        break; +                  case Xml::Attribut: +                        if (tag == "at") +                              at = xml.s2().toInt(); +                        break; +                  case Xml::TagEnd: +                        if (tag == "key") { +                              return at; +                              } +                  default: +                        break; +                  } +            } +      return 0; +      } + + + diff --git a/muse2/muse/keyevent.h b/muse2/muse/keyevent.h new file mode 100644 index 00000000..4a7fc8f9 --- /dev/null +++ b/muse2/muse/keyevent.h @@ -0,0 +1,109 @@ +//========================================================= +//  MusE +//  Linux Music Editor +//  $Id: tempo.h,v 1.2.2.1 2006/09/19 19:07:09 spamatica Exp $ +// +//  (C) Copyright 1999/2000 Werner Schweer (ws@seh.de) +//========================================================= +#ifndef KEYEVENT_H +#define KEYEVENT_H + +#include <map> + +#ifndef MAX_TICK +#define MAX_TICK (0x7fffffff/100) +#endif + +class Xml; + +//don't change this enum! changing the numeric values will affect +//all files using key_enum, and even worse: +//PREVIOUSLY SAVED FILES WILL BE CORRUPT because the keys are +//stored as integers. when the integer -> key mapping changes +//(by inserting or removing elements, for example), this will +//break stuff! (flo) +enum key_enum +{ +	KEY_SHARP_BEGIN, +	KEY_C,   // C or am, uses # for "black keys" +	KEY_G, +	KEY_D, +	KEY_A, +	KEY_E, +	KEY_B, // or H in german. +	KEY_FIS, //replaces F with E# +	KEY_SHARP_END, +	KEY_B_BEGIN, +	KEY_C_B,  // the same as C, but uses b for "black keys" +	KEY_F, +	KEY_BES, // or B in german +	KEY_ES, +	KEY_AS, +	KEY_DES, +	KEY_GES, //sounds like FIS, but uses b instead of # +	KEY_B_END +}; + + + + +//--------------------------------------------------------- +//   Key Event +//--------------------------------------------------------- + +struct KeyEvent { +      key_enum key; +      unsigned tick; + +      int read(Xml&); +      void write(int, Xml&, int) const; + +      KeyEvent() { } +      KeyEvent(key_enum k, unsigned tk) { +            key = k; +            tick  = tk; +            } +      }; + +//--------------------------------------------------------- +//   KeyList +//--------------------------------------------------------- + +typedef std::map<unsigned, KeyEvent, std::less<unsigned> > KEYLIST; +typedef KEYLIST::iterator iKeyEvent; +typedef KEYLIST::const_iterator ciKeyEvent; +typedef KEYLIST::reverse_iterator riKeyEvent; +typedef KEYLIST::const_reverse_iterator criKeyEvent; + + + +class KeyList : public KEYLIST { +      bool useList; +      key_enum _key;             // key if not using key list + +      void add(unsigned tick, key_enum tempo); +      void change(unsigned tick, key_enum newKey); +      void del(iKeyEvent); +      void del(unsigned tick); + +   public: + +      KeyList(); +      void clear(); + +      void read(Xml&); +      void write(int, Xml&) const; +      void dump() const; + +      key_enum keyAtTick(unsigned tick) const; + +      void addKey(unsigned t, key_enum newKey); +      void delKey(unsigned tick); +//      void changeKey(unsigned tick, key_enum newKey); +      bool setMasterFlag(unsigned tick, bool val); +      }; + +extern KeyList keymap; + + +#endif // KEYEVENT_H diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp index 00a09d13..412360e3 100644 --- a/muse2/muse/master/lmaster.cpp +++ b/muse2/muse/master/lmaster.cpp @@ -13,8 +13,8 @@  #include "song.h"  #include "globals.h"  #include "audio.h" -///#include "posedit.h" -///#include "sigedit.h" +//#include "posedit.h" +//#include "sigedit.h"  #include "shortcuts.h"  #include "debug.h" @@ -30,6 +30,7 @@  #include <QToolBar>  #include <QToolButton>  #include <QTreeWidget> +#include <QComboBox>  #define LMASTER_BEAT_COL 0  #define LMASTER_TIME_COL 1 @@ -37,6 +38,55 @@  #define LMASTER_VAL_COL  3  #define LMASTER_MSGBOX_STRING          "MusE: List Editor" + +//don't remove or insert new elements in keyStrs. +//only renaming (keeping the semantic sense) is allowed! (flo( +QStringList keyStrs = QStringList() +                      << "C (sharps)" << "G" << "D" << "A"<< "E" << "B" << "F#" +                      << "C (flats)"<< "F"<< "Bb" << "Eb"<< "Ab"<< "Db"<< "Gb"; + +//don't change this function (except when renaming stuff) +key_enum stringToKey(QString input) //flo +{ +	int index = keyStrs.indexOf(input); +	key_enum map[]={KEY_C, KEY_G, KEY_D, KEY_A, KEY_E, KEY_B, KEY_FIS, KEY_C_B, KEY_F, KEY_BES, KEY_ES, KEY_AS, KEY_DES, KEY_GES}; +	return map[index]; +} + +//don't change this function (except when renaming stuff) +QString keyToString(key_enum key) //flo +{ +	int index; +	switch(key) +	{ +		case KEY_C:   index= 0; break; +		case KEY_G:   index= 1; break; +		case KEY_D:   index= 2; break; +		case KEY_A:   index= 3; break; +		case KEY_E:   index= 4; break; +		case KEY_B:   index= 5; break; +		case KEY_FIS: index= 6; break; +		case KEY_C_B: index= 7; break; +		case KEY_F:   index= 8; break; +		case KEY_BES: index= 9; break; +		case KEY_ES:  index=10; break; +		case KEY_AS:  index=11; break; +		case KEY_DES: index=12; break; +		case KEY_GES: index=13; break; + +		case KEY_SHARP_BEGIN: +		case KEY_SHARP_END: +		case KEY_B_BEGIN: +		case KEY_B_END: +			printf("ILLEGAL FUNCTION CALL: keyToString called with key_sharp_begin etc.\n"); +			break; +		 +		default: +			printf("ILLEGAL FUNCTION CALL: keyToString called with illegal key value (not in enum)\n"); +	} +	return keyStrs[index]; +} +  //---------------------------------------------------------  //   closeEvent  //--------------------------------------------------------- @@ -67,6 +117,7 @@ LMaster::LMaster()        pos_editor = 0;        editor = 0;        sig_editor = 0; +      key_editor = 0;        editedItem = 0;        editingNewItem = false;        setWindowTitle(tr("MusE: Mastertrack")); @@ -80,6 +131,7 @@ LMaster::LMaster()        menuEdit->addSeparator();        tempoAction = menuEdit->addAction(tr("Insert Tempo"));        signAction = menuEdit->addAction(tr("Insert Signature")); +      keyAction = menuEdit->addAction(tr("Insert Key"));        posAction = menuEdit->addAction(tr("Edit Positon"));        valAction = menuEdit->addAction(tr("Edit Value"));        delAction = menuEdit->addAction(tr("Delete Event")); @@ -87,12 +139,14 @@ LMaster::LMaster()        connect(tempoAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(signAction, SIGNAL(triggered()), signalMapper, SLOT(map())); +      connect(keyAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(posAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(valAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        connect(delAction, SIGNAL(triggered()), signalMapper, SLOT(map()));        signalMapper->setMapping(tempoAction, CMD_INSERT_TEMPO);        signalMapper->setMapping(signAction, CMD_INSERT_SIG); +      signalMapper->setMapping(keyAction, CMD_INSERT_KEY);        signalMapper->setMapping(posAction, CMD_EDIT_BEAT);        signalMapper->setMapping(valAction, CMD_EDIT_VALUE);        signalMapper->setMapping(delAction, CMD_DELETE); @@ -103,18 +157,19 @@ LMaster::LMaster()        tools = addToolBar(tr("Master tools"));        tools->addActions(undoRedo->actions()); -      //QToolBar* edit = new QToolBar(this, "edit tools");        QToolBar* edit = addToolBar(tr("Edit tools")); -      //QToolButton* tempoButton = new QToolButton(edit);        QToolButton* tempoButton = new QToolButton(); -      //QToolButton* timeSigButton = new QToolButton(edit);        QToolButton* timeSigButton = new QToolButton(); +      QToolButton* keyButton = new QToolButton();        tempoButton->setText(tr("Tempo"));        timeSigButton->setText(tr("Timesig")); +      keyButton->setText(tr("Key"));        tempoButton->setToolTip(tr("new tempo"));        timeSigButton->setToolTip(tr("new signature")); +      keyButton->setToolTip(tr("new key"));        edit->addWidget(tempoButton);        edit->addWidget(timeSigButton); +      edit->addWidget(keyButton);        ///Q3Accel* qa = new Q3Accel(this);        ///qa->connectItem(qa->insertItem(Qt::CTRL+Qt::Key_Z), song, SLOT(undo())); @@ -153,8 +208,10 @@ LMaster::LMaster()        connect(view, SIGNAL(itemPressed(QTreeWidgetItem*, int)), SLOT(itemPressed(QTreeWidgetItem*, int)));        connect(view, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), SLOT(itemDoubleClicked(QTreeWidgetItem*)));        connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); +      connect(this, SIGNAL(seekTo(int)), song, SLOT(seekTo(int)));        connect(tempoButton, SIGNAL(clicked()), SLOT(tempoButtonClicked()));        connect(timeSigButton, SIGNAL(clicked()), SLOT(timeSigButtonClicked())); +      connect(keyButton, SIGNAL(clicked()), SLOT(insertKey()));        initShortcuts();        } @@ -186,6 +243,10 @@ void LMaster::insertTempo(const TEvent* ev)        new LMasterTempoItem(view, ev);        } +void LMaster::insertKey(const KeyEvent& ev) +      { +      new LMasterKeyEventItem(view, ev); +      }  //---------------------------------------------------------  //   updateList  //--------------------------------------------------------- @@ -204,33 +265,65 @@ void LMaster::updateList()        view->clear();        const TempoList* t = &tempomap;        const AL::SigList* s   = &AL::sigmap; +      const KeyList* k   = &keymap;        criTEvent it   = t->rbegin();        AL::criSigEvent is = s->rbegin(); +      criKeyEvent ik = k->rbegin(); + +        // three lists that should be added to the view. +         // question if it would not be easier to merge the lists and use a sorting algorithm? +         // how often is this function called? A: only on songChanged (SC_TEMPO && SC_SIG) +        for (;;) { -            if (it == t->rend()) { -                  while(is != s->rend()) { -                        insertSig(is->second); -                        ++is; -                        } -                  break; -                  } -            if (is == s->rend()) { -                  while (it != t->rend()) { -                        insertTempo(it->second); -                        ++it; -                        } -                  break; -                  } -            if (is->second->tick > it->second->tick) { -                  insertSig(is->second); -                  ++is; -                  } -            else { -                  insertTempo(it->second); -                  ++it; -                  } -            } + +        // crazy long, must be possible to solve more elegantly... + +        if (ik != k->rend() && is == s->rend() && it == t->rend()) {// ik biggest +          insertKey(ik->second); +          ++ik; +        } +        else if (is != s->rend() && ik == k->rend() && it == t->rend()) {// is biggest +          insertSig(is->second); +          ++is; +        } +        else if (it != t->rend() && ik == k->rend() && is == s->rend()) {// it biggest +          insertTempo(it->second); +          ++it; +        } + +        else if (ik != k->rend() && (is == s->rend() && (ik->second.tick >= it->second->tick) +                || (it == t->rend() && ik->second.tick >= is->second->tick ))) {// ik biggest +          insertKey(ik->second); +          ++ik; +        } +        else if (is != s->rend() && (ik == k->rend() && (is->second->tick >= it->second->tick) +                || (it == t->rend() && is->second->tick >= ik->second.tick ))) {// is biggest +          insertSig(is->second); +          ++is; +        } + +        else if (it != t->rend() && (ik == k->rend() && (it->second->tick >= is->second->tick) +                || (is == s->rend() && it->second->tick >= ik->second.tick ))) {// it biggest +          insertTempo(it->second); +          ++it; +        } + +        else if (ik != k->rend() && ik->second.tick >= is->second->tick && ik->second.tick >= it->second->tick) {// ik biggest +          insertKey(ik->second); +          ++ik; +        } +        else if (is != s->rend() &&  is->second->tick >= it->second->tick && is->second->tick >= ik->second.tick) { // is biggest +          insertSig(is->second); +          ++is; +        } +        else if (it != t->rend() && it->second->tick >= is->second->tick && it->second->tick >= ik->second.tick) { // it biggest +          insertTempo(it->second); +          ++it; +        } +        if (ik == k->rend() && is == s->rend() && it == t->rend() ) +          break; +      }        // Try to reselect the previous selection:        if(selected) @@ -321,6 +414,13 @@ void LMaster::cmd(int cmd)                                      audio->msgRemoveSig(s->tick(), s->z(), s->n());                                      break;                                      } +                              case LMASTER_KEYEVENT: +                                    { +                                    //LMasterKeyEventItem* k = (LMasterKeyEventItem*) l; +                                    keymap.delKey(l->tick()); +                                    //audio->msgRemoveSig(k->tick(), k->z(), k->n()); +                                    break; +                                    }                                default:                                      M_ERROR("Default switch statement reached");                                      break; @@ -334,6 +434,9 @@ void LMaster::cmd(int cmd)              case CMD_INSERT_SIG:                    timeSigButtonClicked();                    break; +            case CMD_INSERT_KEY: +                  insertKey(); +                  break;              case CMD_EDIT_BEAT:              case CMD_EDIT_VALUE:                    cmd == CMD_EDIT_VALUE ? editorColumn = LMASTER_VAL_COL : editorColumn = LMASTER_BEAT_COL; @@ -365,6 +468,7 @@ void LMaster::itemPressed(QTreeWidgetItem* i, int column)  void LMaster::itemDoubleClicked(QTreeWidgetItem* i)        {        //printf("itemDoubleClicked\n"); +      emit seekTo(((LMasterLViewItem*) i)->tick());        if (!editedItem && editorColumn == LMASTER_VAL_COL) {              editedItem = (LMasterLViewItem*) i; @@ -394,7 +498,7 @@ void LMaster::itemDoubleClicked(QTreeWidgetItem* i)                    editor->selectAll();                    connect(editor, SIGNAL(returnPressed()), SLOT(returnPressed()));                    } -            else { // Edit signatur value: +            else if (editedItem->getType() == LMASTER_SIGEVENT) { // Edit signatur value:                    if (!sig_editor)                          sig_editor = new SigEdit(view->viewport());                    sig_editor->setValue(editedItem->text(LMASTER_VAL_COL)); @@ -403,6 +507,23 @@ void LMaster::itemDoubleClicked(QTreeWidgetItem* i)                    sig_editor->setFocus();                    connect(sig_editor, SIGNAL(returnPressed()), SLOT(returnPressed()));                    } +            else if (editedItem->getType() == LMASTER_KEYEVENT) { +                  if (!key_editor) +                  { +                        key_editor = new QComboBox(view->viewport()); +                        key_editor->addItems(keyStrs); +                  } +                  //key_editor->setText(editedItem->text(LMASTER_VAL_COL)); +                  key_editor->setCurrentIndex(keyStrs.indexOf(editedItem->text(LMASTER_VAL_COL))); +                  key_editor->setGeometry(itemRect); +                  key_editor->show(); +                  key_editor->setFocus(); +                  //key_editor->selectAll(); +                  connect(key_editor, SIGNAL(currentIndexChanged(int)), SLOT(returnPressed())); +                  } +            else { +              printf("illegal Master list type\n"); +              }              }        // Edit tempo or signal position:        else if (!editedItem && editorColumn == LMASTER_BEAT_COL) { @@ -523,6 +644,25 @@ void LMaster::returnPressed()                                view->setCurrentItem(newSelected);                                }                          } +                  else if (editedItem->getType() == LMASTER_KEYEVENT) { +                        LMasterKeyEventItem* k = (LMasterKeyEventItem*) editedItem; +                        key_enum key = k->key(); +//                        song->startUndo(); +//                        audio->msgDeleteTempo(oldtick, tempo, false); +//                        audio->msgAddTempo(newtick, tempo, false); +//                        song->endUndo(SC_TEMPO); +                        keymap.delKey(oldtick); +                        keymap.addKey(newtick, key); +                        // Select the item: +                        QTreeWidgetItem* newSelected = (QTreeWidgetItem*) getItemAtPos(newtick, LMASTER_KEYEVENT); +                        if (newSelected) { +                              view->clearSelection(); +                              view->setCurrentItem(newSelected); +                              } +                        } +                  else { +                    printf("unknown master list event type!\n"); +                  }                    }              pos_editor->hide(); @@ -533,7 +673,8 @@ void LMaster::returnPressed()        //        else if (editedItem->getType() == LMASTER_SIGEVENT && editorColumn == LMASTER_VAL_COL)         { -            ///Sig newSig = sig_editor->sig(); +          printf("SIGEVENT return\n"); +          ///Sig newSig = sig_editor->sig();              AL::TimeSignature newSig = sig_editor->sig();              sig_editor->hide(); @@ -541,8 +682,8 @@ void LMaster::returnPressed()              // Added p3.3.43 Prevents aborting with 0 z or n.              if(newSig.isValid())              { -                            LMasterSigEventItem* e = (LMasterSigEventItem*) editedItem; +              printf("adding sig %d %d\n", e->z(),e->n());                int tick = e->tick();                if (!editingNewItem) {                      song->startUndo(); @@ -553,9 +694,38 @@ void LMaster::returnPressed()                      }                else                      audio->msgAddSig(tick, newSig.z, newSig.n, true); -            }         +            } +            else { +              printf("Signature is not valid!\n"); +            }        } +      else if (editedItem->getType() == LMASTER_KEYEVENT && editorColumn == LMASTER_VAL_COL) { +          printf("KEYEVENT return\n"); +          QString input = key_editor->currentText(); +          key_editor->hide(); +          repaint(); +          LMasterKeyEventItem* e = (LMasterKeyEventItem*) editedItem; +          const KeyEvent& t = e->getEvent(); +          unsigned tick = t.tick; +          key_enum key = stringToKey(input); + +          if (!editingNewItem) { +//                      song->startUndo(); +//                      audio->msgDeleteTempo(tick, e->tempo(), false); +//                      audio->msgAddTempo(tick, tempo, false); +//                      song->endUndo(SC_TEMPO); +                      keymap.addKey(tick,key); +                    } +              // +              // New item edited: +              // +              else { +                    //audio->msgAddTempo(tick, tempo, true); +                    keymap.addKey(tick,key); +                    } +          } +      updateList();        view->setFocus();        // No item edited now:        editedItem = 0; @@ -593,6 +763,35 @@ QString LMasterLViewItem::text(int column) const        }  //--------------------------------------------------------- +//   LMasterKeyEventItem +//!  Initializes a LMasterKeyEventItem with a KeyEvent +//--------------------------------------------------------- +LMasterKeyEventItem::LMasterKeyEventItem(QTreeWidget* parent, const KeyEvent& ev) +      : LMasterLViewItem(parent) +      { +      keyEvent = ev; +      unsigned t = ev.tick; +      int bar, beat; +      unsigned tick; +      AL::sigmap.tickValues(t, &bar, &beat, &tick); +      c1.sprintf("%04d.%02d.%03d", bar+1, beat+1, tick); + +      double time = double(tempomap.tick2frame(t)) / double(sampleRate); +      int min = int(time) / 60; +      int sec = int(time) % 60; +      int msec = int((time - (min*60 + sec)) * 1000.0); +      c2.sprintf("%03d:%02d:%03d", min, sec, msec); +      c3 = "Key"; +      //int dt = ev.key; +      c4 = keyToString(ev.key); +      setText(0, c1); +      setText(1, c2); +      setText(2, c3); +      setText(3, c4); +      } + + +//---------------------------------------------------------  //   LMasterTempoItem  //!  Initializes a LMasterTempoItem with a TEvent  //--------------------------------------------------------- @@ -607,7 +806,7 @@ LMasterTempoItem::LMasterTempoItem(QTreeWidget* parent, const TEvent* ev)        AL::sigmap.tickValues(t, &bar, &beat, &tick);        c1.sprintf("%04d.%02d.%03d", bar+1, beat+1, tick); -      double time = double(ev->frame) / double(sampleRate); +      double time = double(tempomap.tick2frame(t) /*ev->frame*/) / double(sampleRate);        int min = int(time) / 60;        int sec = int(time) % 60;        int msec = int((time - (min*60 + sec)) * 1000.0); @@ -655,12 +854,13 @@ LMasterSigEventItem::LMasterSigEventItem(QTreeWidget* parent, const AL::SigEvent  void LMaster::tempoButtonClicked()        {        LMasterTempoItem* lastTempo = (LMasterTempoItem*) getLastOfType(LMASTER_TEMPO); -      QString beatString = ((LMasterLViewItem*)lastTempo)->text(LMASTER_BEAT_COL); -      int m, b, t; -      Pos p = Pos(beatString); -      p.mbt(&m, &b, &t); -      m++; //Next bar -      int newTick = AL::sigmap.bar2tick(m, b, t); +//      QString beatString = ((LMasterLViewItem*)lastTempo)->text(LMASTER_BEAT_COL); +//      int m, b, t; +//      Pos p = Pos(beatString); +//      p.mbt(&m, &b, &t); +//      m++; //Next bar +//      int newTick = AL::sigmap.bar2tick(m, b, t); +      int newTick = song->cpos();        TEvent* ev = new TEvent(lastTempo->tempo(), newTick);        new LMasterTempoItem(view, ev);        QTreeWidgetItem* newTempoItem = view->topLevelItem(0); @@ -675,18 +875,19 @@ void LMaster::tempoButtonClicked()  //--------------------------------------------------------- -//   tempoButtonClicked() +//   timeSigButtonClicked()  //!  inserts a new sig-item in the list and starts the editor for it  //---------------------------------------------------------  void LMaster::timeSigButtonClicked()        {        LMasterSigEventItem* lastSig = (LMasterSigEventItem*) getLastOfType(LMASTER_SIGEVENT); -      QString beatString = ((LMasterLViewItem*)lastSig)->text(LMASTER_BEAT_COL); -      int m, b, t; -      Pos p = Pos(beatString); -      p.mbt(&m, &b, &t); -      m++; -      int newTick = AL::sigmap.bar2tick(m, b, t); +//      QString beatString = ((LMasterLViewItem*)lastSig)->text(LMASTER_BEAT_COL); +//      int m, b, t; +//      Pos p = Pos(beatString); +//      p.mbt(&m, &b, &t); +//      m++; +//      int newTick = AL::sigmap.bar2tick(m, b, t); +      int newTick = song->cpos();        AL::SigEvent* ev = new AL::SigEvent(AL::TimeSignature(lastSig->z(), lastSig->n()), newTick);        new LMasterSigEventItem(view, ev);        QTreeWidgetItem* newSigItem = view->topLevelItem(0); @@ -699,6 +900,32 @@ void LMaster::timeSigButtonClicked()        itemDoubleClicked(newSigItem);        } +//--------------------------------------------------------- +//   insertKey() +//!  inserts a new key in the list and starts the editor for it +//--------------------------------------------------------- +void LMaster::insertKey() +      { +      LMasterKeyEventItem* lastKey = (LMasterKeyEventItem*) getLastOfType(LMASTER_KEYEVENT); + +      //QString beatString = ((LMasterLViewItem*)lastKey)->text(LMASTER_BEAT_COL); +      //int m, b, t; +      //Pos p = Pos(beatString); +      //p.mbt(&m, &b, &t); +      //m++; //Next bar + +      //int newTick = AL::sigmap.bar2tick(m, b, t); +      int newTick = song->cpos(); +      new LMasterKeyEventItem(view, KeyEvent(lastKey->key(), newTick)); +      QTreeWidgetItem* newKeyItem = view->topLevelItem(0); + +      editingNewItem = true; // State +      editorColumn = LMASTER_VAL_COL; // Set that we edit editorColumn +      view->clearSelection(); +      view->setCurrentItem(newKeyItem); +      itemDoubleClicked(newKeyItem); +      } +  /*!      \fn LMaster::getLastOfType(LMASTER_LVTYPE t) @@ -745,6 +972,7 @@ void LMaster::initShortcuts()        {        tempoAction->setShortcut(shortcuts[SHRT_LM_INS_TEMPO].key);        signAction->setShortcut(shortcuts[SHRT_LM_INS_SIG].key); +      keyAction->setShortcut(shortcuts[SHRT_LM_INS_KEY].key);        posAction->setShortcut(shortcuts[SHRT_LM_EDIT_BEAT].key);        valAction->setShortcut(shortcuts[SHRT_LM_EDIT_VALUE].key);        } diff --git a/muse2/muse/master/lmaster.h b/muse2/muse/master/lmaster.h index cd687e45..23c86c82 100644 --- a/muse2/muse/master/lmaster.h +++ b/muse2/muse/master/lmaster.h @@ -12,6 +12,7 @@  #include "noteinfo.h"  #include "cobject.h"  #include "tempo.h" +#include "keyevent.h"  ///#include "sig.h"  //#include "al/sig.h" @@ -30,13 +31,16 @@ using Awl::PosEdit;  using Awl::SigEdit;  class QLineEdit; +class QComboBox;  enum LMASTER_LVTYPE     {        LMASTER_TEMPO = 0, -      LMASTER_SIGEVENT +      LMASTER_SIGEVENT, +      LMASTER_KEYEVENT     }; +  //---------------------------------------------------------  //   LMasterLViewItem  //!  QListViewItem base class for LMasterTempoItem and LMasterSigEventItem @@ -71,6 +75,22 @@ class LMasterTempoItem : public LMasterLViewItem {        };  //--------------------------------------------------------- +//   LMasterKeyItem +//!  QListViewItem which holds data for a KetEvent +//--------------------------------------------------------- +class LMasterKeyEventItem : public LMasterLViewItem { + +   private: +      KeyEvent keyEvent; + +   public: +      LMasterKeyEventItem(QTreeWidget* parent, const KeyEvent& t); +      virtual LMASTER_LVTYPE getType() { return LMASTER_KEYEVENT; } +      const KeyEvent& getEvent() { return keyEvent; } +      virtual unsigned tick() { return keyEvent.tick; } +      key_enum key() { return keyEvent.key; } +      }; +//---------------------------------------------------------  //   LMasterTempoItem  //!  QListViewItem which holds data for a SigEvent  //--------------------------------------------------------- @@ -98,24 +118,26 @@ class LMaster : public MidiEditor {        QToolBar* tools;        QMenu* menuEdit; -      enum { CMD_DELETE, CMD_INSERT_SIG, CMD_INSERT_TEMPO, CMD_EDIT_BEAT, CMD_EDIT_VALUE }; +      enum { CMD_DELETE, CMD_INSERT_SIG, CMD_INSERT_TEMPO, CMD_EDIT_BEAT, CMD_EDIT_VALUE, CMD_INSERT_KEY };        Q_OBJECT        virtual void closeEvent(QCloseEvent*);        void updateList();        void insertTempo(const TEvent*);        void insertSig(const SigEvent*); +      void insertKey(const KeyEvent&);        LMasterLViewItem* getItemAtPos(unsigned tick, LMASTER_LVTYPE t);        void initShortcuts();        QLineEdit* editor;        PosEdit*   pos_editor; +      QComboBox*  key_editor;        // State-like members:        LMasterLViewItem* editedItem;        SigEdit* sig_editor;        int editorColumn;        bool editingNewItem; -      QAction *tempoAction, *signAction, *posAction, *valAction, *delAction; +      QAction *tempoAction, *signAction, *posAction, *valAction, *delAction, *keyAction;     private slots:        void select(QTreeWidgetItem*, QTreeWidgetItem*); @@ -124,6 +146,7 @@ class LMaster : public MidiEditor {        void itemPressed(QTreeWidgetItem* i, int column);        void tempoButtonClicked();        void timeSigButtonClicked(); +      void insertKey();        void cmd(int cmd);     public slots: @@ -132,6 +155,7 @@ class LMaster : public MidiEditor {     signals:        void deleted(unsigned long); +      void seekTo(int tick);     public:        LMaster(); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 18c3bc71..3c4543b3 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -85,7 +85,6 @@ string IntToStr(int i);  //FLO_QUANT = how many ticks has a single quantisation area? -//FINDMICH MARKER  //TODO: quant_max richtig setzen! @@ -117,37 +116,6 @@ string create_random_string(int len=8) -KeyList keymap; - - -KeyList::KeyList() -{ -	clear(); -} - -void KeyList::clear() -{ -	_KeyList::clear(); //DEBUG -- remove these lines and use the commented out below -	insert(std::pair<const unsigned, KeyEvent> (1536, KeyEvent(A, 0))); -	insert(std::pair<const unsigned, KeyEvent> (MAX_TICK, KeyEvent(ES, 1536))); -	 -	//insert(std::pair<const unsigned, KeyEvent> (MAX_TICK, KeyEvent(A, 0))); -} - -tonart_t KeyList::key_at_tick(unsigned tick) -{ -	ciKeyEvent it = upper_bound(tick); -	if (it == end()) -	{ -		cout << "THIS SHOULD NEVER HAPPEN: key at "<<tick<<" not found!" << endl; -		return C; -	} - -	return it->second.key; -} - - - @@ -328,7 +296,7 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,  	mouse_erases_notes=false;  	mouse_inserts_notes=true; -	curr_part=editor->parts()->begin()->second; //TODO FINDMICH +	curr_part=editor->parts()->begin()->second; //TODO FINDMICHJETZT  	last_len=384;  	new_len=-1; @@ -758,28 +726,28 @@ void staff_t::create_appropriate_eventlist(const set<Part*>& parts)  } -bool is_sharp_key(tonart_t t) +bool is_sharp_key(key_enum t)  { -	return ((t>=SHARP_BEGIN) && (t<=SHARP_END)); +	return ((t>=KEY_SHARP_BEGIN) && (t<=KEY_SHARP_END));  } -bool is_b_key(tonart_t t) +bool is_b_key(key_enum t)  { -	return ((t>=B_BEGIN) && (t<=B_END)); +	return ((t>=KEY_B_BEGIN) && (t<=KEY_B_END));  } -int n_accidentials(tonart_t t) +int n_accidentials(key_enum t)  {  	if (is_sharp_key(t)) -		return t-SHARP_BEGIN-1; +		return t-KEY_SHARP_BEGIN-1;  	else -		return t-B_BEGIN-1; +		return t-KEY_B_BEGIN-1;  }  //note needs to be 0..11  //always assumes violin clef  //only for internal use -note_pos_t note_pos_(int note, tonart_t key) +note_pos_t note_pos_(int note, key_enum key)  {  	note_pos_t result;  	           //C CIS D DIS E F FIS G GIS A AIS H @@ -808,7 +776,7 @@ note_pos_t note_pos_(int note, tonart_t key)  	}  	// Special cases for GES / FIS keys -	if (key==GES) +	if (key==KEY_GES)  	{  		// convert a H to a Ces  		if (note==11) @@ -817,7 +785,7 @@ note_pos_t note_pos_(int note, tonart_t key)  			result.vorzeichen=B;  		}  	} -	else if (key==FIS) +	else if (key==KEY_FIS)  	{  		// convert a F to an Eis  		if (note==5) @@ -846,7 +814,7 @@ note_pos_t note_pos_(int note, tonart_t key)  // in violin clef, line 2 is E4  // in bass clef, line 2 is G2 -note_pos_t note_pos (unsigned note, tonart_t key, clef_t clef) +note_pos_t note_pos (unsigned note, key_enum key, clef_t clef)  {  	int octave=(note/12)-1; //integer division. note is unsigned  	note=note%12; @@ -942,7 +910,7 @@ vector<int> create_emphasize_list(const list<int>& nums, int denom)  	return result;  } -vector<int> create_emphasize_list(int num, int denom) //TODO FINDMICH +vector<int> create_emphasize_list(int num, int denom)  {  	list<int> nums; @@ -1075,7 +1043,6 @@ list<note_len_t> parse_note_len(int len_ticks, int begin_tick, vector<int>& foo,  // if total_width is greater than px_per_notepos, there will be collisions!  #define NOTE_MOVE_X (PIXELS_PER_NOTEPOS/2) -//TODO richtige werte finden!  #define REST_AUSWEICH_X 10  #define DOT_XDIST 6  #define DOT_XBEGIN 10 @@ -1158,7 +1125,7 @@ void ScoreCanvas::draw_accidentials(QPainter& p, int x, int y_offset, const list  void staff_t::create_itemlist()  { -	tonart_t tmp_key=C; +	key_enum tmp_key=KEY_C;  	int lastevent=0;  	int next_measure=-1;  	int last_measure=-1; @@ -1178,7 +1145,7 @@ void staff_t::create_itemlist()  		actual_tick=it->second.tick;  		if (actual_tick==-1) actual_tick=t; -		note_pos_t notepos=note_pos(pitch,tmp_key,clef); //TODO einstellmöglichkeiten +		note_pos_t notepos=note_pos(pitch,tmp_key,clef);  		printf("FLO: t=%i\ttype=%i\tpitch=%i\tvel=%i\tlen=%i\n",it->first, it->second.type, it->second.pitch, it->second.vel, it->second.len);  		cout << "\tline="<<notepos.height<<"\tvorzeichen="<<notepos.vorzeichen << endl; @@ -1306,9 +1273,9 @@ void staff_t::create_itemlist()  		}  		else if (type==FloEvent::KEY_CHANGE)  		{ -			cout << "inserting KEY CHANGE ("<<it->second.tonart<<") at "<<t<<endl; -			itemlist[t].insert( FloItem(FloItem::KEY_CHANGE, it->second.tonart) ); -			tmp_key=it->second.tonart; // TODO FINDMICH MARKER das muss schöner werden +			cout << "inserting KEY CHANGE ("<<it->second.key<<") at "<<t<<endl; +			itemlist[t].insert( FloItem(FloItem::KEY_CHANGE, it->second.key) ); +			tmp_key=it->second.key;  		}  	}	  } @@ -1328,7 +1295,7 @@ void staff_t::process_itemlist()  		// phase 0: keep track of active notes, rests -------------------  		//          (and occupied lines) and the last measure -		//          and the current time signature (TODO FINDMICH) +		//          and the current time signature  		for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++)  		{  			if ((it->type==FloItem::NOTE) || (it->type==FloItem::REST)) @@ -1781,7 +1748,9 @@ void ScoreCanvas::draw_note_lines(QPainter& p, int y)  void staff_t::calc_item_pos()  { -	tonart_t curr_key=C; +	key_enum curr_key=KEY_C; //this has to be KEY_C or KEY_C_B and nothing else, +	                         //because only with these two keys the next (initial) +	                         //key signature is properly drawn.  	int pos_add=0;  	for (ScoreItemList::iterator it2=itemlist.begin(); it2!=itemlist.end(); it2++) @@ -1854,7 +1823,7 @@ void staff_t::calc_item_pos()  			}  			else if (it->type==FloItem::KEY_CHANGE)  			{ -				tonart_t new_key=it->tonart; +				key_enum new_key=it->key;  				list<int> aufloes_list=calc_accidentials(curr_key, clef, new_key);  				list<int> new_acc_list=calc_accidentials(new_key, clef); @@ -1882,10 +1851,12 @@ void ScoreCanvas::calc_pos_add_list()  	//process key changes -	tonart_t curr_key=C; +	key_enum curr_key=KEY_C; //this has to be KEY_C or KEY_C_B and nothing else, +	                         //because only with these two keys the next (initial) +	                         //key signature is properly calculated.  	for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++)  	{ -		tonart_t new_key=it->second.key; +		key_enum new_key=it->second.key;  		list<int> aufloes_list=calc_accidentials(curr_key, VIOLIN, new_key); //clef argument is unneccessary  		list<int> new_acc_list=calc_accidentials(new_key, VIOLIN);           //in this case  		int n_acc_drawn=aufloes_list.size() + new_acc_list.size(); @@ -1937,7 +1908,7 @@ void ScoreCanvas::draw_items(QPainter& p, int y_offset, staff_t& staff, ScoreIte  	// init accidentials properly  	vorzeichen_t curr_accidential[7];  	vorzeichen_t default_accidential[7]; -	tonart_t curr_key; +	key_enum curr_key;  	curr_key=key_at_tick(from_it->first);  	list<int> new_acc_list=calc_accidentials(curr_key, staff.clef); @@ -2127,7 +2098,7 @@ void ScoreCanvas::draw_items(QPainter& p, int y_offset, staff_t& staff, ScoreIte  			}  			else if (it->type==FloItem::KEY_CHANGE)  			{ -				tonart_t new_key=it->tonart; +				key_enum new_key=it->key;  				cout << "\tKEY CHANGE: from "<<curr_key<<" to "<<new_key<<endl;  				list<int> aufloes_list=calc_accidentials(curr_key, staff.clef, new_key); @@ -2259,7 +2230,7 @@ void ScoreCanvas::draw_preamble(QPainter& p, int y_offset, clef_t clef)  	// draw accidentials ------------------------------------------------ -	tonart_t key=key_at_tick(tick); +	key_enum key=key_at_tick(tick);  	QPixmap* pix_acc=is_sharp_key(key) ? &pix_sharp[BLACK_PIXMAP] : &pix_b[BLACK_PIXMAP];  	list<int> acclist=calc_accidentials(key,clef); @@ -2343,7 +2314,7 @@ void ScoreCanvas::draw(QPainter& p, const QRect&)  } -list<int> calc_accidentials(tonart_t key, clef_t clef, tonart_t next_key) +list<int> calc_accidentials(key_enum key, clef_t clef, key_enum next_key)  {  	list<int> result; @@ -2419,11 +2390,11 @@ int ScoreCanvas::x_to_tick(int x)  	return t > min_t ? t : min_t;  } -tonart_t ScoreCanvas::key_at_tick(int t_) +key_enum ScoreCanvas::key_at_tick(int t_)  {  	unsigned int t= (t_>=0) ? t_ : 0; -	return keymap.key_at_tick(t); +	return keymap.keyAtTick(t);  }  timesig_t ScoreCanvas::timesig_at_tick(int t_) @@ -2450,7 +2421,7 @@ int ScoreCanvas::height_to_pitch(int h, clef_t clef)  	}  } -int ScoreCanvas::height_to_pitch(int h, clef_t clef, tonart_t key) +int ScoreCanvas::height_to_pitch(int h, clef_t clef, key_enum key)  {  	int add=0; @@ -2928,6 +2899,8 @@ list<staff_t>::iterator ScoreCanvas::staff_at_y(int y)  /* BUGS and potential bugs + *   o updating the keymap doesn't emit a songChanged() signal! + *   o when the keymap is not used, this will probably lead to a bug   *   o when adding a note, it's added to the first stave   *     the problem is: there's always the first part selected   *   o when changing color of a displayed part, note heads aren't redrawn @@ -2988,8 +2961,6 @@ list<staff_t>::iterator ScoreCanvas::staff_at_y(int y)   *   o rename staffs to staves   *   * stuff for the other muse developers - *   o OFFER A WAY TO EDIT THE KEYMAP (and integrate the keymap properly) - *   *   o check if dragging notes is done correctly   *   o after doing the undo stuff right, the "pianoroll isn't informed   *     about score-editor's changes"-bug has vanished. did it vanish diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index a296d8a8..cc1a06ec 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -26,6 +26,7 @@  #include "view.h"  #include "gconfig.h"  #include "part.h" +#include "keyevent.h"  #include <set>  #include <map> @@ -91,26 +92,6 @@ class ScoreEdit : public MidiEditor -enum tonart_t -{ -	SHARP_BEGIN, -	C,   // C or am, uses # for "black keys" -	G, -	D, -	A, -	E, -	H, -	FIS, //produces a #E (sounds like a F) -	SHARP_END, -	B_BEGIN, -	C_B,  // the same as C, but uses b for "black keys" -	F, -	ES, -	AS, -	DES, -	GES, //sounds like FIS, but uses b instead of # -	B_END -};  enum stem_t  { @@ -140,33 +121,7 @@ bool operator< (const note_pos_t& a, const note_pos_t& b); -// FINDMICH put that keymap-stuff to its appropriate place -struct KeyEvent -{ -	tonart_t key; -	unsigned tick; -	 -	KeyEvent(tonart_t k, unsigned t) -	{ -		key=k; -		tick=t; -	} -}; - -typedef std::map<unsigned, KeyEvent, std::less<unsigned> > _KeyList; -typedef _KeyList::iterator iKeyEvent; -typedef _KeyList::const_iterator ciKeyEvent; -typedef _KeyList::reverse_iterator riKeyEvent; -typedef _KeyList::const_reverse_iterator criKeyEvent; -class KeyList : public _KeyList -{ -	public: -		KeyList(); -		void clear(); -		tonart_t key_at_tick(unsigned tick); -		//TODO FINDMICH: more functions, like add(), remove() have to be implemented -}; @@ -186,7 +141,7 @@ class FloEvent  		int num;  		int denom; -		tonart_t tonart; +		key_enum key;  		FloEvent(unsigned ti, int p,int v,int l,typeEnum t, Part* part=NULL, Event* event=NULL) @@ -208,10 +163,10 @@ class FloEvent  			source_event=NULL;  			source_part=NULL;  		} -		FloEvent(unsigned ti, typeEnum t, tonart_t k) +		FloEvent(unsigned ti, typeEnum t, key_enum k)  		{  			type=t; -			tonart=k; +			key=k;  			tick=ti;  			source_event=NULL;  			source_part=NULL; @@ -235,7 +190,7 @@ class FloItem  		int num;  		int denom; -		tonart_t tonart; +		key_enum key;  		mutable stem_t stem;  		mutable int shift; @@ -280,10 +235,10 @@ class FloItem  			source_part=NULL;  		} -		FloItem(typeEnum t, tonart_t k) +		FloItem(typeEnum t, key_enum k)  		{  			type=t; -			tonart=k; +			key=k;  			begin_tick=-1;  			source_event=NULL;  			source_part=NULL; @@ -486,9 +441,9 @@ struct staff_t  	}  }; -list<int> calc_accidentials(tonart_t key, clef_t clef, tonart_t next_key=C); -note_pos_t note_pos_(int note, tonart_t key); -note_pos_t note_pos (unsigned note, tonart_t key, clef_t clef); +list<int> calc_accidentials(key_enum key, clef_t clef, key_enum next_key=KEY_C); +note_pos_t note_pos_(int note, key_enum key); +note_pos_t note_pos (unsigned note, key_enum key, clef_t clef);  int calc_len(int l, int d);  list<note_len_t> parse_note_len(int len_ticks, int begin_tick, vector<int>& foo, bool allow_dots=true, bool allow_normal=true); @@ -518,7 +473,7 @@ class ScoreCanvas : public View -		static int height_to_pitch(int h, clef_t clef, tonart_t key); +		static int height_to_pitch(int h, clef_t clef, key_enum key);  		static int height_to_pitch(int h, clef_t clef);  		static int y_to_height(int y);  		int y_to_pitch(int y, int t, clef_t clef); @@ -539,7 +494,7 @@ class ScoreCanvas : public View  		timesig_t timesig_at_tick(int t); -		tonart_t key_at_tick(int t); +		key_enum key_at_tick(int t);  		int tick_to_x(int t);  		int x_to_tick(int x);  		int calc_posadd(int t); diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp index 66242e17..edaede1f 100644 --- a/muse2/muse/osc.cpp +++ b/muse2/muse/osc.cpp @@ -942,8 +942,8 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin                                if(_oscGuiQProc == 0)                                  //_oscGuiQProc = new QProcess(muse);                                                          _oscGuiQProc = new QProcess();                         -                               -			      //QString program(fi.filePath()); +			       +                              //QString program(fi.filePath());                                QString program(guiPath);  			      QStringList arguments;  			      arguments << oscUrl diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp index 9cbc3726..cd54b096 100644 --- a/muse2/muse/shortcuts.cpp +++ b/muse2/muse/shortcuts.cpp @@ -134,7 +134,7 @@ void initShortCuts()        defShrt(SHRT_SEL_BELOW_ADD,         Qt::SHIFT + Qt::Key_Down, "Edit: Add nearest part on track below", ARRANG_SHRT, "sel_part_below_add");        defShrt(SHRT_INSERT,                Qt::CTRL+Qt::SHIFT+ Qt::Key_I, "Edit: Insert parts, moving time", ARRANG_SHRT, "insert_parts"); -      defShrt(SHRT_INSERTMEAS,            Qt::CTRL+Qt::SHIFT+ Qt::Key_M, "Edit: Insert empty measure", ARRANG_SHRT, "insert_measure"); +      defShrt(SHRT_INSERTMEAS,            Qt::CTRL+Qt::SHIFT+ Qt::Key_O, "Edit: Insert empty measure", ARRANG_SHRT, "insert_measure");        defShrt(SHRT_PASTE_CLONE,           Qt::CTRL+Qt::SHIFT+Qt::Key_V, "Edit: Paste clone", ARRANG_SHRT, "paste_clone");        defShrt(SHRT_PASTE_TO_TRACK,        Qt::CTRL+Qt::Key_B, "Edit: Paste to track", ARRANG_SHRT, "paste_to_track"); @@ -299,7 +299,8 @@ void initShortCuts()        defShrt(SHRT_LM_INS_SIG  ,  Qt::CTRL + Qt::Key_R,            "Insert Signature", LMEDIT_SHRT,  "lm_ins_sig");        defShrt(SHRT_LM_EDIT_BEAT,  Qt::CTRL + Qt::SHIFT+ Qt::Key_E, "Change Event Position",  LMEDIT_SHRT,  "lm_edit_beat");        defShrt(SHRT_LM_EDIT_VALUE, Qt::CTRL + Qt::Key_E,            "Edit Event Value",       LMEDIT_SHRT,  "lm_edit_val"); -       +      defShrt(SHRT_LM_INS_KEY, Qt::CTRL + Qt::Key_K,            "Insert Key",       LMEDIT_SHRT,  "lm_ins_key"); +        defShrt(SHRT_NEXT_MARKER, Qt::Key_F6,            "Goto Next Marker",       ARRANG_SHRT,  "me_sel_next");        defShrt(SHRT_PREV_MARKER, Qt::Key_F5,            "Goto Prev Marker",       ARRANG_SHRT,  "me_sel_prev"); diff --git a/muse2/muse/shortcuts.h b/muse2/muse/shortcuts.h index 6878d177..1098be49 100644 --- a/muse2/muse/shortcuts.h +++ b/muse2/muse/shortcuts.h @@ -316,7 +316,8 @@ enum {        SHRT_LM_INS_SIG,   // Ctrl+R        SHRT_LM_EDIT_BEAT, // Ctrl+Shift+E        SHRT_LM_EDIT_VALUE,// Ctrl+E -       +      SHRT_LM_INS_KEY,   // Ctrl+K +        // Marker view        SHRT_NEXT_MARKER,        SHRT_PREV_MARKER, diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index dbb193d9..a7cff79d 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -42,6 +42,7 @@  #include "midi.h"  ///#include "sig.h"  #include "al/sig.h" +#include "keyevent.h"  #include <sys/wait.h>  extern void clearMidiTransforms(); @@ -1289,6 +1290,17 @@ void Song::swapTracks(int i1, int i2)        }  //--------------------------------------------------------- +//   seekTo +//   setPos slot, only active when not doing playback +//--------------------------------------------------------- +void Song::seekTo(int tick) +{ +  if (!audio->isPlaying()) { +    Pos p(tick, true); +    setPos(0, p); +  } +} +//---------------------------------------------------------  //   setPos  //   song->setPos(Song::CPOS, pos, true, true, true);  //--------------------------------------------------------- @@ -2098,6 +2110,7 @@ void Song::clear(bool signal, bool /*clear_all*/)        tempomap.clear();        AL::sigmap.clear(); +      keymap.clear();        undoList->clearDelete();        redoList->clear();        _markerList->clear(); @@ -2183,6 +2196,7 @@ void Song::cleanupForQuit()        tempomap.clear();        AL::sigmap.clear(); +      keymap.clear();        if(debugMsg)          printf("deleting undoList, clearing redoList\n"); diff --git a/muse2/muse/song.h b/muse2/muse/song.h index c735dfd5..e4695728 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -362,6 +362,7 @@ class Song : public QObject {        void executeScript(const char* scriptfile, PartList* parts, int quant, bool onlyIfSelected);     public slots: +      void seekTo(int tick);        void update(int flags = -1);        void beat(); diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 1e8a849b..7a690f74 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -36,6 +36,7 @@  //#include "mixer/amixer.h"              // p4.0.2  #include "conf.h"  #include "driver/jackmidi.h" +#include "keyevent.h"  //struct ClonePart {        //const EventList* el; @@ -1258,6 +1259,9 @@ void Song::read(Xml& xml)                          else if (tag == "siglist")                                ///sigmap.read(xml);                                AL::sigmap.read(xml); +                        else if (tag == "keylist") { +                              keymap.read(xml); +                              }                          else if (tag == "miditrack") {                                MidiTrack* track = new MidiTrack();                                track->read(xml); @@ -1484,6 +1488,7 @@ void Song::write(int level, Xml& xml) const        tempomap.write(level, xml);        ///sigmap.write(level, xml);        AL::sigmap.write(level, xml); +      keymap.write(level, xml);        _markerList->write(level, xml);        writeDrumMap(level, xml, false); diff --git a/muse2/muse/tempo.cpp b/muse2/muse/tempo.cpp index 418ec031..1e476e45 100644 --- a/muse2/muse/tempo.cpp +++ b/muse2/muse/tempo.cpp @@ -30,6 +30,12 @@ TempoList::TempoList()        useList      = true;        } +TempoList::~TempoList() +      { +      for (iTEvent i = begin(); i != end(); ++i) +            delete i->second; +      } +  //---------------------------------------------------------  //   add  //--------------------------------------------------------- diff --git a/muse2/muse/tempo.h b/muse2/muse/tempo.h index 61ec50f5..632d60bb 100644 --- a/muse2/muse/tempo.h +++ b/muse2/muse/tempo.h @@ -61,6 +61,7 @@ class TempoList : public TEMPOLIST {     public:        TempoList(); +      ~TempoList();        void clear();        void read(Xml&); | 
