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 main(int,char **)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*/ 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 97 static void ctl_close(void) 98 { 99 fflush(outfp); 100 ctl.opened=0; 101 } 102 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 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 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 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 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 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 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 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 */ 264 ControlMode *interface_d_loader(void) 265 { 266 return &ctl; 267 } 268