summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp203
-rw-r--r--muse2/muse/midiedit/scoreedit.h9
2 files changed, 153 insertions, 59 deletions
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 6a302486..d483b5e7 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -1,4 +1,6 @@
-//change FONT_PATH to the correct directory
+//you need to download http://home.arcor.de/michael.jung11/glyphs.tar.bz2
+//and extract it somewhere. then change FONT_PATH to the correct directory
+//the trailing slash is necessary
#define FONT_PATH "/home/flo/muse-glyphs/"
//=========================================================
@@ -170,6 +172,7 @@ string IntToStr(int i)
+#define FONT_PATH "/home/flo/AKTENKOFFER/programme/museueberlegungen/glyphs/"
void ScoreCanvas::load_pixmaps()
{
pix_whole.load(FONT_PATH "whole.png");
@@ -435,11 +438,86 @@ bool operator< (const note_len_t& a,const note_len_t& b) //TODO sane sorting ord
else return false;
}
+
+
+int calc_measure_len(const list<int>& nums, int denom)
+{
+ int sum=0;
+
+ for (list<int>::const_iterator it=nums.begin(); it!=nums.end(); it++)
+ sum+=*it;
+
+ return 64* sum/denom;
+}
+
+vector<int> create_emphasize_list(const list<int>& nums, int denom)
+{
+ cout << "creating emphasize list for ";
+ for (list<int>::const_iterator it=nums.begin(); it!=nums.end(); it++)
+ cout << *it << " ";
+ cout << "/ "<<denom;
+
+ // |----- 8th -----|
+ int foo[]={4,7,6,7,5,7,6,7}; //if 64 changes, this also must change
+ int pos=0;
+ int len=calc_measure_len(nums, denom);
+
+ vector<int> result(len);
+
+ for (int i=0;i<len;i++)
+ result[i]=foo[i%8];
+
+ for (list<int>::const_iterator it=nums.begin(); it!=nums.end(); it++)
+ {
+ result[pos]=1;
+ for (int i=1;i<*it;i++)
+ result[pos + i*64/denom]=2;
+ pos+= *it * 64 / denom;
+ }
+
+ result[0]=0;
+
+ for (int i=0;i<len;i++)
+ {
+ if (i%8==0)
+ cout << endl<<i<<":\t";
+ cout << result[i]<<" ";
+ }
+ cout << endl;
+
+ return result;
+}
+
+vector<int> create_emphasize_list(int num, int denom) //TODO FINDMICH
+{
+ list<int> nums;
+
+ if (num%3 ==0)
+ {
+ for (int i=0;i<num/3;i++)
+ nums.push_back(3);
+ }
+ else if (num%2 ==0)
+ {
+ for (int i=0;i<num/2;i++)
+ nums.push_back(2);
+ }
+ else // num is odd
+ {
+ for (int i=0;i<(num-3)/2;i++)
+ nums.push_back(2);
+
+ nums.push_back(3);
+ }
+
+ return create_emphasize_list(nums, denom);
+}
+
//quant_max must be in log(len), that is
//whole, half, quarter, eighth = 0,1,2,3
//NOT: 1,2,4,8! (think of 2^foo)
//len is in ticks
-list<note_len_t> ScoreCanvas::parse_note_len(int len_ticks, bool allow_dots, bool allow_normal, int begin_tick)
+list<note_len_t> ScoreCanvas::parse_note_len(int len_ticks, int begin_tick, vector<int>& foo, bool allow_dots, bool allow_normal)
{
list<note_len_t> retval;
@@ -458,10 +536,6 @@ list<note_len_t> ScoreCanvas::parse_note_len(int len_ticks, bool allow_dots, boo
//if !allow_normal or if the above failed
- // 1 e + e 2 e + e 3 e + e 4 e + e
- int foo[]={1,7,6,7,5,7,6,7,4,7,6,7,5,7,6,7,3,7,6,7,5,7,6,7,4,7,6,7,5,7,6,7,2,7,6,7,5,7,6,7,4,7,6,7,5,7,6,7,3,7,6,7,5,7,6,7,4,7,6,7,5,7,6,7};
- #define foo_len (sizeof(foo)/sizeof(*foo))
-
int begin=begin_tick * 64 / TICKS_PER_WHOLE;
int len=len_ticks * 64 / TICKS_PER_WHOLE;
@@ -473,26 +547,42 @@ list<note_len_t> ScoreCanvas::parse_note_len(int len_ticks, bool allow_dots, boo
int len_now=0;
int last_number=foo[pos];
- while (! ((foo[pos]<last_number) || (len_done==len) || (pos==foo_len)) ) {pos++;len_done++;len_now++;}
+ do {pos++;len_done++;len_now++;} while (! ((foo[pos]<=last_number) || (len_done==len) || (pos==foo.size())) );
len_now=len_now*TICKS_PER_WHOLE/64;
cout << "add " << len_now << " ticks" << endl;
- for (int i=0; i<=quant_max; i++)
+ if (allow_dots)
+ {
+ int dot_max = quant_max;
+
+ for (int i=0;i<=quant_max;i++)
+ for (int j=0;j<=dot_max-i;j++)
+ if (calc_len(i,j) == len_now)
+ {
+ retval.push_back(note_len_t (i,j));
+ len_now=0;
+ }
+ }
+
+ if (len_now) //the above failed or allow_dots=false
{
- int tmp=calc_len(i,0);
- if (tmp <= len_now)
+ for (int i=0; i<=quant_max; i++)
{
- retval.push_back(note_len_t(i));
- len_now-=tmp;
- if (len_now==0) break;
+ int tmp=calc_len(i,0);
+ if (tmp <= len_now)
+ {
+ retval.push_back(note_len_t(i));
+ len_now-=tmp;
+ if (len_now==0) break;
+ }
}
}
if (len_now!=0)
cout << "WARNING: THIS SHOULD NEVER HAPPEN. wasn't able to split note len properly; len_now="<<len_now << endl;
-
- if (pos==foo_len) //we cross measure boundaries?
+
+ if (pos==foo.size()) //we cross measure boundaries?
pos=0;
}
@@ -546,7 +636,7 @@ list<note_len_t> ScoreCanvas::parse_note_len(int len_ticks, bool allow_dots, boo
#define STEM_LEN 30
#define DOTTED_RESTS true
-#define UNSPLIT_RESTS true
+#define UNSPLIT_RESTS false
#define AUX_LINE_LEN 1.5
@@ -602,6 +692,8 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
tonart_t tmp_key=C;
int lastevent=0;
int next_measure=-1;
+ int last_measure=0;
+ vector<int> emphasize_list=create_emphasize_list(4,4); //actually unneccessary, for safety
for (ScoreEventList::iterator it=eventlist.begin(); it!=eventlist.end(); it++)
{
@@ -629,7 +721,7 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
{
printf("\tend-of-measure: set rest at %i with len %i\n",lastevent,rest);
- list<note_len_t> lens=parse_note_len(rest,DOTTED_RESTS,UNSPLIT_RESTS,lastevent);
+ list<note_len_t> lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,DOTTED_RESTS,UNSPLIT_RESTS);
unsigned tmppos=lastevent;
for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++)
{
@@ -641,6 +733,7 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
}
lastevent=t;
+ last_measure=t;
next_measure=t+len;
itemlist[t].insert( FloItem(FloItem::BAR,no_notepos,0,0) );
@@ -654,7 +747,7 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
// no need to check if the rest crosses measure boundaries;
// it can't.
- list<note_len_t> lens=parse_note_len(rest,DOTTED_RESTS,UNSPLIT_RESTS,lastevent);
+ list<note_len_t> lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,DOTTED_RESTS,UNSPLIT_RESTS);
unsigned tmppos=lastevent;
for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++)
{
@@ -692,7 +785,7 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
tied_note=false;
}
- list<note_len_t> lens=parse_note_len(tmplen,true,true,t);
+ list<note_len_t> lens=parse_note_len(tmplen,t-last_measure,emphasize_list,true,true);
unsigned tmppos=t;
int n_lens=lens.size();
int count=0;
@@ -721,6 +814,8 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
{
cout << "inserting TIME SIGNATURE "<<it->second.num<<"/"<<it->second.denom<<" at "<<t<<endl;
itemlist[t].insert( FloItem(FloItem::TIME_SIG, it->second.num, it->second.denom) );
+
+ emphasize_list=create_emphasize_list(it->second.num, it->second.denom);
}
else if (type==FloEvent::KEY_CHANGE)
{
@@ -736,6 +831,8 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
void ScoreCanvas::process_itemlist(ScoreItemList& itemlist)
{
stdmap<int,int> occupied;
+ int last_measure=0;
+ vector<int> emphasize_list=create_emphasize_list(4,4); //unneccessary, only for safety
//iterate through all times with items
for (ScoreItemList::iterator it2=itemlist.begin(); it2!=itemlist.end(); it2++)
@@ -744,14 +841,19 @@ void ScoreCanvas::process_itemlist(ScoreItemList& itemlist)
cout << "at t="<<it2->first<<endl;
- // phase 0: keep track of active notes and rests -------------------
- // (and occupied lines)
+ // phase 0: keep track of active notes, rests -------------------
+ // (and occupied lines) and the last measure
+ // and the current time signature (TODO FINDMICH)
for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++)
{
if ((it->type==FloItem::NOTE) || (it->type==FloItem::REST))
occupied[it->pos.height]++;
else if ((it->type==FloItem::NOTE_END) || (it->type==FloItem::REST_END))
occupied[it->pos.height]--;
+ else if (it->type==FloItem::BAR)
+ last_measure=it2->first;
+ else if (it->type==FloItem::TIME_SIG)
+ emphasize_list=create_emphasize_list(it->num, it->denom);
}
cout << "occupied: ";
@@ -1080,7 +1182,7 @@ group_them_again:
itemlist[t].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) );
- list<note_len_t> lens=parse_note_len(len_ticks_remaining,true,true,t);
+ list<note_len_t> lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,true,true);
unsigned tmppos=t;
int n_lens=lens.size();
int count=0;
@@ -1125,7 +1227,7 @@ group_them_again:
itemlist[t].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) );
- list<note_len_t> lens=parse_note_len(len_ticks_remaining,true,true,t);
+ list<note_len_t> lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,true,true);
unsigned tmppos=t;
int n_lens=lens.size();
int count=0;
@@ -1882,38 +1984,23 @@ void ScoreCanvas::scroll_event(int x)
// every time something changes.
-
-
-
-//TODO WICHTIG TÖDLICH:
-// bei parse_note_len: BUG (siehe auch bug.mpt)
-// die anfangszeit wird in absoluten ticks statt
-// ticks seit taktbeginn gegeben -> fehler1
-// außerdem funzt die funktion nicht richtig, wenn
-// der takt nicht 4/4 ist!
-
-
-// TODO FINDMICH: tonart aus muses eventliste in meine übernehmen!
-
-// TODO: schöne funktionen fürs takt- und tonart-vorzeichen zeichnen
-// (mit längenangabe!)
-
-
-// TODO: notenschlüssel zeichen!
-// TODO: balken bei 8teln und 16teln etc
-// TODO: die ItemList als map< pos_t , der_rest_t > umändern
-
-//TODO: ausweichen bei ganzen noten!
-
-
-
-//TODO: while dragging notes:
-// send the correct events
-// do undo() stuff
-// etc.
-
-//TODO: support inserting and deleting notes
-//TODO: when a note gets resized so that len=0, erase it
-// but watch out for quantisation stuff then!
-// (when the start is slightly before the beat, len is 2 instead of 0)
-//TODO: deal with double notes?
+/* IMPORTANT TODO
+ * o use a function for drawing timesig changes. support two(or more)-digit-numbers
+ * o create nice functions for drawing keychange-accidentials
+ * o draw clef, maybe support clef changes. support violin and bass at one time
+ * o support inserting notes
+ * o support erasing notes (resize to len=0? watch out for quantisation stuff)
+ * o support undo when dragging notes
+ * o eliminate overlapping notes (e.g. C from 0 with len=10 and C from 5 with len=10)
+ *
+ * less important stuff
+ * o check if "moving away" works for whole notes
+ * o use bars instead of flags over groups of 8ths / 16ths etc
+ * o (change ItemList into map< pos_t , mutable_stuff_t >) [no]
+ *
+ * stuff for the other muse developers
+ * o check if dragging notes works correctly (the pianoroll seems to be not informed :/ )
+ * o process key from muse's event list (has to be implemented first in muse)
+ * o process accurate timesignatures from muse's list (has to be implemented first in muse)
+ * ( (2+2+3)/4 or (3+2+2)/4 instead of 7/4 )
+ */
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 340d8c02..fbda4579 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -26,11 +26,13 @@
#include <set>
#include <map>
#include <list>
+#include <vector>
using std::set;
using std::pair;
using std::map;
using std::list;
+using std::vector;
class MidiPart;
class TimeLabel;
@@ -404,7 +406,7 @@ class ScoreCanvas : public View
note_pos_t note_pos_(int note, tonart_t key);
note_pos_t note_pos (int note, tonart_t key, clef_t clef);
int calc_len(int l, int d);
- list<note_len_t> parse_note_len(int len_ticks, bool allow_dots=true, bool allow_normal=true, int begin_tick=0);
+ list<note_len_t> parse_note_len(int len_ticks, int begin_tick, vector<int>& foo, bool allow_dots=true, bool allow_normal=true);
void draw_tie (QPainter& p, int x1, int x4, int yo, bool up=true);
ScoreItemList create_itemlist(ScoreEventList& eventlist);
void process_itemlist(ScoreItemList& itemlist);
@@ -467,5 +469,10 @@ class ScoreCanvas : public View
~ScoreCanvas(){};
};
+
+int calc_measure_len(const list<int>& nums, int denom);
+vector<int> create_emphasize_list(const list<int>& nums, int denom);
+vector<int> create_emphasize_list(int num, int denom);
+
#endif