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>
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.
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.
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
20 portmidisyn_c.c - PortMIDI synthesizer interface
21 Copyright (c) 2003 Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>
23 I referenced following sources.
24 alsaseq_c.c - ALSA sequencer server interface
25 Copyright (c) 2000 Takashi Iwai <tiwai@suse.de>
31 This interface provides a Portmidi MIDI device interface which receives
32 events and plays it in real-time. On this mode, TiMidity works
33 purely as software (real-time) MIDI render.
35 For invoking PrtMIDI synthesizer interface, run timidity as folows:
36 % timidity -iP (interactively select an Input MIDI device)
38 % timidity -iP 2 (connect to MIDI device No. 2)
40 TiMidity loads instruments dynamically at each time a PRM_CHANGE
41 event is received. It sometimes causes a noise.
42 If you are using a low power machine, invoke timidity as follows:
43 % timidity -s 11025 -iP (set sampling freq. to 11025Hz)
45 % timidity -EFreverb=0 -iP (disable MIDI reverb effect control)
47 TiMidity keeps all loaded instruments during executing.
49 To use TiMidity as output device, you need a MIDI loopback device.
51 I use MIDI Yoke. It can freely be obtained MIDI-OX site
52 (http://www.midiox.com).
54 You can easily meke it. See MIDI router section
56 (http://www.suse.de/~mana/alsa090_howto.html#sect05 ).
59 //#define USE_PORTMIDI 1
60 //#define USE_GTK_GUI 1
64 #endif /* HAVE_CONFIG_H */
69 #include "wsgtk_main.h"
81 static struct termios initial_settings, new_settings;
82 static int peek_character = -1;
85 extern int volatile stream_max_compute; // play_event()
\82Ì compute_data()
\82Å
\8cv
\8eZ
\82ð
\8b\96\82·
\8dÅ
\91å
\8e\9e\8aÔ
87 ///r // define rtsyn_common.c
92 static int ctl_open(int using_stdin, int using_stdout);
93 static void ctl_close(void);
94 static int ctl_read(int32 *valp);
95 static int cmsg(int type, int verbosity_level, char *fmt, ...);
96 static void ctl_event(CtlEvent *e);
97 static int ctl_pass_playing_list(int n, char *args[]);
100 static void init_keybord(void);
101 static void close_keybord(void);
102 static int kbhit(void);
103 static char readch(void);
106 /**********************************/
107 /* export the interface functions */
109 #define ctl portmidisyn_control_mode
113 "PortMIDI Synthesizer interface", 'P',
119 ctl_pass_playing_list,
126 static int32 event_time_offset;
131 static int ctl_open(int using_stdin, int using_stdout)
134 ctl.flags &= ~(CTLF_LIST_RANDOM|CTLF_LIST_SORT);
142 static void ctl_close(void)
153 static int ctl_read(int32 *valp)
159 extern void PutsConsoleWnd(char *str);
160 extern int ConsoleWndFlag;
162 static int cmsg(int type, int verbosity_level, char *fmt, ...)
168 if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
169 ctl.verbosity<verbosity_level)
172 if(type == CMSG_WARNING || type == CMSG_ERROR || type == CMSG_FATAL)
176 vfprintf(stderr, fmt, ap);
181 vfprintf(outfp, fmt, ap);
188 if ( !ConsoleWndFlag ) return 0;
193 vsnprintf(buffer, sizeof(buffer), fmt, ap);
196 if((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
197 ctl.verbosity<verbosity_level)
199 // if(type == CMSG_FATAL)
200 // w32g_msg_box(buffer, "TiMidity Error", MB_OK);
201 PutsConsoleWnd(buffer);
202 PutsConsoleWnd("\n");
210 static void ctl_event(CtlEvent *e)
214 static void doit(void);
217 extern void w32g_syn_doit(void);
218 extern int w32g_syn_ctl_pass_playing_list(int n_, char *args_[]);
221 static int ctl_pass_playing_list(int n, char *args[])
223 return w32g_syn_ctl_pass_playing_list ( n, args );
228 static int ctl_pass_playing_list(int n, char *args[])
230 // 0: OK, 2: Require to reset.
231 int ctl_pass_playing_list2(int n, char *args[])
234 int i, j,devnum,devok;
235 unsigned int port=0 ;
238 #if defined(__W32__) && defined(FORCE_TIME_PERIOD)
240 #endif /* __W32__ && FORCE_TIME_PERIOD */
242 rtsyn_get_port_list();
246 printf( "Usage: timidity -iW [Midi interface No s]\n");
253 while(port<n && n!=0){
254 if( (portID[port] = atoi(args[port]))==0 ){
258 for(i=0;i<rtsyn_nportlist;i++){
259 sscanf( rtsyn_portlist[i],"%d:%s",&devnum,cbuf);
260 if(devnum==portID[port]) devok=1;
267 sprintf ( buff, "MIDI IN Device ID %d is not available. So set a proper ID for the MIDI port %d and restart.", portID[port], port );
268 MessageBox ( NULL, buff, "Error", MB_OK );
280 rtsyn_portnumber=port;
283 #if !defined(IA_W32G_SYN) && !defined(USE_GTK_GUI)
286 printf("Whow many ports do you use?(max %d)\n",MAX_PORT);
288 if (0==scanf("%u",&rtsyn_portnumber)) scanf("%s",cbuf);
289 }while(rtsyn_portnumber == 0 ||rtsyn_portnumber > MAX_PORT);
291 printf("Opening Device drivers:");
292 printf("Available Midi Input devices:\n");
294 for(i=0;i<rtsyn_nportlist;i++){
295 printf("%s\n",rtsyn_portlist[i]);
297 for(port=0;port<rtsyn_portnumber;port++){
298 printf("Keyin Input Device Number of port%d\n",port+1);
301 if (0==scanf("%u",&portID[port])) scanf("%s",cbuf);
302 for(i=0;i<rtsyn_nportlist;i++){
303 sscanf( rtsyn_portlist[i],"%d:%s",&devnum,cbuf);
304 if(devnum==portID[port]) devok=1;
312 for(port=0;port<rtsyn_portnumber;port++){
313 portID[port]=portID[port]-1;
317 #if !defined(IA_W32G_SYN) && !defined(USE_GTK_GUI)
318 printf("TiMidity starting in PortMIDI Synthesizer mode\n");
319 printf("Usage: timidity -iP [Midi interface No]\n");
321 printf("N (Normal mode) M(GM mode) S(GS mode) X(XG mode) \n");
322 printf("(Only in Normal mode, Mode can be changed by MIDI data)\n");
323 printf("m(GM reset) s(GS reset) x(XG reset)\n");
325 printf("Press 'q' key to stop\n");
333 #if defined(__W32__) && defined(FORCE_TIME_PERIOD)
334 if (timeGetDevCaps(&tcaps, sizeof(TIMECAPS)) != TIMERR_NOERROR)
335 tcaps.wPeriodMin = 10;
336 timeBeginPeriod(tcaps.wPeriodMin);
337 #endif /* __W32__ && FORCE_TIME_PERIOD */
339 if(0!=rtsyn_synth_start()){
347 if(0!=rtsyn_synth_start()){
354 #endif /* IA_W32G_SYN */
355 #if defined(__W32__) && defined(FORCE_TIME_PERIOD)
356 timeEndPeriod(tcaps.wPeriodMin);
357 #endif /* __W32__ && FORCE_TIME_PERIOD */
358 #endif /* USE_GTK_GUI */
369 static void init_keybord(void){
370 tcgetattr(0,&initial_settings);
371 tcgetattr(0,&new_settings);
372 new_settings.c_lflag &= ~ICANON;
373 new_settings.c_lflag &= ~ECHO;
374 new_settings.c_lflag &= ~ISIG;
375 new_settings.c_cc[VMIN] = 1;
376 new_settings.c_cc[VTIME] = 0;
377 tcsetattr(0, TCSANOW, &new_settings);
380 static void close_keybord(void){
381 tcsetattr(0, TCSANOW, &initial_settings);
384 static int kbhit(void){
388 if(peek_character != -1)
390 new_settings.c_cc[VMIN]=0;
391 tcsetattr(0,TCSANOW, &new_settings);
392 nread = read(0, &ch, 1);
393 new_settings.c_cc[VMIN]=1;
394 tcsetattr(0,TCSANOW, &new_settings);
404 static char readch(void){
406 if(peek_character != -1){
417 static void doit(void)
445 rtsyn_normal_reset();
457 rtsyn_normal_modeset();
461 rtsyn_play_some_data();
462 rtsyn_play_calculate();
470 #endif /* !IA_W32G_SYN */
474 static int winplaymidi_sleep_level = 2;
475 static DWORD winplaymidi_active_start_time = 0;
478 void winplaymidi(void){
480 if ( winplaymidi_sleep_level < 1 ) {
481 winplaymidi_sleep_level = 1;
483 if( 0 != rtsyn_buf_check() ){
484 winplaymidi_sleep_level =0;
486 rtsyn_play_some_data();
487 if ( winplaymidi_sleep_level == 1 ) {
488 DWORD ct = GetCurrentTime ();
489 if ( winplaymidi_active_start_time == 0 || ct < winplaymidi_active_start_time ) {
490 winplaymidi_active_start_time = ct;
491 } else if ( ct - winplaymidi_active_start_time > 2000 ) {
492 winplaymidi_sleep_level = 2;
494 } else if ( winplaymidi_sleep_level == 0 ) {
495 winplaymidi_active_start_time = 0;
498 rtsyn_play_calculate();
500 if ( winplaymidi_sleep_level >= 2) {
502 } else if ( winplaymidi_sleep_level > 0 ) {
510 * interface_<id>_loader();
512 ControlMode *interface_P_loader(void)