7eb690d4020cfe46ddd8627eca0555c86fd49015
[ardour.git] / libs / midi++2 / midi++ / parser.h
1 /*
2     Copyright (C) 1998 Paul Barton-Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef  __midi_parse_h__
21 #define  __midi_parse_h__
22
23 #include <string>
24 #include <iostream>
25
26 #include "pbd/signals.h"
27
28 #include "midi++/libmidi_visibility.h"
29 #include "midi++/types.h"
30
31 namespace MIDI {
32
33 class Port;
34 class Parser;
35
36 typedef PBD::Signal1<void,Parser&>                   ZeroByteSignal;
37 typedef PBD::Signal2<void,Parser&,unsigned short>    BankSignal;
38 typedef PBD::Signal2<void,Parser&,framecnt_t>        TimestampedSignal;
39 typedef PBD::Signal2<void,Parser&, byte>             OneByteSignal;
40 typedef PBD::Signal2<void,Parser &, EventTwoBytes *> TwoByteSignal;
41 typedef PBD::Signal2<void,Parser &, pitchbend_t>     PitchBendSignal;
42 typedef PBD::Signal2<void,Parser &, uint16_t>        RPNSignal;
43 typedef PBD::Signal3<void,Parser &, byte *, size_t>  Signal;
44
45 class LIBMIDIPP_API Parser {
46  public:
47         Parser ();
48         ~Parser ();
49
50         /* sets the time that will be reported for any MTC or MIDI Clock
51            message the next time ::scanner() parses such a message. It should
52            therefore be set before every byte passed into ::scanner().
53         */
54
55         framecnt_t get_timestamp() const { return _timestamp; }
56         void set_timestamp (const framecnt_t timestamp) { _timestamp = timestamp; }
57
58         /* signals that anyone can connect to */
59
60         BankSignal            bank_change;
61         TwoByteSignal         note_on;
62         TwoByteSignal         note_off;
63         TwoByteSignal         poly_pressure;
64         OneByteSignal         pressure;
65         OneByteSignal         program_change;
66         PitchBendSignal       pitchbend;
67         TwoByteSignal         controller;
68
69         BankSignal            channel_bank_change[16];
70         TwoByteSignal         channel_note_on[16];
71         TwoByteSignal         channel_note_off[16];
72         TwoByteSignal         channel_poly_pressure[16];
73         OneByteSignal         channel_pressure[16];
74         OneByteSignal         channel_program_change[16];
75         PitchBendSignal       channel_pitchbend[16];
76         TwoByteSignal         channel_controller[16];
77         ZeroByteSignal        channel_active_preparse[16];
78         ZeroByteSignal        channel_active_postparse[16];
79         RPNSignal             channel_rpn[16];
80         RPNSignal             channel_nrpn[16];
81         RPNSignal             channel_rpn_increment[16];
82         RPNSignal             channel_rpn_decrement[16];
83         RPNSignal             channel_nrpn_increment[16];
84         RPNSignal             channel_nrpn_decrement[16];
85
86         OneByteSignal         mtc_quarter_frame; /* see below for more useful signals */
87         Signal                mtc;
88         Signal                raw_preparse;
89         Signal                raw_postparse;
90         Signal                any;
91         Signal                sysex;
92         Signal                mmc;
93         Signal                position;
94         Signal                song;
95
96         ZeroByteSignal        all_notes_off;
97         ZeroByteSignal        tune;
98         ZeroByteSignal        active_sense;
99         ZeroByteSignal        reset;
100         ZeroByteSignal        eox;
101
102         TimestampedSignal     timing;
103         TimestampedSignal     start;
104         TimestampedSignal     stop;
105         TimestampedSignal     contineu;  /* note spelling */
106
107         /* This should really be protected, but then derivatives of Port
108            can't access it.
109         */
110
111         void scanner (byte c);
112
113         size_t *message_counts() { return message_counter; }
114         const char *midi_event_type_name (MIDI::eventType);
115         void trace (bool onoff, std::ostream *o, const std::string &prefix = "");
116         bool tracing() { return trace_stream != 0; }
117
118         void set_offline (bool);
119         bool offline() const { return _offline; }
120         PBD::Signal0<void> OfflineStatusChanged;
121
122         PBD::Signal2<int,byte *, size_t> edit;
123
124         void set_mmc_forwarding (bool yn) {
125                 _mmc_forward = yn;
126         }
127
128         /* MTC */
129
130         MTC_FPS mtc_fps() const { return _mtc_fps; }
131         MTC_Status  mtc_running() const { return _mtc_running; }
132         const byte *mtc_current() const { return _mtc_time; }
133         bool        mtc_locked() const  { return _mtc_locked; }
134
135         PBD::Signal3<void, Parser &, int, framecnt_t>      mtc_qtr;
136         PBD::Signal3<void, const byte *, bool, framecnt_t> mtc_time;
137         PBD::Signal1<void, MTC_Status>                     mtc_status;
138         PBD::Signal0<bool>                                 mtc_skipped;
139
140         void set_mtc_forwarding (bool yn) {
141                 _mtc_forward = yn;
142         }
143
144         void reset_mtc_state ();
145
146   private:
147         /* tracing */
148
149         std::ostream *trace_stream;
150         std::string trace_prefix;
151         void trace_event (Parser &p, byte *msg, size_t len);
152         PBD::ScopedConnection trace_connection;
153
154         size_t message_counter[256];
155
156         enum ParseState {
157                 NEEDSTATUS,
158                 NEEDONEBYTE,
159                 NEEDTWOBYTES,
160                 VARIABLELENGTH
161         };
162         ParseState state;
163         unsigned char *msgbuf;
164         int msglen;
165         int msgindex;
166         MIDI::eventType msgtype;
167         channel_t channel;
168         bool _offline;
169         bool runnable;
170         bool was_runnable;
171         bool _mmc_forward;
172         bool _mtc_forward;
173         int   expected_mtc_quarter_frame_code;
174         byte _mtc_time[5];
175         byte _qtr_mtc_time[5];
176         unsigned long consecutive_qtr_frame_cnt;
177         MTC_FPS _mtc_fps;
178         MTC_Status _mtc_running;
179         bool       _mtc_locked;
180         byte last_qtr_frame;
181
182         framecnt_t _timestamp;
183
184         ParseState pre_variable_state;
185         MIDI::eventType pre_variable_msgtype;
186         byte last_status_byte;
187
188         void channel_msg (byte);
189         void realtime_msg (byte);
190         void system_msg (byte);
191         void signal (byte *msg, size_t msglen);
192         bool possible_mmc (byte *msg, size_t msglen);
193         bool possible_mtc (byte *msg, size_t msglen);
194         void process_mtc_quarter_frame (byte *msg);
195 };
196
197 } // namespace MIDI
198
199 #endif   // __midi_parse_h__
200