File: midithread.h

package info (click to toggle)
muse 0.6.3-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 8,936 kB
  • ctags: 7,446
  • sloc: cpp: 66,262; sh: 8,355; makefile: 755; ansic: 172
file content (227 lines) | stat: -rw-r--r-- 6,710 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//=========================================================
//  MusE
//  Linux Music Editor
//  $Id: midithread.h,v 1.1.1.1 2003/10/29 10:05:18 wschweer Exp $
//
//  (C) Copyright 2001 Werner Schweer (ws@seh.de)
//=========================================================

#ifndef __SEQTHREAD_H__
#define __SEQTHREAD_H__

#include <qobject.h>
#include "thread.h"
#include "pos.h"
#include "mpevent.h"

class Part;
class Event;
class MidiPlayEvent;
class MidiEvent;
class Track;
class MidiPort;
class MidiDevice;
class EventList;
class MTC;
struct MidiThreadPrivate;
class SynthI;
class MidiInstrument;

enum State {IDLE, PLAY, START_PLAY, SYNC, PRECOUNT};
static const int REC_NOTE_FIFO_SIZE = 16;

//---------------------------------------------------------
//   MidiMsgId
//    this are the messages send from the GUI thread to
//    the midi thread
//---------------------------------------------------------

enum MidiMsgId {
      SEQM_ADD_TRACK, SEQM_REMOVE_TRACK, SEQM_CHANGE_TRACK, SEQM_MOVE_TRACK,
      SEQM_ADD_PART, SEQM_REMOVE_PART, SEQM_CHANGE_PART,
      SEQM_ADD_EVENT, SEQM_REMOVE_EVENT, SEQM_CHANGE_EVENT,
      SEQM_ADD_TEMPO, SEQM_SET_TEMPO, SEQM_REMOVE_TEMPO, SEQM_ADD_SIG,
      SEQM_SET_GLOBAL_TEMPO,
      SEQM_UNDO, SEQM_REDO,
      SEQM_RESET_DEVICES, SEQM_INIT_DEVICES, SEQM_PANIC,
      SEQM_MIDI_LOCAL_OFF,
      SEQM_MIDI_CTRL, SEQM_MIDI_MASTER_VOLUME,
      SEQM_SET_MIDI_DEVICE,
      SEQM_PLAY_MIDI_EVENT,
      SEQM_SET_MIXDOWN,
      SEQM_SET_RTC_TICKS,
      SEQM_SEEK, SEQM_PLAY,
      SEQM_SCAN_ALSA_MIDI_PORTS,
      SEQM_REMOVE_SYNTHI, SEQM_ADD_SYNTHI,
      MIDI_ADD_SYNTHI, MIDI_SHOW_INSTR_GUI,
      };

//---------------------------------------------------------
//   MidiMsg
//---------------------------------------------------------

struct MidiMsg : public ThreadMsg {
      void* p1;
      void* p2;
      void* p3;

      char port;
      char channel;
      char ctrl;

      int a;
      int b;
      int c;
      };

//---------------------------------------------------------
//   MidiThread
//---------------------------------------------------------

class MidiThread : public QObject, public Thread {
      Q_OBJECT;

      QTimer* heartBeatTimer;       // controls gui refreshes
      State state;
      int timerFd;
      int sigFd;

      // play values:
      int playTickPos;        // current midi tick position in song
      int rtcStartTick;
      int endSlice;

      MPEventList playEvents;
      MPEventList stuckNotes;

      bool controlChanged;

      int recTick;            // ext sync tick position
      int lastTickPos;        // position of last sync tick

      // record values:
      int recNoteFifo[REC_NOTE_FIFO_SIZE];
      volatile int noteFifoSize;
      int noteFifoWindex;
      int noteFifoRindex;

      Pos startRecord;
      Pos endRecord;
      bool loopPassed;

      // run values:
      unsigned _midiTick;

      unsigned rtcTick;             // free running rtcTick
      unsigned rtcTickStart;        // pos 0.0.0

      unsigned samplePos;           // audio sample time base
      unsigned samplePosStart;      // pos 0.0.0

      unsigned midiClock;           // next midi clock pos in midi ticks
      int realRtcTicks;             // current rtc tick rate 1/sec
      int tempoSN;                  // last tempo serial number to track
                                    //    tempo changes
      double mclock1, mclock2;

      unsigned midiClick;
      int clickno;
      int clicksMeasure;
      int ticksBeat;

      virtual void processMsg(const ThreadMsg*);
      virtual void defaultTick();

      void updatePollFd();
      bool setRtcTicks();
      int recTimeStamp() const;
      void recordStop();
      void sendLocalOff();
      bool filterEvent(const MidiPlayEvent* event, int type, bool thru);
      void mtcSyncMsg(const MTC& mtc, bool seekFlag);
      void statePlay();
      static void midiTick(void* p, void*);
      void initDevices();

      void startPlay(int);
      void stopPlay();
      void seek(int pos);
      void playEvent(const MidiPlayEvent* event);
      void processTimerTick();
      void processMidiClock();
      void nextEvents(int starTick, int endTick);
      void panic();

   public slots:
      void seqSignal(int fd);
      void resetDevices();
      void msgInitDevices();
      void localOff();
      void heartBeat();

   signals:
      void midiNote(int, int);

   public:
      MidiThread(int prio, const char* name);
      ~MidiThread();
      void start();
      virtual void threadStop();
      virtual void threadStart(void*);

      bool sendMessage(const MidiMsg* m, bool doUndo);

      bool isPlaying() const;
      void setHeartBeat();

      //-----------------------------------------
      //   message interface
      //-----------------------------------------

      void msgSeek(int val);
      void msgPlay(bool val);

      void msgAddTrack(Track* track, bool u = true);
      void msgRemoveTracks();
      void msgChangeTrack(Track* oldTrack, Track* newTrack, bool u = true);
      void msgMoveTrack(int idx1, int dx2, bool u = true);
      void msgAddPart(Part*, bool u = true);
      void msgRemovePart(Part*, bool u = true);
      void msgChangePart(Part* oldPart, Part* newPart, bool u = true);
      void msgAddEvent(Event*, Part*, bool u = true);
      void msgDeleteEvent(Event*, Part*, bool u = true);
      void msgChangeEvent(Event*, Event*, Part*, bool u = true);
      void msgScanAlsaMidiPorts();
      void msgAddTempo(int tick, int tempo, bool doUndoFlag = true);
      void msgSetTempo(int tick, int tempo, bool doUndoFlag = true);
      void msgSetGlobalTempo(int val);
      void msgDeleteTempo(int tick, int tempo, bool doUndoFlag = true);
      void msgAddSig(int tick, int z, int n, bool doUndoFlag = true);
      void msgAddSynthI(SynthI* synth);
      void msgShowInstrumentGui(MidiInstrument*, bool);
      void msgPanic();

      void undo();
      void redo();
      void ctrlChanged(int port, int channel, int ctrl, int val);
      void masterVolChanged(int val);

      void setMidiDevice(MidiPort*, MidiDevice*);
      void playMidiEvent(MidiPlayEvent* event);
      void rescanAlsaPorts();

      void eventReceived(MidiPlayEvent* event);
      void eventReceived(int port, unsigned char chan, unsigned char c1, unsigned c2);

      void mmcInput(const unsigned char* p, int n);
      void mtcInputQuarter(int, unsigned char c);
      void mtcInputFull(const unsigned char* p, int n);
      void nonRealtimeSystemSysex(const unsigned char*, int);
      void realtimeSystemInput(int, int);
      void setSongPosition(int, int);
      void midiPortsChanged();
      };

extern MidiThread* midiThread;
#endif