1 //========================================================= 2 // MusE 3 // Linux Music Editor 4 // $Id: sync.h,v 1.1.1.1.2.2 2009/04/01 01:37:11 terminator356 Exp $ 5 // 6 // (C) Copyright 2003 Werner Schweer (ws@seh.de) 7 // (C) Copyright 2016 Tim E. Real (terminator356 on sourceforge.net) 8 // 9 // This program is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU General Public License 11 // as published by the Free Software Foundation; version 2 of 12 // the License, or (at your option) any later version. 13 // 14 // This program is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with this program; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 // 23 //========================================================= 24 25 #ifndef __SYNC_H__ 26 #define __SYNC_H__ 27 28 #include "mtc.h" 29 #include "globaldefs.h" 30 31 #include <stdint.h> 32 33 namespace MusECore { 34 35 class Xml; 36 37 class MidiSyncInfo 38 { 39 public: 40 enum SyncRecFilterPresetType { NONE=0, TINY, SMALL, MEDIUM, LARGE, LARGE_WITH_PRE_DETECT, TYPE_END }; 41 42 private: 43 int _port; 44 45 int _idOut; 46 int _idIn; 47 48 bool _sendMC; 49 bool _sendMRT; 50 bool _sendMMC; 51 bool _sendMTC; 52 bool _recMC; 53 bool _recMRT; 54 bool _recMMC; 55 bool _recMTC; 56 57 int _recMTCtype; 58 59 bool _recRewOnStart; 60 61 uint64_t _lastClkTime; 62 uint64_t _lastTickTime; 63 uint64_t _lastMRTTime; 64 uint64_t _lastMMCTime; 65 uint64_t _lastMTCTime; 66 uint64_t _lastActTime[MusECore::MUSE_MIDI_CHANNELS]; 67 68 bool _clockTrig; 69 bool _tickTrig; 70 bool _MRTTrig; 71 bool _MMCTrig; 72 bool _MTCTrig; 73 bool _actTrig[MusECore::MUSE_MIDI_CHANNELS]; 74 bool _clockDetect; 75 bool _tickDetect; 76 bool _MRTDetect; 77 bool _MMCDetect; 78 bool _MTCDetect; 79 bool _actDetect[MusECore::MUSE_MIDI_CHANNELS]; 80 int _actDetectBits; 81 82 public: 83 MidiSyncInfo(); 84 MidiSyncInfo& operator= (const MidiSyncInfo &sp); 85 MidiSyncInfo& copyParams(const MidiSyncInfo &sp); 86 port()87 int port() const { return _port; } setPort(const int p)88 void setPort(const int p) { _port = p; } 89 idOut()90 int idOut() const { return _idOut; } idIn()91 int idIn() const { return _idIn; } setIdOut(const int v)92 void setIdOut(const int v) { _idOut = v; } setIdIn(const int v)93 void setIdIn(const int v) { _idIn = v; } 94 MCOut()95 bool MCOut() const { return _sendMC; } MRTOut()96 bool MRTOut() const { return _sendMRT; } MMCOut()97 bool MMCOut() const { return _sendMMC; } MTCOut()98 bool MTCOut() const { return _sendMTC; } 99 MCIn()100 bool MCIn() const { return _recMC; } MRTIn()101 bool MRTIn() const { return _recMRT; } MMCIn()102 bool MMCIn() const { return _recMMC; } MTCIn()103 bool MTCIn() const { return _recMTC; } 104 setMCOut(const bool v)105 void setMCOut(const bool v) { _sendMC = v; } setMRTOut(const bool v)106 void setMRTOut(const bool v) { _sendMRT = v; } setMMCOut(const bool v)107 void setMMCOut(const bool v) { _sendMMC = v; } setMTCOut(const bool v)108 void setMTCOut(const bool v) { _sendMTC = v; } 109 110 void setMCIn(const bool v); 111 void setMRTIn(const bool v); 112 void setMMCIn(const bool v); 113 void setMTCIn(const bool v); 114 115 void setTime(); 116 recRewOnStart()117 bool recRewOnStart() const { return _recRewOnStart; } setRecRewOnStart(const bool v)118 void setRecRewOnStart(const bool v) { _recRewOnStart = v; } 119 MCSyncDetect()120 bool MCSyncDetect() const { return _clockDetect; } 121 void trigMCSyncDetect(); 122 tickDetect()123 bool tickDetect() const { return _tickDetect; } 124 void trigTickDetect(); 125 MTCDetect()126 bool MTCDetect() const { return _MTCDetect; } 127 void trigMTCDetect(); recMTCtype()128 int recMTCtype() const { return _recMTCtype; } setRecMTCtype(int t)129 void setRecMTCtype(int t) { _recMTCtype = t; } 130 MRTDetect()131 bool MRTDetect() const { return _MRTDetect; } 132 void trigMRTDetect(); 133 MMCDetect()134 bool MMCDetect() const { return _MMCDetect; } 135 void trigMMCDetect(); 136 actDetectBits()137 int actDetectBits() const { return _actDetectBits; } 138 bool actDetect(const int ch) const; 139 void trigActDetect(const int ch); 140 141 bool isDefault() const; 142 void read(Xml& xml); 143 void write(int level, Xml& xml); 144 }; 145 146 147 //--------------------------------------------------------- 148 // ExtMidiClock 149 // Holds the frame of each external clock, 150 // and play state at that time. 151 //--------------------------------------------------------- 152 153 class ExtMidiClock 154 { 155 public: 156 enum ExternState { ExternStopped = 0, ExternStarting, ExternContinuing, ExternStarted, ExternContinued }; 157 158 private: 159 // The frame at which this clock arrived. 160 unsigned int _frame; 161 // The play state of the external device when this clock arrived. 162 ExternState _externState; 163 // Whether this clock is the first clock after a start or continue. 164 bool _isFirstClock; 165 // Whether this is a valid structure. 166 bool _isValid; 167 168 public: ExtMidiClock()169 ExtMidiClock() : _frame(0), _externState(ExternStopped), _isFirstClock(false), _isValid(false) { }; ExtMidiClock(unsigned int frame,ExternState extState,bool firstClock)170 ExtMidiClock(unsigned int frame, ExternState extState, bool firstClock) : 171 _frame(frame), _externState(extState), _isFirstClock(firstClock), _isValid(true) { }; 172 173 // The frame at which this clock arrived. frame()174 unsigned int frame() const { return _frame; } 175 // The play state of the external device when this clock arrived. externState()176 ExternState externState() const { return _externState; } 177 // Whether this clock is the first clock after a start or continue. isFirstClock()178 bool isFirstClock() const { return _isFirstClock; } 179 // Whether this is a valid structure. isValid()180 bool isValid() const { return _isValid; } isPlaying()181 bool isPlaying() const 182 { 183 switch(_externState) 184 { 185 case ExternStopped: 186 case ExternStarting: 187 case ExternContinuing: 188 return false; 189 break; 190 191 case ExternStarted: 192 case ExternContinued: 193 return true; 194 break; 195 }; 196 return false; 197 } isRunning()198 bool isRunning() const 199 { 200 switch(_externState) 201 { 202 case ExternStopped: 203 return false; 204 break; 205 206 case ExternStarting: 207 case ExternContinuing: 208 case ExternStarted: 209 case ExternContinued: 210 return true; 211 break; 212 }; 213 return false; 214 } 215 }; 216 217 //--------------------------------------------------------- 218 // MidiSyncContainer 219 //--------------------------------------------------------- 220 221 class MidiSyncContainer { 222 private: 223 // REMOVE Tim. clock. Removed. 224 unsigned int _midiClock; // Accumulator for clock output. 225 226 /* Testing */ 227 ExtMidiClock::ExternState playStateExt; // used for keeping play state in sync functions 228 int recTick; // ext sync tick position 229 double mclock1, mclock2; 230 double songtick1, songtick2; 231 int recTick1, recTick2; 232 int lastTempo; 233 double timediff[16][48]; 234 int storedtimediffs; 235 int _avgClkDiffCounter[16]; 236 double _lastRealTempo; 237 bool _averagerFull[16]; 238 int _clockAveragerPoles; 239 int* _clockAveragerStages; 240 bool _preDetect; 241 double _tempoQuantizeAmount; 242 MidiSyncInfo::SyncRecFilterPresetType _syncRecFilterPreset; 243 244 void setSyncRecFilterPresetArrays(); 245 void alignAllTicks(int frameOverride = 0); 246 /* Testing */ 247 248 void mtcSyncMsg(const MTC&, int, bool); 249 250 public: 251 MidiSyncContainer(); 252 virtual ~MidiSyncContainer(); 253 254 // REMOVE Tim. clock. Removed. midiClock()255 unsigned int midiClock() const { return _midiClock; } setMidiClock(unsigned int val)256 void setMidiClock(unsigned int val) { _midiClock = val; } externalPlayState()257 ExtMidiClock::ExternState externalPlayState() const { return playStateExt; } setExternalPlayState(ExtMidiClock::ExternState v)258 void setExternalPlayState(ExtMidiClock::ExternState v) { playStateExt = v; } isPlaying()259 bool isPlaying() const 260 { 261 switch(playStateExt) 262 { 263 case ExtMidiClock::ExternStopped: 264 case ExtMidiClock::ExternStarting: 265 case ExtMidiClock::ExternContinuing: 266 return false; 267 break; 268 269 case ExtMidiClock::ExternStarted: 270 case ExtMidiClock::ExternContinued: 271 return true; 272 break; 273 }; 274 return false; 275 } isRunning()276 bool isRunning() const 277 { 278 switch(playStateExt) 279 { 280 case ExtMidiClock::ExternStopped: 281 return false; 282 break; 283 284 case ExtMidiClock::ExternStarting: 285 case ExtMidiClock::ExternContinuing: 286 case ExtMidiClock::ExternStarted: 287 case ExtMidiClock::ExternContinued: 288 return true; 289 break; 290 }; 291 return false; 292 } 293 void realtimeSystemInput(int port, int type); 294 // Starts transport if necessary. Adds clock to tempo list. 295 // Returns a clock structure including frame, state, and whether the clock was a 296 // 'first clock' after a start or continue message. 297 ExtMidiClock midiClockInput(int port, unsigned int frame); 298 void mtcInputQuarter(int, unsigned char); 299 void setSongPosition(int, int); 300 void mmcInput(int, const unsigned char*, int); 301 void mtcInputFull(int, const unsigned char*, int); 302 void nonRealtimeSystemSysex(int, const unsigned char*, int); 303 syncRecFilterPreset()304 MidiSyncInfo::SyncRecFilterPresetType syncRecFilterPreset() const { return _syncRecFilterPreset; } 305 void setSyncRecFilterPreset(MidiSyncInfo::SyncRecFilterPresetType type); recTempoValQuant()306 double recTempoValQuant() const { return _tempoQuantizeAmount; } setRecTempoValQuant(double q)307 void setRecTempoValQuant(double q) { _tempoQuantizeAmount = q; } 308 }; 309 310 } // namespace MusECore 311 312 namespace MusEGlobal { 313 314 extern bool debugSync; 315 316 extern int mtcType; 317 extern MusECore::MTC mtcOffset; 318 extern bool extSyncFlag; 319 extern bool timebaseMasterState; 320 extern bool timebaseMasterForceFlag; 321 extern unsigned int syncSendFirstClockDelay; // In milliseconds. 322 extern unsigned int volatile lastExtMidiSyncTick; 323 extern unsigned int volatile curExtMidiSyncTick; 324 extern MusECore::MidiSyncInfo::SyncRecFilterPresetType syncRecFilterPreset; 325 extern double syncRecTempoValQuant; 326 327 extern MusECore::MidiSyncContainer midiSyncContainer; 328 329 } // namespace MusEGlobal 330 331 #endif 332 333