aboutsummaryrefslogtreecommitdiff
path: root/pd
diff options
context:
space:
mode:
authorMiller Puckette <millerpuckette@users.sourceforge.net>2005-07-16 01:43:18 +0000
committerMiller Puckette <millerpuckette@users.sourceforge.net>2005-07-16 01:43:18 +0000
commit4cbd55491dd86ea99e1ea8190a20bd13e0f328ae (patch)
tree4e85a9ef44fea72ab6fb02bbe22d33af260c936b /pd
parentad9d49bf213f525d122656fc7dc55287b9ae00f0 (diff)
fixed bugs, adopted some patches.
svn path=/trunk/; revision=3347
Diffstat (limited to 'pd')
-rw-r--r--pd/doc/5.reference/vcf~-help.pd29
-rw-r--r--pd/src/configure.in25
-rw-r--r--pd/src/g_all_guis.c3
-rw-r--r--pd/src/g_numbox.c2
-rw-r--r--pd/src/m_glob.c3
-rw-r--r--pd/src/makefile18
-rw-r--r--pd/src/makefile.dependencies33
-rw-r--r--pd/src/notes.txt7
-rw-r--r--pd/src/s_inter.c10
-rw-r--r--pd/src/s_main.c11
-rw-r--r--pd/src/s_midi.c141
-rw-r--r--pd/src/s_midi_alsa.c233
-rw-r--r--pd/src/s_stuff.h19
-rw-r--r--pd/src/u_main.tk193
-rw-r--r--pd/src/u_pdsend.c3
-rw-r--r--pd/src/x_connective.c16
16 files changed, 685 insertions, 61 deletions
diff --git a/pd/doc/5.reference/vcf~-help.pd b/pd/doc/5.reference/vcf~-help.pd
index 45dde1d8..d3a100e7 100644
--- a/pd/doc/5.reference/vcf~-help.pd
+++ b/pd/doc/5.reference/vcf~-help.pd
@@ -4,17 +4,16 @@
#X text 100 341 amp in (db);
#X text 92 144 test frequency;
#X text 224 340 amp out (db);
-#X obj 220 264 vcf~;
#X text 246 144 center frequency;
#X text 374 184 q;
-#X floatatom 122 168 5 0 0;
-#X floatatom 257 171 5 0 0;
+#X floatatom 122 168 5 0 0 0 - - -;
+#X floatatom 257 171 5 0 0 0 - - -;
#X obj 122 193 osc~;
-#X floatatom 353 203 5 0 0;
+#X floatatom 353 203 5 0 0 0 - - -;
#X obj 122 291 env~ 8192;
#X obj 220 290 env~ 8192;
-#X floatatom 121 318 5 0 0;
-#X floatatom 220 319 5 0 0;
+#X floatatom 121 318 5 0 0 0 - - -;
+#X floatatom 220 319 5 0 0 0 - - -;
#X obj 80 13 vcf~;
#X text 135 13 -- voltage-controlled bandpass filter;
#X text 26 395 see also:;
@@ -24,12 +23,14 @@
to set center frequency \, which may thus change continuously in time.
The "Q" or filter sharpness is still only set by messages. More expensive
than bp~ in CPU time but more powerful too.;
-#X connect 0 0 5 1;
-#X connect 5 0 13 0;
-#X connect 8 0 10 0;
-#X connect 9 0 0 0;
-#X connect 10 0 5 0;
-#X connect 10 0 12 0;
-#X connect 11 0 5 2;
+#X obj 220 264 vcf~ 1;
+#X text 286 264 optional argument to initialize q;
+#X connect 0 0 21 1;
+#X connect 7 0 9 0;
+#X connect 8 0 0 0;
+#X connect 9 0 11 0;
+#X connect 9 0 21 0;
+#X connect 10 0 21 2;
+#X connect 11 0 13 0;
#X connect 12 0 14 0;
-#X connect 13 0 15 0;
+#X connect 21 0 12 0;
diff --git a/pd/src/configure.in b/pd/src/configure.in
index 5e0d6474..84ab18c4 100644
--- a/pd/src/configure.in
+++ b/pd/src/configure.in
@@ -13,6 +13,7 @@ AC_SUBST(OPT_CFLAGS)
AC_SUBST(USE_DEBUG_CFLAGS, no)
AC_SUBST(SYSSRC)
AC_SUBST(TCLTK_FRAMEWORKS_PATH)
+AC_SUBST(TCLTK_FRAMEWORKS_PATH)
AC_SUBST(STRIPFLAG)
AC_SUBST(GUINAME)
AC_SUBST(GUIFLAGS)
@@ -169,10 +170,12 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate.
SYSSRC="s_midi_oss.c s_audio_oss.c"
if test x$alsa == "xyes";
then
- SYSSRC=$SYSSRC" s_audio_alsa.c s_audio_alsamm.c"
+ SYSSRC=$SYSSRC" s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c"
MORECFLAGS=$MORECFLAGS" -DPA_USE_ALSA -DUSEAPI_ALSA"
LDFLAGS=$LDFLAGS" -lasound"
fi
+
+
if test x$portaudio == "xyes";
@@ -210,6 +213,24 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate.
OPT_CFLAGS="-g"
else
OPT_CFLAGS="-O6 -funroll-loops -fomit-frame-pointer"
+
+ if test x$jack == "xyes";
+ then
+ LDFLAGS=$LDFLAGS" -lrt -ljack"
+ fi
+ if test x$jack == "xrun";
+ then
+ LDFLAGS=$LDFLAGS" -lrt -ljack"
+ fi
+ fi
+
+ if test x$jack == "xyes";
+ then
+ LDFLAGS=$LDFLAGS" -lrt -ljack"
+ fi
+ if test x$jack == "xrun";
+ then
+ LDFLAGS=$LDFLAGS" -lrt -ljack"
fi
echo OPT_CFLAGS --------------- $OPT_CFLAGS
OSNUMBER=0
@@ -244,7 +265,7 @@ then
-I../portmidi/pm_common -I../portmidi/pm_mac \
-I../portmidi/porttime \
-Wno-error \
- -DUSEAPI_PORTAUDIO -DPA_BIG_ENDIAN -DPA19"
+ -DUSEAPI_PORTAUDIO -DPA_BIG_ENDIAN -DPA19 -DPA_USE_COREAUDIO"
SYSSRC="s_midi_pm.c s_audio_pa.c \
s_audio_pablio.c \
s_audio_paring.c \
diff --git a/pd/src/g_all_guis.c b/pd/src/g_all_guis.c
index da83c2ab..f2df4a4b 100644
--- a/pd/src/g_all_guis.c
+++ b/pd/src/g_all_guis.c
@@ -353,9 +353,6 @@ void iemgui_send(void *x, t_iemgui *iemgui, t_symbol *s)
snd = iemgui_raute2dollar(s);
iemgui->x_snd_unexpanded = snd;
iemgui->x_snd = snd = canvas_realizedollar(iemgui->x_glist, snd);
- post("send: before %s, after %s", iemgui->x_snd_unexpanded->s_name,
- iemgui->x_snd->s_name);
-
iemgui->x_fsf.x_snd_able = sndable;
iemgui_verify_snd_ne_rcv(iemgui);
(*iemgui->x_draw)(x, iemgui->x_glist, IEM_GUI_DRAW_MODE_IO + oldsndrcvable);
diff --git a/pd/src/g_numbox.c b/pd/src/g_numbox.c
index 79fd3e9d..547641c5 100644
--- a/pd/src/g_numbox.c
+++ b/pd/src/g_numbox.c
@@ -36,7 +36,7 @@ static t_class *my_numbox_class;
static void my_numbox_tick_reset(t_my_numbox *x)
{
- if(x->x_gui.x_fsf.x_change && x->x_gui.x_glist)
+ if(x->x_gui.x_fsf.x_change && x->x_gui.x_glist)
{
x->x_gui.x_fsf.x_change = 0;
(*x->x_gui.x_draw)(x, x->x_gui.x_glist, IEM_GUI_DRAW_MODE_UPDATE);
diff --git a/pd/src/m_glob.c b/pd/src/m_glob.c
index 12cfb9b6..bcd9d6f3 100644
--- a/pd/src/m_glob.c
+++ b/pd/src/m_glob.c
@@ -23,6 +23,7 @@ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv);
void glob_audio_setapi(t_pd *dummy, t_floatarg f);
void glob_midi_properties(t_pd *dummy, t_floatarg flongform);
void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv);
+void glob_midi_setapi(t_pd *dummy, t_floatarg f);
void glob_start_path_dialog(t_pd *dummy, t_floatarg flongform);
void glob_path_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv);
void glob_start_startup_dialog(t_pd *dummy, t_floatarg flongform);
@@ -93,6 +94,8 @@ void glob_init(void)
gensym("audio-dialog"), A_GIMME, 0);
class_addmethod(glob_pdobject, (t_method)glob_audio_setapi,
gensym("audio-setapi"), A_FLOAT, 0);
+ class_addmethod(glob_pdobject, (t_method)glob_midi_setapi,
+ gensym("midi-setapi"), A_FLOAT, 0);
class_addmethod(glob_pdobject, (t_method)glob_midi_properties,
gensym("midi-properties"), A_DEFFLOAT, 0);
class_addmethod(glob_pdobject, (t_method)glob_midi_dialog,
diff --git a/pd/src/makefile b/pd/src/makefile
index 188977c1..f69e9a00 100644
--- a/pd/src/makefile
+++ b/pd/src/makefile
@@ -28,7 +28,7 @@ CFLAGS = -Werror $(ARCH_CFLAGS) $(WARN_CFLAGS) $(OPT_CFLAGS) $(MORECFLAGS)
# the sources
-SYSSRC += s_midi_oss.c s_audio_oss.c s_audio_alsa.c s_audio_alsamm.c
+SYSSRC += s_midi_oss.c s_audio_oss.c s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c
SRC = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_io.c \
g_scalar.c g_traversal.c g_guiconnect.c g_readwrite.c g_editor.c \
@@ -97,11 +97,17 @@ $(BIN_DIR)/pd.tk: u_main.tk
cp u_main.tk $(BIN_DIR)/pd.tk
#this is for Max OSX only...
-$(BIN_DIR)/pdtcl: $(GOBJ) $(GSRC)
- cd ../obj; libtool -dynamic -o $(BIN_DIR)/pdtcl $(GOBJ) \
- ../../Frameworks/Tk.framework/Versions/Current/Tk \
- ../../Frameworks/Tcl.framework/Versions/Current/Tcl \
- /usr/lib/libSystem.B.dylib
+$(BIN_DIR)/libPdTcl.dylib: $(GOBJ) $(GSRC)
+ cd ../obj && $(CC) -dynamiclib -read_only_relocs warning \
+ -o $(BIN_DIR)/libPdTcl.dylib $(GOBJ) \
+ -F \
+ -framework Tcl -framework Tk -framework System \
+ -Wl,-install_name,@executable_path/../Resources/bin/libPdTcl.dylib
+ install_name_tool -change /Tcl.framework/Versions/8.4/Tcl\
+ @executable_path/../Frameworks/Tcl.framework/Versions/8.4/Tcl \
+ -change /Tk.framework/Versions/8.4/Tk \
+ @executable_path/../Frameworks/Tk.framework/Versions/8.4/Tk \
+ ../bin/libPdTcl.dylib
externs:
cd ../extra/bonk~;make
diff --git a/pd/src/makefile.dependencies b/pd/src/makefile.dependencies
index 3b0b06e6..79c847aa 100644
--- a/pd/src/makefile.dependencies
+++ b/pd/src/makefile.dependencies
@@ -1034,3 +1034,36 @@ s_audio_alsamm.o: s_audio_alsamm.c /usr/include/alsa/asoundlib.h \
/usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
/usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
/usr/include/sched.h s_audio_alsa.h
+s_midi_alsa.o: s_midi_alsa.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/typesizes.h /usr/include/libio.h \
+ /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
+ /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
+ /usr/include/getopt.h /usr/include/stdlib.h /usr/include/sys/types.h \
+ /usr/include/time.h /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/sigset.h /usr/include/bits/time.h \
+ /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+ /usr/include/bits/sched.h /usr/include/alloca.h /usr/include/sys/stat.h \
+ /usr/include/bits/stat.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \
+ /usr/include/errno.h /usr/include/bits/errno.h \
+ /usr/include/linux/errno.h /usr/include/asm/errno.h \
+ /usr/include/alsa/asoundlib.h /usr/include/string.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h \
+ /usr/include/assert.h /usr/include/sys/poll.h /usr/include/bits/poll.h \
+ /usr/include/alsa/asoundef.h /usr/include/alsa/version.h \
+ /usr/include/alsa/global.h /usr/include/alsa/input.h \
+ /usr/include/alsa/output.h /usr/include/alsa/error.h \
+ /usr/include/alsa/conf.h /usr/include/alsa/pcm.h \
+ /usr/include/alsa/rawmidi.h /usr/include/alsa/timer.h \
+ /usr/include/alsa/hwdep.h /usr/include/alsa/control.h \
+ /usr/include/alsa/mixer.h /usr/include/alsa/seq_event.h \
+ /usr/include/alsa/seq.h /usr/include/alsa/seqmid.h \
+ /usr/include/alsa/seq_midi_event.h /usr/include/alsa/conv.h \
+ /usr/include/alsa/instr.h m_pd.h s_stuff.h
diff --git a/pd/src/notes.txt b/pd/src/notes.txt
index 2faef8a0..038c2a94 100644
--- a/pd/src/notes.txt
+++ b/pd/src/notes.txt
@@ -16,11 +16,10 @@ GOP font depends on abstraction, not parent
------------ 0.39 ---------
problems:
-array dimension change gives TK erro (doesn't update)
-throwing new array on canvas makes red rectangle?
-dialog doesn't start array dialog, just canvas one
+TK commands to nonexistent windows? (maybe fixed)
+array name changes don't show up on parent
arrays that don't fit in bounds don't update (same as red rectangle problem?)
-
+what about upsampling inlet~s? ask Pd list...
flag for array to suppress printing name
diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c
index f95dbc50..5eb931ec 100644
--- a/pd/src/s_inter.c
+++ b/pd/src/s_inter.c
@@ -851,7 +851,7 @@ int sys_startgui(const char *guidir)
#ifdef UNISTD
int stdinpipe[2];
#endif
-
+ fprintf(stderr, "gui; %s\n", guidir);
/* create an empty FD poll list */
sys_fdpoll = (t_fdpoll *)t_getbytes(0);
sys_nfdpoll = 0;
@@ -1029,6 +1029,9 @@ int sys_startgui(const char *guidir)
#ifdef MACOSX
char *homedir = getenv("HOME"), filename[250];
struct stat statbuf;
+ sprintf(filename, "%s/../../MacOS/Pd", guidir);
+ if (stat(filename, &statbuf) >= 0)
+ goto foundit;
if (!homedir || strlen(homedir) > 150)
goto nohomedir;
sprintf(filename,
@@ -1196,7 +1199,7 @@ int sys_startgui(const char *guidir)
}
if (!sys_nogui)
{
- char buf[256];
+ char buf[256], buf2[256];
sys_socketreceiver = socketreceiver_new(0, 0, 0, 0);
sys_addpollfn(sys_guisock, (t_fdpollfn)socketreceiver_read,
sys_socketreceiver);
@@ -1207,7 +1210,8 @@ int sys_startgui(const char *guidir)
sys_gui("pdtk_watchdog\n");
#endif
sys_get_audio_apis(buf);
- sys_vgui("pdtk_pd_startup {%s} %s {%s}\n", pd_version, buf,
+ sys_get_midi_apis(buf2);
+ sys_vgui("pdtk_pd_startup {%s} %s %s {%s}\n", pd_version, buf, buf2,
sys_font);
}
return (0);
diff --git a/pd/src/s_main.c b/pd/src/s_main.c
index a8030f40..1aa106d6 100644
--- a/pd/src/s_main.c
+++ b/pd/src/s_main.c
@@ -2,7 +2,7 @@
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
-char pd_version[] = "Pd version 0.39 TEST 3\n";
+char pd_version[] = "Pd version 0.39 TEST 4\n";
char pd_compiletime[] = __TIME__;
char pd_compiledate[] = __DATE__;
@@ -346,6 +346,10 @@ static char *(usagemessage[]) = {
"-nomidiin -- suppress MIDI input\n",
"-nomidiout -- suppress MIDI output\n",
"-nomidi -- suppress MIDI input and output\n",
+#ifdef USEAPI_ALSA
+"-alsamidi -- use ALSA midi API\n",
+#endif
+
"\nother flags:\n",
"-path <path> -- add to file search path\n",
@@ -604,6 +608,11 @@ int sys_argparse(int argc, char **argv)
else goto usage;
argc -= 2; argv +=2;
}
+ else if (!strcmp(*argv, "-alsamidi"))
+ {
+ sys_set_midi_api(API_ALSA);
+ argc--; argv++;
+ }
#endif
#ifdef USEAPI_JACK
else if (!strcmp(*argv, "-jack"))
diff --git a/pd/src/s_midi.c b/pd/src/s_midi.c
index fbab4283..77943121 100644
--- a/pd/src/s_midi.c
+++ b/pd/src/s_midi.c
@@ -42,6 +42,8 @@ t_midiqelem midi_inqueue[MIDIQSIZE];
int midi_inhead, midi_intail;
static double sys_midiinittime;
+int sys_midiapi = API_DEFAULT;
+
/* this is our current estimate for at what "system" real time the
current logical time's output should occur. */
static double sys_dactimeminusrealtime;
@@ -99,11 +101,24 @@ static double sys_getmidiinrealtime( void)
static void sys_putnext( void)
{
int portno = midi_outqueue[midi_outtail].q_portno;
- if (midi_outqueue[midi_outtail].q_onebyte)
- sys_putmidibyte(portno, midi_outqueue[midi_outtail].q_byte1);
- else sys_putmidimess(portno, midi_outqueue[midi_outtail].q_byte1,
- midi_outqueue[midi_outtail].q_byte2,
- midi_outqueue[midi_outtail].q_byte3);
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ {
+ if (midi_outqueue[midi_outtail].q_onebyte)
+ sys_alsa_putmidibyte(portno, midi_outqueue[midi_outtail].q_byte1);
+ else sys_alsa_putmidimess(portno, midi_outqueue[midi_outtail].q_byte1,
+ midi_outqueue[midi_outtail].q_byte2,
+ midi_outqueue[midi_outtail].q_byte3);
+ }
+ else
+#endif /* ALSA */
+ {
+ if (midi_outqueue[midi_outtail].q_onebyte)
+ sys_putmidibyte(portno, midi_outqueue[midi_outtail].q_byte1);
+ else sys_putmidimess(portno, midi_outqueue[midi_outtail].q_byte1,
+ midi_outqueue[midi_outtail].q_byte2,
+ midi_outqueue[midi_outtail].q_byte3);
+ }
midi_outtail = (midi_outtail + 1 == MIDIQSIZE ? 0 : midi_outtail + 1);
}
@@ -441,6 +456,11 @@ void sys_pollmidiqueue( void)
post("delay %d", (int)(1000 * (newtime - lasttime)));
lasttime = newtime;
#endif
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ sys_alsa_poll_midi();
+ else
+#endif /* ALSA */
sys_poll_midi(); /* OS dependent poll for MIDI input */
sys_pollmidioutqueue();
sys_pollmidiinqueue();
@@ -448,6 +468,9 @@ void sys_pollmidiqueue( void)
/******************** dialog window and device listing ********************/
+#ifdef USEAPI_ALSA
+void midi_alsa_init( void);
+#endif
#ifdef USEAPI_OSS
void midi_oss_init( void);
#endif
@@ -458,6 +481,21 @@ static int midi_midiindev[MAXMIDIINDEV];
static int midi_nmidioutdev;
static int midi_midioutdev[MAXMIDIOUTDEV];
+
+void sys_get_midi_apis(char *buf)
+{
+ int n = 0;
+ strcpy(buf, "{ ");
+ sprintf(buf + strlen(buf), "{default-MIDI %d} ", API_DEFAULT); n++;
+#ifdef USEAPI_ALSA
+ sprintf(buf + strlen(buf), "{ALSA-MIDI %d} ", API_ALSA); n++;
+#endif
+ strcat(buf, "}");
+ /* then again, if only one API (or none) we don't offer any choice. */
+ if (n < 2)
+ strcpy(buf, "{}");
+
+}
void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,
int *pnmidioutdev, int *pmidioutdev)
{
@@ -486,13 +524,24 @@ static void sys_save_midi_params(
void sys_open_midi(int nmidiindev, int *midiindev,
int nmidioutdev, int *midioutdev, int enable)
{
+#ifdef USEAPI_ALSA
+ midi_alsa_init();
+#endif
#ifdef USEAPI_OSS
midi_oss_init();
#endif
if (enable)
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ sys_alsa_do_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev);
+ else
+#endif /* ALSA */
sys_do_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev);
sys_save_midi_params(nmidiindev, midiindev,
nmidioutdev, midioutdev);
+
+ sys_vgui("set pd_whichmidiapi %d\n", sys_midiapi);
+
}
/* open midi using whatever parameters were last used */
@@ -514,6 +563,12 @@ void sys_listmididevs(void )
char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
int nindevs = 0, noutdevs = 0, i;
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ midi_alsa_getdevs(indevlist, &nindevs, outdevlist, &noutdevs,
+ MAXNDEV, DEVDESCSIZE);
+ else
+#endif /* ALSA */
midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs,
MAXNDEV, DEVDESCSIZE);
@@ -535,6 +590,50 @@ void sys_listmididevs(void )
}
}
+void sys_set_midi_api(int which)
+{
+ sys_midiapi = which;
+ if (sys_verbose)
+ post("sys_midiapi %d", sys_midiapi);
+}
+
+void glob_midi_properties(t_pd *dummy, t_floatarg flongform);
+
+void glob_midi_setapi(void *dummy, t_floatarg f)
+{
+ int newapi = f;
+ if (newapi)
+ {
+ if (newapi == sys_midiapi)
+ {
+ //if (!midi_isopen())
+ // s_reopen_midi();
+ }
+ else
+ {
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ sys_alsa_close_midi();
+ else
+#endif
+ sys_close_midi();
+ sys_midiapi = newapi;
+ /* bash device params back to default */
+ midi_nmidiindev = midi_nmidioutdev = 1;
+ //midi_midiindev[0] = midi_midioutdev[0] = DEFAULTMIDIDEV;
+ //midi_midichindev[0] = midi_midichoutdev[0] = SYS_DEFAULTCH;
+ sys_reopen_midi();
+ }
+
+ glob_midi_properties(0, 0);
+ }
+ else //if (midi_isopen())
+ {
+ sys_close_midi();
+ //midi_state = 0;
+ }
+}
+
extern t_class *glob_pdobject;
/* start an midi settings dialog window */
@@ -589,6 +688,19 @@ void glob_midi_properties(t_pd *dummy, t_floatarg flongform)
midioutdev3 = (noutdev > 2 && midioutdev[2]>=0 ? midioutdev[2]+1 : 0);
midioutdev4 = (noutdev > 3 && midioutdev[3]>=0 ? midioutdev[3]+1 : 0);
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ sprintf(buf,
+"pdtk_alsa_midi_dialog %%s \
+%s %d %d %d %d %s %d %d %d %d \
+%d 1\n",
+ indevliststring,
+ midiindev1, midiindev2, midiindev3, midiindev4,
+ outdevliststring,
+ midioutdev1, midioutdev2, midioutdev3, midioutdev4,
+ (flongform != 0));
+ else
+#endif
sprintf(buf,
"pdtk_midi_dialog %%s \
%s %d %d %d %d %s %d %d %d %d \
@@ -598,6 +710,7 @@ void glob_midi_properties(t_pd *dummy, t_floatarg flongform)
outdevliststring,
midioutdev1, midioutdev2, midioutdev3, midioutdev4,
(flongform != 0));
+
gfxstub_deleteforkey(0);
gfxstub_new(&glob_pdobject, (void *)glob_midi_properties, buf);
}
@@ -609,6 +722,7 @@ void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
int i, nindev, noutdev;
int newmidiindev[4], newmidioutdev[4];
+ int alsadevin, alsadevout;
for (i = 0; i < 4; i++)
{
@@ -632,7 +746,20 @@ void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
noutdev++;
}
}
+ alsadevin = atom_getintarg(8, argc, argv);
+ alsadevout = atom_getintarg(9, argc, argv);
+
+#ifdef USEAPI_ALSA
+ if (sys_midiapi == API_ALSA)
+ {
+ sys_alsa_close_midi();
+ sys_open_midi(alsadevin, newmidiindev, alsadevout, newmidioutdev, 1);
+ }
+ else
+#endif
+ {
+ sys_close_midi();
+ sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev, 1);
+ }
- sys_close_midi();
- sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev, 1);
}
diff --git a/pd/src/s_midi_alsa.c b/pd/src/s_midi_alsa.c
new file mode 100644
index 00000000..437ac792
--- /dev/null
+++ b/pd/src/s_midi_alsa.c
@@ -0,0 +1,233 @@
+/* Copyright (c) 1997-1999 Guenter Geiger, Miller Puckette, Larry Troxler,
+* Winfried Ritsch, Karl MacMillan, and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI I/O for Linux using ALSA */
+
+#include <stdio.h>
+#ifdef UNISTD
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <alsa/asoundlib.h>
+#include "m_pd.h"
+#include "s_stuff.h"
+
+static int alsa_nmidiin;
+static int alsa_midiinfd[MAXMIDIINDEV];
+static int alsa_nmidiout;
+static int alsa_midioutfd[MAXMIDIOUTDEV];
+
+static snd_seq_t *midi_handle;
+
+static snd_midi_event_t *midiev;
+
+
+
+static unsigned short CombineBytes(unsigned char First, unsigned char Second)
+{
+ unsigned short _14bit;
+ _14bit = (unsigned short)Second;
+ _14bit <<= 7;
+ _14bit |= (unsigned short)First;
+ return(_14bit);
+}
+
+void sys_alsa_do_open_midi(int nmidiin, int *midiinvec,
+ int nmidiout, int *midioutvec)
+{
+
+ char portname[50];
+ int err = 0;
+ int client;
+ int i;
+ alsa_nmidiin = 0;
+ alsa_nmidiout = 0;
+
+ if (nmidiin>0 && nmidiout>0)
+ err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0);
+ else if (nmidiin > 0)
+ err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0);
+ else if (nmidiout > 0)
+ err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0);
+
+ if (err!=0)
+ {
+ sys_setalarm(1000000);
+ post("couldn't open alsa sequencer");
+ return;
+ }
+ for (i=0;i<nmidiout;i++)
+ {
+ int port;
+ sprintf(portname,"Pure Data Midi-In %d",i+1);
+ port = snd_seq_create_simple_port(midi_handle,portname,SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE , SND_SEQ_PORT_TYPE_APPLICATION);
+ alsa_midiinfd[i] = port;
+ if (port < 0) goto error;
+ }
+
+ for (i=0;i<nmidiin;i++)
+ {
+ int port;
+ sprintf(portname,"Pure Data Midi-Out %d",i+1);
+ port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_READ, SND_SEQ_PORT_TYPE_APPLICATION);
+ alsa_midioutfd[i] = port;
+ if (port < 0) goto error;
+ }
+
+ if (nmidiout == 0 && nmidiin == 0) return;
+ snd_seq_client_info_t *alsainfo;
+ snd_seq_client_info_malloc(&alsainfo);
+ snd_seq_get_client_info(midi_handle,alsainfo);
+ snd_seq_client_info_set_name(alsainfo,"Pure Data");
+ client = snd_seq_client_info_get_client(alsainfo);
+ snd_seq_set_client_info(midi_handle,alsainfo);
+ snd_seq_client_info_free(alsainfo);
+ post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout);
+ sys_setalarm(0);
+ snd_midi_event_new(20,&midiev);
+ alsa_nmidiout = nmidiout;
+ alsa_nmidiin = nmidiin;
+ return;
+ error:
+ sys_setalarm(1000000);
+ post("couldn't open alsa MIDI output device");
+ return;
+}
+
+#define md_msglen(x) (((x)<0xC0)?2:((x)<0xE0)?1:((x)<0xF0)?2:\
+ ((x)==0xF2)?2:((x)<0xF4)?1:0)
+
+void sys_alsa_putmidimess(int portno, int a, int b, int c)
+{
+ int channel;
+ snd_seq_event_t ev;
+ snd_seq_ev_clear(&ev);
+ if (portno >= 0 && portno < alsa_nmidiout)
+ {
+ if (a >= 224) // pitchbend
+ {
+ channel = a-224;
+ snd_seq_ev_set_pitchbend(&ev,channel,CombineBytes(b,c));
+ }
+ else if (a >= 208) // touch
+ {
+ channel = a-208;
+ snd_seq_ev_set_chanpress(&ev,channel,b);
+ }
+ else if (a >= 192) // program
+ {
+ channel = a-192;
+ snd_seq_ev_set_pgmchange(&ev,channel,b);
+ }
+ else if (a >= 176) // controller
+ {
+ channel = a-176;
+ snd_seq_ev_set_controller(&ev,channel,b,c);
+ }
+ else if (a >= 160) // polytouch
+ {
+ channel = a-160;
+ snd_seq_ev_set_keypress(&ev,channel,b,c);
+ }
+ else if (a >= 144) // note
+ {
+ channel = a-144;
+ if (c)
+ snd_seq_ev_set_noteon(&ev,channel,b,c);
+ else
+ snd_seq_ev_set_noteoff(&ev,channel,b,c);
+ }
+ snd_seq_ev_set_direct(&ev);
+ snd_seq_ev_set_subs(&ev);
+ snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]);
+ snd_seq_event_output_direct(midi_handle,&ev);
+ }
+ //post("%d %d %d\n",a,b,c);
+}
+
+void sys_alsa_putmidibyte(int portno, int byte)
+{
+ snd_seq_event_t ev;
+ snd_seq_ev_clear(&ev);
+ if (portno >= 0 && portno < alsa_nmidiout)
+ {
+ // repack into 1 byte char and put somewhere to point at
+ unsigned char data = (unsigned char)byte;
+ unsigned char *dataptr = malloc(1);
+ memcpy(dataptr,&byte,1);
+
+ snd_seq_ev_set_sysex(&ev,1,dataptr); //...set_variable *should* have worked but didn't
+ snd_seq_ev_set_direct(&ev);
+ snd_seq_ev_set_subs(&ev);
+ snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]);
+ snd_seq_event_output_direct(midi_handle,&ev);
+ }
+}
+
+
+ /* this version uses the asynchronous "read()" ... */
+void sys_alsa_poll_midi(void)
+{
+ char buf[20];
+ int count, alsa_source;
+ int i;
+ snd_seq_event_t *midievent = NULL;
+
+ if (alsa_nmidiout == 0 && alsa_nmidiin == 0) return;
+
+ snd_midi_event_init(midiev);
+
+ if (!alsa_nmidiout && !alsa_nmidiin) return;
+ count = snd_seq_event_input_pending(midi_handle,1);
+ if (count != 0)
+ count = snd_seq_event_input(midi_handle,&midievent);
+ if (midievent != NULL)
+ {
+ count = snd_midi_event_decode(midiev,buf,20,midievent);
+ alsa_source = midievent->dest.port;
+ for(i=0;i<count;i++)
+ sys_midibytein(alsa_source, (buf[i] & 0xff));
+ //post("received %d midi bytes\n",count);
+ }
+}
+
+void sys_alsa_close_midi()
+{
+ alsa_nmidiin = alsa_nmidiout = 0;
+ snd_seq_close(midi_handle);
+ snd_midi_event_free(midiev);
+}
+
+#define NSEARCH 10
+static int alsa_nmidiindevs, alsa_nmidioutdevs, alsa_initted;
+
+void midi_alsa_init(void)
+{
+ int i;
+ if (alsa_initted)
+ return;
+ alsa_initted = 1;
+}
+
+void midi_alsa_getdevs(char *indevlist, int *nindevs,
+ char *outdevlist, int *noutdevs, int maxndev, int devdescsize)
+{
+ int i, ndev;
+ if ((ndev = alsa_nmidiindevs) > maxndev)
+ ndev = maxndev;
+ for (i = 0; i < ndev; i++)
+ sprintf(indevlist + i * devdescsize, "ALSA MIDI device #%d", i+1);
+ *nindevs = ndev;
+
+ if ((ndev = alsa_nmidioutdevs) > maxndev)
+ ndev = maxndev;
+ for (i = 0; i < ndev; i++)
+ sprintf(outdevlist + i * devdescsize, "ALSA MIDI device #%d", i+1);
+ *noutdevs = ndev;
+}
diff --git a/pd/src/s_stuff.h b/pd/src/s_stuff.h
index b03ce4e6..4304f288 100644
--- a/pd/src/s_stuff.h
+++ b/pd/src/s_stuff.h
@@ -95,6 +95,8 @@ void sys_open_midi(int nmidiin, int *midiinvec,
void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,
int *pnmidioutdev, int *pmidioutdev);
+void sys_get_midi_apis(char *buf);
+
void sys_reopen_midi( void);
void sys_close_midi( void);
EXTERN void sys_putmidimess(int portno, int a, int b, int c);
@@ -109,6 +111,22 @@ void midi_getdevs(char *indevlist, int *nindevs,
void sys_do_open_midi(int nmidiindev, int *midiindev,
int nmidioutdev, int *midioutdev);
+#ifdef USEAPI_ALSA
+EXTERN void sys_alsa_putmidimess(int portno, int a, int b, int c);
+EXTERN void sys_alsa_putmidibyte(int portno, int a);
+EXTERN void sys_alsa_poll_midi(void);
+EXTERN void sys_alsa_setmiditimediff(double inbuftime, double outbuftime);
+EXTERN void sys_alsa_midibytein(int portno, int byte);
+EXTERN void sys_alsa_close_midi( void);
+
+
+ /* implemented in the system dependent MIDI code (s_midi_pm.c, etc. ) */
+void midi_alsa_getdevs(char *indevlist, int *nindevs,
+ char *outdevlist, int *noutdevs, int maxndev, int devdescsize);
+void sys_alsa_do_open_midi(int nmidiindev, int *midiindev,
+ int nmidioutdev, int *midioutdev);
+#endif
+
/* m_sched.c */
EXTERN void sys_log_error(int type);
#define ERR_NOTHING 0
@@ -233,6 +251,7 @@ void mmio_getdevs(char *indevlist, int *nindevs,
int maxndev, int devdescsize);
void sys_listmididevs(void);
+void sys_set_midi_api(int whichapi);
void sys_set_audio_api(int whichapi);
void sys_get_audio_apis(char *buf);
extern int sys_audioapi;
diff --git a/pd/src/u_main.tk b/pd/src/u_main.tk
index f6233efa..8da41f7a 100644
--- a/pd/src/u_main.tk
+++ b/pd/src/u_main.tk
@@ -44,6 +44,12 @@ if {$pd_nt == 1} {
if {$pd_nt == 2} {
# turn on James Tittle II's fast drawing (wait until I can test this...):
# set tk::mac::useCGDrawing 1
+ # set minimum line size for anti-aliasing. If set to 1 or 0, then every
+ # line will be anti-aliased. While this makes connections and circles in
+ # [bng] and such look really good, it makes boxes and messages look out of
+ # focus. Setting this to 2 makes it so the thick audio rate connections
+ # are anti-aliased. <hans@at.or.at> 2005-06-09
+ set tk::mac::CGAntialiasLimit 2
global pd_guidir
global pd_tearoff
set pd_gui2 [string range $argv0 0 [expr [string last / $argv0 ] - 1]]
@@ -338,10 +344,10 @@ proc menu_opentext {filename} {
global doc_number
global pd_guidir
global pd_myversion
- global pd_font3
+# global pd_font3
set name [format ".help%d" $doc_number]
toplevel $name
- text $name.text -relief raised -bd 2 -font $pd_font3 \
+ text $name.text -relief raised -bd 2 -font -*-times-regular--normal--14-* \
-yscrollcommand "$name.scroll set" -background white
scrollbar $name.scroll -command "$name.text yview"
pack $name.scroll -side right -fill y
@@ -451,7 +457,7 @@ proc doc_submenu {helpmenu subdir} {
############# routine to add media, help, and apple menu items ###############
proc menu_addstd {mbar} {
- global pd_apilist pd_nt pd_tearoff
+ global pd_apilist pd_midiapilist pd_nt pd_tearoff
# the "Audio" menu
$mbar.audio add command -label {audio ON} -accelerator [accel_munge "Ctrl+/"] \
-command {menu_audio 1}
@@ -463,6 +469,12 @@ proc menu_addstd {mbar} {
-value [lindex [lindex $pd_apilist $x] 1]\
-command {pd [concat pd audio-setapi $pd_whichapi \;]}
}
+ for {set x 0} {$x<[llength $pd_midiapilist]} {incr x} {
+ $mbar.audio add radiobutton -label [lindex [lindex $pd_midiapilist $x] 0] \
+ -command {menu_midi 0} -variable pd_whichmidiapi \
+ -value [lindex [lindex $pd_midiapilist $x] 1]\
+ -command {pd [concat pd midi-setapi $pd_whichmidiapi \;]}
+ }
if {$pd_nt != 2} {
$mbar.audio add command -label {Audio settings...} \
-command {pd pd audio-properties \;}
@@ -3112,7 +3124,7 @@ proc pdtk_data_dialog {name stuff} {
pack $name.buttonframe.ok -side left -expand 1
text $name.text -relief raised -bd 2 -height 40 -width 60 \
- -yscrollcommand "$name.scroll set" -font pd_font3
+ -yscrollcommand "$name.scroll set" -font $pd_font3
scrollbar $name.scroll -command "$name.text yview"
pack $name.scroll -side right -fill y
pack $name.text -side left -fill both -expand 1
@@ -3182,20 +3194,21 @@ proc pdtk_pd_ctrlkey {name key shift} {
# font sizes 8, 10, 12, 14, 16, and 24.
# tb: user defined typefaces
-proc pdtk_pd_startup {version apilist fontname} {
+proc pdtk_pd_startup {version apilist midiapilist fontname} {
# puts stderr [concat $version $apilist $fontname]
- global pd_myversion pd_apilist
+ global pd_myversion pd_apilist pd_midiapilist
set pd_myversion $version
set pd_apilist $apilist
- global pd_font1 pd_font2 pd_font3 pd_font4 pd_font5 pd_font6 pd_font7
+ set pd_midiapilist $midiapilist
+ global pd_font1 pd_font2 pd_font3 pd_font4 pd_font5 pd_font6 pd_font7
- set pd_font1 [format -*-%s-bold--normal--8-* $fontname]
- set pd_font2 [format -*-%s-bold--normal--10-* $fontname]
- set pd_font3 [format -*-%s-bold--normal--12-* $fontname]
- set pd_font4 [format -*-%s-bold--normal--14-* $fontname]
- set pd_font5 [format -*-%s-bold--normal--16-* $fontname]
- set pd_font6 [format -*-%s-bold--normal--24-* $fontname]
- set pd_font7 [format -*-%s-bold--normal--36-* $fontname]
+ set pd_font1 [format -*-%s-bold--normal--8-* $fontname]
+ set pd_font2 [format -*-%s-bold--normal--10-* $fontname]
+ set pd_font3 [format -*-%s-bold--normal--12-* $fontname]
+ set pd_font4 [format -*-%s-bold--normal--14-* $fontname]
+ set pd_font5 [format -*-%s-bold--normal--16-* $fontname]
+ set pd_font6 [format -*-%s-bold--normal--24-* $fontname]
+ set pd_font7 [format -*-%s-bold--normal--36-* $fontname]
set width1 [font measure $pd_font1 x]
set height1 [lindex [font metrics $pd_font1] 5]
@@ -3676,11 +3689,11 @@ proc pdtk_audio_dialog {id indevlist indev1 indev2 indev3 indev4 \
pdtk_standardkeybindings $id.out1f.x2
}
-####################### midi dialog ##################3
+####################### midi dialog ##################
proc midi_apply {id} {
global midi_indev1 midi_indev2 midi_indev3 midi_indev4
- global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4
+ global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4 midi_alsain midi_alsaout
pd [concat pd midi-dialog \
$midi_indev1 \
@@ -3691,6 +3704,8 @@ proc midi_apply {id} {
$midi_outdev2 \
$midi_outdev3 \
$midi_outdev4 \
+ $midi_alsain \
+ $midi_alsaout \
\;]
}
@@ -3727,12 +3742,12 @@ proc midi_popup {name buttonname varname devlist} {
# start a dialog window to select midi devices. "longform" asks us to make
# controls for opening several devices; if not, we get an extra button to
# turn longform on and restart the dialog.
-
proc pdtk_midi_dialog {id indevlist indev1 indev2 indev3 indev4 \
outdevlist outdev1 outdev2 outdev3 outdev4 longform} {
global midi_indev1 midi_indev2 midi_indev3 midi_indev4
global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4
global midi_indevlist midi_outdevlist
+ global midi_alsain midi_alsaout
set midi_indev1 $indev1
set midi_indev2 $indev2
@@ -3744,6 +3759,8 @@ proc pdtk_midi_dialog {id indevlist indev1 indev2 indev3 indev4 \
set midi_outdev4 $outdev4
set midi_indevlist $indevlist
set midi_outdevlist $outdevlist
+ set midi_alsain [llength $indevlist]
+ set midi_alsaout [llength $outdevlist]
toplevel $id
wm title $id {midi}
@@ -3857,6 +3874,148 @@ proc pdtk_midi_dialog {id indevlist indev1 indev2 indev3 indev4 \
}
}
+proc pdtk_alsa_midi_dialog {id indevlist indev1 indev2 indev3 indev4 \
+ outdevlist outdev1 outdev2 outdev3 outdev4 longform alsa} {
+ global midi_indev1 midi_indev2 midi_indev3 midi_indev4
+ global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4
+ global midi_indevlist midi_outdevlist
+ global midi_alsain midi_alsaout
+
+ set midi_indev1 $indev1
+ set midi_indev2 $indev2
+ set midi_indev3 $indev3
+ set midi_indev4 $indev4
+ set midi_outdev1 $outdev1
+ set midi_outdev2 $outdev2
+ set midi_outdev3 $outdev3
+ set midi_outdev4 $outdev4
+ set midi_indevlist $indevlist
+ set midi_outdevlist $outdevlist
+ set midi_alsain [llength $indevlist]
+ set midi_alsaout [llength $outdevlist]
+
+ toplevel $id
+ wm title $id {midi}
+ wm protocol $id WM_DELETE_WINDOW [concat midi_cancel $id]
+
+ frame $id.buttonframe
+ pack $id.buttonframe -side bottom -fill x -pady 2m
+ button $id.buttonframe.cancel -text {Cancel}\
+ -command "midi_cancel $id"
+ button $id.buttonframe.apply -text {Apply}\
+ -command "midi_apply $id"
+ button $id.buttonframe.ok -text {OK}\
+ -command "midi_ok $id"
+ pack $id.buttonframe.cancel -side left -expand 1
+ pack $id.buttonframe.apply -side left -expand 1
+ pack $id.buttonframe.ok -side left -expand 1
+
+ frame $id.in1f
+ pack $id.in1f -side top
+
+ if {$alsa == 0} {
+ # input device 1
+ label $id.in1f.l1 -text "input device 1:"
+ button $id.in1f.x1 -text [lindex $indevlist $midi_indev1] \
+ -command [list midi_popup $id $id.in1f.x1 midi_indev1 $indevlist]
+ pack $id.in1f.l1 $id.in1f.x1 -side left
+
+ # input device 2
+ if {$longform && [llength $indevlist] > 2} {
+ frame $id.in2f
+ pack $id.in2f -side top
+
+ label $id.in2f.l1 -text "input device 2:"
+ button $id.in2f.x1 -text [lindex $indevlist $midi_indev2] \
+ -command [list midi_popup $id $id.in2f.x1 midi_indev2 $indevlist]
+ pack $id.in2f.l1 $id.in2f.x1 -side left
+ }
+
+ # input device 3
+ if {$longform && [llength $indevlist] > 3} {
+ frame $id.in3f
+ pack $id.in3f -side top
+
+ label $id.in3f.l1 -text "input device 3:"
+ button $id.in3f.x1 -text [lindex $indevlist $midi_indev3] \
+ -command [list midi_popup $id $id.in3f.x1 midi_indev3 $indevlist]
+ pack $id.in3f.l1 $id.in3f.x1 -side left
+ }
+
+ # input device 4
+ if {$longform && [llength $indevlist] > 4} {
+ frame $id.in4f
+ pack $id.in4f -side top
+
+ label $id.in4f.l1 -text "input device 4:"
+ button $id.in4f.x1 -text [lindex $indevlist $midi_indev4] \
+ -command [list midi_popup $id $id.in4f.x1 midi_indev4 $indevlist]
+ pack $id.in4f.l1 $id.in4f.x1 -side left
+ }
+
+ # output device 1
+
+ frame $id.out1f
+ pack $id.out1f -side top
+ label $id.out1f.l1 -text "output device 1:"
+ button $id.out1f.x1 -text [lindex $outdevlist $midi_outdev1] \
+ -command [list midi_popup $id $id.out1f.x1 midi_outdev1 $outdevlist]
+ pack $id.out1f.l1 $id.out1f.x1 -side left
+
+ # output device 2
+ if {$longform && [llength $indevlist] > 2} {
+ frame $id.out2f
+ pack $id.out2f -side top
+ label $id.out2f.l1 -text "output device 2:"
+ button $id.out2f.x1 -text [lindex $outdevlist $midi_outdev2] \
+ -command \
+ [list midi_popup $id $id.out2f.x1 midi_outdev2 $outdevlist]
+ pack $id.out2f.l1 $id.out2f.x1 -side left
+ }
+
+ # output device 3
+ if {$longform && [llength $indevlist] > 3} {
+ frame $id.out3f
+ pack $id.out3f -side top
+ label $id.out3f.l1 -text "output device 3:"
+ button $id.out3f.x1 -text [lindex $outdevlist $midi_outdev3] \
+ -command \
+ [list midi_popup $id $id.out3f.x1 midi_outdev3 $outdevlist]
+ pack $id.out3f.l1 $id.out3f.x1 -side left
+ }
+
+ # output device 4
+ if {$longform && [llength $indevlist] > 4} {
+ frame $id.out4f
+ pack $id.out4f -side top
+ label $id.out4f.l1 -text "output device 4:"
+ button $id.out4f.x1 -text [lindex $outdevlist $midi_outdev4] \
+ -command \
+ [list midi_popup $id $id.out4f.x1 midi_outdev4 $outdevlist]
+ pack $id.out4f.l1 $id.out4f.x1 -side left
+ }
+
+ # if not the "long form" make a button to
+ # restart with longform set.
+
+ if {$longform == 0} {
+ frame $id.longbutton
+ pack $id.longbutton -side top
+ button $id.longbutton.b -text {use multiple alsa devices} \
+ -command {pd pd midi-properties 1 \;}
+ pack $id.longbutton.b
+ }
+ }
+ if {$alsa} {
+ label $id.in1f.l1 -text "In Channels:"
+ entry $id.in1f.x1 -textvariable midi_alsain -width 4
+ pack $id.in1f.l1 $id.in1f.x1 -side left
+ label $id.in1f.l2 -text "Out Channels:"
+ entry $id.in1f.x2 -textvariable midi_alsaout -width 4
+ pack $id.in1f.l2 $id.in1f.x2 -side left
+ }
+}
+
############ pdtk_path_dialog -- dialog window for search path #########
proc path_apply {id} {
diff --git a/pd/src/u_pdsend.c b/pd/src/u_pdsend.c
index 7b464cad..663889cc 100644
--- a/pd/src/u_pdsend.c
+++ b/pd/src/u_pdsend.c
@@ -105,7 +105,8 @@ connected: ;
/* now loop reading stdin and sending it to socket */
while (1)
{
- char buf[BUFSIZE], *bp, nsent, nsend;
+ char buf[BUFSIZE], *bp;
+ int nsent, nsend;
if (!fgets(buf, BUFSIZE, stdin))
break;
nsend = strlen(buf);
diff --git a/pd/src/x_connective.c b/pd/src/x_connective.c
index 3d62b319..ad6219cd 100644
--- a/pd/src/x_connective.c
+++ b/pd/src/x_connective.c
@@ -505,7 +505,11 @@ static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv)
if (x->x_type == A_FLOAT)
{
float f;
- if (!argc) return;
+ if (!argc) /* empty lists go out reject outlet */
+ {
+ outlet_bang(x->x_rejectout);
+ return;
+ }
f = atom_getfloat(argv);
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
if (e->e_w.w_float == f)
@@ -580,7 +584,8 @@ static void *route_new(t_symbol *s, int argc, t_atom *argv)
{
int n;
t_routeelement *e;
- t_route *x = (t_route *)pd_new(route_class);
+ t_route *x;
+
t_atom a;
if (argc == 0)
{
@@ -588,6 +593,13 @@ static void *route_new(t_symbol *s, int argc, t_atom *argv)
SETFLOAT(&a, 0);
argv = &a;
}
+ for (n = 1; n < argc; n++)
+ if (argv[n].a_type != argv[0].a_type)
+ {
+ error("route: creation with mixed argument types failed");
+ return (0);
+ }
+ x = (t_route *)pd_new(route_class);
x->x_type = argv[0].a_type;
x->x_nelement = argc;
x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec));