-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
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
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)])
arts: aRts
esd: EsounD - Enlightened Sound Daemon
portaudio: PortAudio
+ npipe: Named Pipe(windows)
jack: JACK
ao: Libao
vorbis: Ogg Vorbis
[ --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"
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)
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
.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 ;;
# 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]
,
[ 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,
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
--- /dev/null
+/*
+ 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;
+}
+
+
/* 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];
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
//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',
'\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]={
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){
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){
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();
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++){
rtsyn_server_reset();
}
}
-
+*/
/*
printf("SyeEx length=%x bytes \n", exlen);
for(i=0;i<exlen;i++){
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);
--- /dev/null
+/*
+ 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);
+}
mfnode.h \
nas_a.c \
portaudio_a.c \
+ npipe_a.c \
sun_a.c \
vorbis_a.c \
flac_a.c \
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 */
#ifdef IA_PORTMIDISYN
&portmidisyn_control_mode,
#endif
+#ifdef IA_NPSYN
+ &npsyn_control_mode,
+#endif
0
};
--- /dev/null
+/*
+ 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;
+ }
+
+}
+
+
+
#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 */
#endif
#endif /* AU_PORTAUDIO */
+#if defined(AU_NPIPE)
+ &npipe_play_mode,
+#endif /*AU_NPIPE*/
+
#if defined(AU_JACK)
&jack_play_mode,
#endif /* AU_PORTAUDIO */
void free_gauss_table(void)
{
- free(gauss_table[0]);
+ if(gauss_table[0] != 0)
+ free(gauss_table[0]);
gauss_table[0] = NULL;
}
{ "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 },
{ "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 )
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 *);
{
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;
}
}
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)
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
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)
{
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;
" --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)",
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;
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
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];
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);
}
#include "config.h"
#include "sysdep.h"
+#include "output.h"
#include "timiwp_timidity.h"
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){
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:
MIDIHDR *IIMidiHdr;
UINT evbpoint;
- static DWORD processPriority;
int exlen = 0;
char *sysexbuffer = NULL ;
hRtsynThread=(HANDLE)_beginthreadex(NULL,0,threadfunc2,0,0,&thrdaddr);
modm_closed = 0;
}
-
-
SetPriorityClass(GetCurrentProcess(), processPriority);
return MMSYSERR_NOERROR;
break;
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);
SetPriorityClass(GetCurrentProcess(), processPriority);
modm_closed=1;
}else{
+*/
if(OpenCount < 0){
OpenCount = 0;
return MMSYSERR_NOTENABLED;
}
- }
+// }
return MMSYSERR_NOERROR;
break;
default:
}
-
int timiwp_main_close(void)
{
int i;
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);
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();