~alpine/aports

[alpine-aports] [PATCH] testing/portmidi: new aport

Details
Message ID
<20180221163334.17140-1-taner76@gmail.com>
Sender timestamp
1519230814
DKIM signature
missing
Download raw message
Patch: +1617 -0
http://portmedia.sourceforge.net/
PortMidi is a platform independent library for MIDI input/output.
---
 testing/portmidi/00_cmake.patch            |   33 +
 testing/portmidi/01_pmlinux.patch          |   17 +
 testing/portmidi/02_pmlinuxalsa.patch      |   33 +
 testing/portmidi/03_pm_test_Makefile.patch |   39 ++
 testing/portmidi/11-pmlinuxalsa.patch      |   70 ++
 testing/portmidi/13-disablejni.patch       |   86 +++
 testing/portmidi/20-movetest.patch         | 1001 ++++++++++++++++++++++++++++
 testing/portmidi/21-hardentests.patch      |   93 +++
 testing/portmidi/30-porttime_cmake.patch   |   32 +
 testing/portmidi/40-test_sysex.patch       |   19 +
 testing/portmidi/41-pm_linux.patch         |   77 +++
 testing/portmidi/50-change_assert.patch    |   41 ++
 testing/portmidi/51-remove_assert.patch    |   13 +
 testing/portmidi/APKBUILD                  |   63 ++
 14 files changed, 1617 insertions(+)
 create mode 100644 testing/portmidi/00_cmake.patch
 create mode 100644 testing/portmidi/01_pmlinux.patch
 create mode 100644 testing/portmidi/02_pmlinuxalsa.patch
 create mode 100644 testing/portmidi/03_pm_test_Makefile.patch
 create mode 100644 testing/portmidi/11-pmlinuxalsa.patch
 create mode 100644 testing/portmidi/13-disablejni.patch
 create mode 100644 testing/portmidi/20-movetest.patch
 create mode 100644 testing/portmidi/21-hardentests.patch
 create mode 100644 testing/portmidi/30-porttime_cmake.patch
 create mode 100644 testing/portmidi/40-test_sysex.patch
 create mode 100644 testing/portmidi/41-pm_linux.patch
 create mode 100644 testing/portmidi/50-change_assert.patch
 create mode 100644 testing/portmidi/51-remove_assert.patch
 create mode 100644 testing/portmidi/APKBUILD

diff --git a/testing/portmidi/00_cmake.patch b/testing/portmidi/00_cmake.patch
new file mode 100644
index 000000000..af8062c0e
--- /dev/null
+++ b/testing/portmidi/00_cmake.patch
@@ -0,0 +1,33 @@
--- a/pm_dylib/CMakeLists.txt
+++ b/pm_dylib/CMakeLists.txt
@@ -115,13 +115,14 @@
 
 add_library(portmidi-dynamic SHARED ${LIBSRC})
 set_target_properties(portmidi-dynamic PROPERTIES OUTPUT_NAME "portmidi")
+set_target_properties(portmidi-dynamic PROPERTIES VERSION "0.0.0" SOVERSION "0")
 target_link_libraries(portmidi-dynamic ${PM_NEEDED_LIBS})
 
 # install the libraries (Linux and Mac OS X command line)
 if(UNIX)
   INSTALL(TARGETS portmidi-dynamic
-    LIBRARY DESTINATION /usr/local/lib
-    ARCHIVE DESTINATION /usr/local/lib)
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
   INSTALL(FILES ../pm_common/portmidi.h ../porttime/porttime.h
-    DESTINATION /usr/local/include)
+    DESTINATION include)
 endif(UNIX)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4919b78..4067a5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,8 @@
 
 cmake_minimum_required(VERSION 2.6)
 
+include(GNUInstallDirs)
+
 if(UNIX)
   # allow user to set Release or Debug
   set(CMAKE_BUILD_TYPE Release CACHE STRING 
diff --git a/testing/portmidi/01_pmlinux.patch b/testing/portmidi/01_pmlinux.patch
new file mode 100644
index 000000000..e37be1af9
--- /dev/null
+++ b/testing/portmidi/01_pmlinux.patch
@@ -0,0 +1,17 @@
Index: portmidi-200/pm_linux/pmlinux.c
===================================================================
--- portmidi-200.orig/pm_linux/pmlinux.c	2010-02-14 17:35:40.000000000 -0500
+++ portmidi-200/pm_linux/pmlinux.c	2010-02-14 17:36:17.000000000 -0500
@@ -34,10 +34,10 @@
      * devices.
      */
     #ifdef PMALSA
-	pm_linuxalsa_init();
+	return pm_linuxalsa_init();
     #endif
     #ifdef PMNULL
-        pm_linuxnull_init();
+        return pm_linuxnull_init();
     #endif
     // this is set when we return to Pm_Initialize, but we need it
     // now in order to (successfully) call Pm_CountDevices()
diff --git a/testing/portmidi/02_pmlinuxalsa.patch b/testing/portmidi/02_pmlinuxalsa.patch
new file mode 100644
index 000000000..246447518
--- /dev/null
+++ b/testing/portmidi/02_pmlinuxalsa.patch
@@ -0,0 +1,33 @@
--- portmidi~/pm_linux/pmlinuxalsa.c	2009-09-16 05:41:04.000000000 +0200
+++ portmidi/pm_linux/pmlinuxalsa.c	2009-09-16 05:45:29.000000000 +0200
@@ -242,8 +242,8 @@
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
     if (!desc) return pmBadPtr;
 
-    if (pm_hosterror = snd_seq_disconnect_to(seq, desc->this_port, 
-                                             desc->client, desc->port)) {
+    if ((pm_hosterror = snd_seq_disconnect_to(seq, desc->this_port, 
+                                             desc->client, desc->port))) {
         // if there's an error, try to delete the port anyway, but don't
         // change the pm_hosterror value so we retain the first error
         snd_seq_delete_port(seq, desc->this_port);
@@ -332,8 +332,8 @@
 {
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
     if (!desc) return pmBadPtr;
-    if (pm_hosterror = snd_seq_disconnect_from(seq, desc->this_port, 
-                                               desc->client, desc->port)) {
+    if ((pm_hosterror = snd_seq_disconnect_from(seq, desc->this_port, 
+                                               desc->client, desc->port))) {
         snd_seq_delete_port(seq, desc->this_port); /* try to close port */
     } else {
         pm_hosterror = snd_seq_delete_port(seq, desc->this_port);
@@ -606,7 +606,7 @@
     case SND_SEQ_EVENT_SYSEX: {
         const BYTE *ptr = (const BYTE *) ev->data.ext.ptr;
         /* assume there is one sysex byte to process */
-        pm_read_bytes(midi, ptr, ev->data.ext.len, timestamp);
+        pm_read_bytes(midi, (unsigned char*)ptr, ev->data.ext.len, timestamp);
         break;
     }
     }
diff --git a/testing/portmidi/03_pm_test_Makefile.patch b/testing/portmidi/03_pm_test_Makefile.patch
new file mode 100644
index 000000000..b1a2c380b
--- /dev/null
+++ b/testing/portmidi/03_pm_test_Makefile.patch
@@ -0,0 +1,39 @@
--- portmidi-20041117.orig/pm_test/debian/Makefile
+++ portmidi-20041117/pm_test/debian/Makefile
@@ -0,0 +1,36 @@
+# For debugging, define PM_CHECK_ERRORS
+PMFLAGS = -DPM_CHECK_ERRORS
+# Use this for linux alsa (0.9x) version
+ALSALIB = -lasound
+pmlib = -lportmidi
+ptlib = -lporttime
+VFLAGS = -DPMALSA
+
+CC = gcc $(CFLAGS) $(VFLAGS) $(PMFLAGS) -g
+
+all: simple_test sysex midithread latency midithru mm
+
+simple_test: simple_test.o
+	$(CC) simple_test.c -o simple_test $(pmlib) $(ptlib) $(ALSALIB)
+
+sysex: sysex.o
+	$(CC) sysex.c -o sysex $(pmlib) $(ptlib) $(ALSALIB)
+
+midithread: midithread.o
+	$(CC) midithread.c -o midithread \
+		$(pmlib) $(ptlib) $(ALSALIB)
+
+latency: latency.o
+	$(CC) latency.c -o latency $(pmlib) $(ptlib) \
+		$(ALSALIB) -lpthread -lm
+
+midithru: midithru.o
+	$(CC) midithru.c -o midithru $(pmlib) $(ptlib) \
+		$(ALSALIB) -lpthread -lm
+
+mm: mm.o
+	$(CC) mm.c -o mm $(pmlib) $(ptlib) \
+		$(ALSALIB) -lpthread -lm
+
+clean:
+	rm -f *.o mm midithru latency midithread sysex simple_test
diff --git a/testing/portmidi/11-pmlinuxalsa.patch b/testing/portmidi/11-pmlinuxalsa.patch
new file mode 100644
index 000000000..eb98a79df
--- /dev/null
+++ b/testing/portmidi/11-pmlinuxalsa.patch
@@ -0,0 +1,70 @@
Subject: Prevent SIGSEGV on handling events for already closed devices.
Bug: http://sourceforge.net/apps/trac/portmedia/ticket/3
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=695842
Bug-Ubuntu: https://launchpad.net/bugs/1073484
Applied-Upstream: yes
---
 pm_linux/pmlinuxalsa.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- portmidi-200.orig/pm_linux/pmlinuxalsa.c
+++ portmidi-200/pm_linux/pmlinuxalsa.c
@@ -193,6 +193,7 @@ static PmError alsa_write_byte(PmInterna
     snd_seq_event_t ev;
     int err;
 
+    if (!desc) return pmBadPtr;
     snd_seq_ev_clear(&ev);
     if (snd_midi_event_encode_byte(desc->parser, byte, &ev) == 1) {
         snd_seq_ev_set_dest(&ev, desc->client, desc->port);
@@ -339,6 +340,7 @@ static PmError alsa_in_close(PmInternal
         pm_hosterror = snd_seq_delete_port(seq, desc->this_port);
     }
     alsa_unuse_queue();
+    midi->descriptor = NULL;
     pm_free(desc);
     if (pm_hosterror) {
         get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, 
@@ -433,6 +435,7 @@ static PmError alsa_write(PmInternal *mi
 static PmError alsa_write_flush(PmInternal *midi, PmTimestamp timestamp)
 {
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
+    if (!desc) return pmBadPtr;
     VERBOSE printf("snd_seq_drain_output: 0x%x\n", (unsigned int) seq);
     desc->error = snd_seq_drain_output(seq);
     if (desc->error < 0) return pmHostError;
@@ -448,6 +451,7 @@ static PmError alsa_write_short(PmIntern
     PmMessage msg = event->message;
     int i;
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
+    if (!desc) return pmBadPtr;
     for (i = 0; i < bytes; i++) {
         unsigned char byte = msg;
         VERBOSE printf("sending 0x%x\n", byte);
@@ -481,6 +485,10 @@ static void handle_event(snd_seq_event_t
 {
     int device_id = ev->dest.port;
     PmInternal *midi = descriptors[device_id].internalDescriptor;
+    /* The device we received events for might have been closed before we
+       processed them. */
+    if (!midi)
+        return;
     PmEvent pm_ev;
     PmTimeProcPtr time_proc = midi->time_proc;
     PmTimestamp timestamp;
@@ -650,6 +658,7 @@ static PmError alsa_poll(PmInternal *mid
 static unsigned int alsa_has_host_error(PmInternal *midi)
 {
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
+    if (!desc) return 0;
     return desc->error;
 }
 
@@ -657,6 +666,7 @@ static unsigned int alsa_has_host_error(
 static void alsa_get_host_error(PmInternal *midi, char *msg, unsigned int len)
 {
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
+    if (!desc) return;
     int err = (pm_hosterror || desc->error);
     get_alsa_error_text(msg, len, err);
 }
diff --git a/testing/portmidi/13-disablejni.patch b/testing/portmidi/13-disablejni.patch
new file mode 100644
index 000000000..cddabe14e
--- /dev/null
+++ b/testing/portmidi/13-disablejni.patch
@@ -0,0 +1,86 @@
diff --git a/pm_java/CMakeLists.txt b/pm_java/CMakeLists.txt
index a350620..b491bbd 100644
--- a/pm_java/CMakeLists.txt
+++ b/pm_java/CMakeLists.txt
@@ -1,6 +1,7 @@
 # pm_java
 
 if(UNIX)
+else (UNIX)
   if(APPLE)
     # java not dealt with in CMake -- see pm_mac/pm_mac.xcodeproj
   else(APPLE)
diff --git a/pm_common/CMakeLists.txt b/pm_common/CMakeLists.txt
index e171047..68ac212 100644
--- a/pm_common/CMakeLists.txt
+++ b/pm_common/CMakeLists.txt
@@ -66,19 +66,19 @@ if(UNIX)
     set(JAVA_INCLUDE_PATHS ${JAVAVM_LIB}/Headers)
     message(STATUS "SYSROOT: " ${CMAKE_OSX_SYSROOT})
   else(APPLE)
-    # LINUX settings...
-    include(FindJNI)
-    message(STATUS "JAVA_JVM_LIB_PATH is " ${JAVA_JVM_LIB_PATH})
-    message(STATUS "JAVA_INCLUDE_PATH is " ${JAVA_INCLUDE_PATH})
-    message(STATUS "JAVA_INCLUDE_PATH2 is " ${JAVA_INCLUDE_PATH2})
-    message(STATUS "JAVA_JVM_LIBRARY is " ${JAVA_JVM_LIBRARY})
-    set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
-    # libjvm.so is found relative to JAVA_INCLUDE_PATH:
-    set(JAVAVM_LIB ${JAVA_JVM_LIBRARY}/libjvm.so)
+#    # LINUX settings...
+#    include(FindJNI)
+#    message(STATUS "JAVA_JVM_LIB_PATH is " ${JAVA_JVM_LIB_PATH})
+#    message(STATUS "JAVA_INCLUDE_PATH is " ${JAVA_INCLUDE_PATH})
+#    message(STATUS "JAVA_INCLUDE_PATH2 is " ${JAVA_INCLUDE_PATH2})
+#    message(STATUS "JAVA_JVM_LIBRARY is " ${JAVA_JVM_LIBRARY})
+#    set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
+#    # libjvm.so is found relative to JAVA_INCLUDE_PATH:
+#    set(JAVAVM_LIB ${JAVA_JVM_LIBRARY}/libjvm.so)

     set(LINUXSRC pmlinuxalsa pmlinux finddefault)
     prepend_path(LIBSRC ../pm_linux/ ${LINUXSRC})
-    list(APPEND LIBSRC ../porttime/ptlinux)
+    #list(APPEND LIBSRC ../porttime/ptlinux)

     set(PM_NEEDED_LIBS pthread asound)
   endif(APPLE)
@@ -104,24 +104,24 @@ set(JNI_EXTRA_LIBS ${PM_NEEDED_LIBS} ${JAVA_JVM_LIBRARY})
 # this completes the list of library sources by adding shared code
 list(APPEND LIBSRC pmutil portmidi)

-# now add the shared files to make the complete list of library sources
-add_library(portmidi-static ${LIBSRC})
-set_target_properties(portmidi-static PROPERTIES OUTPUT_NAME "portmidi_s")
+## now add the shared files to make the complete list of library sources
+add_library(portmidi-static STATIC ${LIBSRC})
+set_target_properties(portmidi-static PROPERTIES OUTPUT_NAME "portmidi")
 target_link_libraries(portmidi-static ${PM_NEEDED_LIBS})
-
-# define the jni library
-include_directories(${JAVA_INCLUDE_PATHS})
-
-set(JNISRC ${LIBSRC} ../pm_java/pmjni/pmjni.c)
-add_library(pmjni SHARED ${JNISRC})
-target_link_libraries(pmjni ${JNI_EXTRA_LIBS})
-set_target_properties(pmjni PROPERTIES EXECUTABLE_EXTENSION "jnilib")
-
+#
+## define the jni library
+#include_directories(${JAVA_INCLUDE_PATHS})
+#
+#set(JNISRC ${LIBSRC} ../pm_java/pmjni/pmjni.c)
+#add_library(pmjni SHARED ${JNISRC})
+#target_link_libraries(pmjni ${JNI_EXTRA_LIBS})
+#set_target_properties(pmjni PROPERTIES EXECUTABLE_EXTENSION "jnilib")
+#
 # install the libraries (Linux and Mac OS X command line)
 if(UNIX)
-  INSTALL(TARGETS portmidi-static pmjni
-    LIBRARY DESTINATION /usr/local/lib
-    ARCHIVE DESTINATION /usr/local/lib)
+  INSTALL(TARGETS portmidi-static
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 # .h files installed by pm_dylib/CMakeLists.txt, so don't need them here
 #  INSTALL(FILES portmidi.h ../porttime/porttime.h
 #    DESTINATION /usr/local/include)
diff --git a/testing/portmidi/20-movetest.patch b/testing/portmidi/20-movetest.patch
new file mode 100644
index 000000000..69d65b261
--- /dev/null
+++ b/testing/portmidi/20-movetest.patch
@@ -0,0 +1,1001 @@
--- a/pm_test/CMakeLists.txt
+++ b/pm_test/CMakeLists.txt
@@ -12,11 +12,11 @@
 
 macro(make_a_test name)
   add_executable(${name} ${name}.c)
-  target_link_libraries(${name} portmidi-static ${PM_NEEDED_LIBS})
-  add_dependencies(${name} portmidi-static)
+  target_link_libraries(${name} portmidi-dynamic ${PM_NEEDED_LIBS})
+  add_dependencies(${name} portmidi-dynamic)
 endmacro(make_a_test)
 
-make_a_test(test)
+make_a_test(simple_test)
 make_a_test(midithread)
 make_a_test(midithru)
 make_a_test(sysex)
--- /dev/null
+++ b/pm_test/simple_test.c
@@ -0,0 +1,489 @@
+#include "portmidi.h"
+#include "porttime.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "string.h"
+#include "assert.h"
+
+#define INPUT_BUFFER_SIZE 100
+#define OUTPUT_BUFFER_SIZE 0
+#define DRIVER_INFO NULL
+#define TIME_PROC ((int32_t (*)(void *)) Pt_Time)
+#define TIME_INFO NULL
+#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
+
+#define STRING_MAX 80 /* used for console input */
+
+int32_t latency = 0;
+
+/* crash the program to test whether midi ports are closed */
+/**/
+void doSomethingReallyStupid() {
+	int * tmp = NULL;
+	*tmp = 5;
+}
+
+
+/* exit the program without any explicit cleanup */
+/**/
+void doSomethingStupid() {
+	assert(0);
+}
+
+
+/* read a number from console */
+/**/
+int get_number(char *prompt)
+{
+    char line[STRING_MAX];
+    int n = 0, i;
+    printf("%s\n", prompt);
+    while (n != 1) {
+        n = scanf("%d", &i);
+        fgets(line, STRING_MAX, stdin);
+
+    }
+    return i;
+}
+
+
+/*
+ * the somethingStupid parameter can be set to simulate a program crash.
+ * We want PortMidi to close Midi ports automatically in the event of a
+ * crash because Windows does not (and this may cause an OS crash)
+ */
+void main_test_input(unsigned int somethingStupid) {
+    PmStream * midi;
+    PmError status, length;
+    PmEvent buffer[1];
+    int num = 10;
+    int i = get_number("Type input number: ");
+    /* It is recommended to start timer before Midi; otherwise, PortMidi may
+       start the timer with its (default) parameters
+     */
+    TIME_START;
+
+    /* open input device */
+    Pm_OpenInput(&midi, 
+                 i,
+                 DRIVER_INFO, 
+                 INPUT_BUFFER_SIZE, 
+                 TIME_PROC, 
+                 TIME_INFO);
+
+    printf("Midi Input opened. Reading %d Midi messages...\n", num);
+    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
+    /* empty the buffer after setting filter, just in case anything
+       got through */
+    while (Pm_Poll(midi)) {
+        Pm_Read(midi, buffer, 1);
+    }
+    /* now start paying attention to messages */
+    i = 0; /* count messages as they arrive */
+    while (i < num) {
+        status = Pm_Poll(midi);
+        if (status == TRUE) {
+            length = Pm_Read(midi,buffer, 1);
+            if (length > 0) {
+                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
+                       i,
+                       (long) buffer[0].timestamp,
+                       (long) Pm_MessageStatus(buffer[0].message),
+                       (long) Pm_MessageData1(buffer[0].message),
+                       (long) Pm_MessageData2(buffer[0].message));
+                i++;
+            } else {
+                assert(0);
+            }
+        }
+        /* simulate crash if somethingStupid is 1 or 2 */
+        if ((i > (num/2)) && (somethingStupid == 1)) {
+            doSomethingStupid();
+        } else if ((i > (num/2)) && (somethingStupid == 2)) {
+            doSomethingReallyStupid();
+        }
+    }
+
+    /* close device (this not explicitly needed in most implementations) */
+    printf("ready to close...");
+
+    Pm_Close(midi);
+    printf("done closing...");
+}
+
+
+
+void main_test_output() {
+    PmStream * midi;
+	char line[80];
+    int32_t off_time;
+    int chord[] = { 60, 67, 76, 83, 90 };
+    #define chord_size 5 
+    PmEvent buffer[chord_size];
+    PmTimestamp timestamp;
+
+    /* determine which output device to use */
+    int i = get_number("Type output number: ");
+
+    /* It is recommended to start timer before PortMidi */
+    TIME_START;
+
+    /* open output device -- since PortMidi avoids opening a timer
+       when latency is zero, we will pass in a NULL timer pointer
+       for that case. If PortMidi tries to access the time_proc,
+       we will crash, so this test will tell us something. */
+    Pm_OpenOutput(&midi, 
+                  i, 
+                  DRIVER_INFO,
+                  OUTPUT_BUFFER_SIZE, 
+                  (latency == 0 ? NULL : TIME_PROC),
+                  (latency == 0 ? NULL : TIME_INFO), 
+                  latency);
+    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
+
+    /* output note on/off w/latency offset; hold until user prompts */
+    printf("ready to send program 1 change... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+    /* if we were writing midi for immediate output, we could always use
+       timestamps of zero, but since we may be writing with latency, we
+       will explicitly set the timestamp to "now" by getting the time.
+       The source of timestamps should always correspond to the TIME_PROC
+       and TIME_INFO parameters used in Pm_OpenOutput(). */
+    buffer[0].timestamp = TIME_PROC(TIME_INFO);
+    /* Send a program change to increase the chances we will hear notes */
+    /* Program 0 is usually a piano, but you can change it here: */
+#define PROGRAM 0
+    buffer[0].message = Pm_Message(0xC0, PROGRAM, 0);
+    Pm_Write(midi, buffer, 1);
+
+    printf("ready to note-on... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+    buffer[0].timestamp = TIME_PROC(TIME_INFO);
+    buffer[0].message = Pm_Message(0x90, 60, 100);
+    Pm_Write(midi, buffer, 1);
+    printf("ready to note-off... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+    buffer[0].timestamp = TIME_PROC(TIME_INFO);
+    buffer[0].message = Pm_Message(0x90, 60, 0);
+    Pm_Write(midi, buffer, 1);
+
+    /* output short note on/off w/latency offset; hold until user prompts */
+    printf("ready to note-on (short form)... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
+                  Pm_Message(0x90, 60, 100));
+    printf("ready to note-off (short form)... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
+                  Pm_Message(0x90, 60, 0));
+
+    /* output several note on/offs to test timing. 
+       Should be 1s between notes */
+    printf("chord will arpeggiate if latency > 0\n");
+    printf("ready to chord-on/chord-off... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+    timestamp = TIME_PROC(TIME_INFO);
+    for (i = 0; i < chord_size; i++) {
+        buffer[i].timestamp = timestamp + 1000 * i;
+        buffer[i].message = Pm_Message(0x90, chord[i], 100);
+    }
+    Pm_Write(midi, buffer, chord_size);
+
+    off_time = timestamp + 1000 + chord_size * 1000; 
+    while (TIME_PROC(TIME_INFO) < off_time) 
+		/* busy wait */;
+    for (i = 0; i < chord_size; i++) {
+        buffer[i].timestamp = timestamp + 1000 * i;
+        buffer[i].message = Pm_Message(0x90, chord[i], 0);
+    }
+    Pm_Write(midi, buffer, chord_size);    
+
+    /* close device (this not explicitly needed in most implementations) */
+    printf("ready to close and terminate... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+	
+    Pm_Close(midi);
+    Pm_Terminate();
+    printf("done closing and terminating...\n");
+}
+
+
+void main_test_both()
+{
+    int i = 0;
+    int in, out;
+    PmStream * midi, * midiOut;
+    PmEvent buffer[1];
+    PmError status, length;
+    int num = 10;
+    
+    in = get_number("Type input number: ");
+    out = get_number("Type output number: ");
+
+    /* In is recommended to start timer before PortMidi */
+    TIME_START;
+
+    Pm_OpenOutput(&midiOut, 
+                  out, 
+                  DRIVER_INFO,
+                  OUTPUT_BUFFER_SIZE, 
+                  TIME_PROC,
+                  TIME_INFO, 
+                  latency);
+    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
+    /* open input device */
+    Pm_OpenInput(&midi, 
+                 in,
+                 DRIVER_INFO, 
+                 INPUT_BUFFER_SIZE, 
+                 TIME_PROC, 
+                 TIME_INFO);
+    printf("Midi Input opened. Reading %d Midi messages...\n",num);
+    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
+    /* empty the buffer after setting filter, just in case anything
+       got through */
+    while (Pm_Poll(midi)) {
+        Pm_Read(midi, buffer, 1);
+    }
+    i = 0;
+    while (i < num) {
+        status = Pm_Poll(midi);
+        if (status == TRUE) {
+            length = Pm_Read(midi,buffer,1);
+            if (length > 0) {
+                Pm_Write(midiOut, buffer, 1);
+                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
+                       i,
+                       (long) buffer[0].timestamp,
+                       (long) Pm_MessageStatus(buffer[0].message),
+                       (long) Pm_MessageData1(buffer[0].message),
+                       (long) Pm_MessageData2(buffer[0].message));
+                i++;
+            } else {
+                assert(0);
+            }
+        }
+    }
+
+    /* close midi devices */
+    Pm_Close(midi);
+    Pm_Close(midiOut);
+    Pm_Terminate(); 
+}
+
+
+/* main_test_stream exercises windows winmm API's stream mode */
+/*    The winmm stream mode is used for latency>0, and sends
+   timestamped messages. The timestamps are relative (delta) 
+   times, whereas PortMidi times are absolute. Since peculiar
+   things happen when messages are not always sent in advance,
+   this function allows us to exercise the system and test it.
+ */
+void main_test_stream() {
+    PmStream * midi;
+	char line[80];
+    PmEvent buffer[16];
+
+	/* determine which output device to use */
+    int i = get_number("Type output number: ");
+
+	latency = 500; /* ignore LATENCY for this test and
+				      fix the latency at 500ms */
+
+    /* It is recommended to start timer before PortMidi */
+    TIME_START;
+
+	/* open output device */
+    Pm_OpenOutput(&midi, 
+                  i, 
+                  DRIVER_INFO,
+                  OUTPUT_BUFFER_SIZE, 
+                  TIME_PROC,
+                  TIME_INFO, 
+                  latency);
+    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
+
+    /* output note on/off w/latency offset; hold until user prompts */
+    printf("ready to send output... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+
+    /* if we were writing midi for immediate output, we could always use
+       timestamps of zero, but since we may be writing with latency, we
+       will explicitly set the timestamp to "now" by getting the time.
+       The source of timestamps should always correspond to the TIME_PROC
+       and TIME_INFO parameters used in Pm_OpenOutput(). */
+    buffer[0].timestamp = TIME_PROC(TIME_INFO);
+    buffer[0].message = Pm_Message(0xC0, 0, 0);
+	buffer[1].timestamp = buffer[0].timestamp;
+	buffer[1].message = Pm_Message(0x90, 60, 100);
+	buffer[2].timestamp = buffer[0].timestamp + 1000;
+	buffer[2].message = Pm_Message(0x90, 62, 100);
+	buffer[3].timestamp = buffer[0].timestamp + 2000;
+	buffer[3].message = Pm_Message(0x90, 64, 100);
+	buffer[4].timestamp = buffer[0].timestamp + 3000;
+	buffer[4].message = Pm_Message(0x90, 66, 100);
+	buffer[5].timestamp = buffer[0].timestamp + 4000;
+	buffer[5].message = Pm_Message(0x90, 60, 0);
+	buffer[6].timestamp = buffer[0].timestamp + 4000;
+	buffer[6].message = Pm_Message(0x90, 62, 0);
+	buffer[7].timestamp = buffer[0].timestamp + 4000;
+	buffer[7].message = Pm_Message(0x90, 64, 0);
+	buffer[8].timestamp = buffer[0].timestamp + 4000;
+	buffer[8].message = Pm_Message(0x90, 66, 0);
+
+    Pm_Write(midi, buffer, 9);
+#ifdef SEND8
+	/* Now, we're ready for the real test.
+	   Play 4 notes at now, now+500, now+1000, and now+1500
+	   Then wait until now+2000.
+	   Play 4 more notes as before.
+	   We should hear 8 evenly spaced notes. */
+	now = TIME_PROC(TIME_INFO);
+	for (i = 0; i < 4; i++) {
+		buffer[i * 2].timestamp = now + (i * 500);
+		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
+		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
+		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
+	}
+    Pm_Write(midi, buffer, 8);
+
+    while (Pt_Time() < now + 2500) 
+		/* busy wait */;
+	/* now we are 500 ms behind schedule, but since the latency
+	   is 500, the delay should not be audible */
+	now += 2000;
+	for (i = 0; i < 4; i++) {
+		buffer[i * 2].timestamp = now + (i * 500);
+		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
+		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
+		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
+	}
+    Pm_Write(midi, buffer, 8);
+#endif
+    /* close device (this not explicitly needed in most implementations) */
+    printf("ready to close and terminate... (type RETURN):");
+    fgets(line, STRING_MAX, stdin);
+	
+    Pm_Close(midi);
+    Pm_Terminate();
+    printf("done closing and terminating...\n");
+}
+
+
+void show_usage()
+{
+    printf("Usage: test [-h] [-l latency-in-ms]\n");
+    exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+    int default_in;
+    int default_out;
+    int i = 0, n = 0;
+    char line[STRING_MAX];
+    int test_input = 0, test_output = 0, test_both = 0, somethingStupid = 0;
+    int stream_test = 0;
+    int latency_valid = FALSE;
+    
+    if (sizeof(void *) == 8) 
+        printf("Apparently this is a 64-bit machine.\n");
+    else if (sizeof(void *) == 4) 
+        printf ("Apparently this is a 32-bit machine.\n");
+    
+    for (i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "-h") == 0) {
+            show_usage();
+        } else if (strcmp(argv[i], "-l") == 0 && (i + 1 < argc)) {
+            i = i + 1;
+            latency = atoi(argv[i]);
+            printf("Latency will be %ld\n", (long) latency);
+            latency_valid = TRUE;
+        } else {
+            show_usage();
+        }
+    }
+
+    while (!latency_valid) {
+        int lat; // declared int to match "%d"
+        printf("Latency in ms: ");
+        if (scanf("%d", &lat) == 1) {
+            latency = (int32_t) lat; // coerce from "%d" to known size
+	    latency_valid = TRUE;
+        }
+    }
+
+    /* determine what type of test to run */
+    printf("begin portMidi test...\n");
+    printf("%s%s%s%s%s",
+           "enter your choice...\n    1: test input\n",
+           "    2: test input (fail w/assert)\n",
+           "    3: test input (fail w/NULL assign)\n",
+           "    4: test output\n    5: test both\n",
+           "    6: stream test\n");
+    while (n != 1) {
+        n = scanf("%d", &i);
+        fgets(line, STRING_MAX, stdin);
+        switch(i) {
+        case 1: 
+            test_input = 1;
+            break;
+        case 2: 
+            test_input = 1;
+            somethingStupid = 1;
+            break;
+        case 3: 
+            test_input = 1;
+            somethingStupid = 2;
+            break;
+        case 4: 
+            test_output = 1;
+            break;
+        case 5:
+            test_both = 1;
+            break;
+		case 6:
+			stream_test = 1;
+			break;
+        default:
+            printf("got %d (invalid input)\n", n);
+            break;
+        }
+    }
+    
+    /* list device information */
+    default_in = Pm_GetDefaultInputDeviceID();
+    default_out = Pm_GetDefaultOutputDeviceID();
+    for (i = 0; i < Pm_CountDevices(); i++) {
+        char *deflt;
+        const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
+        if (((test_input  | test_both) & info->input) |
+            ((test_output | test_both | stream_test) & info->output)) {
+            printf("%d: %s, %s", i, info->interf, info->name);
+            if (info->input) {
+                deflt = (i == default_in ? "default " : "");
+                printf(" (%sinput)", deflt);
+            }
+            if (info->output) {
+                deflt = (i == default_out ? "default " : "");
+                printf(" (%soutput)", deflt);
+            }
+            printf("\n");
+        }
+    }
+    
+    /* run test */
+    if (stream_test) {
+        main_test_stream();
+    } else if (test_input) {
+        main_test_input(somethingStupid);
+    } else if (test_output) {
+        main_test_output();
+    } else if (test_both) {
+        main_test_both();
+    }
+    
+    printf("finished portMidi test...type ENTER to quit...");
+    fgets(line, STRING_MAX, stdin);
+    return 0;
+}
--- a/pm_test/test.c
+++ /dev/null
@@ -1,489 +0,0 @@
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define INPUT_BUFFER_SIZE 100
-#define OUTPUT_BUFFER_SIZE 0
-#define DRIVER_INFO NULL
-#define TIME_PROC ((int32_t (*)(void *)) Pt_Time)
-#define TIME_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-#define STRING_MAX 80 /* used for console input */
-
-int32_t latency = 0;
-
-/* crash the program to test whether midi ports are closed */
-/**/
-void doSomethingReallyStupid() {
-	int * tmp = NULL;
-	*tmp = 5;
-}
-
-
-/* exit the program without any explicit cleanup */
-/**/
-void doSomethingStupid() {
-	assert(0);
-}
-
-
-/* read a number from console */
-/**/
-int get_number(char *prompt)
-{
-    char line[STRING_MAX];
-    int n = 0, i;
-    printf(prompt);
-    while (n != 1) {
-        n = scanf("%d", &i);
-        fgets(line, STRING_MAX, stdin);
-
-    }
-    return i;
-}
-
-
-/*
- * the somethingStupid parameter can be set to simulate a program crash.
- * We want PortMidi to close Midi ports automatically in the event of a
- * crash because Windows does not (and this may cause an OS crash)
- */
-void main_test_input(unsigned int somethingStupid) {
-    PmStream * midi;
-    PmError status, length;
-    PmEvent buffer[1];
-    int num = 10;
-    int i = get_number("Type input number: ");
-    /* It is recommended to start timer before Midi; otherwise, PortMidi may
-       start the timer with its (default) parameters
-     */
-    TIME_START;
-
-    /* open input device */
-    Pm_OpenInput(&midi, 
-                 i,
-                 DRIVER_INFO, 
-                 INPUT_BUFFER_SIZE, 
-                 TIME_PROC, 
-                 TIME_INFO);
-
-    printf("Midi Input opened. Reading %d Midi messages...\n", num);
-    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
-    /* empty the buffer after setting filter, just in case anything
-       got through */
-    while (Pm_Poll(midi)) {
-        Pm_Read(midi, buffer, 1);
-    }
-    /* now start paying attention to messages */
-    i = 0; /* count messages as they arrive */
-    while (i < num) {
-        status = Pm_Poll(midi);
-        if (status == TRUE) {
-            length = Pm_Read(midi,buffer, 1);
-            if (length > 0) {
-                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
-                       i,
-                       (long) buffer[0].timestamp,
-                       (long) Pm_MessageStatus(buffer[0].message),
-                       (long) Pm_MessageData1(buffer[0].message),
-                       (long) Pm_MessageData2(buffer[0].message));
-                i++;
-            } else {
-                assert(0);
-            }
-        }
-        /* simulate crash if somethingStupid is 1 or 2 */
-        if ((i > (num/2)) && (somethingStupid == 1)) {
-            doSomethingStupid();
-        } else if ((i > (num/2)) && (somethingStupid == 2)) {
-            doSomethingReallyStupid();
-        }
-    }
-
-    /* close device (this not explicitly needed in most implementations) */
-    printf("ready to close...");
-
-    Pm_Close(midi);
-    printf("done closing...");
-}
-
-
-
-void main_test_output() {
-    PmStream * midi;
-	char line[80];
-    int32_t off_time;
-    int chord[] = { 60, 67, 76, 83, 90 };
-    #define chord_size 5 
-    PmEvent buffer[chord_size];
-    PmTimestamp timestamp;
-
-    /* determine which output device to use */
-    int i = get_number("Type output number: ");
-
-    /* It is recommended to start timer before PortMidi */
-    TIME_START;
-
-    /* open output device -- since PortMidi avoids opening a timer
-       when latency is zero, we will pass in a NULL timer pointer
-       for that case. If PortMidi tries to access the time_proc,
-       we will crash, so this test will tell us something. */
-    Pm_OpenOutput(&midi, 
-                  i, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE, 
-                  (latency == 0 ? NULL : TIME_PROC),
-                  (latency == 0 ? NULL : TIME_INFO), 
-                  latency);
-    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
-
-    /* output note on/off w/latency offset; hold until user prompts */
-    printf("ready to send program 1 change... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    /* if we were writing midi for immediate output, we could always use
-       timestamps of zero, but since we may be writing with latency, we
-       will explicitly set the timestamp to "now" by getting the time.
-       The source of timestamps should always correspond to the TIME_PROC
-       and TIME_INFO parameters used in Pm_OpenOutput(). */
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    /* Send a program change to increase the chances we will hear notes */
-    /* Program 0 is usually a piano, but you can change it here: */
-#define PROGRAM 0
-    buffer[0].message = Pm_Message(0xC0, PROGRAM, 0);
-    Pm_Write(midi, buffer, 1);
-
-    printf("ready to note-on... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0x90, 60, 100);
-    Pm_Write(midi, buffer, 1);
-    printf("ready to note-off... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0x90, 60, 0);
-    Pm_Write(midi, buffer, 1);
-
-    /* output short note on/off w/latency offset; hold until user prompts */
-    printf("ready to note-on (short form)... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
-                  Pm_Message(0x90, 60, 100));
-    printf("ready to note-off (short form)... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
-                  Pm_Message(0x90, 60, 0));
-
-    /* output several note on/offs to test timing. 
-       Should be 1s between notes */
-    printf("chord will arpeggiate if latency > 0\n");
-    printf("ready to chord-on/chord-off... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-    timestamp = TIME_PROC(TIME_INFO);
-    for (i = 0; i < chord_size; i++) {
-        buffer[i].timestamp = timestamp + 1000 * i;
-        buffer[i].message = Pm_Message(0x90, chord[i], 100);
-    }
-    Pm_Write(midi, buffer, chord_size);
-
-    off_time = timestamp + 1000 + chord_size * 1000; 
-    while (TIME_PROC(TIME_INFO) < off_time) 
-		/* busy wait */;
-    for (i = 0; i < chord_size; i++) {
-        buffer[i].timestamp = timestamp + 1000 * i;
-        buffer[i].message = Pm_Message(0x90, chord[i], 0);
-    }
-    Pm_Write(midi, buffer, chord_size);    
-
-    /* close device (this not explicitly needed in most implementations) */
-    printf("ready to close and terminate... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-	
-    Pm_Close(midi);
-    Pm_Terminate();
-    printf("done closing and terminating...\n");
-}
-
-
-void main_test_both()
-{
-    int i = 0;
-    int in, out;
-    PmStream * midi, * midiOut;
-    PmEvent buffer[1];
-    PmError status, length;
-    int num = 10;
-    
-    in = get_number("Type input number: ");
-    out = get_number("Type output number: ");
-
-    /* In is recommended to start timer before PortMidi */
-    TIME_START;
-
-    Pm_OpenOutput(&midiOut, 
-                  out, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE, 
-                  TIME_PROC,
-                  TIME_INFO, 
-                  latency);
-    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
-    /* open input device */
-    Pm_OpenInput(&midi, 
-                 in,
-                 DRIVER_INFO, 
-                 INPUT_BUFFER_SIZE, 
-                 TIME_PROC, 
-                 TIME_INFO);
-    printf("Midi Input opened. Reading %d Midi messages...\n",num);
-    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
-    /* empty the buffer after setting filter, just in case anything
-       got through */
-    while (Pm_Poll(midi)) {
-        Pm_Read(midi, buffer, 1);
-    }
-    i = 0;
-    while (i < num) {
-        status = Pm_Poll(midi);
-        if (status == TRUE) {
-            length = Pm_Read(midi,buffer,1);
-            if (length > 0) {
-                Pm_Write(midiOut, buffer, 1);
-                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
-                       i,
-                       (long) buffer[0].timestamp,
-                       (long) Pm_MessageStatus(buffer[0].message),
-                       (long) Pm_MessageData1(buffer[0].message),
-                       (long) Pm_MessageData2(buffer[0].message));
-                i++;
-            } else {
-                assert(0);
-            }
-        }
-    }
-
-    /* close midi devices */
-    Pm_Close(midi);
-    Pm_Close(midiOut);
-    Pm_Terminate(); 
-}
-
-
-/* main_test_stream exercises windows winmm API's stream mode */
-/*    The winmm stream mode is used for latency>0, and sends
-   timestamped messages. The timestamps are relative (delta) 
-   times, whereas PortMidi times are absolute. Since peculiar
-   things happen when messages are not always sent in advance,
-   this function allows us to exercise the system and test it.
- */
-void main_test_stream() {
-    PmStream * midi;
-	char line[80];
-    PmEvent buffer[16];
-
-	/* determine which output device to use */
-    int i = get_number("Type output number: ");
-
-	latency = 500; /* ignore LATENCY for this test and
-				      fix the latency at 500ms */
-
-    /* It is recommended to start timer before PortMidi */
-    TIME_START;
-
-	/* open output device */
-    Pm_OpenOutput(&midi, 
-                  i, 
-                  DRIVER_INFO,
-                  OUTPUT_BUFFER_SIZE, 
-                  TIME_PROC,
-                  TIME_INFO, 
-                  latency);
-    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
-
-    /* output note on/off w/latency offset; hold until user prompts */
-    printf("ready to send output... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-
-    /* if we were writing midi for immediate output, we could always use
-       timestamps of zero, but since we may be writing with latency, we
-       will explicitly set the timestamp to "now" by getting the time.
-       The source of timestamps should always correspond to the TIME_PROC
-       and TIME_INFO parameters used in Pm_OpenOutput(). */
-    buffer[0].timestamp = TIME_PROC(TIME_INFO);
-    buffer[0].message = Pm_Message(0xC0, 0, 0);
-	buffer[1].timestamp = buffer[0].timestamp;
-	buffer[1].message = Pm_Message(0x90, 60, 100);
-	buffer[2].timestamp = buffer[0].timestamp + 1000;
-	buffer[2].message = Pm_Message(0x90, 62, 100);
-	buffer[3].timestamp = buffer[0].timestamp + 2000;
-	buffer[3].message = Pm_Message(0x90, 64, 100);
-	buffer[4].timestamp = buffer[0].timestamp + 3000;
-	buffer[4].message = Pm_Message(0x90, 66, 100);
-	buffer[5].timestamp = buffer[0].timestamp + 4000;
-	buffer[5].message = Pm_Message(0x90, 60, 0);
-	buffer[6].timestamp = buffer[0].timestamp + 4000;
-	buffer[6].message = Pm_Message(0x90, 62, 0);
-	buffer[7].timestamp = buffer[0].timestamp + 4000;
-	buffer[7].message = Pm_Message(0x90, 64, 0);
-	buffer[8].timestamp = buffer[0].timestamp + 4000;
-	buffer[8].message = Pm_Message(0x90, 66, 0);
-
-    Pm_Write(midi, buffer, 9);
-#ifdef SEND8
-	/* Now, we're ready for the real test.
-	   Play 4 notes at now, now+500, now+1000, and now+1500
-	   Then wait until now+2000.
-	   Play 4 more notes as before.
-	   We should hear 8 evenly spaced notes. */
-	now = TIME_PROC(TIME_INFO);
-	for (i = 0; i < 4; i++) {
-		buffer[i * 2].timestamp = now + (i * 500);
-		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
-		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
-		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
-	}
-    Pm_Write(midi, buffer, 8);
-
-    while (Pt_Time() < now + 2500) 
-		/* busy wait */;
-	/* now we are 500 ms behind schedule, but since the latency
-	   is 500, the delay should not be audible */
-	now += 2000;
-	for (i = 0; i < 4; i++) {
-		buffer[i * 2].timestamp = now + (i * 500);
-		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
-		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
-		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
-	}
-    Pm_Write(midi, buffer, 8);
-#endif
-    /* close device (this not explicitly needed in most implementations) */
-    printf("ready to close and terminate... (type RETURN):");
-    fgets(line, STRING_MAX, stdin);
-	
-    Pm_Close(midi);
-    Pm_Terminate();
-    printf("done closing and terminating...\n");
-}
-
-
-void show_usage()
-{
-    printf("Usage: test [-h] [-l latency-in-ms]\n");
-    exit(0);
-}
-
-int main(int argc, char *argv[])
-{
-    int default_in;
-    int default_out;
-    int i = 0, n = 0;
-    char line[STRING_MAX];
-    int test_input = 0, test_output = 0, test_both = 0, somethingStupid = 0;
-    int stream_test = 0;
-    int latency_valid = FALSE;
-    
-    if (sizeof(void *) == 8) 
-        printf("Apparently this is a 64-bit machine.\n");
-    else if (sizeof(void *) == 4) 
-        printf ("Apparently this is a 32-bit machine.\n");
-    
-    for (i = 1; i < argc; i++) {
-        if (strcmp(argv[i], "-h") == 0) {
-            show_usage();
-        } else if (strcmp(argv[i], "-l") == 0 && (i + 1 < argc)) {
-            i = i + 1;
-            latency = atoi(argv[i]);
-            printf("Latency will be %ld\n", (long) latency);
-            latency_valid = TRUE;
-        } else {
-            show_usage();
-        }
-    }
-
-    while (!latency_valid) {
-        int lat; // declared int to match "%d"
-        printf("Latency in ms: ");
-        if (scanf("%d", &lat) == 1) {
-            latency = (int32_t) lat; // coerce from "%d" to known size
-	    latency_valid = TRUE;
-        }
-    }
-
-    /* determine what type of test to run */
-    printf("begin portMidi test...\n");
-    printf("%s%s%s%s%s",
-           "enter your choice...\n    1: test input\n",
-           "    2: test input (fail w/assert)\n",
-           "    3: test input (fail w/NULL assign)\n",
-           "    4: test output\n    5: test both\n",
-           "    6: stream test\n");
-    while (n != 1) {
-        n = scanf("%d", &i);
-        fgets(line, STRING_MAX, stdin);
-        switch(i) {
-        case 1: 
-            test_input = 1;
-            break;
-        case 2: 
-            test_input = 1;
-            somethingStupid = 1;
-            break;
-        case 3: 
-            test_input = 1;
-            somethingStupid = 2;
-            break;
-        case 4: 
-            test_output = 1;
-            break;
-        case 5:
-            test_both = 1;
-            break;
-		case 6:
-			stream_test = 1;
-			break;
-        default:
-            printf("got %d (invalid input)\n", n);
-            break;
-        }
-    }
-    
-    /* list device information */
-    default_in = Pm_GetDefaultInputDeviceID();
-    default_out = Pm_GetDefaultOutputDeviceID();
-    for (i = 0; i < Pm_CountDevices(); i++) {
-        char *deflt;
-        const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
-        if (((test_input  | test_both) & info->input) |
-            ((test_output | test_both | stream_test) & info->output)) {
-            printf("%d: %s, %s", i, info->interf, info->name);
-            if (info->input) {
-                deflt = (i == default_in ? "default " : "");
-                printf(" (%sinput)", deflt);
-            }
-            if (info->output) {
-                deflt = (i == default_out ? "default " : "");
-                printf(" (%soutput)", deflt);
-            }
-            printf("\n");
-        }
-    }
-    
-    /* run test */
-    if (stream_test) {
-        main_test_stream();
-    } else if (test_input) {
-        main_test_input(somethingStupid);
-    } else if (test_output) {
-        main_test_output();
-    } else if (test_both) {
-        main_test_both();
-    }
-    
-    printf("finished portMidi test...type ENTER to quit...");
-    fgets(line, STRING_MAX, stdin);
-    return 0;
-}
diff --git a/testing/portmidi/21-hardentests.patch b/testing/portmidi/21-hardentests.patch
new file mode 100644
index 000000000..9097003fd
--- /dev/null
+++ b/testing/portmidi/21-hardentests.patch
@@ -0,0 +1,93 @@
diff --git a/pm_test/latency.c b/pm_test/latency.c
old mode 100755
new mode 100644
index bfcdc0c..87f6a5e
--- a/pm_test/latency.c
+++ b/pm_test/latency.c
@@ -280,7 +280,7 @@ int get_number(char *prompt)
 {
     char line[STRING_MAX];
     int n = 0, i;
-    printf(prompt);
+    printf("%s\n", prompt);
     while (n != 1) {
         n = scanf("%d", &i);
         fgets(line, STRING_MAX, stdin);
diff --git a/pm_test/mm.c b/pm_test/mm.c
old mode 100755
new mode 100644
index 0f2a52e..3f04a30
--- a/pm_test/mm.c
+++ b/pm_test/mm.c
@@ -119,7 +119,7 @@ int get_number(char *prompt)
 {
     char line[STRING_MAX];
     int n = 0, i;
-    printf(prompt);
+    printf("%s", prompt);
     while (n != 1) {
         n = scanf("%d", &i);
         fgets(line, STRING_MAX, stdin);
@@ -136,7 +136,7 @@ void receive_poll(PtTimestamp timestamp, void *userData)
     if (!active) return;
     while ((count = Pm_Read(midi_in, &event, 1))) {
         if (count == 1) output(event.message);
-        else            printf(Pm_GetErrorText(count));
+        else            printf("%s", Pm_GetErrorText(count));
     }
 }
 
@@ -168,7 +168,7 @@ int main(int argc, char **argv)
     inp = get_number("Type input device number: ");
     err = Pm_OpenInput(&midi_in, inp, NULL, 512, NULL, NULL);
     if (err) {
-        printf(Pm_GetErrorText(err));
+        printf("%s", Pm_GetErrorText(err));
         Pt_Stop();
         mmexit(1);
     }
@@ -484,7 +484,7 @@ private int put_pitch(int p)
         "gs", "a", "bf", "b"    };
     /* note octave correction below */
     sprintf(result, "%s%d", ptos[p % 12], (p / 12) - 1);
-    printf(result);
+    printf("%s\n", result);
     return strlen(result);
 }
 
diff --git a/pm_test/midiclock.c b/pm_test/midiclock.c
index 60fcf7a..def511a 100644
--- a/pm_test/midiclock.c
+++ b/pm_test/midiclock.c
@@ -167,7 +167,7 @@ int get_number(char *prompt)
 {
     char line[STRING_MAX];
     int n = 0, i;
-    printf(prompt);
+    printf("%s", prompt);
     while (n != 1) {
         n = scanf("%d", &i);
         fgets(line, STRING_MAX, stdin);
@@ -256,7 +256,7 @@ int main(int argc, char **argv)
     err = Pm_OpenOutput(&midi, outp, DRIVER_INFO, OUTPUT_BUFFER_SIZE, 
                         TIME_PROC, TIME_INFO, LATENCY);
     if (err) {
-        printf(Pm_GetErrorText(err));
+        printf("%s", Pm_GetErrorText(err));
         goto error_exit_no_device;
     }
     active = true;
diff --git a/pm_test/sysex.c b/pm_test/sysex.c
index 7bbcf0e..812d979 100755
--- a/pm_test/sysex.c
+++ b/pm_test/sysex.c
@@ -39,7 +39,7 @@ int get_number(char *prompt)
 {
     char line[STRING_MAX];
     int n = 0, i;
-    printf(prompt);
+    printf("%s", prompt);
     while (n != 1) {
         n = scanf("%d", &i);
         fgets(line, STRING_MAX, stdin);

diff --git a/testing/portmidi/30-porttime_cmake.patch b/testing/portmidi/30-porttime_cmake.patch
new file mode 100644
index 000000000..f03e33fca
--- /dev/null
+++ b/testing/portmidi/30-porttime_cmake.patch
@@ -0,0 +1,32 @@
diff --git a/porttime/CMakeLists.txt b/porttime/CMakeLists.txt
new file mode 100644
index 0000000..7c4da89
--- /dev/null
+++ b/porttime/CMakeLists.txt
@@ -0,0 +1,13 @@
+if(UNIX)
+  list(APPEND LIBSRC ptlinux)
+  set(PM_NEEDED_LIBS pthread asound)
+  add_library(porttime SHARED ${LIBSRC})
+  set_target_properties(porttime PROPERTIES VERSION "0.0.0" SOVERSION "0")
+  target_link_libraries(porttime ${PM_NEEDED_LIBS})
+  add_library(porttime-static ${LIBSRC})
+  set_target_properties(porttime-static PROPERTIES OUTPUT_NAME "porttime")
+  target_link_libraries(porttime-static ${PM_NEEDED_LIBS})
+  INSTALL(TARGETS porttime porttime-static
+    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+endif(UNIX)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4919b78..08301a0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -74,6 +74,8 @@
 
 add_subdirectory(pm_dylib)
 
+add_subdirectory(porttime)
+
 # Cannot figure out how to make an xcode Java application with CMake
 add_subdirectory(pm_java)
 
diff --git a/testing/portmidi/40-test_sysex.patch b/testing/portmidi/40-test_sysex.patch
new file mode 100644
index 000000000..66ca01d1f
--- /dev/null
+++ b/testing/portmidi/40-test_sysex.patch
@@ -0,0 +1,19 @@
--- a/pm_test/sysex.c
+++ b/pm_test/sysex.c
@@ -171,7 +171,7 @@
 	    if (seconds == 0) seconds = 1;
             printf("Correctly received %d byte sysex message.\n", i);
 	    total_bytes += i;
-	    printf("Cummulative bytes/sec: %d\n", total_bytes / seconds);
+	    printf("Cummulative bytes/sec: %ld\n", total_bytes / seconds);
         }
     }
 cleanup:
@@ -231,6 +231,7 @@
         Pm_WriteSysEx(midi_out, 0, msg);
     }
     stop_time = Pt_Time();
+    printf("Delay was: %x\n", start_time - stop_time);
     Pm_Close(midi_out);
     return;
 }
diff --git a/testing/portmidi/41-pm_linux.patch b/testing/portmidi/41-pm_linux.patch
new file mode 100644
index 000000000..5404bddc6
--- /dev/null
+++ b/testing/portmidi/41-pm_linux.patch
@@ -0,0 +1,77 @@
--- a/pm_linux/finddefault.c
+++ b/pm_linux/finddefault.c
@@ -5,10 +5,13 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 #include "portmidi.h"
 
 #define STRING_MAX 256
 
+extern int pm_find_default_device(char *pattern, int is_input);
+
 /* skip over spaces, return first non-space */
 void skip_spaces(FILE *inf)
 {
@@ -26,7 +29,6 @@
 } 
 
 
-/* 
 /* Parse preference files, find default device, search devices --
  */
 PmDeviceID find_default_device(char *path, int input, PmDeviceID id)
@@ -80,7 +82,7 @@
             pref_str[i] = c;
         }
         if (i == STRING_MAX) continue; // value too long, ignore
-        pref_str[i] == 0;
+        //pref_str[i] == 0;
         i = pm_find_default_device(pref_str, input);
         if (i != pmNoDevice) {
             id = i;
--- a/pm_linux/pmlinux.c
+++ b/pm_linux/pmlinux.c
@@ -26,6 +26,8 @@
 PmDeviceID pm_default_input_device_id = -1;
 PmDeviceID pm_default_output_device_id = -1;
 
+extern int find_default_device(char *path, int input, PmDeviceID id);
+
 void pm_init()
 {
     /* Note: it is not an error for PMALSA to fail to initialize. 
--- a/pm_linux/pmlinuxalsa.c
+++ b/pm_linux/pmlinuxalsa.c
@@ -32,9 +32,9 @@
 #endif
 
 /* to store client/port in the device descriptor */
-#define MAKE_DESCRIPTOR(client, port) ((void*)(((client) << 8) | (port)))
-#define GET_DESCRIPTOR_CLIENT(info) ((((int)(info)) >> 8) & 0xff)
-#define GET_DESCRIPTOR_PORT(info) (((int)(info)) & 0xff)
+#define MAKE_DESCRIPTOR(client, port) ((void*)((((size_t)client) << 8) | (port)))
+#define GET_DESCRIPTOR_CLIENT(info) ((((size_t)(info)) >> 8) & 0xff)
+#define GET_DESCRIPTOR_PORT(info) (((size_t)(info)) & 0xff)
 
 #define BYTE unsigned char
 
@@ -422,7 +422,7 @@
     }
     if (desc->error < 0) return pmHostError;
 
-    VERBOSE printf("snd_seq_drain_output: 0x%x\n", (unsigned int) seq);
+    VERBOSE printf("snd_seq_drain_output: 0x%zx\n", (size_t) seq);
     desc->error = snd_seq_drain_output(seq);
     if (desc->error < 0) return pmHostError;
 
@@ -436,7 +436,7 @@
 {
     alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor;
     if (!desc) return pmBadPtr;
-    VERBOSE printf("snd_seq_drain_output: 0x%x\n", (unsigned int) seq);
+    VERBOSE printf("snd_seq_drain_output: 0x%zx\n", (size_t) seq);
     desc->error = snd_seq_drain_output(seq);
     if (desc->error < 0) return pmHostError;
 
diff --git a/testing/portmidi/50-change_assert.patch b/testing/portmidi/50-change_assert.patch
new file mode 100644
index 000000000..05a2bf709
--- /dev/null
+++ b/testing/portmidi/50-change_assert.patch
@@ -0,0 +1,41 @@
diff --git a/pm_common/portmidi.c b/pm_common/portmidi.c
index b716170..9a469b1 100755
--- a/pm_common/portmidi.c
+++ b/pm_common/portmidi.c
@@ -9,7 +9,6 @@
 #include "porttime.h"
 #include "pmutil.h"
 #include "pminternal.h"
-#include <assert.h>
 
 #define MIDI_CLOCK      0xf8
 #define MIDI_ACTIVE     0xfe
@@ -293,8 +292,8 @@ PMEXPORT const char *Pm_GetErrorText( PmError errnum ) {
  * The error will always be in the global pm_hosterror_text.
  */
 PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len) {
-    assert(msg);
-    assert(len > 0);
+    if (!msg) return;
+    if (len <= 0) return;
     if (pm_hosterror) {
         strncpy(msg, (char *) pm_hosterror_text, len);
         pm_hosterror = FALSE;
@@ -1016,7 +1015,7 @@ void pm_read_short(PmInternal *midi, PmEvent *event)
 { 
     int status;
     /* arg checking */
-    assert(midi != NULL);
+    if (!midi) return;
     /* midi filtering is applied here */
     status = Pm_MessageStatus(event->message);
     if (!pm_status_filtered(status, midi->filters)
@@ -1058,7 +1057,7 @@ unsigned int pm_read_bytes(PmInternal *midi, const unsigned char *data,
     int i = 0; /* index into data, must not be unsigned (!) */
     PmEvent event;
     event.timestamp = timestamp;
-    assert(midi);
+    if (!midi) return 0;
     /* note that since buffers may not have multiples of 4 bytes,
      * pm_read_bytes may be called in the middle of an outgoing
      * 4-byte PortMidi message. sysex_in_progress indicates that
diff --git a/testing/portmidi/51-remove_assert.patch b/testing/portmidi/51-remove_assert.patch
new file mode 100644
index 000000000..fd29501fd
--- /dev/null
+++ b/testing/portmidi/51-remove_assert.patch
@@ -0,0 +1,13 @@
diff --git a/pm_linux/pmlinuxalsa.c b/pm_linux/pmlinuxalsa.c
index 8e85cfe..1ec3e56 100755
--- a/pm_linux/pmlinuxalsa.c
+++ b/pm_linux/pmlinuxalsa.c
@@ -494,7 +494,7 @@ static void handle_event(snd_seq_event_t *ev)
     PmTimestamp timestamp;
 
     /* time stamp should be in ticks, using our queue where 1 tick = 1ms */
-    assert((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_TICK);
+    if ((ev->flags & SND_SEQ_TIME_STAMP_MASK) != SND_SEQ_TIME_STAMP_TICK) return;
 
     /* if no time_proc, just return "native" ticks (ms) */
     if (time_proc == NULL) {
diff --git a/testing/portmidi/APKBUILD b/testing/portmidi/APKBUILD
new file mode 100644
index 000000000..48a715052
--- /dev/null
+++ b/testing/portmidi/APKBUILD
@@ -0,0 +1,63 @@
# Contributor: Taner Tas <taner76@gmail.com>
# Maintainer: Taner Tas <taner76@gmail.com>
pkgname=portmidi
pkgver=217
pkgrel=0
pkgdesc="PortMidi is a platform independent library for MIDI input/output."
url="http://portmedia.sourceforge.net/"
arch="all"
license="MIT"
makedepends="dos2unix cmake alsa-lib-dev"
subpackages="$pkgname-dev"
options="!check"
source="http://downloads.sourceforge.net/portmedia/${pkgname}-src-${pkgver}.zip
	00_cmake.patch
	01_pmlinux.patch
	02_pmlinuxalsa.patch
	03_pm_test_Makefile.patch
	11-pmlinuxalsa.patch
	13-disablejni.patch
	20-movetest.patch
	21-hardentests.patch
	30-porttime_cmake.patch
	40-test_sysex.patch
	41-pm_linux.patch
	50-change_assert.patch
	51-remove_assert.patch"
builddir="${srcdir}/${pkgname}"

prepare() {
	cd "${builddir}"
	find  . -type f -exec dos2unix -s -q {} \;
	default_prepare
}
build() {
	cd "$builddir"
	cmake . \
	-DCMAKE_BUILD_TYPE="Release" \
	-DCMAKE_INSTALL_PREFIX=/usr \
	-DCMAKE_INSTALL_LIBDIR=/usr/lib \
	-DCMAKE_CACHEFILE_DIR="${builddir}"/build
	make 
}

package() {
	cd "$builddir"
	make DESTDIR="${pkgdir}" install
	rm -f "${pkgdir}"/usr/lib/*.a
}

sha512sums="d08d4d57429d26d292b5fe6868b7c7a32f2f1d2428f6695cd403a697e2d91629bd4380242ab2720e8f21c895bb75cb56b709fb663a20e8e623120e50bfc5d90b  portmidi-src-217.zip
39a7c30a58f71be517d57d11c1fedfdd7c56cfdf71593f35027323e64c41dd29065791bcce6ce0f373679c9e26caba390867c93904f5efc47605ac05feaccc45  00_cmake.patch
39ce54128b3f9712d47064557d6331bb9a44e65c2b13e2dd36bc474dfa073b391b0f3a8b01da54b0f56a14379ced2967f22b8822da46afaec62972b732b17442  01_pmlinux.patch
032c8777dbda6af1b17fdd7664300c41b6a9ccb06ad2a68595fd8d0216fdbef7452f3c407b2be2eb0445d08243adb8929096df1f3f1ee4d032a2928495acda81  02_pmlinuxalsa.patch
baf8231d0288079b5734e886e8cfe27d48ac5bf4bf181e956f6f0161235d21f3794ef4fcc77e8d6d3a3cf51461fa0c6f065c3b80d711ddfe736f4e6592d65400  03_pm_test_Makefile.patch
fcfc350e37940fd9ebb070f1efc727f1903a8cf23e21866c56b09766a31479a98676327a981f50905c11e93e32119ef56fef9d3a0de51182a85f175b1dfd3155  11-pmlinuxalsa.patch
58c638793f5e4eff7782f9844a7d19cb98e7a763497a03f77dbdc15e60a2d3dcfb2ae94cc3bc7a7ddfd880db8d5dd552dff659f1f300f7635b3a484bec35fb60  13-disablejni.patch
186358ec42a003b943672820ceb71c421b397bb47bb20cdbe92080755bbba3a5238c06632154c72878a92b10e32364d7f8c059fd8f6c864a87a9b9ebe546d15e  20-movetest.patch
8fa0944be2a70b4aede2a1967e1b38c863812245db6d725c0c253457f3443864a9cfba582d96ff0cc9d8fd1dd38fbb2e04e9447d2bd1abb5d2a933728135e8e4  21-hardentests.patch
15e529aa8757c4f74a372bcb43748fb0f88d7fc4c858d00199989ad92d0eb0b2edc72d591ba471ee534b38e5756e1c72255ef93c3eb670a64a7b35a973d8368c  30-porttime_cmake.patch
e52396df909b9ed1f8d58fad929c551a1124a2e5137f635087ac078bdf133162c618a17a9ecc4159acdfc48a640aaae06a4e392aacb1bc69a2389d9cfa18519d  40-test_sysex.patch
4c56ebc01ed51acec3fe4a0b9fe54a6f61cdcb9640f24a076d94788174c4ebd1fd958adcedb355dc78d9a11a22d79cb276eaa2f5248d5790142bd5ced178172e  41-pm_linux.patch
e4ffd1d49569b8279baeec45dd22b58a9724b396b927aa6c10198ab135290fbfb570d373b59317dae1d0a26ce71dcaf568325c728bc9302677d6fd28a74f4749  50-change_assert.patch
a40e268719f949d519285fbed477b587e47434eb9b8d97de5aa4f0e6209e2a24afb8a373d4f7616c88d141525a812e23105f10a0fd457be80c93989286963c56  51-remove_assert.patch"
-- 
2.16.1



---
Unsubscribe:  alpine-aports+unsubscribe@lists.alpinelinux.org
Help:         alpine-aports+help@lists.alpinelinux.org
---
Reply to thread Export thread (mbox)