1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 dumb_c.c
21 Minimal control mode -- no interaction, just prints out messages.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif /* HAVE_CONFIG_H */
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #ifndef NO_STRING_H
31 #include <string.h>
32 #else
33 #include <strings.h>
34 #endif
35
36 #include "timidity.h"
37 #include "common.h"
38 #include "output.h"
39 #include "controls.h"
40 #include "instrum.h"
41 #include "playmidi.h"
42 #include "readmidi.h"
43 #ifdef __W32__
44 #include "wrd.h"
45 #endif /* __W32__ */
46
47 static int ctl_open(int using_stdin, int using_stdout);
48 static void ctl_close(void);
49 static int ctl_read(int32 *valp);
50 static int cmsg(int type, int verbosity_level, char *fmt, ...);
51 static void ctl_total_time(long tt);
52 static void ctl_file_name(char *name);
53 static void ctl_current_time(int ct);
54 static void ctl_metronome(int, int);
55 static void ctl_lyric(int lyricid);
56 static void ctl_event(CtlEvent *e);
57
58 /**********************************/
59 /* export the interface functions */
60
61 #define ctl dumb_control_mode
62
63 ControlMode ctl=
64 {
65 "dumb interface", 'd',
66 "dumb",
67 1,0,0,
68 0,
69 ctl_open,
70 ctl_close,
71 dumb_pass_playing_list,
72 ctl_read,
73 NULL,
74 cmsg,
75 ctl_event
76 };
77
78 static uint32 cuepoint = 0;
79 static int cuepoint_pending = 0;
80
81 static int curr_secs, curr_meas, curr_beat;
82
83 static FILE *outfp;
84 int dumb_error_count;
85
86 /*ARGSUSED*/
ctl_open(int using_stdin,int using_stdout)87 static int ctl_open(int using_stdin, int using_stdout)
88 {
89 if(using_stdout)
90 outfp=stderr;
91 else
92 outfp=stdout;
93 ctl.opened=1;
94 return 0;
95 }
96
ctl_close(void)97 static void ctl_close(void)
98 {
99 fflush(outfp);
100 ctl.opened=0;
101 }
102
ctl_read(int32 * valp)103 static int ctl_read(int32 *valp)
104 {
105 if (cuepoint_pending) {
106 *valp = cuepoint;
107 cuepoint_pending = 0;
108 return RC_FORWARD;
109 }
110 return RC_NONE;
111 }
112
cmsg(int type,int verbosity_level,char * fmt,...)113 static int cmsg(int type, int verbosity_level, char *fmt, ...)
114 {
115 va_list ap;
116
117 if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
118 ctl.verbosity<verbosity_level)
119 return 0;
120 va_start(ap, fmt);
121 if(type == CMSG_WARNING || type == CMSG_ERROR || type == CMSG_FATAL)
122 dumb_error_count++;
123 if (!ctl.opened)
124 {
125 vfprintf(stderr, fmt, ap);
126 fputs(NLS, stderr);
127 }
128 else
129 {
130 vfprintf(outfp, fmt, ap);
131 fputs(NLS, outfp);
132 fflush(outfp);
133 }
134 va_end(ap);
135 return 0;
136 }
137
ctl_total_time(long tt)138 static void ctl_total_time(long tt)
139 {
140 int mins, secs;
141 if (ctl.trace_playing)
142 {
143 secs=(int)(tt/play_mode->rate);
144 mins=secs/60;
145 secs-=mins*60;
146 cmsg(CMSG_INFO, VERB_NORMAL,
147 "Total playing time: %3d min %02d s", mins, secs);
148 }
149 }
150
ctl_file_name(char * name)151 static void ctl_file_name(char *name)
152 {
153 if (ctl.verbosity>=0 || ctl.trace_playing)
154 cmsg(CMSG_INFO, VERB_NORMAL, "Playing %s", name);
155 }
156
ctl_current_time(int secs)157 static void ctl_current_time(int secs)
158 {
159 int mins, meas, beat;
160 static int prev_secs = -1;
161
162 #ifdef __W32__
163 if(wrdt->id == 'w')
164 return;
165 #endif /* __W32__ */
166 if (ctl.trace_playing && secs != prev_secs)
167 {
168 curr_secs = prev_secs = secs;
169 mins=secs/60;
170 secs-=mins*60;
171 meas = curr_meas, beat = curr_beat;
172 fprintf(outfp, "\r%3d:%02d %03d.%02d", mins, secs, meas, beat);
173 fflush(outfp);
174 }
175 }
176
ctl_metronome(int meas,int beat)177 static void ctl_metronome(int meas, int beat)
178 {
179 int mins, secs;
180 static int prev_meas = -1, prev_beat = -1;
181
182 #ifdef __W32__
183 if (wrdt->id == 'w')
184 return;
185 #endif /* __W32__ */
186 if (ctl.trace_playing && (meas != prev_meas || beat != prev_beat)) {
187 mins = curr_secs / 60, secs = curr_secs % 60;
188 curr_meas = prev_meas = meas, curr_beat = prev_beat = beat;
189 fprintf(outfp, "\r%3d:%02d %03d.%02d", mins, secs, meas, beat);
190 fflush(outfp);
191 }
192 }
193
ctl_lyric(int lyricid)194 static void ctl_lyric(int lyricid)
195 {
196 char *lyric;
197
198 lyric = event2string(lyricid);
199 if(lyric != NULL)
200 {
201 if(lyric[0] == ME_KARAOKE_LYRIC)
202 {
203 if(lyric[1] == '/' || lyric[1] == '\\')
204 {
205 fprintf(outfp, "\n%s", lyric + 2);
206 fflush(outfp);
207 }
208 else if(lyric[1] == '@')
209 {
210 if(lyric[2] == 'L')
211 fprintf(outfp, "\nLanguage: %s\n", lyric + 3);
212 else if(lyric[2] == 'T')
213 fprintf(outfp, "Title: %s\n", lyric + 3);
214 else
215 fprintf(outfp, "%s\n", lyric + 1);
216 }
217 else
218 {
219 fputs(lyric + 1, outfp);
220 fflush(outfp);
221 }
222 }
223 else
224 {
225 if(lyric[0] == ME_CHORUS_TEXT || lyric[0] == ME_INSERT_TEXT)
226 fprintf(outfp, "\r");
227 fputs(lyric + 1, outfp);
228 fflush(outfp);
229 }
230 }
231 }
232
ctl_event(CtlEvent * e)233 static void ctl_event(CtlEvent *e)
234 {
235 switch(e->type)
236 {
237 case CTLE_NOW_LOADING:
238 ctl_file_name((char *)e->v1);
239 break;
240 case CTLE_PLAY_START:
241 ctl_total_time(e->v1);
242 break;
243 case CTLE_CUEPOINT:
244 cuepoint = e->v1;
245 cuepoint_pending = 1;
246 break;
247 case CTLE_CURRENT_TIME:
248 ctl_current_time((int)e->v1);
249 break;
250 case CTLE_METRONOME:
251 ctl_metronome(e->v1, e->v2);
252 break;
253 #ifndef CFG_FOR_SF
254 case CTLE_LYRIC:
255 ctl_lyric((int)e->v1);
256 break;
257 #endif
258 }
259 }
260
261 /*
262 * interface_<id>_loader();
263 */
interface_d_loader(void)264 ControlMode *interface_d_loader(void)
265 {
266 return &ctl;
267 }
268