diff options
| author | Robert Jonsson <spamatica@gmail.com> | 2011-03-07 19:01:11 +0000 | 
|---|---|---|
| committer | Robert Jonsson <spamatica@gmail.com> | 2011-03-07 19:01:11 +0000 | 
| commit | e40fc849149dd97c248866a4a1d026dda5e57b62 (patch) | |
| tree | b12b358f3b3a0608001d30403358f8443118ec5f /attic/muse_qt4_evolution/al/tempo.cpp | |
| parent | 1bd4f2e8d9745cabb667b043171cad22c8577768 (diff) | |
clean3
Diffstat (limited to 'attic/muse_qt4_evolution/al/tempo.cpp')
| -rw-r--r-- | attic/muse_qt4_evolution/al/tempo.cpp | 393 | 
1 files changed, 393 insertions, 0 deletions
| diff --git a/attic/muse_qt4_evolution/al/tempo.cpp b/attic/muse_qt4_evolution/al/tempo.cpp new file mode 100644 index 00000000..7d65c732 --- /dev/null +++ b/attic/muse_qt4_evolution/al/tempo.cpp @@ -0,0 +1,393 @@ +//============================================================================= +//  AL +//  Audio Utility Library +//  $Id:$ +// +//  Copyright (C) 2002-2006 by Werner Schweer and others +// +//  This program is free software; you can redistribute it and/or modify +//  it under the terms of the GNU General Public License version 2. +// +//  This program is distributed in the hope that it will be useful, +//  but WITHOUT ANY WARRANTY; without even the implied warranty of +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +//  GNU General Public License for more details. +// +//  You should have received a copy of the GNU General Public License +//  along with this program; if not, write to the Free Software +//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "al.h" +#include "tempo.h" +#include "xml.h" + +namespace AL { + +TempoList tempomap; + +//--------------------------------------------------------- +//   TempoList +//--------------------------------------------------------- + +TempoList::TempoList() +      { +      _tempo   = 500000; +      insert(std::pair<const unsigned, TEvent*> (MAX_TICK+1, new TEvent(_tempo, 0))); +      _tempoSN     = 1; +      _globalTempo = 100; +      useList      = true; +      } + +//--------------------------------------------------------- +//   add +//--------------------------------------------------------- + +void TempoList::add(unsigned tick, int tempo) +      { +      if (tick > MAX_TICK) +            tick = MAX_TICK; + +      iTEvent e = upper_bound(tick); + +      if (tick == e->second->tick) +            e->second->tempo = tempo; +      else { +            TEvent* ne = e->second; +            TEvent* ev = new TEvent(ne->tempo, ne->tick); +            ne->tempo  = tempo; +            ne->tick   = tick; +            insert(std::pair<const unsigned, TEvent*> (tick, ev)); +            } +      normalize(); +      } + +//--------------------------------------------------------- +//   TempoList::normalize +//--------------------------------------------------------- + +void TempoList::normalize() +      { +      int frame = 0; +      for (iTEvent e = begin(); e != end(); ++e) { +            e->second->frame = frame; +            unsigned dtick = e->first - e->second->tick; +            double dtime = double(dtick) / (division * _globalTempo * 10000.0/e->second->tempo); +            frame += lrint(dtime * sampleRate); +            } +      } + +//--------------------------------------------------------- +//   TempoList::dump +//--------------------------------------------------------- + +void TempoList::dump() const +      { +      printf("\nTempoList:\n"); +      for (ciTEvent i = begin(); i != end(); ++i) { +            printf("%6d %06d Tempo %6d Frame %d\n", +               i->first, i->second->tick, i->second->tempo, +               i->second->frame); +            } +      } + +//--------------------------------------------------------- +//   clear +//--------------------------------------------------------- + +void TempoList::clear() +      { +      for (iTEvent i = begin(); i != end(); ++i) +            delete i->second; +      TEMPOLIST::clear(); +      insert(std::pair<const unsigned, TEvent*> (MAX_TICK+1, new TEvent(500000, 0))); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   tempo +//--------------------------------------------------------- + +int TempoList::tempo(unsigned tick) const +      { +      if (useList) { +            ciTEvent i = upper_bound(tick); +            if (i == end()) { +                  printf("no TEMPO at tick %d,0x%x\n", tick, tick); +                  return 1000; +                  } +            return i->second->tempo; +            } +      else +            return _tempo; +      } + +//--------------------------------------------------------- +//   del +//--------------------------------------------------------- + +void TempoList::del(unsigned tick) +      { +// printf("TempoList::del(%d)\n", tick); +      iTEvent e = find(tick); +      if (e == end()) { +            printf("TempoList::del(%d): not found\n", tick); +            return; +            } +      del(e); +      ++_tempoSN; +      } + +void TempoList::del(iTEvent e) +      { +      iTEvent ne = e; +      ++ne; +      if (ne == end()) { +            printf("TempoList::del(): not found\n"); +            return; +            } +      ne->second->tempo = e->second->tempo; +      ne->second->tick  = e->second->tick; +      erase(e); +      normalize(); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   change +//--------------------------------------------------------- + +void TempoList::change(unsigned tick, int newTempo) +      { +      iTEvent e = find(tick); +      e->second->tempo = newTempo; +      normalize(); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   setTempo +//    called from transport window +//    & slave mode tempo changes +//--------------------------------------------------------- + +void TempoList::setTempo(unsigned tick, int newTempo) +      { +      if (useList) +            add(tick, newTempo); +      else +            _tempo = newTempo; +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   setGlobalTempo +//--------------------------------------------------------- + +void TempoList::setGlobalTempo(int val) +      { +      _globalTempo = val; +      ++_tempoSN; +      normalize(); +      } + +//--------------------------------------------------------- +//   addTempo +//--------------------------------------------------------- + +void TempoList::addTempo(unsigned t, int tempo) +      { +      add(t, tempo); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   delTempo +//--------------------------------------------------------- + +void TempoList::delTempo(unsigned tick) +      { +      del(tick); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   changeTempo +//--------------------------------------------------------- + +void TempoList::changeTempo(unsigned tick, int newTempo) +      { +      change(tick, newTempo); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   setMasterFlag +//--------------------------------------------------------- + +bool TempoList::setMasterFlag(unsigned /*tick*/, bool val) +      { +      if (useList != val) { +            useList = val; +            ++_tempoSN; +            return true; +            } +      return false; +      } + +//--------------------------------------------------------- +//   tick2frame +//--------------------------------------------------------- + +unsigned TempoList::tick2frame(unsigned tick, unsigned frame, int* sn) const +      { +      return (*sn == _tempoSN) ? frame : tick2frame(tick, sn); +      } + +//--------------------------------------------------------- +//   tick2frame +//--------------------------------------------------------- + +unsigned TempoList::tick2frame(unsigned tick, int* sn) const +      { +      int f; +      if (useList) { +            ciTEvent i = upper_bound(tick); +            if (i == end()) { +                  printf("tick2frame(%d,0x%x): not found\n", tick, tick); +                  abort();  // debug +                  return 0; +                  } +            unsigned dtick = tick - i->second->tick; +            double dtime   = double(dtick) / (division * _globalTempo * 10000.0/ i->second->tempo); +            unsigned dframe   = lrint(dtime * sampleRate); +            f = i->second->frame + dframe; +            } +      else { +            double t = (double(tick) * double(_tempo)) / (double(division) * _globalTempo * 10000.0); +            f = lrint(t * sampleRate); +            } +      if (sn) +            *sn = _tempoSN; +      return f; +      } + +//--------------------------------------------------------- +//   frame2tick +//    return cached value t if list did not change +//--------------------------------------------------------- + +unsigned TempoList::frame2tick(unsigned frame, unsigned t, int* sn) const +      { +      return (*sn == _tempoSN) ? t : frame2tick(frame, sn); +      } + +//--------------------------------------------------------- +//   frame2tick +//--------------------------------------------------------- + +unsigned TempoList::frame2tick(unsigned frame, int* sn) const +      { +      unsigned tick; +      if (useList) { +            ciTEvent e; +            for (e = begin(); e != end();) { +                  ciTEvent ee = e; +                  ++ee; +                  if (ee == end()) +                        break; +                  if (frame < ee->second->frame) +                        break; +                  e = ee; +                  } +            unsigned te  = e->second->tempo; +            int dframe   = frame - e->second->frame; +            double dtime = double(dframe) / double(sampleRate); +            tick         = e->second->tick + lrint(dtime * _globalTempo * division * 10000.0 / te); +            } +      else +            tick = lrint((double(frame)/double(sampleRate)) * _globalTempo * division * 10000.0 / double(_tempo)); +      if (sn) +            *sn = _tempoSN; +      return tick; +      } + +//--------------------------------------------------------- +//   TempoList::write +//--------------------------------------------------------- + +void TempoList::write(Xml& xml) const +      { +      xml.stag(QString("tempolist fix=\"%1\"").arg(_tempo)); +      if (_globalTempo != 100) +            xml.tag("globalTempo", _globalTempo); +      for (ciTEvent i = begin(); i != end(); ++i) +            i->second->write(xml, i->first); +      xml.etag("tempolist"); +      } + +//--------------------------------------------------------- +//   TempoList::read +//--------------------------------------------------------- + +void TempoList::read(QDomNode node) +      { +      QDomElement e = node.toElement(); +      _tempo = e.attribute("fix","500000").toInt(); + +      node = node.firstChild(); +      while (!node.isNull()) { +            e = node.toElement(); +            if (e.tagName() == "tempo") { +                  TEvent* t = new TEvent(); +                  unsigned tick = t->read(node); +                  iTEvent pos = find(tick); +                  if (pos != end()) +                        erase(pos); +                  insert(std::pair<const int, TEvent*> (tick, t)); +                  } +            else if (e.tagName() == "globalTempo") +                  _globalTempo = e.text().toInt(); +            else +                  printf("MusE:Tempolist: unknown tag %s\n", e.tagName().toLatin1().data()); +            node = node.nextSibling(); +            } +      normalize(); +      ++_tempoSN; +      } + +//--------------------------------------------------------- +//   TEvent::write +//--------------------------------------------------------- + +void TEvent::write(Xml& xml, int at) const +      { +      xml.stag(QString("tempo at=\"%1\"").arg(at)); +      xml.tag("tick", tick); +      xml.tag("val", tempo); +      xml.etag("tempo"); +      } + +//--------------------------------------------------------- +//   TEvent::read +//--------------------------------------------------------- + +int TEvent::read(QDomNode node) +      { +      QDomElement e = node.toElement(); +      int at = e.attribute("at","0").toInt(); + +      node = node.firstChild(); +      while (!node.isNull()) { +            e = node.toElement(); +            if (e.tagName() == "tick") +                  tick = e.text().toInt(); +            else if (e.tagName() == "val") +                  tempo = e.text().toInt(); +            else +                  printf("MusE:TEvent: unknown tag %s\n", e.tagName().toLatin1().data()); +            node = node.nextSibling(); +            } +      return at; +      } +} | 
