summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-04-17 15:46:34 +0000
committerFlorian Jung <flo@windfisch.org>2011-04-17 15:46:34 +0000
commita166bf3113c24a02c154bcd94f5f4291d6e675fe (patch)
tree4d8f5a2d6a6b675e976c764b91aa8b62cbb19f2b /muse2
parent47a10173ea203de2036dd00791fe5c24fb673135 (diff)
parentaab05a914e357938f0ccb3d592186320e0646366 (diff)
a mastertrack keymap editor has been inserted and used
merged with current trunk, removed attic/
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog18
-rw-r--r--muse2/al/sig.cpp6
-rw-r--r--muse2/al/sig.h1
-rw-r--r--muse2/awl/sigedit.cpp13
-rw-r--r--muse2/awl/sigedit.h1
-rw-r--r--muse2/muse/CMakeLists.txt1
-rw-r--r--muse2/muse/arranger/pcanvas.cpp19
-rw-r--r--muse2/muse/dssihost.cpp10
-rw-r--r--muse2/muse/keyevent.cpp291
-rw-r--r--muse2/muse/keyevent.h109
-rw-r--r--muse2/muse/master/lmaster.cpp320
-rw-r--r--muse2/muse/master/lmaster.h30
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp101
-rw-r--r--muse2/muse/midiedit/scoreedit.h69
-rw-r--r--muse2/muse/osc.cpp4
-rw-r--r--muse2/muse/shortcuts.cpp5
-rw-r--r--muse2/muse/shortcuts.h3
-rw-r--r--muse2/muse/song.cpp14
-rw-r--r--muse2/muse/song.h1
-rw-r--r--muse2/muse/songfile.cpp5
-rw-r--r--muse2/muse/tempo.cpp6
-rw-r--r--muse2/muse/tempo.h1
22 files changed, 840 insertions, 188 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 9d5e7237..002b8bf6 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,21 @@
+16.04.2011:
+ - Added KeyList for keeping key change events and ability to edit it in
+ master list editor (rj)
+ - fixed stuff in master list editor (rj)
+ * editing tempo signature is now atleast working
+ * editing time position is now atleast working
+ * double clicking a line moves the playpointer to this position if we are not playing
+ * changed adding tempo/sig/key so they pick the postion from the play pointer instead
+ of just incrementing the time position, I can't fathom when that would be preferrable
+ (if there is a time, I'm sure someone will let me know :) )
+ - song changed not implemented yet
+ - undo/redo is not implemented
+ - Fixed crash in dssihost.cpp - my bad from recent p4.0.20 changes. (Tim)
+ - Added destructors to sigmap and tempomap. Test OK. (Tim)
+15.04.2011:
+ - And while we're at it... Invert drum track 'slivers' in arranger parts. (Tim)
+ - Move part name text to bottom to accommodate drum 'slivers'.
+ Use lowest gradient colour from new gGradientFromQColor(), to determine whether to invert.
14.04.2011:
- Fixed notes 'sliver' drawing in arranger midi parts. Invert if too dark. (Tim)
- Gave arranger part name text drawing a shadow to help contrast with drawn events.
diff --git a/muse2/al/sig.cpp b/muse2/al/sig.cpp
index 7eeae6be..293a5b3e 100644
--- a/muse2/al/sig.cpp
+++ b/muse2/al/sig.cpp
@@ -64,6 +64,12 @@ SigList::SigList()
insert(std::pair<const unsigned, SigEvent*> (MAX_TICK, new SigEvent(TimeSignature(4, 4), 0)));
}
+SigList::~SigList()
+ {
+ for (iSigEvent i = begin(); i != end(); ++i)
+ delete i->second;
+ }
+
//---------------------------------------------------------
// add
// signatures are only allowed at the beginning of
diff --git a/muse2/al/sig.h b/muse2/al/sig.h
index ed18981f..618cd53c 100644
--- a/muse2/al/sig.h
+++ b/muse2/al/sig.h
@@ -85,6 +85,7 @@ class SigList : public SIGLIST {
public:
SigList();
+ ~SigList();
void clear();
void add(unsigned tick, const TimeSignature& s);
//void add(unsigned tick, int z, int n);
diff --git a/muse2/awl/sigedit.cpp b/muse2/awl/sigedit.cpp
index 826182ca..460aafe4 100644
--- a/muse2/awl/sigedit.cpp
+++ b/muse2/awl/sigedit.cpp
@@ -58,6 +58,16 @@ bool SigEdit::event(QEvent* event)
if (event->type() == QEvent::KeyPress) {
QKeyEvent* ke = static_cast<QKeyEvent*>(event);
int segment = curSegment();
+ if (ke->key() == Qt::Key_Return)
+ {
+ int z, n;
+ sscanf(lineEdit()->text().toLatin1().data(), "%d/%d", &z, &n);
+ AL::TimeSignature sig(z, n);
+ _sig = sig;
+
+ emit returnPressed();
+ return true;
+ }
if (ke->key() == Qt::Key_Backtab) {
if (segment == 2) {
lineEdit()->setSelection(5, 2);
@@ -117,6 +127,7 @@ void SigEdit::setValue(const QString& s)
void SigEdit::updateValue()
{
+ //printf("updateValue\n");
char buffer[64];
sprintf(buffer, "%d/%d", _sig.z, _sig.n);
lineEdit()->setText(buffer);
@@ -160,7 +171,7 @@ void SigEdit::fixup(QString& input) const
QValidator::State SigEdit::validate(QString&,int&) const
{
// TODO
- // printf("validate\n");
+ //printf("validate\n");
return QValidator::Acceptable;
}
diff --git a/muse2/awl/sigedit.h b/muse2/awl/sigedit.h
index dd059ea2..d2494798 100644
--- a/muse2/awl/sigedit.h
+++ b/muse2/awl/sigedit.h
@@ -54,6 +54,7 @@ class SigEdit : public QAbstractSpinBox
signals:
void valueChanged(const AL::TimeSignature&);
+ void returnPressed();
public slots:
void setValue(const AL::TimeSignature&);
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&);