1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: mpevent.h,v 1.8.2.5 2009/11/25 09:09:43 terminator356 Exp $
5 //
6 //  (C) Copyright 1999-2002 Werner Schweer (ws@seh.de)
7 //  (C) Copyright 2012 Tim E. Real (terminator356 on users dot sourceforge dot 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 __MPEVENT_H__
26 #define __MPEVENT_H__
27 
28 #include <set>
29 #include "evdata.h"
30 #include "memory.h"
31 #include <cstddef>
32 
33 // Play events ring buffer size
34 #define MIDI_FIFO_SIZE    4096
35 
36 // Record events ring buffer size
37 #define MIDI_REC_FIFO_SIZE  256
38 
39 namespace MusECore {
40 
41 //---------------------------------------------------------
42 //   MEvent
43 //    baseclass for MidiPlayEvent and MidiRecordEvent
44 //---------------------------------------------------------
45 
46 //---------------------------------------------------------
47 //   MEvent
48 //---------------------------------------------------------
49 
50 class MEvent {
51       unsigned _time;
52       EvData edata;
53       unsigned char _port, _channel, _type;
54       int _a, _b;
55       int _loopNum; // The loop count when the note was recorded.
56 
57    public:
MEvent()58       MEvent() : _time(0), _port(0), _channel(0), _type(0), _a(0), _b(0), _loopNum(0) { }
MEvent(const MEvent & e)59       MEvent(const MEvent& e) : _time(e._time), edata(e.edata), _port(e._port), _channel(e._channel),
60              _type(e._type), _a(e._a), _b(e._b), _loopNum(e._loopNum) { }
MEvent(unsigned tm,int p,int c,int t,int a,int b)61       MEvent(unsigned tm, int p, int c, int t, int a, int b)
62         : _time(tm), _port(p), _channel(c & 0xf), _type(t), _a(a), _b(b), _loopNum(0) { }
63       MEvent(unsigned t, int p, int type, const unsigned char* data, int len);
MEvent(unsigned t,int p,int tpe,EvData d)64       MEvent(unsigned t, int p, int tpe, EvData d) : _time(t), edata(d), _port(p), _type(tpe), _loopNum(0) { }
65 
~MEvent()66       virtual ~MEvent()         {}
67 
68       MEvent& operator=(const MEvent& ed) {
69             _time    = ed._time;
70             edata    = ed.edata;
71             _port    = ed._port;
72             _channel = ed._channel;
73             _type    = ed._type;
74             _a       = ed._a;
75             _b       = ed._b;
76             _loopNum = ed._loopNum;
77             return *this;
78             }
79 
80       int sortingWeight() const;
81 
port()82       int port()    const      { return _port;    }
channel()83       int channel() const      { return _channel; }
type()84       int type()    const      { return _type;    }
dataA()85       int dataA()   const      { return _a;       }
dataB()86       int dataB()   const      { return _b;       }
time()87       unsigned time() const    { return _time;    }
loopNum()88       int loopNum() const      { return _loopNum; }
89 
setPort(int val)90       void setPort(int val)    { _port = val;     }
setChannel(int val)91       void setChannel(int val) { _channel = val;  }
setType(int val)92       void setType(int val)    { _type = val;     }
setA(int val)93       void setA(int val)       { _a = val;        }
setB(int val)94       void setB(int val)       { _b = val;        }
setTime(unsigned val)95       void setTime(unsigned val) { _time = val;   }
setLoopNum(int n)96       void setLoopNum(int n)   { _loopNum = n;    }
97 
eventData()98       const EvData& eventData() const { return edata; }
data()99       unsigned char* data()    { return edata.data(); }
constData()100       const unsigned char* constData() const { return edata.constData(); }
len()101       int len() const                 { return edata.dataLen(); }
setData(const EvData & e)102       void setData(const EvData& e)   { edata = e; }
setData(const unsigned char * p,int len)103       void setData(const unsigned char* p, int len) { edata.setData(p, len); }
104 
isNote()105       bool isNote() const      { return _type == 0x90; }
isNoteOff()106       bool isNoteOff() const   { return (_type == 0x80)||(_type == 0x90 && _b == 0); }
107       bool operator<(const MEvent&) const;
isValid()108       bool isValid() const { return _type != 0; }
109 
110       // Returns a valid source controller number (above zero),
111       //  translated from the event to proper internal control type.
112       // For example
113       //  ME_CONTROLLER + Data(A = CTRL_HBANK) = CTRL_PROGRAM
114       //  ME_CONTROLLER + Data(A = CTRL_LBANK) = CTRL_PROGRAM
115       //  ME_PROGRAM                           = CTRL_PROGRAM
116       //  ME_PITCHBEND                         = CTRL_PITCH
117       //  ME_CONTROLLER + Data(A = ctrl)       = ctrl
118       // Otherwise returns -1 if the event is not translatable to a controller,
119       //  or an error occurred.
120       int translateCtrlNum() const;
121       };
122 
123 //---------------------------------------------------------
124 //   MidiRecordEvent
125 //    allocated and deleted in midiseq thread context
126 //---------------------------------------------------------
127 
128 class MidiRecordEvent : public MEvent {
129    private:
130       unsigned int _tick; // To store tick when external sync is on, required besides frame.
131    public:
MidiRecordEvent()132       MidiRecordEvent() : MEvent() {}
MidiRecordEvent(const MidiRecordEvent & e)133       MidiRecordEvent(const MidiRecordEvent& e) : MEvent(e), _tick(e._tick) {}
MidiRecordEvent(const MEvent & e)134       MidiRecordEvent(const MEvent& e) : MEvent(e), _tick(0) {}
MidiRecordEvent(unsigned tm,int p,int c,int t,int a,int b)135       MidiRecordEvent(unsigned tm, int p, int c, int t, int a, int b)
136         : MEvent(tm, p, c, t, a, b) {}
MidiRecordEvent(unsigned t,int p,int tpe,const unsigned char * data,int len)137       MidiRecordEvent(unsigned t, int p, int tpe, const unsigned char* data, int len)
138         : MEvent(t, p, tpe, data, len) {}
MidiRecordEvent(unsigned t,int p,int type,EvData data)139       MidiRecordEvent(unsigned t, int p, int type, EvData data)
140         : MEvent(t, p, type, data) {}
~MidiRecordEvent()141       virtual ~MidiRecordEvent() {}
142 
143       MidiRecordEvent& operator=(const MidiRecordEvent& e) { MEvent::operator=(e); _tick = e._tick; return *this; }
144 
tick()145       unsigned int tick() {return _tick;}
setTick(unsigned int tick)146       void setTick(unsigned int tick) {_tick = tick;}
147       };
148 
149 //---------------------------------------------------------
150 //   MidiPlayEvent
151 //    allocated and deleted in audio thread context
152 //---------------------------------------------------------
153 
154 class MidiPlayEvent : public MEvent {
155    public:
MidiPlayEvent()156       MidiPlayEvent() : MEvent() {}
MidiPlayEvent(const MidiPlayEvent & e)157       MidiPlayEvent(const MidiPlayEvent& e) : MEvent(e) {}
MidiPlayEvent(const MEvent & e)158       MidiPlayEvent(const MEvent& e) : MEvent(e) {}
MidiPlayEvent(unsigned tm,int p,int c,int t,int a,int b)159       MidiPlayEvent(unsigned tm, int p, int c, int t, int a, int b)
160         : MEvent(tm, p, c, t, a, b) {}
MidiPlayEvent(unsigned t,int p,int type,const unsigned char * data,int len)161       MidiPlayEvent(unsigned t, int p, int type, const unsigned char* data, int len)
162         : MEvent(t, p, type, data, len) {}
MidiPlayEvent(unsigned t,int p,int type,EvData data)163       MidiPlayEvent(unsigned t, int p, int type, EvData data)
164         : MEvent(t, p, type, data) {}
~MidiPlayEvent()165       virtual ~MidiPlayEvent() {}
166 
167       MidiPlayEvent& operator=(const MidiPlayEvent& e) { MEvent::operator=(e); return *this; }
168       };
169 
170 //---------------------------------------------------------
171 //   MidiRecFifo
172 //---------------------------------------------------------
173 
174 class MidiRecFifo {
175       MidiRecordEvent fifo[MIDI_REC_FIFO_SIZE];
176       volatile int size;
177       int wIndex;
178       int rIndex;
179 
180    public:
MidiRecFifo()181       MidiRecFifo()  { clear(); }
182       bool put(const MidiRecordEvent& event);   // returns true on fifo overflow
183       MidiRecordEvent get();
184       const MidiRecordEvent& peek(int = 0);
185       void remove();
isEmpty()186       bool isEmpty() const { return size == 0; }
clear()187       void clear()         { size = 0, wIndex = 0, rIndex = 0; }
getSize()188       int getSize() const  { return size; }
189       };
190 
191 //---------------------------------------------------------
192 //   audioMPEventRTalloc
193 //---------------------------------------------------------
194 
195 template <typename T> class audioMPEventRTalloc
196 {
197   private:
198     static TypedMemoryPool<T, 2048> pool;
199 
200   public:
201     typedef T         value_type;
202     typedef size_t    size_type;
203     typedef ptrdiff_t difference_type;
204 
205     typedef T*        pointer;
206     typedef const T*  const_pointer;
207 
208     typedef T&        reference;
209     typedef const T&  const_reference;
210 
address(reference x)211     pointer address(reference x) const { return &x; }
address(const_reference x)212     const_pointer address(const_reference x) const { return &x; }
213 
audioMPEventRTalloc()214     audioMPEventRTalloc() { }
audioMPEventRTalloc(const audioMPEventRTalloc<U> &)215     template <typename U> audioMPEventRTalloc(const audioMPEventRTalloc<U>&) {}
~audioMPEventRTalloc()216     ~audioMPEventRTalloc() {}
217 
218     pointer allocate(size_type n, void * = 0) { return static_cast<T*>(pool.alloc(n)); }
deallocate(pointer p,size_type n)219     void deallocate(pointer p, size_type n) { pool.free(p, n); }
220 
221     audioMPEventRTalloc<T>&  operator=(const audioMPEventRTalloc&) { return *this; }
construct(pointer p,const T & val)222     void construct(pointer p, const T& val) { new ((T*) p) T(val); }
destroy(pointer p)223     void destroy(pointer p) { p->~T(); }
max_size()224     size_type max_size() const { return size_t(-1); }
225 
226     template <typename U> struct rebind { typedef audioMPEventRTalloc<U> other; };
227     template <typename U> audioMPEventRTalloc& operator=(const audioMPEventRTalloc<U>&) { return *this; }
228 };
229 
230 //---------------------------------------------------------
231 //   seqMPEventRTalloc
232 //---------------------------------------------------------
233 
234 template <typename T> class seqMPEventRTalloc
235 {
236   private:
237     static TypedMemoryPool<T, 2048> pool;
238 
239   public:
240     typedef T         value_type;
241     typedef size_t    size_type;
242     typedef ptrdiff_t difference_type;
243 
244     typedef T*        pointer;
245     typedef const T*  const_pointer;
246 
247     typedef T&        reference;
248     typedef const T&  const_reference;
249 
address(reference x)250     pointer address(reference x) const { return &x; }
address(const_reference x)251     const_pointer address(const_reference x) const { return &x; }
252 
seqMPEventRTalloc()253     seqMPEventRTalloc() { }
seqMPEventRTalloc(const seqMPEventRTalloc<U> &)254     template <typename U> seqMPEventRTalloc(const seqMPEventRTalloc<U>&) {}
~seqMPEventRTalloc()255     ~seqMPEventRTalloc() {}
256 
257     pointer allocate(size_type n, void * = 0) { return static_cast<T*>(pool.alloc(n)); }
deallocate(pointer p,size_type n)258     void deallocate(pointer p, size_type n) { pool.free(p, n); }
259 
260     seqMPEventRTalloc<T>&  operator=(const seqMPEventRTalloc&) { return *this; }
construct(pointer p,const T & val)261     void construct(pointer p, const T& val) { new ((T*) p) T(val); }
destroy(pointer p)262     void destroy(pointer p) { p->~T(); }
max_size()263     size_type max_size() const { return size_t(-1); }
264 
265     template <typename U> struct rebind { typedef seqMPEventRTalloc<U> other; };
266     template <typename U> seqMPEventRTalloc& operator=(const seqMPEventRTalloc<U>&) { return *this; }
267 };
268 
269 //---------------------------------------------------------
270 //   MPEventList
271 //    memory allocation in audio thread domain
272 //---------------------------------------------------------
273 
274 typedef std::multiset<MidiPlayEvent, std::less<MidiPlayEvent>, audioMPEventRTalloc<MidiPlayEvent> > MPEL;
275 
276 class MPEventList : public MPEL {
277   public:
278       // Optimize to eliminate duplicate events at the SAME time.
279       // It will not handle duplicate events at DIFFERENT times.
280       // Replaces event if it already exists.
281       void add(const MidiPlayEvent& ev);
282 };
283 
284 typedef MPEventList::iterator iMPEvent;
285 typedef MPEventList::const_iterator ciMPEvent;
286 typedef std::pair<iMPEvent, iMPEvent> MPEventListRangePair_t;
287 
288 //---------------------------------------------------------
289 //   SeqMPEventList
290 //    memory allocation in sequencer thread domain
291 //---------------------------------------------------------
292 
293 typedef std::multiset<MidiPlayEvent, std::less<MidiPlayEvent>, seqMPEventRTalloc<MidiPlayEvent> > SMPEL;
294 
295 class SeqMPEventList : public SMPEL {
296   public:
297       // Optimize to eliminate duplicate events at the SAME time.
298       // It will not handle duplicate events at DIFFERENT times.
299       // Replaces event if it already exists.
300       void add(const MidiPlayEvent& ev);
301 };
302 
303 typedef SeqMPEventList::iterator iSeqMPEvent;
304 typedef SeqMPEventList::const_iterator ciSeqMPEvent;
305 typedef std::pair<iSeqMPEvent, iSeqMPEvent> SeqMPEventListRangePair_t;
306 
307 
308 } // namespace MusECore
309 
310 #endif
311 
312