00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef TSE3_SCHEDULER_H
00018 #define TSE3_SCHEDULER_H
00019
00020 #include "tse3/listen/MidiScheduler.h"
00021
00022 #include "tse3/Notifier.h"
00023 #include "tse3/Midi.h"
00024 #include "tse3/util/MulDiv.h"
00025
00026 #include <cstddef>
00027 #include <vector>
00028
00029 namespace TSE3
00030 {
00043 class MidiSchedulerFactory
00044 {
00045 public:
00046
00057 MidiSchedulerFactory(bool canReturnNull = false);
00058 virtual ~MidiSchedulerFactory();
00059
00070 MidiScheduler *createScheduler();
00071
00072 private:
00073
00074 MidiSchedulerFactory &operator=(const MidiSchedulerFactory &);
00075 MidiSchedulerFactory(const MidiSchedulerFactory &);
00076
00077 bool _canReturnNull;
00078 };
00079
00171 class MidiScheduler : public Notifier<MidiSchedulerListener>
00172 {
00173 public:
00174
00175 MidiScheduler();
00176
00180 virtual ~MidiScheduler();
00181
00188 const char *implementationName() const
00189 {
00190 return this->impl_implementationName();
00191 }
00192
00193
00194
00195
00196
00210 size_t numPorts() const { return _portNumbers.size(); }
00211
00218 bool validPort(int port) const;
00219
00234 int portNumber(size_t index) const
00235 {
00236 return _portNumbers[index].first;
00237 }
00238
00249 size_t numberToIndex(int number) const;
00250
00258 void portNumbers(std::vector<int> &numbers) const;
00259
00269 const char *portName(int port) const;
00270
00281 const char *portType(int port) const;
00282
00295 bool portReadable(int port) const;
00296
00311 bool portWriteable(int port) const;
00312
00326 bool portInternal(int port) const;
00327
00339 int defaultInternalPort() const;
00340
00352 int defaultExternalPort() const;
00353
00354
00355
00356
00357
00363 void start(Clock startTime) { this->impl_start(startTime); }
00364
00369 void start() { this->impl_start(_restingClock); }
00370
00378 void stop(Clock stopTime = -1);
00379
00385 bool running() const { return _running; }
00386
00398 void moveTo(Clock moveTime, Clock newTime);
00399
00405 void moveTo(Clock moveTime) { moveTo(clock(), moveTime); }
00406
00416 Clock clock()
00417 {
00418 return _running ? this->impl_clock() : _restingClock; }
00419
00425 int msecs() { return this->impl_msecs(); }
00426
00433 int tempo() const { return _tempo; }
00434
00448 void setTempo(int newTempo, Clock changeTime)
00449 {
00450 if (newTempo >= 0)
00451 {
00452 this->impl_setTempo(newTempo, changeTime);
00453 _tempo = newTempo;
00454 }
00455 }
00456
00457
00458
00459
00460
00469 bool eventWaiting() { return this->impl_eventWaiting(); }
00470
00486 MidiEvent rx();
00487
00496 void tx(MidiCommand mc);
00497
00514 void tx(MidiEvent event);
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 void txSysEx(int port, const unsigned char *data, size_t size);
00535
00536
00537
00538
00539
00546 bool remoteControl() const { return _remote; }
00547
00554 void setRemoteControl(bool s) { _remote = s; }
00555
00556 bool consumeRemoveEvents() const { return _consumeRemote; }
00557
00565 unsigned int startNote() const { return _startNote; }
00566
00573 void setStartNote(unsigned int n) { _startNote = n; }
00574
00582 unsigned int stopNote() const { return _stopNote; }
00583
00590 void setStopNote(unsigned int n) { _stopNote = n; }
00591
00592 protected:
00593
00594 MidiScheduler(const MidiScheduler &);
00595 MidiScheduler &operator=(const MidiScheduler &);
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 virtual const char *impl_implementationName() const = 0;
00633 virtual const char *impl_portName(int port) const = 0;
00634 virtual const char *impl_portType(int port) const = 0;
00635 virtual bool impl_portReadable(int port) const = 0;
00636 virtual bool impl_portWriteable(int port) const = 0;
00642 virtual void impl_start(Clock clock) = 0;
00649 virtual void impl_stop(Clock clock) = 0;
00655 virtual void impl_moveTo(Clock moveTime, Clock newTime) = 0;
00659 virtual Clock impl_clock() = 0;
00663 virtual int impl_msecs() = 0;
00670 virtual void impl_setTempo(int tempo, Clock changeTime) = 0;
00671 virtual bool impl_eventWaiting() = 0;
00676 virtual MidiEvent impl_rx() = 0;
00682 virtual void impl_tx(MidiCommand mc) = 0;
00693 virtual void impl_tx(MidiEvent mc) = 0;
00697 virtual void impl_txSysEx(int port,
00698 const unsigned char *data,
00699 size_t size) = 0;
00700
00701
00702
00703
00704
00705
00706
00707
00708
00729 int addPort(int portIndex, bool isInternal, int requestedPort = 0);
00730
00735 void removePort(int portIndex);
00736 void clockStarted(Clock startTime);
00737 void clockStopped(Clock stopTime);
00738 void clockMoved(const Clock moveTime, Clock newTime);
00739 void tempoChanged(int tempo, Clock changeTime);
00740
00741
00742
00743
00744
00751 Clock startClock;
00752
00753
00754
00759 int clockToMs(Clock time)
00760 {
00761 return Util::muldiv(time-startClock, 60000/Clock::PPQN, _tempo);
00762 }
00763
00768 Clock msToClock(int ms)
00769 {
00770 return startClock + Util::muldiv(ms, _tempo, 60000/Clock::PPQN);
00771 }
00772
00773 private:
00774
00775
00776
00777
00778
00786 MidiEvent doRemoteControl(MidiEvent e);
00787
00795 bool validChannel(int channel) const
00796 {
00797 return channel >= 0 && channel <= 15;
00798 }
00799 bool validChannel(MidiCommand mc) const
00800 {
00801 return validChannel(mc.channel);
00802 }
00803
00809 bool lookUpPortNumber(MidiCommand &mc) const;
00810 bool lookUpPortNumber(int &port) const;
00811
00817 void setToPortNumber(MidiCommand &mc) const;
00818
00819
00820
00821
00822
00828 struct PortInfo
00829 {
00830 int index;
00831 bool isInternal;
00832 PortInfo(int n, bool i) : index(n), isInternal(i) {}
00833 };
00834 typedef std::vector<std::pair<int,PortInfo> > port_vector;
00835
00836 port_vector _portNumbers;
00837
00838 bool _running;
00839 int _tempo;
00840 Clock _restingClock;
00841 bool _remote;
00842 bool _consumeRemote;
00843 unsigned int _startNote;
00844 unsigned int _stopNote;
00845 int _defaultInternal;
00846 int _defaultExternal;
00847 };
00848 }
00849
00850 #endif
00851