TempoList.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * TempoList.cpp
  3. * Copyright © 2010-2012 HAL
  4. * Copyright © 2012 kbinani
  5. *
  6. * This file is part of vConnect-STAND.
  7. *
  8. * vConnect-STAND is free software; you can redistribute it and/or
  9. * modify it under the terms of the GPL License.
  10. *
  11. * vConnect-STAND is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. */
  15. #include "TempoList.h"
  16. #include "Sequence.h"
  17. namespace vconnect
  18. {
  19. const double TempoList::DEFAULT_TEMPO = 120.0;
  20. double TempoList::tickToSecond( long tick )
  21. {
  22. if( false == this->isUpdated ){
  23. this->updateTempoInfo();
  24. }
  25. double secPerClock;
  26. double coeff = 60.0 / Sequence::getTickPerBeat();
  27. map<long, TempoBP>::reverse_iterator i = this->points.rbegin();
  28. for( ; i != this->points.rend(); i++ ){
  29. if( i->first < tick ){
  30. double init = i->second.time;
  31. long delta = tick - i->first;
  32. secPerClock = coeff / i->second.tempo;
  33. return init + delta * secPerClock;
  34. }
  35. }
  36. secPerClock = coeff / TempoList::DEFAULT_TEMPO;
  37. return tick * secPerClock;
  38. }
  39. void TempoList::updateTempoInfo()
  40. {
  41. TempoBP first;
  42. first.tempo = TempoList::DEFAULT_TEMPO;
  43. first.time = 0.0;
  44. if( this->points.size() == 0 ){
  45. this->points.insert( make_pair( 0L, first ) );
  46. }else{
  47. if( this->points.begin()->first != 0 ){
  48. this->points.insert( make_pair( 0L, first ) );
  49. }
  50. }
  51. double coeff = 60.0 / Sequence::getTickPerBeat();
  52. double lastTime;
  53. long lastClock;
  54. double lastTempo;
  55. map<long, TempoBP>::iterator i = this->points.begin();
  56. for( ; i != this->points.end(); i++ ){
  57. if( i == this->points.begin() ){
  58. i->second.time = 0.0;
  59. lastClock = 0;
  60. lastTempo = i->second.tempo;
  61. lastTime = i->second.time;
  62. }else{
  63. i->second.time = lastTime + (i->first - lastClock) * coeff / lastTempo;
  64. lastClock = i->first;
  65. lastTempo = i->second.tempo;
  66. lastTime = i->second.time;
  67. }
  68. }
  69. this->isUpdated = true;
  70. }
  71. void TempoList::push( long tick, double tempo )
  72. {
  73. this->isUpdated = false;
  74. TempoBP point;
  75. point.tempo = tempo;
  76. this->points.insert( make_pair( tick, point ) );
  77. }
  78. }