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 npsyn_c.c - Windows synthesizer interface
21 Copyright (c) 2007 Keishi Suenaga <s_keishi@yahoo.co.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 Windows 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 Windows synthesizer interface, run timidity as folows:
36 % timidity -iW (interactively select an Input MIDI device)
38 % timidity -iW 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 -iW (set sampling freq. to 11025Hz)
45 % timidity -EFreverb=0 -iW (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.
50 I use MIDI Yoke. It can freely be obtained MIDI-OX site
51 (http://www.midiox.com).
54 //#define USE_PORTMIDI 1
55 //#define USE_GTK_GUI 1
59 #endif /* HAVE_CONFIG_H */
62 #include <sys/types.h>
67 #include "wsgtk_main.h"
81 #if defined(__W32__) && !defined(__GNUC__)
82 #define HAVE_DOS_KEYBOARD 1
86 #ifndef HAVE_DOS_KEYBOARD
87 static struct termios initial_settings, new_settings;
88 static int peek_character = -1;
91 extern int volatile stream_max_compute; // play_event()
\82Ì compute_data()
\82Å
\8cv
\8eZ
\82ð
\8b\96\82·
\8dÅ
\91å
\8e\9e\8aÔ
92 extern int seq_quit; // rtsyn_common.c
94 static int ctl_open(int using_stdin, int using_stdout);
95 static void ctl_close(void);
96 static int ctl_read(ptr_size_t *valp);
97 static int cmsg(int type, int verbosity_level, const char *fmt, ...);
98 static void ctl_event(CtlEvent *e);
99 static int ctl_pass_playing_list(int n, char *args[]);
101 #ifndef HAVE_DOS_KEYBOARD
102 static void init_keybord(void);
103 static void close_keybord(void);
104 static int kbhit(void);
105 static char readch(void);
108 /**********************************/
109 /* export the interface functions */
111 #define ctl npsyn_control_mode
115 "Windows Named Pipe Synthesizer interface", 'N',
121 ctl_pass_playing_list,
128 static int32 event_time_offset;
133 static int ctl_open(int using_stdin, int using_stdout)
136 ctl.flags &= ~(CTLF_LIST_RANDOM | CTLF_LIST_SORT);
144 static void ctl_close(void)
148 rtsyn_np_synth_stop();
155 static int ctl_read(ptr_size_t *valp)
161 extern void PutsConsoleWnd(char *str);
162 extern int ConsoleWndFlag;
164 static int cmsg(int type, int verbosity_level, const char *fmt, ...)
170 if ((type == CMSG_TEXT || type == CMSG_INFO || type == CMSG_WARNING) &&
171 ctl.verbosity < verbosity_level)
174 if (type == CMSG_WARNING || type == CMSG_ERROR || type == CMSG_FATAL)
178 vfprintf(stderr, fmt, ap);
183 vfprintf(outfp, fmt, ap);
189 if (!ConsoleWndFlag) return 0;
194 vsnprintf(buffer, sizeof(buffer), fmt, ap);
197 if ((type == CMSG_TEXT || type == CMSG_INFO || type == CMSG_WARNING) &&
198 ctl.verbosity < verbosity_level)
200 // if (type == CMSG_FATAL)
201 // w32g_msg_box(buffer, "TiMidity Error", MB_OK);
202 PutsConsoleWnd(buffer);
203 PutsConsoleWnd("\n");
206 #endif /* !IA_W32G_SYN */
211 static void ctl_event(CtlEvent *e)
215 static void doit(void);
218 extern void w32g_syn_doit(void);
219 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);
225 #endif /* IA_W32G_SYN */
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[])
236 if ((n < 1) || (n > 2)) {
237 ctl.cmsg(CMSG_WARNING, VERB_NORMAL, "Usage: timidity -iN [Named Pipe Name] SampleTimeMode(1 or 0) \n");
241 rtsyn_np_set_pipe_name(args[0]);
243 rtsyn_sample_time_mode = 0;
245 rtsyn_sample_time_mode = atoi(args[1]);
248 #if !defined(IA_W32G_SYN) && !defined(USE_GTK_GUI)
249 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
250 "TiMidity starting in Windows Named Pipe Synthesizer mode\n");
251 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
252 "Usage: timidity -iN [Named Pipe Name] SampleTimeMode(1 or 0) \n");
253 ctl.cmsg(CMSG_WARNING, VERB_NORMAL, "\n");
254 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
255 "N (Normal mode) M(GM mode) S(GS mode) X(XG mode) G(GM2 mode) D(SD mode) K(KG mode) J(CM mode)\n");
256 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
257 "(Only in Normal mode, Mode can be changed by MIDI data)\n");
258 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
259 "m(GM reset) s(GS reset) x(XG reset) g(GM2 reset) d(SD reset) k(KG reset) j(CM reset)\n");
260 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
262 ctl.cmsg(CMSG_WARNING, VERB_NORMAL,
263 "Press 'q' key to stop\n");
268 #ifdef FORCE_TIME_PERIOD
269 if (timeGetDevCaps(&tcaps, sizeof(TIMECAPS)) != TIMERR_NOERROR)
270 tcaps.wPeriodMin = 10;
271 timeBeginPeriod(tcaps.wPeriodMin);
272 #endif /* FORCE_TIME_PERIOD */
278 if (0 != rtsyn_np_synth_start()) {
280 while (seq_quit == 0) {
283 rtsyn_np_synth_stop();
286 if (0 != rtsyn_np_synth_start()) {
288 while (seq_quit == 0) {
291 rtsyn_np_synth_stop();
293 #endif /* IA_W32G_SYN */
294 #endif /* USE_GTK_GUI */
295 #ifdef FORCE_TIME_PERIOD
296 timeEndPeriod(tcaps.wPeriodMin);
297 #endif /* FORCE_TIME_PERIOD */
307 #ifndef HAVE_DOS_KEYBOARD
308 static void init_keybord(void) {
309 tcgetattr(0, &initial_settings);
310 tcgetattr(0, &new_settings);
311 new_settings.c_lflag &= ~ICANON;
312 new_settings.c_lflag &= ~ECHO;
313 new_settings.c_lflag &= ~ISIG;
314 new_settings.c_cc[VMIN] = 1;
315 new_settings.c_cc[VTIME] = 0;
316 tcsetattr(0, TCSANOW, &new_settings);
319 static void close_keybord(void) {
320 tcsetattr(0, TCSANOW, &initial_settings);
323 static int kbhit(void) {
327 if (peek_character != -1)
329 new_settings.c_cc[VMIN] = 0;
330 tcsetattr(0, TCSANOW, &new_settings);
331 nread = read(0, &ch, 1);
332 new_settings.c_cc[VMIN] = 1;
333 tcsetattr(0, TCSANOW, &new_settings);
343 static char readch(void) {
345 if (peek_character != -1) {
353 #endif /* !HAVE_DOS_KEYBOARD */
356 static void doit(void)
358 #ifndef HAVE_DOS_KEYBOARD
362 while (seq_quit == 0) {
363 #ifdef HAVE_DOS_KEYBOARD
396 rtsyn_normal_reset();
420 rtsyn_normal_modeset();
424 rtsyn_np_play_some_data();
425 if (rtsyn_sample_time_mode == 0)
426 rtsyn_play_calculate();
427 if (intr) seq_quit = ~0;
430 #ifndef HAVE_DOS_KEYBOARD
435 #endif /* !IA_W32G_SYN */
439 static int winplaymidi_sleep_level = 2;
440 static DWORD winplaymidi_active_start_time = 0;
443 void winplaymidi(void) {
445 if (winplaymidi_sleep_level < 1) {
446 winplaymidi_sleep_level = 1;
448 if (0 != rtsyn_buf_check()) {
449 winplaymidi_sleep_level =0;
451 rtsyn_np_play_some_data();
452 if (winplaymidi_sleep_level == 1) {
453 DWORD ct = GetCurrentTime();
454 if (winplaymidi_active_start_time == 0 || ct < winplaymidi_active_start_time) {
455 winplaymidi_active_start_time = ct;
456 } else if (ct - winplaymidi_active_start_time > 60000) {
457 winplaymidi_sleep_level = 2;
459 } else if (winplaymidi_sleep_level == 0) {
460 winplaymidi_active_start_time = 0;
463 rtsyn_play_calculate();
465 if (winplaymidi_sleep_level >= 2) {
467 } else if (winplaymidi_sleep_level > 0) {
471 #endif /* IA_W32G_SYN */
475 * interface_<id>_loader();
477 ControlMode *interface_N_loader(void)