diff options
| author | Florian Jung <flo@windfisch.org> | 2011-10-09 13:20:51 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-10-09 13:20:51 +0000 | 
| commit | 159a2b58fd28c7a00b9b723dcea77e6c2ec2e874 (patch) | |
| tree | ac8427059e7786cf63e33949201394e88a6222da /muse2/muse | |
| parent | 9cd7615aaa5bc2818ae5f9425173f08673bbc194 (diff) | |
updated MidiTrack::read and ::write
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/midiedit/drummap.cpp | 9 | ||||
| -rw-r--r-- | muse2/muse/midiedit/drummap.h | 1 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 6 | ||||
| -rw-r--r-- | muse2/muse/track.cpp | 245 | ||||
| -rw-r--r-- | muse2/muse/track.h | 9 | 
5 files changed, 246 insertions, 24 deletions
| diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp index 43e66345..47232011 100644 --- a/muse2/muse/midiedit/drummap.cpp +++ b/muse2/muse/midiedit/drummap.cpp @@ -43,6 +43,15 @@ namespace MusECore {  const DrumMap blankdm = { QString(""), 100, 16, 32, 9, 0, 70, 90, 127, 110, 127, 127, false }; +// this map must have 128 entries, as it's used for initalising new-style-drummaps as well. +// new-style-drummaps only have 128 entries. also, the every "out-note" ("anote") must be +// represented exactly once in that map, and there may be no duplicate or unused "out-notes". +// reason: the track's drummap are inited as follows: iterate through the full idrumMap[], +//         tracks_drummap[ idrumMap[i].anote ] = idrumMap[i] +// if you ever want to change this, you will need to go through track.cpp/.h and  +// {dlist,dcanvas,drumedit,drummap}{.cpp,.h} (and possibly some more) and find every usage +// of idrumMap by new style drummaps, and fix the problem. a possible fix would be duplicating +// idrumMap, change idrumMap, and use the duplicate for the new style stuff instead.  const DrumMap idrumMap[DRUM_MAPSIZE] = {        { QString("Acoustic Bass Drum"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 35, 35, false },        { QString("Bass Drum 1"),        100, 16, 32, 9, 0, 70, 90, 127, 110, 36, 36, false }, diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h index f3186afa..3b6ffaf3 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -51,6 +51,7 @@ struct DrumMap {        bool operator!=(const DrumMap& map) const { return !operator==(map); }        }; +// please let this at "128". idrumMap must have length 128 (see drummap.cpp for details)  #define DRUM_MAPSIZE  128  extern const DrumMap idrumMap[DRUM_MAPSIZE]; //FINDMICH dummy! diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 5770ee6c..8f647966 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4608,7 +4608,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo   *        o clearly state in the changelog: when having multiple drumeditors open,   *          the mute-column may not work, because another editor is overriding this.   *        o respect "_drummap_tied_to_patch": IMPLEMENT - *        o save hide, ordering, track's drumlists + *        o allow loading and saving track-drumlists to external files   * 				o "copy drumlist" from one track to another   *        o whenever changing the patch and maintained_automatically==true,   *          the drumlist is replaced by the according one (for example, "jazz" drum kit's list) @@ -4616,11 +4616,13 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo   *          ask the user if he wants to proceed, and then set maintained_automatically to false   *        o offer some way to set maintained_automatically to true again   *        o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions + *        x save hide, ordering, track's drumlists   *   *   x when playing back a flo-drum-track: treat as a MIDI track,   *     EXCEPT that the drum list's mute entries are respected!   *   o when recording or echoing a flo-drum-track: watch out for In-Notes! - *   o update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator= + *   * update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator= + *     _should_ be okay, but i'm not sure   *   * IMPORTANT TODO   *   o all places where i added doubleclick-edits: only react on left-click double clicks! diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 32344b6e..e24ddad9 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -405,19 +405,7 @@ MidiTrack::MidiTrack()        _drummap=new DrumMap[128];        _drummap_hidden=new bool[128]; -      for (int i=0;i<128;i++) -      { -        int idx=idrumMap[i].anote; -        if (idx < 0 || idx >= 128) -          printf ("ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx); -        else -          _drummap[idx]=idrumMap[i]; -         -        MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); -      } -      for (int i=0;i<128;i++) -        _drummap_hidden[i]=false; - +      init_drummap(true /* write drummap ordering information as well */);        }  //MidiTrack::MidiTrack(const MidiTrack& mt) @@ -460,16 +448,18 @@ MidiTrack::~MidiTrack()        delete [] _drummap;        delete [] _drummap_hidden; -      // remove ourselves from the global_drum_ordering list -      // this is not really necessary, but cleaner -      for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end();) -        if (it->first == this) -          it=MusEGlobal::global_drum_ordering.erase(it); -        else -          it++; - +      remove_ourselves_from_drum_ordering();        } +void MidiTrack::remove_ourselves_from_drum_ordering() +{ +  for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end();) +    if (it->first == this) +      it=MusEGlobal::global_drum_ordering.erase(it); +    else +      it++; +} +  //---------------------------------------------------------  //   init  //--------------------------------------------------------- @@ -491,6 +481,26 @@ void MidiTrack::init()        _recEcho       = true;        } +void MidiTrack::init_drummap(bool write_ordering) +{ +  for (int i=0;i<128;i++) +  { +    int idx=idrumMap[i].anote; +    if (idx < 0 || idx >= 128) +      printf ("ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx); +    else +      _drummap[idx]=idrumMap[i]; +     +    if (write_ordering) +      MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); +  } +   +  for (int i=0;i<128;i++) +    _drummap_hidden[i]=false; +} + + +  //---------------------------------------------------------  //   height  //--------------------------------------------------------- @@ -793,9 +803,77 @@ void MidiTrack::write(int level, Xml& xml) const        const PartList* pl = cparts();        for (ciPart p = pl->begin(); p != pl->end(); ++p)              p->second->write(level, xml); +       +      writeOurDrumSettings(level, xml); +              xml.etag(level, tag);        } +void MidiTrack::writeOurDrumSettings(int level, Xml& xml) const +{ +  xml.tag(level++, "our_drum_settings"); +   +  xml.intTag(level, "tied", _drummap_tied_to_patch); +   +  writeOurDrumMap(level, xml); +   +  xml.etag(level, "our_drum_settings"); +} + +void MidiTrack::writeOurDrumMap(int level, Xml& xml) const +{ +  xml.tag(level++, "our_drummap"); +   +  for (int i=0;i<128;i++) +  { +    int j; +    for (j=0;j<128;j++) +      if (idrumMap[j].anote == i) break; +     +    if (j==128) +      printf("THIS SHOULD NEVER HAPPEN: couldn't find initial drum map entry in MidiTrack::writeOurDrumMap()\n"); +    else +    { +      DrumMap* dm = &_drummap[i]; +      const DrumMap* idm = &idrumMap[j]; +     +      if ( (dm->name != idm->name) || (dm->vol != idm->vol) || +           (dm->quant != idm->quant) || (dm->len != idm->len) || +           (dm->lv1 != idm->lv1) || (dm->lv2 != idm->lv2) || +           (dm->lv3 != idm->lv3) || (dm->lv4 != idm->lv4) || +           (dm->enote != idm->enote) || (dm->mute != idm->mute) || +           _drummap_hidden[i] ) +      { +        xml.tag(level++, "entry pitch=\"%d\"", i); +         +        // when any of these "if"s changes, also update the large "if" +        // above (this scope's parent) +        if (dm->name != idm->name)   xml.strTag(level, "name", dm->name); +        if (dm->vol != idm->vol)     xml.intTag(level, "vol", dm->vol); +        if (dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant); +        if (dm->len != idm->len)     xml.intTag(level, "len", dm->len); +        if (dm->lv1 != idm->lv1)     xml.intTag(level, "lv1", dm->lv1); +        if (dm->lv2 != idm->lv2)     xml.intTag(level, "lv2", dm->lv2); +        if (dm->lv3 != idm->lv3)     xml.intTag(level, "lv3", dm->lv3); +        if (dm->lv4 != idm->lv4)     xml.intTag(level, "lv4", dm->lv4); +        if (dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote); +        if (dm->mute != idm->mute)   xml.intTag(level, "mute", dm->mute); +        if (_drummap_hidden[i])      xml.intTag(level, "hide", _drummap_hidden[i]); +         +        // anote is ignored anyway, as dm->anote == i, and this is +        // already stored in the begin tag (pitch=...) +         +        // channel and port are ignored as well, as they're not used +        // in new-style-drum-mode +         +        xml.tag(level--, "/entry"); +      } +    } +  } +   +  xml.etag(level, "our_drummap"); +} +  //---------------------------------------------------------  //   MidiTrack::read  //--------------------------------------------------------- @@ -852,6 +930,8 @@ void MidiTrack::read(Xml& xml)                                setAutomationType(AutomationType(xml.parseInt()));                          else if (tag == "clef")                                clefType = (clefTypes)xml.parseInt(); +                        else if (tag == "our_drum_settings") +                              readOurDrumSettings(xml);                          else if (Track::readProperties(xml, tag)) {                                // version 1.0 compatibility:                                if (tag == "track" && xml.majorVersion() == 1 && xml.minorVersion() == 0) @@ -873,6 +953,129 @@ void MidiTrack::read(Xml& xml)              }        } +void MidiTrack::readOurDrumSettings(Xml& xml) +{ +	for (;;) +	{ +		Xml::Token token = xml.parse(); +		if (token == Xml::Error || token == Xml::End) +			break; +		const QString& tag = xml.s1(); +		switch (token) +		{ +			case Xml::TagStart: +				if (tag == "tied")  +					_drummap_tied_to_patch = xml.parseInt(); +				else if (tag == "our_drummap")  +					readOurDrumMap(xml); +				else +					xml.unknown("MidiTrack::readOurDrumSettings"); +				break; + +			case Xml::TagEnd: +				if (tag == "our_drum_settings") +					return; + +			default: +				break; +		} +	} +} + +void MidiTrack::readOurDrumMap(Xml& xml) +{ +  init_drummap(false); +   +	for (;;) +	{ +		Xml::Token token = xml.parse(); +		if (token == Xml::Error || token == Xml::End) +			break; +		const QString& tag = xml.s1(); +		switch (token) +		{ +			case Xml::TagStart: +				if (tag == "entry")  // then read that entry with a nested loop +        { +					DrumMap* dm=NULL; +          bool* hidden=NULL; +          for (;;) // nested loop +          { +            Xml::Token token = xml.parse(); +            const QString& tag = xml.s1(); +            switch (token) +            { +              case Xml::Error: +              case Xml::End: +                goto end_of_nested_for; +               +              case Xml::Attribut: +                if (tag == "pitch") +                { +                  int pitch = xml.s2().toInt() & 0x7f; +                  if (pitch < 0 || pitch > 127) +                    printf("ERROR: THIS SHOULD NEVER HAPPEN: invalid pitch in MidiTrack::readOurDrumMap()!\n"); +                  else +                  { +                    dm = &_drummap[pitch]; +                    hidden = &_drummap_hidden[pitch]; +                  } +                } +                break; +               +              case Xml::TagStart: +                if (dm==NULL) +                  printf("ERROR: THIS SHOULD NEVER HAPPEN: no valid 'pitch' attribute in <entry> tag, but sub-tags follow in MidiTrack::readOurDrumMap()!\n"); +                else if (tag == "name") +                  dm->name = xml.parse(QString("name")); +                else if (tag == "vol") +                  dm->vol = (unsigned char)xml.parseInt(); +                else if (tag == "quant") +                  dm->quant = xml.parseInt(); +                else if (tag == "len") +                  dm->len = xml.parseInt(); +                else if (tag == "lv1") +                  dm->lv1 = xml.parseInt(); +                else if (tag == "lv2") +                  dm->lv2 = xml.parseInt(); +                else if (tag == "lv3") +                  dm->lv3 = xml.parseInt(); +                else if (tag == "lv4") +                  dm->lv4 = xml.parseInt(); +                else if (tag == "enote") +                  dm->enote = xml.parseInt(); +                else if (tag == "mute") +                  dm->mute = xml.parseInt(); +                else if (tag == "hide") +                  *hidden = xml.parseInt(); +                else +                  xml.unknown("MidiTrack::readOurDrumMap"); +                break; +               +              case Xml::TagEnd: +                if (tag == "entry") +                  goto end_of_nested_for; +               +              default: +                break; +            } +          } // end of nested loop +          end_of_nested_for: ; +        } // end of 'if (tag == "entry")' +				else +					xml.unknown("MidiTrack::readOurDrumMap"); +				break; + +			case Xml::TagEnd: +				if (tag == "our_drummap") +					return; + +			default: +				break; +		} +	} +} +  //---------------------------------------------------------  //   addPart diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 0911b4f1..a958ca74 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -230,10 +230,17 @@ class MidiTrack : public Track {        clefTypes clefType;        DrumMap* _drummap; // _drummap[foo].anote is always equal to foo +      bool* _drummap_hidden; // _drummap und _drummap_hidden will be an array[128]        bool _drummap_tied_to_patch; //if true, changing patch also changes drummap -      bool* _drummap_hidden;        void init(); +      void init_drummap(bool write_ordering=false); +      void remove_ourselves_from_drum_ordering(); +       +      void writeOurDrumSettings(int level, Xml& xml) const; +      void writeOurDrumMap(int level, Xml& xml) const; +      void readOurDrumSettings(Xml& xml); +      void readOurDrumMap(Xml& xml);     public:        MidiTrack(); | 
