Initial revision
[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     $Id$
19 */
20
21 #ifndef  __midi_parse_h__
22 #define  __midi_parse_h__
23
24 #include <string>
25 #include <iostream>
26
27 #include <sigc++/sigc++.h>
28
29 #include <midi++/types.h>
30
31 namespace MIDI {
32
33 class Port;
34 class Parser;
35
36 typedef sigc::signal<void, Parser &, byte>                 OneByteSignal;
37 typedef sigc::signal<void, Parser &, EventTwoBytes *>      TwoByteSignal;
38 typedef sigc::signal<void, Parser &, pitchbend_t>          PitchBendSignal;
39 typedef sigc::signal<void, Parser &, byte *, size_t> Signal;
40
41 class Parser : public sigc::trackable {
42  public:
43         Parser (Port &p);
44         ~Parser ();
45         
46         /* signals that anyone can connect to */
47         
48         OneByteSignal         bank_change;
49         TwoByteSignal         note_on;
50         TwoByteSignal         note_off;
51         TwoByteSignal         poly_pressure;
52         OneByteSignal         pressure;
53         OneByteSignal         program_change;
54         PitchBendSignal       pitchbend;
55         TwoByteSignal         controller;
56
57         OneByteSignal         channel_bank_change[16];
58         TwoByteSignal         channel_note_on[16];
59         TwoByteSignal         channel_note_off[16];
60         TwoByteSignal         channel_poly_pressure[16];
61         OneByteSignal         channel_pressure[16];
62         OneByteSignal         channel_program_change[16];
63         PitchBendSignal       channel_pitchbend[16];
64         TwoByteSignal         channel_controller[16];
65         sigc::signal<void, Parser &>          channel_active_preparse[16];
66         sigc::signal<void, Parser &>          channel_active_postparse[16];
67
68         OneByteSignal         mtc_quarter_frame;
69
70         Signal                raw_preparse;
71         Signal                raw_postparse;
72         Signal                any;
73         Signal                sysex;
74         Signal                mmc;
75         Signal                position;
76         Signal                song;
77
78         Signal                        mtc;
79         sigc::signal<void,Parser&>   mtc_qtr;
80
81         sigc::signal<void, Parser &>          all_notes_off;
82         sigc::signal<void, Parser &>          tune;
83         sigc::signal<void, Parser &>          timing;
84         sigc::signal<void, Parser &>          start;
85         sigc::signal<void, Parser &>          stop;
86         sigc::signal<void, Parser &>          contineu;  /* note spelling */
87         sigc::signal<void, Parser &>          active_sense;
88         sigc::signal<void, Parser &>          reset;
89         sigc::signal<void, Parser &>          eox;
90
91         /* This should really be protected, but then derivatives of Port
92            can't access it.
93         */
94
95         void scanner (byte c);
96
97         size_t *message_counts() { return message_counter; }
98         const char *midi_event_type_name (MIDI::eventType);
99         void trace (bool onoff, std::ostream *o, const std::string &prefix = "");
100         bool tracing() { return trace_stream != 0; }
101         Port &port() { return _port; }
102
103         void set_offline (bool);
104         bool offline() const { return _offline; }
105         sigc::signal<void> OfflineStatusChanged;
106
107         sigc::signal<int, byte *, size_t> edit;
108
109         void set_mmc_forwarding (bool yn) {
110                 _mmc_forward = yn;
111         }
112
113         /* MTC */
114
115         enum MTC_Status {
116                 MTC_Stopped = 0,
117                 MTC_Forward,
118                 MTC_Backward
119         };
120
121         MTC_FPS mtc_fps() const { return _mtc_fps; }
122         MTC_Status  mtc_running() const { return _mtc_running; }
123         const byte *mtc_current() const { return _mtc_time; }
124         bool        mtc_locked() const  { return _mtc_locked; }
125
126         sigc::signal<void,MTC_Status> mtc_status;
127         sigc::signal<bool>            mtc_skipped;
128         sigc::signal<void,const byte*,bool> mtc_time;
129
130         void set_mtc_forwarding (bool yn) {
131                 _mtc_forward = yn;
132         }
133
134         void reset_mtc_state ();
135         
136   private:
137         Port &_port;
138         /* tracing */
139
140         std::ostream *trace_stream;
141         std::string trace_prefix;
142         void trace_event (Parser &p, byte *msg, size_t len);
143         sigc::connection trace_connection;
144
145         size_t message_counter[256];
146
147         enum ParseState { 
148                 NEEDSTATUS,
149                 NEEDONEBYTE,
150                 NEEDTWOBYTES,
151                 VARIABLELENGTH
152         };
153         ParseState state;
154         unsigned char *msgbuf;
155         int msglen;
156         int msgindex;
157         MIDI::eventType msgtype;
158         channel_t channel;
159         bool _offline;
160         bool runnable;
161         bool was_runnable;
162         bool _mmc_forward;
163         bool _mtc_forward;
164         int   expected_mtc_quarter_frame_code;
165         byte _mtc_time[4];
166         byte _qtr_mtc_time[4];
167         unsigned long consecutive_qtr_frame_cnt;
168         MTC_FPS _mtc_fps;
169         MTC_Status _mtc_running;
170         bool       _mtc_locked;
171         byte last_qtr_frame;
172
173         ParseState pre_variable_state;
174         MIDI::eventType pre_variable_msgtype;
175         byte last_status_byte;
176
177         void channel_msg (byte);
178         void realtime_msg (byte);
179         void system_msg (byte);
180         void signal (byte *msg, size_t msglen);
181         bool possible_mmc (byte *msg, size_t msglen);
182         bool possible_mtc (byte *msg, size_t msglen);
183         void process_mtc_quarter_frame (byte *msg);
184 };
185
186 }; /* namespace MIDI */
187
188 #endif   // __midi_parse_h__
189