1 /*
2  * Author: Harry van Haaren 2013
3  *         harryhaaren@gmail.com
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef LUPPP_MIDI_H
20 #define LUPPP_MIDI_H
21 
22 #include <vector>
23 
24 /** SeqEvent
25  *  Simple bass class for deriving sequencable events from. Allows for future
26  *  expansion of the Sequencer to hold arbitrary new types of events.
27  */
28 class SeqEventBase
29 {
30 public:
31 	/// create new EventBase: optionally specify time and duration
32 	SeqEventBase( float time = -1, float duration = -1 );
~SeqEventBase()33 	virtual ~SeqEventBase() {};
34 
35 	/// get the event's unique ID
36 	unsigned long getID();
37 
38 	/// get/set the time of the event
getTime()39 	float getTime()
40 	{
41 		return time;
42 	}
setTime(float t)43 	void setTime(float t)
44 	{
45 		time = t;
46 	}
47 
48 	/// returns integer beat from start of loop
getBeat()49 	int getBeat()
50 	{
51 		return int(time);
52 	}
53 
getDuration()54 	float getDuration()
55 	{
56 		return duration;
57 	}
58 
59 	/// returns amount of time from the previous beat as float between 0-1.
60 	/// 0 is exactly on the beat, while 0.25 is 25% of the way from the current
61 	/// beat towards the next beat
getOffset()62 	float getOffset()
63 	{
64 		return ( time - int(time) );
65 	}
66 
67 protected:
setUniqueID(unsigned long uid)68 	void setUniqueID( unsigned long uid )
69 	{
70 		ID = uid;
71 	}
72 
73 private:
74 	unsigned long ID;
75 	static unsigned long privateID;
76 
77 	/// The timestamp of any SeqEvent.
78 	float time;
79 
80 	/// If duration makes sense, the events end time is time+duration
81 	float duration;
82 };
83 
84 /** MidiEvent
85  *  Represents a single MIDI event. Always 3 bytes, interpret as standard MIDI.
86  */
87 class MidiEvent : public SeqEventBase
88 {
89 public:
90 	/// create empty midi event
91 	MidiEvent();
92 
93 	/// creates a new MidiEvent specifying start time & duration: optional data
94 	MidiEvent( float time, float duration, unsigned char* d = 0);
95 
96 	void setData( unsigned char* d );
97 	unsigned char data[3];
98 };
99 
100 /** SeqEventList
101  *  Holds a list of SeqEvents, allows for adding / swapping contents.
102  *  MidiLooper uses instances to hold & interact with clip contents.
103  */
104 class SeqEventList
105 {
106 public:
107 	SeqEventList(int scene);
108 	~SeqEventList();
109 
110 	int getLoopLength();
111 	void setLoopLenght(int l);
112 
113 	void add( MidiEvent* m );
114 	void modify( MidiEvent m );
115 
116 	int numEvents();
117 	SeqEventBase* getNext();
118 
119 	/// move to next event. True if there was one, false if not
120 	bool moveToNextEvent();
121 
122 	/// restart the clip from the beginning
123 	void queueFromStart();
124 
125 	/// clear all contents, freeing memory: non-RT safe
126 	void nonRtClear();
127 
128 private:
129 	unsigned long ID;
130 	static unsigned long privateID;
131 
132 	int scene;
133 
134 	int loopLengthBeats;
135 
136 	/// number of events in clip
137 	unsigned int eventCount;
138 
139 	/// current index of event
140 	unsigned int eventIndex;
141 
142 	/// holds pointers to each event
143 	int eventCapacity;
144 	std::vector<SeqEventBase*> events;
145 };
146 
147 
148 
149 #endif // LUPPP_MIDI_H
150 
151