OSDN Git Service

* configure.in
authorKeishi Suenaga <s_keishi@mutt.freemail.ne.jp>
Thu, 8 Feb 2007 23:20:51 +0000 (23:20 +0000)
committerKeishi Suenaga <s_keishi@mutt.freemail.ne.jp>
Thu, 8 Feb 2007 23:20:51 +0000 (23:20 +0000)
  interface/Makefile.am
  interface/npsyn_c.c (add)
  interface/rtsyn.h
  interface/rtsyn_common.c
  interface/rtsyn_npipe.c (add)
  timidity/Makefile.am
  timidity/npipe_a.c (add)
  timidity/output.c
  timidity/timidity.c
  timidity/controls.c:      Windows Named Pipe Interface(new)
* timidity/resample.c       small fix frreing gauss_table.
* windrv/timiditydrv.c
* windrv/timiwp_timidity.c: fix for WindowsMediaPlayer.

15 files changed:
ChangeLog
configure.in
interface/Makefile.am
interface/npsyn_c.c [new file with mode: 0755]
interface/rtsyn.h
interface/rtsyn_common.c
interface/rtsyn_npipe.c [new file with mode: 0755]
timidity/Makefile.am
timidity/controls.c
timidity/npipe_a.c [new file with mode: 0755]
timidity/output.c
timidity/resample.c
timidity/timidity.c
windrv/timiditydrv.c
windrv/timiwp_timidity.c

index 3fd6556..b1f80c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,21 @@
-2007-01-28  Keishi Suenaga <skeishi@yahoo.co.jp>
+2007-02-9  Keishi Suenaga <skeishi@yahoo.co.jp>
+
+       * configure.in
+         interface/Makefile.am
+         interface/npsyn_c.c (add)
+         interface/rtsyn.h
+         interface/rtsyn_common.c
+         interface/rtsyn_npipe.c (add)
+         timidity/Makefile.am
+         timidity/npipe_a.c (add)
+         timidity/output.c
+         timidity/timidity.c       
+         timidity/controls.c:      Windows Named Pipe Interface(new)
+       * timidity/resample.c       small fix frreing gauss_table.
+       * windrv/timiditydrv.c
+       * windrv/timiwp_timidity.c: fix for WindowsMediaPlayer.
+
+\r2007-01-28  Keishi Suenaga <skeishi@yahoo.co.jp>
 \r
        * interface/rtsyn_common.c: fix sysex check \r
        * timidity/portaudio_a.c    small fix for compiling\r
index 2188633..7f0b712 100644 (file)
@@ -712,6 +712,7 @@ dnl nas(n):     Network Audio System
 dnl arts(R):   aRts
 dnl esd(e):     EsounD
 dnl portaudio(p) PortAudio
+dnl npipe(N)   Windows named pipe;
 dnl vorbis(v):  Ogg Vorbis
 dnl flac(F):    FLAC / OggFLAC
 dnl speex(S):   Ogg Speex
@@ -719,7 +720,7 @@ dnl gogo(g):    MP3 GOGO
 dnl jack(j):    JACK
 dnl ao(O):      Libao
 
-audio_targets='default oss alsa sun hpux irix mme sb_dsp w32 alib nas arts esd vorbis flac gogo portaudio jack ao'
+audio_targets='default oss alsa sun hpux irix mme sb_dsp w32 alib nas arts esd vorbis flac gogo portaudio npipe jack ao'
 
 AC_ARG_WITH(nas-library,
   [  --with-nas-library=library NAS absolute library path(Don't use -laudio)])
@@ -744,6 +745,7 @@ AC_ARG_ENABLE(audio,
                               arts:      aRts
                               esd:       EsounD - Enlightened Sound Daemon
                               portaudio: PortAudio
+                              npipe:     Named Pipe(windows)
                               jack:      JACK
                               ao:        Libao
                               vorbis:    Ogg Vorbis
@@ -770,7 +772,7 @@ AC_ARG_WITH(default-output,
   [  --with-default-output=<mode>  Specify default output mode (optional):
                                 (default|alsa|alib|arts|nas|
                                 esd|wav|au|aiff|list|vorbis|flac|speex|
-                                gogo|portaudio|jack|ao)],
+                                gogo|portaudio|npipe|jack|ao)],
   [ if test "$enable_audio" != no; then
     DEFAULT_PLAYMODE=$withval
     eval "au_enable_$DEFAULT_PLAYMODE=yes"
@@ -1152,7 +1154,7 @@ else
   AC_MSG_RESULT(no)
 fi
 
-dnl portaudio E
+dnl portaudio
 AC_MSG_CHECKING(enable_audio=portaudio)
 if test "x$au_enable_portaudio" = xyes; then
   AC_MSG_RESULT(yes)
@@ -1169,6 +1171,17 @@ else
   AC_MSG_RESULT(no)
 fi
 
+dnl npipe (windows named pipe)
+AC_MSG_CHECKING(enable_audio=npipe)
+if test "x$au_enable_npipe" = xyes; then
+  AC_MSG_RESULT(yes)
+       SYSEXTRAS="$SYSEXTRAS npipe_a.c"
+       EXTRADEFS="$EXTRADEFS -DAU_NPIPE"
+else
+  AC_MSG_RESULT(no)
+fi
+
+
 dnl JACK
 AC_MSG_CHECKING(enable_audio=jack)
 if test "x$au_enable_jack" = xyes; then
@@ -1332,6 +1345,7 @@ case ".$DEFAULT_PLAYMODE" in
   .arts)     TIMIDITY_OUTPUT_ID=R ;;
   .esd)      TIMIDITY_OUTPUT_ID=e ;;
   .portaudio)      TIMIDITY_OUTPUT_ID=p ;;  
+  .npipe)    TIMIDITY_OUTPUT_ID=N ;;
   .wav)      TIMIDITY_OUTPUT_ID=w ;;
   .au)       TIMIDITY_OUTPUT_ID=u ;;
   .aiff)     TIMIDITY_OUTPUT_ID=a ;;
@@ -1350,7 +1364,7 @@ AC_MSG_RESULT($DEFAULT_PLAYMODE/$TIMIDITY_OUTPUT_ID)
 # Interface Section
 #
 
-interface_targets='dynamic ncurses slang motif tcltk emacs vt100 xaw xskin gtk alsaseq winsyn winsyng portmidisyng'
+interface_targets='dynamic ncurses slang motif tcltk emacs vt100 xaw xskin gtk alsaseq winsyn winsyng portmidisyng npsyn'
 
 AC_ARG_ENABLE(interface,
   [  --enable-interface=[interface_list]
@@ -1770,6 +1784,16 @@ CONFIG_INTERFACE(portmidisyn,PORTMIDISYN,P,
   ,
   [ INTERFACE_SRCS="$INTERFACE_SRCS portmidisyn_c.c rtsyn_common.c rtsyn_portmidi.c" ])
 
+dnl TiMidity Windows synthesizer server
+AM_CONDITIONAL(ENABLE_NPSYN, false)
+CONFIG_INTERFACE(npsyn,NPSYN,W,
+  [  --enable-npsyn        Enable Windows Named Pipe Synthesizer interface
+                                                          (default is no)],
+  ,
+  [ NPSYN="yes"; INTERFACE_SRCS="$INTERFACE_SRCS npsyn_c.c rtsyn_common.c rtsyn_npipe.c" ])
+
+
+
 dnl TiMidity Windows GUI synthesizer server
 AM_CONDITIONAL(ENABLE_W32G_SYN, false)
 CONFIG_INTERFACE(winsyng,W32G_SYN,W,
index db9c856..ea60eb9 100644 (file)
@@ -125,10 +125,12 @@ EXTRA_libinterface_a_SOURCES = \
        w32g_dib.c \
        w32g_dib.h \
        winsyn_c.c \
+       npsyn_c.d \
        rtsyn.h \
        rtsyn_common.c \
        rtsyn_winmm.c \
        rtsyn_portmidi.c \
+       rtsyn_npipe.c\
        portmidisyn_c.c
 
 if ENABLE_WRD
diff --git a/interface/npsyn_c.c b/interface/npsyn_c.c
new file mode 100755 (executable)
index 0000000..8f260a8
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+    TiMidity++ -- MIDI to WAVE converter and player
+    Copyright (C) 1999-2004 Masanao Izumo <iz@onicos.co.jp>
+    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+    npsyn_c.c - Windows synthesizer interface
+        Copyright (c) 2007 Keishi Suenaga <s_keishi@yahoo.co.jp>
+
+    I referenced following sources.
+        alsaseq_c.c - ALSA sequencer server interface
+            Copyright (c) 2000  Takashi Iwai <tiwai@suse.de>
+        readmidi.c
+
+    DESCRIPTION
+    ===========
+
+    This interface provides a Windows MIDI device interface which receives
+    events and plays it in real-time.  On this mode, TiMidity works
+    purely as software (real-time) MIDI render.
+
+    For invoking Windows synthesizer interface, run timidity as folows:
+      % timidity -iW    (interactively select an Input MIDI device)
+    or
+      % timidity -iW 2  (connect to MIDI device No. 2)
+
+    TiMidity loads instruments dynamically at each time a PRM_CHANGE
+    event is received.  It sometimes causes a noise.
+    If you are using a low power machine, invoke timidity as follows:
+      % timidity -s 11025 -iW       (set sampling freq. to 11025Hz)
+    or
+      % timidity -EFreverb=0 -iW    (disable MIDI reverb effect control)
+
+    TiMidity keeps all loaded instruments during executing.
+
+    To use TiMidity as output device, you need a MIDI loopback device.
+    I use MIDI Yoke. It can freely be obtained MIDI-OX site
+    (http://www.midiox.com).
+*/
+
+//#define  USE_PORTMIDI 1
+//#define USE_GTK_GUI 1
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __POCC__
+#include <sys/types.h>
+#endif
+
+#include "rtsyn.h"
+#ifdef USE_GTK_GUI
+#include "wsgtk_main.h"
+#endif
+
+#ifndef __W32__
+#include <stdio.h>
+#include <termios.h>
+//#include <term.h>
+#include <unistd.h>
+#endif
+
+
+#ifndef __W32__
+static struct termios initial_settings, new_settings;
+static int peek_character = -1;
+#endif
+
+extern int volatile stream_max_compute;        // play_event() \82Ì compute_data() \82Å\8cv\8eZ\82ð\8b\96\82·\8dÅ\91å\8e\9e\8aÔ
+static int seq_quit=~0;
+
+
+static int ctl_open(int using_stdin, int using_stdout);
+static void ctl_close(void);
+static int ctl_read(int32 *valp);
+static int cmsg(int type, int verbosity_level, char *fmt, ...);
+static void ctl_event(CtlEvent *e);
+static int ctl_pass_playing_list(int n, char *args[]);
+
+#ifndef __W32__
+static void init_keybord(void);
+static void close_keybord(void);
+static int kbhit(void);
+static char readch(void);
+#endif
+
+/**********************************/
+/* export the interface functions */
+
+#define ctl npsyn_control_mode
+
+ControlMode ctl=
+{
+    "Windows Named Pipe Synthesizer interface", 'N',
+    "npsyn",
+    1,0,0,
+    0,
+    ctl_open,
+    ctl_close,
+    ctl_pass_playing_list,
+    ctl_read,
+    NULL,
+    cmsg,
+    ctl_event
+};
+
+static int32 event_time_offset;
+static FILE *outfp;
+
+/*ARGSUSED*/
+
+static int ctl_open(int using_stdin, int using_stdout)
+{
+       ctl.opened = 1;
+       ctl.flags &= ~(CTLF_LIST_RANDOM|CTLF_LIST_SORT);
+       if (using_stdout)
+               outfp = stderr;
+       else
+               outfp = stdout;
+       return 0;
+}
+
+static void ctl_close(void)
+{
+  fflush(outfp);
+  if(seq_quit==0){
+       rtsyn_np_synth_stop();
+       rtsyn_close();
+       seq_quit=~0;
+  }
+  ctl.opened=0;
+}
+
+static int ctl_read(int32 *valp)
+{
+    return RC_NONE;
+}
+
+#ifdef IA_W32G_SYN
+extern void PutsConsoleWnd(char *str);
+extern int ConsoleWndFlag;
+#endif
+static int cmsg(int type, int verbosity_level, char *fmt, ...)
+{
+#ifndef WINDRV
+#ifndef IA_W32G_SYN
+
+       va_list ap;
+
+  if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
+      ctl.verbosity<verbosity_level)
+    return 0;
+  va_start(ap, fmt);
+  if(type == CMSG_WARNING || type == CMSG_ERROR || type == CMSG_FATAL)
+      dumb_error_count++;
+  if (!ctl.opened)
+    {
+      vfprintf(stderr, fmt, ap);
+      fputs(NLS, stderr);
+    }
+  else
+    {
+      vfprintf(outfp, fmt, ap);
+      fputs(NLS, outfp);
+      fflush(outfp);
+    }
+  va_end(ap);
+
+#else
+       if ( !ConsoleWndFlag ) return 0;
+       {
+    char buffer[1024];
+    va_list ap;
+    va_start(ap, fmt);
+       vsnprintf(buffer, sizeof(buffer), fmt, ap);
+    va_end(ap);
+
+    if((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
+       ctl.verbosity<verbosity_level) 
+       return 0;
+//    if(type == CMSG_FATAL)
+//     w32g_msg_box(buffer, "TiMidity Error", MB_OK);
+    PutsConsoleWnd(buffer);
+    PutsConsoleWnd("\n");
+    return 0;
+       }
+#endif
+#endif
+    return 0;
+}
+
+static void ctl_event(CtlEvent *e)
+{
+}
+
+static void doit(void);
+
+#ifdef IA_W32G_SYN
+extern void w32g_syn_doit(void);
+extern int w32g_syn_ctl_pass_playing_list(int n_, char *args_[]);
+
+
+static int ctl_pass_playing_list(int n, char *args[])
+{
+       return w32g_syn_ctl_pass_playing_list ( n, args );
+}
+#endif
+
+#ifndef IA_W32G_SYN
+static int ctl_pass_playing_list(int n, char *args[])
+#else
+// 0: OK, 2: Require to reset.
+int ctl_pass_playing_list2(int n, char *args[])
+#endif
+{ 
+       if(n != 1){
+               ctl.cmsg(CMSG_WARNING, VERB_NORMAL, "Usage: timidity -iN [Named Pipe Name]\n");
+               return 1;
+       }
+       
+       rtsyn_np_set_pipe_name(args[0]);
+
+#if !defined(IA_W32G_SYN) && !defined(USE_GTK_GUI)
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "TiMidity starting in Windows Named Pipe Synthesizer mode\n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "Usage: timidity -iN [Named Pipe Name]\n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, "\n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "N (Normal mode) M(GM mode) S(GS mode) X(XG mode) \n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "(Only in Normal mode, Mode can be changed by MIDI data)\n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "m(GM reset) s(GS reset) x(XG reset)\n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "\n");
+       ctl.cmsg(CMSG_WARNING, VERB_NORMAL, 
+               "Press 'q' key to stop\n");
+
+#endif
+
+       rtsyn_init();
+
+#ifdef USE_GTK_GUI
+       twgtk_main();
+#else 
+#ifdef IA_W32G_SYN
+       if(0!=rtsyn_np_synth_start()){
+               seq_quit=0;
+               while(seq_quit==0) {
+                       w32g_syn_doit();
+               }
+               rtsyn_np_synth_stop();
+       }
+#else
+       if(0!=rtsyn_np_synth_start()){
+               seq_quit=0;
+               while(seq_quit==0) {
+                       doit();
+               }
+               rtsyn_np_synth_stop();
+       }
+#endif /* IA_W32G_SYN */
+#endif /* USE_GTK_GUI */
+       rtsyn_close();
+
+       return 0;
+}
+
+
+#ifndef IA_W32G_SYN
+
+
+#ifndef __W32__
+static void init_keybord(void){
+       tcgetattr(0,&initial_settings);
+       tcgetattr(0,&new_settings);
+       new_settings.c_lflag &= ~ICANON;
+       new_settings.c_lflag &= ~ECHO;
+       new_settings.c_lflag &= ~ISIG;
+       new_settings.c_cc[VMIN] = 1;
+       new_settings.c_cc[VTIME] = 0;
+       tcsetattr(0, TCSANOW, &new_settings);
+}
+
+static void close_keybord(void){
+       tcsetattr(0, TCSANOW, &initial_settings);
+}
+
+static int kbhit(void){
+       char ch;
+       int nread;
+       
+       if(peek_character != -1)
+               return 1;
+       new_settings.c_cc[VMIN]=0;
+       tcsetattr(0,TCSANOW, &new_settings);
+       nread = read(0, &ch, 1);
+       new_settings.c_cc[VMIN]=1;
+       tcsetattr(0,TCSANOW, &new_settings);
+       
+       if(nread == 1) {
+               peek_character = ch;
+               return 1;
+       }
+       return 0;
+}
+
+
+static char readch(void){
+       char ch;
+       if(peek_character != -1){
+               ch = peek_character;
+               peek_character = -1;
+               return ch;
+       }
+       read(0,&ch,1);
+       return ch;
+}
+#endif         
+
+
+static void doit(void)
+{
+#ifndef __W32__
+               init_keybord();
+#endif
+
+       while(seq_quit==0){
+#ifdef __W32__
+               if(kbhit()){
+                       switch(getch()){
+#else                  
+               if(kbhit()){
+                       switch(readch()){
+#endif
+                               case 'Q':
+                               case 'q':
+                                       seq_quit=~0;
+                               break;
+                               case 'm':
+                                       rtsyn_gm_reset();
+                               break;
+                               case 's':
+                                       rtsyn_gs_reset();
+                               break;
+                               case 'x':
+                                       rtsyn_xg_reset();
+                               break;
+                               case 'c':
+                                       rtsyn_normal_reset();
+                               break;
+                               case 'M':
+                                       rtsyn_gm_modeset();
+                               break;
+                               case 'S':
+                                       rtsyn_gs_modeset();
+                               break;
+                               case 'X':
+                                       rtsyn_xg_modeset();
+                               break;
+                               case 'N':
+                                       rtsyn_normal_modeset();
+                               break;
+                       }
+               }
+               rtsyn_np_play_some_data();
+               rtsyn_play_calculate();
+               if(intr) seq_quit=~0;
+               sleep(1);
+       }
+#ifndef __W32__
+       close_keybord();
+#endif
+}
+
+#endif /* !IA_W32G_SYN */
+
+
+#ifdef IA_W32G_SYN
+static int winplaymidi_sleep_level = 2;
+static DWORD winplaymidi_active_start_time = 0;
+
+
+void winplaymidi(void){
+
+       if ( winplaymidi_sleep_level < 1 ) {
+               winplaymidi_sleep_level = 1;
+       }
+       if( 0 != rtsyn_buf_check() ){
+                       winplaymidi_sleep_level =0;
+       }
+       rtsyn_np_play_some_data();
+       if ( winplaymidi_sleep_level == 1 ) {
+               DWORD ct = GetCurrentTime ();
+               if ( winplaymidi_active_start_time == 0 || ct < winplaymidi_active_start_time ) {
+                       winplaymidi_active_start_time = ct;
+               } else if ( ct - winplaymidi_active_start_time > 2000 ) {
+                       winplaymidi_sleep_level = 2;
+               }
+       } else if ( winplaymidi_sleep_level == 0 ) {
+               winplaymidi_active_start_time = 0;
+       }
+       
+       rtsyn_play_calculate();
+       
+       if ( winplaymidi_sleep_level >= 2) {
+               Sleep ( 100 );
+       } else if ( winplaymidi_sleep_level > 0 ) {
+               Sleep ( 1 );
+       }
+}
+#endif
+               
+
+/*
+ * interface_<id>_loader();
+ */
+ControlMode *interface_N_loader(void)
+{
+    return &ctl;
+}
+
+
index 4b59ac8..d959153 100644 (file)
@@ -132,6 +132,8 @@ void rtsyn_play_calculate(void);
 /*  Interface dependent functions (see rtsyn_winmm.c rtsyn_portmidi.c)        */
 /*                                                                            */
 /******************************************************************************/
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN) 
+
 #define MAX_PORT 4
 extern int rtsyn_portnumber;
 extern unsigned int portID[MAX_PORT];
@@ -144,12 +146,33 @@ void rtsyn_synth_stop(void);
 int rtsyn_play_some_data (void);
 void rtsyn_midiports_close(void);
 
-
 #if defined(IA_WINSYN) || defined(IA_W32G_SYN)
 int rtsyn_buf_check(void);
 #endif
 
-
+#endif /* IA_WINSYN IA_PORTMIDISYN IA_W32G_SYN */
+
+#ifdef IA_NPSYN
+#define RTSYN_NP_DATA 1
+#define RTSYN_NP_LONGDATA 2
+typedef struct rtsyn_np_evbuf_t{
+       uint32 wMsg;
+       union {
+               uint32 port;
+               uint32  exlen;
+       };
+       union {
+               uint32  dwParam1;
+       };
+       uint32  dwParam2;
+}  RtsynNpEvBuf;
+
+void rtsyn_np_set_pipe_name(char*);
+int rtsyn_np_synth_start(void);
+void rtsyn_np_synth_stop(void);
+int rtsyn_np_play_some_data (void);
+void rtsyn_np_pipe_close();
+#endif
 
 #ifdef USE_WINSYN_TIMER_I
 
index e544724..e8398ec 100644 (file)
@@ -94,7 +94,7 @@ static double active_sensing_time=0;
 
 //timer interrupt
 
-
+/*
 #define EX_RESET_NO 7
 static char sysex_resets[EX_RESET_NO][11]={
                '\xf0','\x7e','\x7f','\x09','\x00','\xf7','\x00','\x00','\x00','\x00','\x00',
@@ -104,6 +104,7 @@ static char sysex_resets[EX_RESET_NO][11]={
                '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x00','\x01','\xf7',
                '\xf0','\x41','\x10','\x42','\x12','\x00','\x00','\x7f','\x01','\x00','\xf7',
                '\xf0','\x43','\x10','\x4c','\x00','\x00','\x7E','\x00','\xf7','\x00','\x00' };
+*/
 /*
 #define EX_RESET_NO 9
 static char sysex_resets[EX_RESET_NO][11]={
@@ -254,9 +255,6 @@ void rtsyn_play_event_time(MidiEvent *ev, double event_time){
        int32 max_compute;
        MidiEvent nev;
 
-       gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
-       if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
-
                max_compute = rtsyn_latency * 1000.0;
                max_compute = (stream_max_compute > max_compute) ? stream_max_compute : max_compute;
                if ( (event_time - last_event_time) > (double)max_compute/1000.0){
@@ -279,21 +277,19 @@ void rtsyn_play_event_time(MidiEvent *ev, double event_time){
                                        play_event(&nev);
                                        aq_fill_nonblocking();
                                }
-                               rtsyn_seq_set_time(ev,event_time);
-                               play_event(ev);
-                               aq_fill_nonblocking();
-                               last_event_time = (event_time  > last_event_time) ? event_time : last_event_time ;
-               
-                       }else{
-                               rtsyn_seq_set_time(ev, event_time);
-                               play_event(ev);
-                               aq_fill_nonblocking();
-                               last_event_time = (event_time  > last_event_time) ? event_time : last_event_time ;
                        }
-               }
+                               gch = GLOBAL_CHANNEL_EVENT_TYPE(ev->type);
+                               if(gch || !IS_SET_CHANNELMASK(quietchannels, ev->channel) ){
+                                       rtsyn_seq_set_time(ev,event_time);
+                                       play_event(ev);
+                                       aq_fill_nonblocking();
+                                       last_event_time = (event_time  > last_event_time) ? event_time : last_event_time ;
+                               }
+                       }
+//             }
 //             }
                rtsyn_played = 1;
-       }
+
 
 }
 void rtsyn_play_event(MidiEvent *ev){
@@ -312,8 +308,9 @@ void rtsyn_server_reset(void){
                free_instruments(0);
        }
        aq_flush(1);
-       play_mode->close_output();      // PM_REQ_PLAY_START wlll called in playmidi_stream_init()
-       play_mode->open_output();       // but w32_a.c does not have it.
+//     play_mode->close_output();      // PM_REQ_PLAY_START wlll called in playmidi_stream_init()
+//     play_mode->open_output();       // but w32_a.c does not have it.
+        play_mode->acntl(PM_REQ_FLUSH, NULL);
 
        readmidi_read_init();
        playmidi_stream_init();
@@ -479,9 +476,14 @@ void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
        
        event_time = event_time + rtsyn_latency;
 
+       if( (sysexbuffer[0] != '\xf0') && (sysexbuffer[0] != '\xf7') ) return ;
+
+/* // this is bad check  someone send SysEx f0xxxxxxxxxxx without xf7 format.
        if(   ((sysexbuffer[0] != '\xf0') && (sysexbuffer[0] != '\xf7')) ||
        ((sysexbuffer[0] == '\xf0') && (sysexbuffer[exlen-1] != '\xf7'))  ) return ;
+*/
 
+/*
        for(i=0;i<EX_RESET_NO;i++){
                chk=0;
                for(j=0;(j<exlen)&&(j<11);j++){
@@ -493,7 +495,7 @@ void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
                         rtsyn_server_reset();
                }
        }
-
+*/
 /*
                printf("SyeEx length=%x bytes \n", exlen);
                for(i=0;i<exlen;i++){
@@ -502,6 +504,7 @@ void rtsyn_play_one_sysex (char *sysexbuffer, int exlen, double event_time ){
                printf("\n");
 */
        if(parse_sysex_event(sysexbuffer+1,exlen-1,&ev)){
+               if(ev.type==ME_RESET)  rtsyn_server_reset();
                if(ev.type==ME_RESET && rtsyn_system_mode!=DEFAULT_SYSTEM_MODE){
                        ev.a=rtsyn_system_mode;
                        change_system_mode(rtsyn_system_mode);
diff --git a/interface/rtsyn_npipe.c b/interface/rtsyn_npipe.c
new file mode 100755 (executable)
index 0000000..98e436b
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+    TiMidity++ -- MIDI to WAVE converter and player
+    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
+    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+    rtsyn_npipe.c
+        Copyright (c) 2007 Keishi Suenaga <s_keishi@mutt.freemail.ne.jp>
+
+    I referenced following sources.
+        alsaseq_c.c - ALSA sequencer server interface
+            Copyright (c) 2000  Takashi Iwai <tiwai@suse.de>
+        readmidi.c
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include "interface.h"
+
+#ifdef __POCC__
+#include <sys/types.h>
+#endif //for off_t
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#endif
+#ifndef NO_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <math.h>
+#include <signal.h>
+
+#include "server_defs.h"
+
+#ifdef __W32__
+#include <windows.h>
+#endif
+
+#include "timidity.h"
+#include "common.h"
+#include "controls.h"
+#include "instrum.h"
+#include "playmidi.h"
+#include "readmidi.h"
+#include "recache.h"
+#include "output.h"
+#include "aq.h"
+#include "timer.h"
+
+#include "rtsyn.h"
+
+
+#define PIPE_BUFFER_SIZE (8192)
+static HANDLE hPipe=NULL;
+
+
+
+
+static char pipe_name[256];
+
+#define EVBUFF_SIZE 512
+typedef struct rtsyn_evbuf_t{
+       UINT wMsg;
+       UINT port;
+       DWORD   dwParam1;
+       DWORD   dwParam2;
+       int  exlen;
+       char *exbuffer;
+}  RtsynEvBuf;
+static RtsynEvBuf evbuf[EVBUFF_SIZE];
+static UINT  np_evbwpoint=0;
+static UINT  np_evbrpoint=0;
+static UINT evbsysexpoint;
+
+static CRITICAL_SECTION mim_np_section;
+
+int first_ev = 1;
+static double mim_start_time;
+
+static char npipe_buffer[2*PIPE_BUFFER_SIZE];
+static int npipe_len=0;
+
+
+
+void rtsyn_np_set_pipe_name(char* name)
+{
+       strncpy(pipe_name, name, 256-1);
+       pipe_name[256-1]='\0';
+}
+
+static int npipe_input_open(const char *pipe_name)
+{
+  static OVERLAPPED overlapped;
+  static HANDLE hEvent;
+  char PipeName[256];
+  DWORD ret;
+
+ hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ memset( &overlapped, 0, sizeof(OVERLAPPED));
+ overlapped.hEvent = hEvent;
+       
+  sprintf(PipeName, "\\\\.\\pipe\\%s", pipe_name);
+  hPipe = CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, 
+//    PIPE_WAIT|
+       PIPE_READMODE_BYTE |PIPE_TYPE_BYTE, 2, 
+   0, PIPE_BUFFER_SIZE, 0, NULL);
+  if (hPipe == INVALID_HANDLE_VALUE) {
+    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't create Named Pipe %s : %ld",
+       pipe_name, GetLastError());
+       return -1;
+  }
+  ret = ConnectNamedPipe(hPipe, &overlapped);
+       if ( (ret == 0)  && (ERROR_IO_PENDING!=GetLastError()) ){
+    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "CnnectNamePipe(%ld) error %s",
+       GetLastError(), pipe_name);
+        CloseHandle(hPipe);
+           hPipe=NULL;
+        return -1;
+   }
+//     WaitForSingleObject(overlapped.hEvent, 1000);
+       CloseHandle(hEvent);
+  return 0;
+}
+       
+int rtsyn_np_synth_start()
+{
+       if( 0 != npipe_input_open(pipe_name)) return 0;
+//     npipe_input_open(pipe_name);
+       np_evbwpoint=0;
+       np_evbrpoint=0;
+       InitializeCriticalSection(&mim_np_section);
+       first_ev = 1;
+       npipe_len=0;
+       return ~0;
+}
+
+void rtsyn_np_synth_stop()
+{
+       rtsyn_stop_playing();
+       //      play_mode->close_output();
+       DeleteCriticalSection(&mim_np_section);
+       CloseHandle(hPipe);
+       hPipe=NULL;
+       return;
+}
+
+int rtsyn_np_buf_check(void)
+{
+       int retval;
+       EnterCriticalSection(&mim_np_section);
+       retval = (np_evbrpoint != np_evbwpoint) ? 0 :  -1;
+       LeaveCriticalSection(&mim_np_section);
+       return retval;
+}
+
+static int read_pipe_data(void);
+
+int rtsyn_np_play_some_data(void)
+{
+       UINT wMsg;
+       DWORD   dwParam1;
+       DWORD   dwParam2;
+       MidiEvent ev;
+       MidiEvent evm[260];
+       UINT evbpoint;
+       MIDIHDR *IIMidiHdr;
+       int exlen;
+       char *sysexbuffer;
+       int ne,i,j,chk,played;
+       UINT port;
+       static DWORD  pre_time;
+       static DWORD timeoffset;
+       double event_time;
+       
+//     rtsyn_play_one_data (0,0x007f3c90, get_current_calender_time());
+       if ( 0 != read_pipe_data()) return 0;
+       
+       played=0;
+               if( -1 == rtsyn_np_buf_check() ){ 
+                       played=~0;
+                       return played;
+               }
+
+               do{
+
+                       
+                       EnterCriticalSection(&mim_np_section);
+                       evbpoint=np_evbrpoint;
+                       if (++np_evbrpoint >= EVBUFF_SIZE)
+                                       np_evbrpoint -= EVBUFF_SIZE;
+                       wMsg=evbuf[evbpoint].wMsg;
+                       port=evbuf[evbpoint].port;
+                       dwParam1=evbuf[evbpoint].dwParam1;
+                       dwParam2=evbuf[evbpoint].dwParam2;
+                       exlen = evbuf[evbpoint].exlen;
+                       sysexbuffer = evbuf[evbpoint].exbuffer;                 
+                       LeaveCriticalSection(&mim_np_section);
+                       if((first_ev == 1)  || ( pre_time > dwParam2)){
+                               pre_time=dwParam2;
+                               timeoffset=dwParam2;
+                               mim_start_time = get_current_calender_time();
+                               first_ev=0;
+                       }
+                       if(dwParam2 !=0){
+                            event_time= mim_start_time+((double)(dwParam2-timeoffset))*(double)1.0/(double)1000.0;
+                       }else{
+                               event_time = get_current_calender_time();
+                       }
+                       switch (wMsg) {
+                       case RTSYN_NP_DATA:
+                               rtsyn_play_one_data (port, dwParam1, event_time);
+                               break;
+                       case RTSYN_NP_LONGDATA:
+                               rtsyn_play_one_sysex (sysexbuffer,exlen, event_time);
+                               free(sysexbuffer);
+                               break;
+                       }
+                       pre_time =dwParam2;
+                       
+               }while( 0==rtsyn_np_buf_check());
+
+       return played;
+}
+
+static void parse_ev(char* buffer, int *len){
+       UINT wMsg;
+       UINT port;
+       DWORD   dwParam1;
+       DWORD   dwParam2;
+       int  exlen;
+       char *exbuffer;
+       
+       char *bp, *sp;
+       UINT evbpoint;
+       RtsynNpEvBuf *npevbuf;
+
+/*
+       printf ("buhihi %d \n", *len);
+       {
+               int i,j;
+               
+               for(j=0; j < 4; j++){
+                       for(i=0; i <16;i++){
+                               printf("%2X:", buffer[j*16+i]);
+                       }
+                       printf ("\n");
+               }       
+       }
+*/
+       bp=buffer;
+       sp=buffer;
+       while(1){
+               npevbuf=(RtsynNpEvBuf*)sp;
+               if(*len >= sizeof(RtsynNpEvBuf)){
+                       wMsg=npevbuf->wMsg;
+               }else{
+                       memmove(buffer, sp, *len);
+                       return;
+               }
+               if( ( wMsg != RTSYN_NP_LONGDATA ) && ( wMsg != RTSYN_NP_DATA ) ){
+                       *len = 0;
+                       return;
+               }
+               if( wMsg == RTSYN_NP_DATA){
+                       port=npevbuf->port;
+                       dwParam1=npevbuf->dwParam1;
+                       dwParam2=npevbuf->dwParam2;
+                       bp = sp+sizeof(RtsynNpEvBuf);
+               }
+
+               if( wMsg == RTSYN_NP_LONGDATA ){
+                       exlen=npevbuf->exlen;
+                       bp = sp+sizeof(RtsynNpEvBuf);
+                       
+                   if (*len >= sizeof(RtsynNpEvBuf)+exlen){
+                               exbuffer= (char *)malloc( sizeof(char) * exlen);
+                               memmove(exbuffer,sp+sizeof(RtsynNpEvBuf), exlen);
+                               bp += exlen;
+                   }else{
+                       memmove(buffer, sp, *len);
+                               return;
+                       }
+
+               }
+               EnterCriticalSection(&mim_np_section);
+               evbpoint = np_evbwpoint;
+               if (++np_evbwpoint >= EVBUFF_SIZE)
+                       np_evbwpoint -= EVBUFF_SIZE;
+               evbuf[evbpoint].wMsg = wMsg;
+               evbuf[evbpoint].port = port;
+               evbuf[evbpoint].dwParam1 = dwParam1;
+               evbuf[evbpoint].dwParam2 = dwParam2;
+               evbuf[evbpoint].exlen = exlen;
+               evbuf[evbpoint].exbuffer = exbuffer;
+               LeaveCriticalSection(&mim_np_section);
+
+               *len -= (bp -sp);
+               sp=bp;
+               if(*len <= 0){
+                       len = 0;
+                       return;
+               }
+       };
+}
+
+static int read_pipe_data()
+{
+       DWORD last_error;
+       DWORD n;
+       DWORD length;
+       
+       OVERLAPPED overlapped;
+       HANDLE hEvent;
+       
+       if( hPipe == NULL ) return -1;
+       
+//     if ( ( 0 == PeekNamedPipe(hPipe,NULL,0,NULL,&length,NULL)) &&\r
+//              (GetLastError()==ERROR_BAD_PIPE) )  return -1;
+       if ( 0 == PeekNamedPipe(hPipe,NULL,0,NULL,&length,NULL))  return -1;
+       if(length == 0) return -1;
+
+        hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+       memset( &overlapped, 0, sizeof(OVERLAPPED));
+       overlapped.hEvent = hEvent;
+       npipe_len=0;   // not good fix
+       memset(npipe_buffer+npipe_len, 0, PIPE_BUFFER_SIZE-npipe_len);
+       if(length <=  PIPE_BUFFER_SIZE - npipe_len){
+               ReadFile(hPipe, npipe_buffer+npipe_len,length, &n, &overlapped);
+               last_error = GetLastError();
+               if(last_error == ERROR_IO_PENDING){
+                       GetOverlappedResult(hPipe, &overlapped,&n,TRUE) ;
+                       last_error = GetLastError();
+               }
+       }else{
+               ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Named Pipe buffer overlow");
+               return -1;
+       }
+       if(last_error == ERROR_SUCCESS){
+               npipe_len += n;
+               parse_ev(npipe_buffer,&npipe_len);
+       }
+       CloseHandle(hEvent);
+       if ( (last_error != ERROR_SUCCESS) &&
+               (last_error != ERROR_NOACCESS) ){ 
+               ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Named Pipe Error: %ld",last_error);
+                       return -1;
+       }
+       return 0;
+}
+       
+void rtsyn_np_pipe_close()
+{
+       CloseHandle(hPipe);
+}
index 3c4f404..4ae08b1 100644 (file)
@@ -139,6 +139,7 @@ EXTRA_timidity_SOURCES = \
        mfnode.h \
        nas_a.c \
        portaudio_a.c \
+       npipe_a.c \
        sun_a.c \
        vorbis_a.c \
        flac_a.c \
index f39ae11..23dc35d 100644 (file)
@@ -150,6 +150,11 @@ extern ControlMode winsyn_control_mode;
 extern ControlMode portmidisyn_control_mode;
 #endif /* IA_PORTMIDISYN */
 
+#ifdef IA_NPSYN
+extern ControlMode npsyn_control_mode;
+#endif /* IA_NPSYN */
+
+
 #ifdef IA_MACOSX
 extern ControlMode macosx_control_mode;
 #endif /* IA_MACOSX */
@@ -227,6 +232,9 @@ ControlMode *ctl_list[]={
 #ifdef IA_PORTMIDISYN
   &portmidisyn_control_mode,
 #endif
+#ifdef IA_NPSYN
+  &npsyn_control_mode,
+#endif
   0
 };
 
diff --git a/timidity/npipe_a.c b/timidity/npipe_a.c
new file mode 100755 (executable)
index 0000000..77f389d
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+    TiMidity++ -- MIDI to WAVE converter and player
+    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
+    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    npipe_.c
+
+    Functions to output raw sound data to a windows Named Pipe.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+
+#ifdef __POCC__
+#include <sys/types.h>
+#endif //for off_t
+
+#ifdef __W32__
+#include <windows.h>
+#include <stdlib.h>
+#include <io.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#elif HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include <fcntl.h>
+
+#ifdef __FreeBSD__
+#include <stdio.h>
+#endif
+
+#include "timidity.h"
+#include "common.h"
+#include "output.h"
+#include "controls.h"
+#include "instrum.h"
+#include "playmidi.h"
+#include "readmidi.h"
+
+//#define PIPE_BUFFER_SIZE (AUDIO_BUFFER_SIZE * 8)
+#define PIPE_BUFFER_SIZE (88200)
+static HANDLE hPipe=NULL;
+static volatile int pipe_close=-1;
+static volatile int clear_pipe=-1;
+
+static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
+static void close_output(void);
+static int output_data(char *buf, int32 bytes);
+static int acntl(int request, void *arg);
+
+/* export the playback mode */
+
+#define dpm npipe_play_mode
+
+PlayMode dpm = {
+    DEFAULT_RATE,
+       PE_16BIT|PE_SIGNED, PF_PCM_STREAM,
+    -1,
+    {0,0,0,0,0},
+    "Windows Named Pipe", 'N',
+    NULL,
+    open_output,
+    close_output,
+    output_data,
+    acntl
+};
+
+/*************************************************************************/
+
+static int npipe_output_open(const char *pipe_name)
+{
+  char PipeName[256];
+  OVERLAPPED pipe_ovlpd;
+  HANDLE hPipeEvent;  
+  DWORD ret;
+  DWORD n;
+  int i;
+       
+
+ if (hPipe != NULL) return 0;
+ hPipeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ memset( &pipe_ovlpd, 0, sizeof(OVERLAPPED));
+ pipe_ovlpd.hEvent = hPipeEvent;
+       
+  sprintf(PipeName, "\\\\.\\pipe\\%s", pipe_name);
+  hPipe = CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, 
+//    PIPE_WAIT|
+       PIPE_READMODE_BYTE |PIPE_TYPE_BYTE, 2, 
+   PIPE_BUFFER_SIZE, 0, 0, NULL);
+  if (hPipe == INVALID_HANDLE_VALUE) {
+    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't create Named Pipe %s : %ld",
+       pipe_name, GetLastError());
+       return -1;
+  }
+  ret = ConnectNamedPipe(hPipe, &pipe_ovlpd);
+       if ( (ret == 0)  && (ERROR_IO_PENDING!=GetLastError()) ){
+    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "CnnectNamePipe(%ld) error %s",
+       GetLastError(), pipe_name);
+        CloseHandle(hPipe);
+           hPipe=NULL;\r
+        return -1;\r
+   }
+//     WaitForSingleObject(pipe_ovlpd.hPipeEvent, 1000);
+       CloseHandle(hPipeEvent);
+       return 0;
+}
+
+static int open_output(void)
+{
+  dpm.encoding = validate_encoding(dpm.encoding, 0, 0);
+
+  if(dpm.name == NULL) {
+    if (NULL==current_file_info || NULL==current_file_info->filename){
+      return -1;
+       }
+  }else{
+             if ( -1 == npipe_output_open(dpm.name))
+                       return -1;
+  }
+  dpm.fd = 1;
+  return 0;
+}
+
+static int output_data(char *buf, int32 bytes)
+{
+       DWORD n;
+       int ret;
+       int32 retnum;
+       retnum = bytes;
+       DWORD length;
+       
+       if (hPipe == NULL) return -1;
+       if ( ( 0 == PeekNamedPipe(hPipe,NULL,0,NULL,&length,NULL)) &&\r
+                (GetLastError()==ERROR_BAD_PIPE) )  return -1;
+       if(dpm.fd == -1) return -1;
+       if (pipe_close = 0){
+                 hPipe=NULL;
+                 dpm.fd = -1;
+                 return retnum;
+       }
+       
+       if (0 != PeekNamedPipe(hPipe,NULL,0,NULL,&length,NULL)){
+               if( (bytes <= PIPE_BUFFER_SIZE-length) && (clear_pipe == -1) ){
+                       ret=WriteFile(hPipe,buf,bytes,&n,NULL);
+                       if( (GetLastError() != ERROR_SUCCESS) &&
+                               (GetLastError() != ERROR_BAD_PIPE) ){      //why BAD_PIPE occurs here?
+                       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "npipe_a_error %s: %ld",
+                               dpm.name, GetLastError());
+                               if(hPipe != NULL) CloseHandle(hPipe);
+                               hPipe=NULL;
+                               dpm.fd = -1;
+                                       
+                               return -1;
+               }
+               }else{
+                       clear_pipe= -1 ;
+               }
+       }
+
+       return retnum;
+}
+
+static void close_output(void)
+{
+       if(dpm.fd != -1){
+               CloseHandle(hPipe);
+               hPipe=NULL;
+       dpm.fd = -1;
+       }
+}
+
+static int acntl(int request, void *arg)
+{
+  switch(request) {
+  case PM_REQ_PLAY_START:
+    return 0;
+  case PM_REQ_PLAY_END:
+    return 0;
+  case PM_REQ_DISCARD:
+  case PM_REQ_FLUSH:
+               clear_pipe=0;
+       return 0;
+
+  }
+  return -1;
+}
+
+int npipe_a_pipe_close()
+{
+       int count;
+       if (hPipe == NULL) return;
+       pipe_close=0;
+       count = 100;
+       while( (hPipe != NULL) && (count >0)) Sleep(10);
+       if (hPipe != NULL){
+               CloseHandle(hPipe);
+               hPipe=NULL;
+       }
+       
+}
+
+
+
index 3e1e7bb..02149d1 100644 (file)
@@ -100,6 +100,10 @@ extern PlayMode portaudio_win_wmme_play_mode;
 #endif
 #endif /* AU_PORTAUDIO */
 
+#ifdef AU_NPIPE
+extern PlayMode npipe_play_mode;
+#endif /* AU_NPIPE */
+
 #ifdef AU_JACK
 extern PlayMode jack_play_mode;
 #endif /* AU_NAS */
@@ -164,6 +168,10 @@ PlayMode *play_mode_list[] = {
 #endif
 #endif /* AU_PORTAUDIO */
 
+#if defined(AU_NPIPE)
+  &npipe_play_mode,
+#endif /*AU_NPIPE*/
+
 #if defined(AU_JACK)
   &jack_play_mode,
 #endif /* AU_PORTAUDIO */
index 2f040db..b84469e 100644 (file)
@@ -463,7 +463,8 @@ void initialize_gauss_table(int n)
 
 void free_gauss_table(void)
 {
-       free(gauss_table[0]);
+       if(gauss_table[0] != 0)
+         free(gauss_table[0]);
        gauss_table[0] = NULL;
 }
 
index 9d1f772..a0c48a5 100644 (file)
@@ -297,7 +297,7 @@ static const struct option longopts[] = {
        { "realtime-priority",      required_argument, NULL, TIM_OPT_RT_PRIO },
        { "sequencer-ports",        required_argument, NULL, TIM_OPT_SEQ_PORTS },
 #endif
-#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN) || defined(IA_W32GUI)
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_NPSYN) || defined(IA_W32G_SYN) || defined(IA_W32GUI)
        { "rtsyn-latency",          required_argument, NULL, TIM_OPT_RTSYN_LATENCY },
 #endif
        { "no-realtime-load",       no_argument,       NULL, TIM_OPT_REALTIME_LOAD },
@@ -367,7 +367,7 @@ static const struct option longopts[] = {
        { "module",                 required_argument, NULL, TIM_OPT_MODULE },
        { NULL,                     no_argument,       NULL, '\0'     }
 };
-#define INTERACTIVE_INTERFACE_IDS "kmqagrwAWP"
+#define INTERACTIVE_INTERFACE_IDS "kmqagrwAWNP"
 
 /* main interfaces (To be used another main) */
 #if defined(main) || defined(ANOTHER_MAIN) || defined ( IA_W32GUI ) || defined ( IA_W32G_SYN )
@@ -454,7 +454,7 @@ static inline int parse_opt_background(const char *);
 static inline int parse_opt_rt_prio(const char *);
 static inline int parse_opt_seq_ports(const char *);
 #endif
-#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN) || defined(IA_W32GUI)
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_NPSYN) || defined(IA_W32G_SYN) || defined(IA_W32GUI)
 static inline int parse_opt_rtsyn_latency(const char *);
 #endif
 static inline int parse_opt_j(const char *);
@@ -606,8 +606,16 @@ static BOOL WINAPI handler(DWORD dw)
        {
        rtsyn_midiports_close();
        }
-#endif 
-    printf ("***BREAK" NLS); fflush(stdout);
+#endif
+
+
+#if defined(IA_NPSYN)
+       if( ctl->id_character == 'N')
+       {
+               return FALSE;  //why FALSE need?  It must close by intr++;
+       }
+#endif
+       printf ("***BREAK" NLS); fflush(stdout);
     intr++;
     return TRUE;
 }
@@ -2657,6 +2665,16 @@ MAIN_INTERFACE int set_tim_opt_short(int c, char *optarg)
        }
        return 0;
 }
+MAIN_INTERFACE int set_tim_opt_short_cfg(int c, char *optarg)
+{
+       int err = 0;
+       
+       switch (c) {
+       case 'c':
+               return parse_opt_c(optarg);
+       }
+       return 0;
+}
 
 /* -------- getopt_long -------- */
 MAIN_INTERFACE int set_tim_opt_long(int c, char *optarg, int index)
@@ -2769,7 +2787,7 @@ MAIN_INTERFACE int set_tim_opt_long(int c, char *optarg, int index)
        case TIM_OPT_SEQ_PORTS:
                return parse_opt_seq_ports(arg);
 #endif
-#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN) || defined(IA_W32GUI)
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_NPSYN) || defined(IA_W32G_SYN) || defined(IA_W32GUI)
        case TIM_OPT_RTSYN_LATENCY:
                return parse_opt_rtsyn_latency(arg);
 #endif
@@ -2897,6 +2915,24 @@ MAIN_INTERFACE int set_tim_opt_long(int c, char *optarg, int index)
                abort();
        }
 }
+MAIN_INTERFACE int set_tim_opt_long_cfg(int c, char *optarg, int index)
+{
+       const struct option *the_option = &(longopts[index]);
+       char *arg;
+       
+       if (c == '?')   /* getopt_long failed parsing */
+               parse_opt_fail(optarg);
+       else if (c < TIM_OPT_FIRST)
+               return set_tim_opt_short_cfg(c, optarg);
+       if (! strncmp(the_option->name, "no-", 3))
+               arg = "no";             /* `reverse' switch */
+       else
+               arg = optarg;
+       switch (c) {
+       case TIM_OPT_CONFIG_FILE:
+               return parse_opt_c(arg);
+       }
+}
 
 static inline int parse_opt_A(const char *arg)
 {
@@ -2956,6 +2992,9 @@ static inline int parse_opt_C(const char *arg)
 
 static inline int parse_opt_c(char *arg)
 {
+#ifdef __W32__
+       if(got_a_configuration == 1) retrun 0;
+#endif
        if (read_config_file(arg, 0))
                return 1;
        got_a_configuration = 1;
@@ -3652,7 +3691,7 @@ static int parse_opt_h(const char *arg)
 "             --sequencer-ports=n (for alsaseq only)",
 "               Set the number of opened sequencer ports (default is 4)",
 #endif
-#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN)
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_NPSYN) || defined(IA_W32G_SYN)
 "             --rtsyn-latency=sec (for rtsyn only)",
 "               Set the realtime latency (sec)",
 "                 (default is 0.2 sec, minimum is 0.04 sec)",
@@ -4219,7 +4258,7 @@ static inline int parse_opt_rtsyn_latency(const char *arg)
        return 0;
 }
 #endif
-#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_W32G_SYN)
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) ||defined(IA_NPSYN) || defined(IA_W32G_SYN)
 static inline int parse_opt_rtsyn_latency(const char *arg)
 {
        double latency;
@@ -5751,24 +5790,29 @@ int main(int argc, char **argv)
                        argv[c] = p;
                }
 #endif /* IA_W32GUI || IA_W32G_SYN */
-#ifdef __WIN32__
+#if defined(IA_WINSYN) || defined(IA_PORTMIDISYN) || defined(IA_NPSYN) || defined(IA_W32G_SYN)
        opt_sf_close_each_file = 0;
-#else
-       if ((err = timidity_pre_load_configuration()) != 0)
-               return err;
-#endif
+#endif 
        optind = longind = 0;
 #if defined(__CYGWIN__) || defined(__MINGW32__)
        optreset = 1;
 #endif
+#ifdef __W32__
        while ((c = getopt_long(argc, argv, optcommands, longopts, &longind)) > 0)
-               if ((err = set_tim_opt_long(c, optarg, longind)) != 0)
+               if ((err = set_tim_opt_long_cfg(c, optarg, longind)) != 0)
                        break;
-#ifdef __WIN32__
-       if (got_a_configuration != 1)
+#endif
+       if (got_a_configuration != 1){  
                if ((err = timidity_pre_load_configuration()) != 0)
                        return err;
+       }
+       optind = longind = 0;
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+       optreset = 1;
 #endif
+       while ((c = getopt_long(argc, argv, optcommands, longopts, &longind)) > 0)
+               if ((err = set_tim_opt_long(c, optarg, longind)) != 0)
+                       break;
        err += timidity_post_load_configuration();
        /* If there were problems, give up now */
        if (err || (optind >= argc
@@ -5820,7 +5864,7 @@ int main(int argc, char **argv)
        files  = argv + optind;
        if (nfiles > 0
                        && ctl->id_character != 'r' && ctl->id_character != 'A'
-                       && ctl->id_character != 'W' && ctl->id_character != 'P')
+                       && ctl->id_character != 'W' && ctl->id_character != 'N' && ctl->id_character != 'P')
                files = expand_file_archives(files, &nfiles);
        if (nfiles > 0)
                files_nbuf = files[0];
@@ -5877,7 +5921,7 @@ int main(int argc, char **argv)
                free(wrdt_open_opts);
        if (nfiles > 0
                        && ctl->id_character != 'r' && ctl->id_character != 'A'
-                       && ctl->id_character != 'W' && ctl->id_character != 'P') {
+                       && ctl->id_character != 'W' && ctl->id_character != 'N'  && ctl->id_character != 'P') {
                free(files_nbuf);
                free(files);
        }
index ab6728c..79f844b 100644 (file)
@@ -93,6 +93,7 @@ const GUID CLSID_tim_synth = {0x0FEC4C35,0xA705,0x41d7,{0xA3,0xBB,0xD5,0x87,0xA2
 
 #include "config.h"
 #include "sysdep.h"
+#include "output.h"
 
 #include "timiwp_timidity.h"
 
@@ -107,6 +108,7 @@ static volatile int stop_thread = 0;
 static volatile int stop_rtthread = 0;
 static HANDLE hCalcThread = NULL;
 static HANDLE hRtsynThread = NULL;
+static DWORD processPriority;
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ){
        if (fdwReason == DLL_PROCESS_ATTACH){
@@ -142,9 +144,25 @@ STDAPI_(LONG) DriverProc(DWORD dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1,
  
        switch(msg) {
        case DRV_REMOVE:
+               if (modm_closed == 0){
+                       int maxloop=500;
+                       
+                       stop_thread = 1;    //why thread can't stop by this????
+                       while( stop_thread != 0 && maxloop-- > 0) Sleep(10);
+                       if(stop_thread == 0) {
+                               stop_rtthread = 1;
+                               while( stop_rtthread != 0 && maxloop-- > 0) Sleep(10);
+                       }
+                       if(stop_thread != 0) TerminateThread(hCalcThread, FALSE);
+                       if(stop_rtthread != 0) TerminateThread(hRtsynThread, FALSE);
+                       CloseHandle(hRtsynThread);
+                       CloseHandle(hCalcThread);
+                       SetPriorityClass(GetCurrentProcess(), processPriority);
+               }
                DeleteCriticalSection(&mim_section);
                return 1;
        case DRV_LOAD:
+               processPriority = GetPriorityClass(GetCurrentProcess());
                InitializeCriticalSection(&mim_section);
                return 1;
        case DRV_CLOSE:
@@ -377,7 +395,6 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1
        
        MIDIHDR *IIMidiHdr;     
        UINT evbpoint;
-       static DWORD processPriority;
        
        int exlen = 0;
        char *sysexbuffer = NULL ;
@@ -392,8 +409,6 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1
                        hRtsynThread=(HANDLE)_beginthreadex(NULL,0,threadfunc2,0,0,&thrdaddr);
                        modm_closed = 0;
                }
-               
-       
                SetPriorityClass(GetCurrentProcess(), processPriority);
                return MMSYSERR_NOERROR;
                break;
@@ -451,17 +466,19 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1
        case MODM_CLOSE:
                if ( stop_rtthread != 0 || stop_thread != 0 ) return MIDIERR_STILLPLAYING;
                --OpenCount;
-               if( OpenCount == 0){
-                       int maxloop=1000;
+/*
+               if( ( OpenCount == 0) && (play_mode->id_character != 'd') ){
+                       int maxloop=100;
                        
                        stop_thread = 1;
-                       while( stop_thread != 0 && maxloop-- > 0) Sleep(1);
+                       while( stop_thread != 0 && maxloop-- > 0) Sleep(10);
                        if(stop_thread == 0) {
                                stop_rtthread = 1;
-                               while( stop_rtthread != 0 && maxloop-- > 0) Sleep(1);
+                               while( stop_rtthread != 0 && maxloop-- > 0) Sleep(10);
                        }
-                       if(stop_rtthread != 0) TerminateThread(hRtsynThread, GetExitCodeThread(hRtsynThread,&Exit));
-                       if(stop_thread != 0) TerminateThread(hCalcThread, GetExitCodeThread(hCalcThread,&Exit));
+                       if(stop_thread != 0) TerminateThread(hCalcThread, FALSE);
+                       if(stop_rtthread != 0) TerminateThread(hRtsynThread, FALSE);
+                       
                        if(maxloop == 0){
                                DeleteCriticalSection(&mim_section);
                                InitializeCriticalSection(&mim_section);
@@ -473,11 +490,12 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1
                        SetPriorityClass(GetCurrentProcess(), processPriority);
                        modm_closed=1;
                }else{ 
+*/
                        if(OpenCount < 0){
                                OpenCount = 0;
                                return MMSYSERR_NOTENABLED;
                        }
-               }
+//             }
                return MMSYSERR_NOERROR;
                break;
        default:
index f7c3885..623ff07 100755 (executable)
@@ -199,7 +199,6 @@ int timiwp_main_ini(int argc, char **argv)
 
 }
 
-
 int timiwp_main_close(void)
 {
        int i;
@@ -225,10 +224,6 @@ int timiwp_main_close(void)
        if (user_mailaddr)
                free(user_mailaddr);
 #endif
-#ifdef IA_DYNAMIC
-       if (dynamic_lib_root)
-               free(dynamic_lib_root);
-#endif
 #if 0
        if (pcm_alternate_file)
                free(pcm_alternate_file);
@@ -242,20 +237,25 @@ int timiwp_main_close(void)
                free(output_text_code);
        if (wrdt_open_opts)
                free(wrdt_open_opts);
-
-       for(i =0 ; i < nfiles ;i++) free(files[i]);
-       free(files);
+       if (nfiles > 0
+                       && ctl->id_character != 'r' && ctl->id_character != 'A'
+                       && ctl->id_character != 'W' && ctl->id_character != 'N'  && ctl->id_character != 'P') {
+               free(files_nbuf);
+               free(files);
+       }
 #endif
+//#if 0
        free_soft_queue();
        free_instruments(0);
        free_soundfonts();
        free_cache_data();
+       free_wrd();
+       free_readmidi();
+
        free_global_mblock();
-       free_all_midi_file_info();
-       free_userdrum();
-       free_userinst();
        tmdy_free_config();
        free_reverb_buffer();
+
        free_effect_buffers();
        free(voice);
        free_gauss_table();