summaryrefslogtreecommitdiff
path: root/portmidi/pm_test
diff options
context:
space:
mode:
Diffstat (limited to 'portmidi/pm_test')
-rw-r--r--portmidi/pm_test/CMakeLists.txt46
-rw-r--r--portmidi/pm_test/README.txt363
-rw-r--r--portmidi/pm_test/fast.c290
-rw-r--r--portmidi/pm_test/fastrcv.c255
-rwxr-xr-xportmidi/pm_test/latency.c287
-rw-r--r--portmidi/pm_test/midiclock.c282
-rwxr-xr-xportmidi/pm_test/midithread.c343
-rwxr-xr-xportmidi/pm_test/midithru.c455
-rwxr-xr-xportmidi/pm_test/mm.c595
-rw-r--r--portmidi/pm_test/multivirtual.c223
-rw-r--r--portmidi/pm_test/pmlist.c63
-rw-r--r--portmidi/pm_test/qtest.c174
-rw-r--r--portmidi/pm_test/recvvirtual.c175
-rw-r--r--portmidi/pm_test/sendvirtual.c194
-rwxr-xr-xportmidi/pm_test/sysex.c556
-rwxr-xr-xportmidi/pm_test/testio.c594
-rwxr-xr-xportmidi/pm_test/txdata.syx257
-rw-r--r--portmidi/pm_test/virttest.c339
18 files changed, 0 insertions, 5491 deletions
diff --git a/portmidi/pm_test/CMakeLists.txt b/portmidi/pm_test/CMakeLists.txt
deleted file mode 100644
index ae0fe48..0000000
--- a/portmidi/pm_test/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-# CMake file to build tests in this directory: pm_test
-
-# set the build directory to be in portmidi, not in portmidi/pm_test
-# this is required for Xcode:
-if(APPLE)
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
-endif(APPLE)
-
-# if(WIN32)
-# if(NOT BUILD_SHARED_LIBS)
- # /MDd is multithread debug DLL, /MTd is multithread debug
- # /MD is multithread DLL, /MT is multithread. Change to static:
-# include(../pm_win/static.cmake)
-# endif()
-# endif(WIN32)
-
-if(HAIKU)
- add_compile_options(-fPIC) # Haiku x86_64 needs this explicitly
-endif()
-
-macro(add_test name)
- add_executable(${name} ${name}.c)
- target_link_libraries(${name} PRIVATE portmidi)
- set_property(TARGET ${name} PROPERTY MSVC_RUNTIME_LIBRARY
- "MultiThreaded$<$<CONFIG:Debug>:Debug>${MSVCRT_DLL}")
-endmacro(add_test)
-
-add_test(testio)
-add_test(midithread)
-add_test(midithru)
-add_test(sysex)
-add_test(latency)
-add_test(mm)
-add_test(midiclock)
-add_test(qtest)
-add_test(fast)
-add_test(fastrcv)
-add_test(pmlist)
-if(WIN32)
-# windows does not implement Pm_CreateVirtualInput or Pm_CreateVirtualOutput
-else(WIN32)
-add_test(recvvirtual)
-add_test(sendvirtual)
-add_test(multivirtual)
-add_test(virttest)
-endif(WIN32)
diff --git a/portmidi/pm_test/README.txt b/portmidi/pm_test/README.txt
deleted file mode 100644
index 6c0c7ab..0000000
--- a/portmidi/pm_test/README.txt
+++ /dev/null
@@ -1,363 +0,0 @@
-README.txt - for pm_test directory
-
-These are all test programs for PortMidi
-
-Because device numbers depend on the system, there is no automated
-script to run all tests on PortMidi.
-
-To run the full set of tests manually:
-
-Note: everything is run from the ../Debug or ../Release directory.
-Actual or example input is marked with >>, e.g., >>0 means type 0<ENTER>
-Comments are shown in square brackets [like this]
-
-1. ./qtest -- output should show a bunch of tests and no error message.
-
-2. ./testio [test input]
-Latency in ms: >>0
-enter your choice... >>1
-Type input number: >>6 [pick a working input device]
-[play some notes, look for note-on (0x90) with pitch and velocity data]
-
-3. ./testio [test input (fail w/assert)]
-Latency in ms: >>0
-enter your choice... >>2
-Type input number: >>6 [pick a working input device]
-[play some notes, program will abort after 5 messages
-(this test only applies to a Debug build, otherwise
-the assert() macro is disabled.)]
-
-4. ./testio [test input (fail w/NULL assign)]
-Latency in ms: >>0
-enter your choice... >>3
-Type input number: >>6 [pick a working input device]
-[play some notes, program will Segmentation fault after 5 messages
-(this test may not Segfault in the Release build; if not
-try testing with a Debug build.)]
-
-5. ./testio [test output, no latency]
-Latency in ms: >>0
-enter your choice... >>4
-Type output number: >>2 [pick a working output device]
->> [type ENTER when prompted (7 times)]
-[hear note on, note off, note on, note off, chord]
-
-6. ./testio [test output, latency > 0]
-Latency in ms: >>300
-enter your choice... >>4
-Type output number: >>2 [pick a working output device]
->> [type ENTER when prompted (7 times)]
-[hear note on, note off, note on, note off, arpeggiated chord
- (delay of 300ms should be apparent)]
-
-7. ./testio [for both, no latency]
-Latency in ms: >>0
-enter your choice... >>5
-Type input number: >>6 [pick a working input device]
-Type output number: >>2 [pick a working output device]
-[play notes on input, hear them on output]
-
-8. ./testio [for both, latency > 0]
-Latency in ms: >>300
-enter your choice... >>5
-Type input number: >>6 [pick a working input device]
-Type output number: >>2 [pick a working output device]
-[play notes on input, hear them on output (delay of 300ms is apparent)]
-
-9. ./testio [stream test]
-Latency in ms: >>0 [does not matter]
-enter your choice... >>6
-Type output number: >>2 [pick a working output device]
->> [type ENTER to start]
-[hear 4 notes: C D E F# at one note per second, then all turn off]
-ready to close and terminate... (type ENTER) :>> [type ENTER (twice)]
-
-10. ./testio [isochronous out]
-Latency in ms: >>300
-enter your choice... >>7
-Type output number: >>2 [pick a working output device]
-ready to send program 1 change... (type ENTER): >> [type ENTER]
-[hear 80 notes, exactly 4 notes per second, no jitter]
-
-11. ./latency [no MIDI, histogram]
-Choose timer period (in ms, >= 1): >>1
-? >>1 [No MIDI traffic option]
-[wait about 10 seconds]
->> [type ENTER]
-[output should be something like ... Maximum latency: 1 milliseconds]
-
-12. ./latency [MIDI input, histogram]
-Choose timer period (in ms, >= 1): >>1
-? >>2 [MIDI input option]
-Midi input device number: >>6 [pick a working input device]
-[wait about 5 seconds, play input for 10 seconds ]
->> [type ENTER]
-[output should be something like ... Maximum latency: 3 milliseconds]
-
-13. ./latency [MIDI output, histogram]
-Choose timer period (in ms, >= 1): >>1
-? >>3 [MIDI output option]
-Midi output device number: >>2 [pick a working output device]
-Midi output should be sent every __ callback iterations: >>50
-[wait until you hear notes for 5 or 10 seconds]
->> [type ENTER to stop]
-[output should be something like ... Maximum latency: 2 milliseconds]
-
-14. ./latency [MIDI input and output, histogram]
-Choose timer period (in ms, >= 1): >>1
-? >>4 [MIDI input and output option]
-Midi input device number: >>6 [pick a working input device]
-Midi output device number: >>2 [pick a working output device]
-Midi output should be sent every __ callback iterations: >>50
-[wait until you hear notes, simultaneously play notes for 5 or 10 seconds]
->> [type ENTER to stop]
-[output should be something like ... Maximum latency: 1 milliseconds]
-
-15. ./mm [test with device input]
-Type input device number: >>6 [pick a working input device]
-[play some notes, see notes printed]
->>q [Type q ENTER when finished to exit]
-
-16. ./midithread -i 6 -o 2 [use working input/output device numbers]
->>5 [enter a transposition number]
-[play some notes, hear parallel 4ths]
->>q [quit after ENTER a couple of times]
-
-17. ./midiclock [in one shell]
- ./mm [in another shell]
-[Goal is send clock messages to MIDI monitor program. This requires
- either a hardware loopback (MIDI cable from OUT to IN on interface)
- or a software loopback (macOS IAC bus or ALSA MIDI Through Port)]
-[For midiclock application:]
- Type output device number: >>0 [pick a device with loopback]
- Type ENTER to start MIDI CLOCK: >> [type ENTER]
-[For mm application:]
- Type input device number: >>1 [pick device with loopback]
- [Wait a few seconds]
- >>s [to get Clock Count]
- >>s [expect to get a higher Clock Count]
-[For midiclock application:]
- >>c [turn off clocks]
-[For mm application:]
- >>s [to get Clock Count]
- >>s [expect to Clock Count stays the same]
-[For midiclock application:]
- >>t [turn on time code, see Time Code Quarter Frame messages from mm]
- >>q [to quit]
-[For mm application:]
- >>q [to quit]
-
-18. ./midithru -i 6 -o 2 [use working input/output device numbers]
-[Play notes on input evice; notes are sent immediately and also with a
- 2 sec delay to the output device; program terminates in 60 seconds or
- when you play B3 (B below Middle C)]
->> [ENTER to exit]
-
-19. ./recvvirtual -h [in one shell, macOS and Linux only]
- ./recvvirtual -m vvv [for mac, or -c vvv -p vvvport for linux]
- ./testio [in another shell]
-[For testio application:]
- Latency in ms: >>0
- enter your choice... >>4 [test output]
- Type output number: >>9 [select the "portmidi (output)" device]
- [type ENTER to each prompt, see that recvvirtual "Got message 0"
- through "Got message 9"]
- >> [ENTER to quit]
-[For recvvirtual application:]
- >> [ENTER to quit]
-
-20. ./sendvirtual -h [in one shell, macOS and Linux only]
- ./sendvirtual -m vvv [for mac, or -c vvv -p vvvport for linux]
- ./mm [in another shell]
-[For mm application:]
- Type input device number: >>10 [select the "portmidi" device]
-[For sendvirtual application:]
- Type ENTER to send messages: >> [type ENTER]
- [see NoteOn and off messages received by mm for Key 60-64]
- >> [ENTER to quit]
-[For mm application:]
- >>q [and ENTER twice to quit]
-
-21. ./sysex [no latency]
-[This requires either a hardware loopback (MIDI cable from OUT to IN
- on interface) or a software loopback (macOS IAC bus or ALSA MIDI
- Through Port)]
->>l [for loopback test]
-Type output device number: >>0 [pick output device to loopback]
-Latency in milliseconds: >>0
-Type input device number: >>0 [pick input device for loopback]
-[Program will send 100,000 bytes. After awhile, program will quit.
- You can read the Cummulative bytes/sec value.]
-
-22. ./sysex [latency > 0]
-[This requires either a hardware loopback (MIDI cable from OUT to IN
- on interface) or a software loopback (macOS IAC bus or ALSA MIDI
- Through Port)]
->>l [for loopback test]
-Type output device number: >>0 [pick output device to loopback]
-Latency in milliseconds: >>100
-Type input device number: >>0 [pick input device for loopback]
-[Program will send 100,000 bytes. After awhile, program will quit. You
- can read the Cummulative bytes/sec value; it is affected by latency.]
-
-23. ./fast [no latency]
- ./fastrcv [in another shell]
-[This is a speed check, especially for macOSX IAC bus connections,
- which are known to drop messages if you send messages too fast.
- fast and fastrcv must use a loopback to function.]
-[In fastrcv:]
- Input device number: >>1 [pick a non-hardware device if possible]
-[In fast:]
- Latency in ms: >>0
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>0 [pick a non-hardware device if possible]
- sending output...
-[see message counts and times; on Linux you should get about 10000
- messages/s; on macOS you should get about 1800 messages/s; Windows
- does not have software ports, so data rate might be limited by the
- loopback device you use.]
-
-Check output of fastrcv: there should be no errors, just msg/sec.]
-
-24. ./fast [latency > 0]
- ./fastrcv [in another shell]
-[This is a speed check, especially for macOSX IAC bus connections,
- which are known to drop messages if you send messages too fast.
- fast and fastrcv must use a loopback to function.]
-[In fastrcv:]
- Input device number: >>1 [pick a non-hardware device if possible]
-[In fast:]
- Latency in ms: >>30 [Note for ALSA, use latency * msgs/ms < 400]
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>0 [pick a non-hardware device if possible]
- sending output...
-[see message counts and times; on Linux you should get about 10000
- messages/s; on macOS you should get about 1800 messages/s; Windows
- does not have software ports, so data rate might be limited by the
- loopback device you use.]
-
-Check output of fastrcv: there should be no errors, just msg/sec.]
-
-25. ./fast [virtual output port, latency = 0, macOS and Linux only]
- ./fastrcv [in another shell]
-[Start fast first:]
- Latency in ms: >>0
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>9 [enter number listed for "Create virtual
- port named 'fast' (output)"]
- Pausing so you can connect a receiver to the newly created
- "fast" port. Type ENTER to proceed:
-[In fastrcv:]
- Input device number: >>3 [pick the device named "fast (input)"]
-[In fast:]
- >> [type ENTER to start]
-[see message counts and times as above ]
-
-Check output of fastrcv: there should be no errors, just msg/sec.]
-
-26. ./fast [virtual output port, latency > 0, macOS and Linux only]
- ./fastrcv [in another shell]
-[Start fast first:]
- Latency in ms: >>30 [Note for ALSA, use latency * msgs/ms < 400]
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>9 [enter number listed for "Create virtual
- port named 'fast' (output)"]
- Pausing so you can connect a receiver to the newly created
- "fast" port. Type ENTER to proceed:
-[In fastrcv:]
- Input device number: >>3 [pick the device named "fast (input)"]
-[In fast:]
- >> [type ENTER to start]
-[see message counts and times as above ]
-
-Check output of fastrcv: there should be no errors, just msg/sec.]
-
-27. ./fast [latency = 0, macOS and Linux only]
- ./fastrcv [virtual input port, in another shell]
-[In fastrcv:]
- Input device number: >>8 [enter number listed for "Create virtual
- port named 'fastrcv' (input)"]
-[In fast:]
- Latency in ms: >>0
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>7 [pick the device named "fastrcv (output)"]
- sending output...
-[see message counts and times as above ]
-
-Check output of fastrcv: there should be no errors, just msg/sec.]
-
-28. ./fast [latency > 0, macOS and Linux only]
- ./fastrcv [virtual input port, in another shell]
-[In fastrcv:]
- Input device number: >>8 [enter number listed for "Create virtual
- port named 'fastrcv' (input)"]
-[In fast:]
- Latency in ms: >>30 [Note for ALSA, use latency * msgs/ms < 400]
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>7 [pick the device named "fastrcv (output)"]
- sending output...
-[see message counts and times as above ]
-
-Check output of fastrcv: there should be no errors, just msg/sec.]
-
-29. ./midithru -v -n [virtual input and output, macOS and Linux only]
- ./fast [latency = 0]
- ./fastrcv [in another shell]
-[Start midithru first, it will run for 60 seconds]
-[In fastrcv:]
- Input device number: >>3 [pick the device named
- port named "midithru (input)"]
-[In fast:]
- Latency in ms: >>0
- Rate in messages per second: >>10000
- Duration in seconds: >>10
- Output device number: >>8 [pick the device named "midithru (output)"]
- sending output...
-[see message counts and times as above, on Mac, output from fast to
- midithru AND output from midithru to fastrcv are rate limited, so
- as in other tests, it will take more than 10s to receive all the
- messages and the receiving message rate will be about 1800 messages/second]
-
-30. ./multivirtual [macOS and Linux only]
- ./testio
- ./testio
-[Start multivirtual first]
-[In first testio:]
- Latency in ms: >>0
- enter your choice... >>5 [test both]
- Type input number: >>1 [pick portmidi1 (input)
- Type output number: >>4 [pick portmidi1 (output)
-[In second testio:]
- Latency in ms: >>10
- enter your choice... >>5 [test both]
- Type input number: >>2 [pick portmidi2 (input)
- Type output number: >>5 [pick portmidi2 (output)
-[In multivirtual:]
- Type ENTER to send messages: >> [type ENTER to start]
-[see that each testio gets 11 messages (0 to 10) at reasonable times
- (e.g. 2077 to 7580, and the "@" times (real times) should match the
- timestamps). multivirtual should also report reasonable times and
- line near the end of output should be "Got 11 messages from
- portmidi1 and 11 from portmidi2; expected 11."]
-
-31. ./multivirtual [macOS and Linux only]
- ./multivirtual
-[Second instance should report "PortMidi call failed...
- PortMidi: Cannot create virtual device: name is taken"]
-
-32. pmlist
- ./pmlist [check the output]
- [plug in or remove a device]
- >> [type RETURN]
- [check for changes in device list]
- >>q
-
-
-
-
diff --git a/portmidi/pm_test/fast.c b/portmidi/pm_test/fast.c
deleted file mode 100644
index 102697e..0000000
--- a/portmidi/pm_test/fast.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* fast.c -- send many MIDI messages very fast.
- *
- * This is a stress test created to explore reports of
- * pm_write() call blocking (forever) on Linux when
- * sending very dense MIDI sequences.
- *
- * Modified 8 Aug 2017 with -n to send expired timestamps
- * to test a theory about why Linux ALSA hangs in Audacity.
- *
- * Modified 9 Aug 2017 with -m, -p to test when timestamps are
- * wrapping from negative to positive or positive to negative.
- *
- * Roger B. Dannenberg, Aug 2017
- */
-
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define DEVICE_INFO NULL
-#define DRIVER_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-#define STRING_MAX 80 /* used for console input */
-// need to get declaration for Sleep()
-#ifdef WIN32
-#include "windows.h"
-#else
-#include <unistd.h>
-#define Sleep(n) usleep(n * 1000)
-#endif
-
-
-int32_t latency = 0;
-int32_t msgrate = 0;
-int deviceno = -9999;
-int duration = 0;
-int expired_timestamps = FALSE;
-int use_timeoffset = 0;
-
-/* read a number from console */
-/**/
-int get_number(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- while (getchar() != '\n') ;
- }
- return i;
-}
-
-
-/* get_time -- the time reference. Normally, this will be the default
- * time, Pt_Time(), but if you use the -p or -m option, the time
- * reference will start at an offset of -10s for -m, or
- * maximum_time - 10s for -p, so that we can observe what happens
- * with negative time or when time changes sign or wraps (by
- * generating output for more than 10s).
- */
-PmTimestamp get_time(void *info)
-{
- PmTimestamp now = (PmTimestamp) (Pt_Time() + use_timeoffset);
- return now;
-}
-
-
-void fast_test()
-{
- PmStream *midi;
- char line[STRING_MAX];
- int pause = FALSE; /* pause if this is a virtual output port */
- PmError err = pmNoError;
- /* output buffer size should be a little more than
- msgrate * latency / 1000. PortMidi will guarantee
- a minimum of latency / 2 */
- int buffer_size = msgrate * latency / 900;
- PmTimestamp start, now;
- int msgcnt = 0;
- int polling_count = 0;
- int pitch = 60;
- int printtime = 1000;
-
- /* It is recommended to start timer before PortMidi */
- TIME_START;
-
- /* open output device */
- if (deviceno == Pm_CountDevices()) {
- deviceno = Pm_CreateVirtualOutput("fast", NULL, DEVICE_INFO);
- if (deviceno >= 0) {
- err = Pm_OpenOutput(&midi, deviceno, DRIVER_INFO, buffer_size,
- get_time, NULL, latency);
- pause = TRUE;
- }
- } else if (err >= pmNoError) {
- err = Pm_OpenOutput(&midi, deviceno, DRIVER_INFO, buffer_size,
- get_time, NULL, latency);
- }
- if (err == pmHostError) {
- Pm_GetHostErrorText(line, STRING_MAX);
- printf("PortMidi found host error...\n %s\n", line);
- goto done;
- } else if (err < 0) {
- printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
- goto done;
- }
- printf("Midi Output opened with %ld ms latency.\n", (long) latency);
- if (pause) {
- printf("Pausing so you can connect a receiver to the newly created\n"
- " \"fast\" port. Type ENTER to proceed: ");
- while (getchar() != '\n') ;
- }
- /* wait a sec after printing previous line */
- start = get_time(NULL) + 1000;
- while (start > get_time(NULL)) {
- Sleep(10);
- }
- printf("sending output...\n");
- fflush(stdout); /* make sure message goes to console */
-
- /* every 10ms send on/off pairs at timestamps set to current time */
- now = get_time(NULL);
- /* if expired_timestamps, we want to send timestamps that have
- * expired. They should be sent immediately, but there's a suggestion
- * that negative delay might cause problems in the ALSA implementation
- * so this is something we can test using the -n flag.
- */
- if (expired_timestamps) {
- now = now - 2 * latency;
- }
-
- while (((PmTimestamp) (now - start)) < duration * 1000 || pitch != 60) {
- /* how many messages do we send? Total should be
- * (elapsed * rate) / 1000
- */
- int send_total = (((PmTimestamp) ((now - start))) * msgrate) / 1000;
- /* always send until pitch would be 60 so if we run again, the
- next pitch (60) will be expected */
- if (msgcnt < send_total) {
- if ((msgcnt & 1) == 0) {
- Pm_WriteShort(midi, now, Pm_Message(0x90, pitch, 100));
- } else {
- Pm_WriteShort(midi, now, Pm_Message(0x90, pitch, 0));
- /* play 60, 61, 62, ... 71, then wrap back to 60, 61, ... */
- pitch = (pitch - 59) % 12 + 60;
- }
- msgcnt += 1;
- if (((PmTimestamp) (now - start)) >= printtime) {
- printf("%d at %dms, polling count %d\n", msgcnt, now - start,
- polling_count);
- fflush(stdout); /* make sure message goes to console */
- printtime += 1000; /* next msg in 1s */
- }
- }
- now = get_time(NULL);
- polling_count++;
- }
- /* close device (this not explicitly needed in most implementations) */
- printf("ready to close and terminate... (type RETURN):");
- while (getchar() != '\n') ;
-
- Pm_Close(midi);
- done:
- Pm_Terminate();
- printf("done closing and terminating...\n");
-}
-
-
-void show_usage()
-{
- printf("Usage: fast [-h] [-l latency] [-r rate] [-d device] [-s dur] "
- "[-n] [-p] [-m]\n"
- ", where latency is in ms,\n"
- " rate is messages per second,\n"
- " device is the PortMidi device number,\n"
- " dur is the length of the test in seconds,\n"
- " -n means send timestamps in the past,\n"
- " -p means use a large positive time offset,\n"
- " -m means use a large negative time offset, and\n"
- " -h means help.\n");
-}
-
-int main(int argc, char *argv[])
-{
- int default_in;
- int default_out;
- char *deflt;
- int i = 0;
- int latency_valid = FALSE;
- int rate_valid = FALSE;
- int device_valid = FALSE;
- int dur_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");
-
- if (argc <= 1) {
- show_usage();
- } else {
- 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 if (strcmp(argv[i], "-r") == 0) {
- i = i + 1;
- msgrate = atoi(argv[i]);
- printf("Rate will be %d messages/second\n", msgrate);
- rate_valid = TRUE;
- } else if (strcmp(argv[i], "-d") == 0) {
- i = i + 1;
- deviceno = atoi(argv[i]);
- printf("Device will be %d\n", deviceno);
- } else if (strcmp(argv[i], "-s") == 0) {
- i = i + 1;
- duration = atoi(argv[i]);
- printf("Duration will be %d seconds\n", duration);
- dur_valid = TRUE;
- } else if (strcmp(argv[i], "-n") == 0) {
- printf("Sending expired timestamps (-n)\n");
- expired_timestamps = TRUE;
- } else if (strcmp(argv[i], "-p") == 0) {
- printf("Time offset set to 2147473648 (-p)\n");
- use_timeoffset = 2147473648;
- } else if (strcmp(argv[i], "-m") == 0) {
- printf("Time offset set to -10000 (-m)\n");
- use_timeoffset = -10000;
- } else {
- show_usage();
- }
- }
- }
-
- if (!latency_valid) {
- // coerce to known size
- latency = (int32_t) get_number("Latency in ms: ");
- }
-
- if (!rate_valid) {
- // coerce from "%d" to known size
- msgrate = (int32_t) get_number("Rate in messages per second: ");
- }
-
- if (!dur_valid) {
- duration = get_number("Duration in seconds: ");
- }
-
- /* list device information */
- default_in = Pm_GetDefaultInputDeviceID();
- default_out = Pm_GetDefaultOutputDeviceID();
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if (info->output) {
- printf("%d: %s, %s", i, info->interf, info->name);
- if (i == deviceno) {
- device_valid = TRUE;
- deflt = "selected ";
- } else if (i == default_out) {
- deflt = "default ";
- } else {
- deflt = "";
- }
- printf(" (%soutput)\n", deflt);
- }
- }
- printf("%d: Create virtual port named \"fast\"", i);
- if (i == deviceno) {
- device_valid = TRUE;
- deflt = "selected ";
- } else {
- deflt = "";
- }
- printf(" (%soutput)\n", deflt);
-
- if (!device_valid) {
- deviceno = get_number("Output device number: ");
- }
-
- fast_test();
- return 0;
-}
diff --git a/portmidi/pm_test/fastrcv.c b/portmidi/pm_test/fastrcv.c
deleted file mode 100644
index dabf9fa..0000000
--- a/portmidi/pm_test/fastrcv.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* fastrcv.c -- send many MIDI messages very fast.
- *
- * This is a stress test created to explore reports of
- * pm_write() call blocking (forever) on Linux when
- * sending very dense MIDI sequences.
- *
- * Modified 8 Aug 2017 with -n to send expired timestamps
- * to test a theory about why Linux ALSA hangs in Audacity.
- *
- * Roger B. Dannenberg, Aug 2017
- */
-
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define INPUT_BUFFER_SIZE 1000 /* big to avoid losing any input */
-#define DEVICE_INFO NULL
-#define DRIVER_INFO NULL
-#define TIME_PROC ((PmTimeProcPtr) 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 */
-// need to get declaration for Sleep()
-#ifdef WIN32
-#include "windows.h"
-#else
-#include <unistd.h>
-#define Sleep(n) usleep(n * 1000)
-#endif
-
-
-int deviceno = -9999;
-int verbose = FALSE;
-
-
-static void prompt_and_exit(void)
-{
- printf("type ENTER...");
- while (getchar() != '\n') ;
- /* this will clean up open ports: */
- exit(-1);
-}
-
-
-static PmError checkerror(PmError err)
-{
- if (err == pmHostError) {
- /* it seems pointless to allocate memory and copy the string,
- * so I will do the work of Pm_GetHostErrorText directly
- */
- char errmsg[80];
- Pm_GetHostErrorText(errmsg, 80);
- printf("PortMidi found host error...\n %s\n", errmsg);
- prompt_and_exit();
- } else if (err < 0) {
- printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
- prompt_and_exit();
- }
- return err;
-}
-
-
-/* read a number from console */
-/**/
-int get_number(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- while (getchar() != '\n') ;
- }
- return i;
-}
-
-
-void fastrcv_test()
-{
- PmStream * midi;
- PmError status, length;
- PmEvent buffer[1];
- PmTimestamp start;
- /* every 10ms read all messages, keep counts */
- /* every 1000ms, print report */
- int msgcnt = 0;
- /* expect repeating sequence of 60 through 71, alternating on/off */
- int expected_pitch = 60;
- int expected_on = TRUE;
- int report_time;
- PmTimestamp last_timestamp = -1;
- PmTimestamp last_delta = -1;
-
- /* It is recommended to start timer before PortMidi */
- TIME_START;
-
- /* open output device */
- if (deviceno == Pm_CountDevices()) {
- int id = Pm_CreateVirtualInput("fastrcv", NULL, DEVICE_INFO);
- if (id < 0) checkerror(id); /* error reporting */
- checkerror(Pm_OpenInput(&midi, id, DRIVER_INFO,
- INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO));
- } else {
- Pm_OpenInput(&midi, deviceno, DRIVER_INFO, INPUT_BUFFER_SIZE,
- TIME_PROC, TIME_INFO);
- }
- printf("Midi Input opened.\n");
-
- /* wait a sec after printing previous line */
- start = Pt_Time() + 1000;
- while (start > Pt_Time()) {
- Sleep(10);
- }
-
- report_time = Pt_Time() + 1000; /* report every 1s */
- while (TRUE) {
- PmTimestamp now = Pt_Time();
- status = Pm_Poll(midi);
- if (status == TRUE) {
- length = Pm_Read(midi, buffer, 1);
- if (length > 0) {
- int status = Pm_MessageStatus(buffer[0].message);
- if (status == 0x80) { /* convert NoteOff to NoteOn, vel=0 */
- status = 0x90;
- buffer[0].message = Pm_Message(status,
- Pm_MessageData1(buffer[0].message), 0);
- }
- /* only listen to NOTEON messages */
- if (status == 0x90) {
- int pitch = Pm_MessageData1(buffer[0].message);
- int vel = Pm_MessageData2(buffer[0].message);
- int is_on = (vel > 0);
- if (verbose) {
- printf("Note pitch %d vel %d\n", pitch, vel);
- }
- msgcnt++;
- if (pitch != expected_pitch || expected_on != is_on) {
- printf("Unexpected note-on: pitch %d vel %d, "
- "expected: pitch %d Note%s\n", pitch, vel,
- expected_pitch, (expected_on ? "On" : "Off"));
- }
- if (is_on) {
- expected_on = FALSE;
- expected_pitch = pitch;
- } else {
- expected_on = TRUE;
- expected_pitch = (pitch + 1) % 72;
- if (expected_pitch < 60) expected_pitch = 60;
- }
- if (last_timestamp >= 0) {
- last_delta = buffer[0].timestamp - last_timestamp;
- }
- last_timestamp = buffer[0].timestamp;
- }
- }
- }
- if (now >= report_time) {
- printf("%d msgs/sec", msgcnt);
- /* if available, print the last timestamp and last delta time */
- if (last_timestamp >= 0) {
- printf(" last timestamp %d", (int) last_timestamp);
- last_timestamp = -1;
- }
- if (last_delta >= 0) {
- printf(" last delta time %d", (int) last_delta);
- last_delta = -1;
- }
- printf("\n");
- report_time += 1000;
- msgcnt = 0;
- }
- }
-}
-
-
-void show_usage()
-{
- printf("Usage: fastrcv [-h] [-v] [-d device], where\n"
- "device is the PortMidi device number,\n"
- "-h means help,\n"
- "-v means verbose (print messages)\n");
-}
-
-int main(int argc, char *argv[])
-{
- int default_in;
- int default_out;
- char *deflt;
-
- int i = 0;
- int test_input = 0, test_output = 0, test_both = 0;
- int stream_test = 0;
- int device_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");
-
- if (argc <= 1) {
- show_usage();
- } else {
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-h") == 0) {
- show_usage();
- } else if (strcmp(argv[i], "-v") == 0) {
- verbose = TRUE;
- } else if (strcmp(argv[i], "-d") == 0) {
- i = i + 1;
- deviceno = atoi(argv[i]);
- printf("Device will be %d\n", deviceno);
- } else {
- show_usage();
- }
- }
- }
-
- /* list device information */
- default_in = Pm_GetDefaultInputDeviceID();
- default_out = Pm_GetDefaultOutputDeviceID();
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if (!info->output) {
- printf("%d: %s, %s", i, info->interf, info->name);
- if (i == deviceno) {
- device_valid = TRUE;
- deflt = "selected ";
- } else if (i == default_out) {
- deflt = "default ";
- } else {
- deflt = "";
- }
- printf(" (%sinput)\n", deflt);
- }
- }
- printf("%d: Create virtual port named \"fastrcv\"", i);
- if (i == deviceno) {
- device_valid = TRUE;
- deflt = "selected ";
- } else {
- deflt = "";
- }
- printf(" (%sinput)\n", deflt);
-
- if (!device_valid) {
- deviceno = get_number("Input device number: ");
- }
-
- fastrcv_test();
- return 0;
-}
diff --git a/portmidi/pm_test/latency.c b/portmidi/pm_test/latency.c
deleted file mode 100755
index 06ea80d..0000000
--- a/portmidi/pm_test/latency.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* latency.c -- measure latency of OS */
-
-#include "porttime.h"
-#include "portmidi.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-/* Latency is defined here to mean the time starting when a
- process becomes ready to run, and ending when the process
- actually runs. Latency is due to contention for the
- processor, usually due to other processes, OS activity
- including device drivers handling interrupts, and
- waiting for the scheduler to suspend the currently running
- process and activate the one that is waiting.
-
- Latency can affect PortMidi applications: if a process fails
- to wake up promptly, MIDI input may sit in the input buffer
- waiting to be handled, and MIDI output may not be generated
- with accurate timing. Using the latency parameter when
- opening a MIDI output port allows the caller to defer timing
- to PortMidi, which in most implementations will pass the
- data on to the OS. By passing timestamps and data to the
- OS kernel, device driver, or even hardware, there are fewer
- sources of latency that can affect the ultimate timing of
- the data. On the other hand, the application must generate
- and deliver the data ahead of the timestamp. The amount by
- which data is computed early must be at least as large as
- the worst-case latency to avoid timing problems.
-
- Latency is even more important in audio applications. If an
- application lets an audio output buffer underflow, an audible
- pop or click is produced. Audio input buffers can overflow,
- causing data to be lost. In general the audio buffers must
- be large enough to buffer the worst-case latency that the
- application will encounter.
-
- This program measures latency by recording the difference
- between the scheduled callback time and the current real time.
- We do not really know the scheduled callback time, so we will
- record the differences between the real time of each callback
- and the real time of the previous callback. Differences that
- are larger than the scheduled difference are recorded. Smaller
- differences indicate the system is recovering from an earlier
- latency, so these are ignored.
- Since printing by the callback process can cause all sorts of
- delays, this program records latency observations in a
- histogram. When the program is stopped, the histogram is
- printed to the console.
-
- Optionally the system can be tested under a load of MIDI input,
- MIDI output, or both. If MIDI input is selected, the callback
- thread will read any waiting MIDI events each iteration. You
- must generate events on this interface for the test to actually
- put any appreciable load on PortMidi. If MIDI output is
- selected, alternating note on and note off events are sent each
- X iterations, where you specify X. For example, with a timer
- callback period of 2ms and X=1, a MIDI event is sent every 2ms.
-
-
- INTERPRETING RESULTS: Time is quantized to 1ms, so there is
- some uncertainty due to rounding. A microsecond latency that
- spans the time when the clock is incremented will be reported
- as a latency of 1. On the other hand, a latency of almost
- 1ms that falls between two clock ticks will be reported as
- zero. In general, if the highest nonzero bin is numbered N,
- then the maximum latency is N+1.
-
-CHANGE LOG
-
-18-Jul-03 Mark Nelson -- Added code to generate MIDI or receive
- MIDI during test, and made period user-settable.
- */
-
-#define HIST_LEN 21 /* how many 1ms bins in the histogram */
-
-#define STRING_MAX 80 /* used for console input */
-
-#define INPUT_BUFFER_SIZE 100
-#define OUTPUT_BUFFER_SIZE 0
-
-#ifndef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef min
-#define min(a, b) ((a) <= (b) ? (a) : (b))
-#endif
-
-int get_number(const char *prompt);
-
-PtTimestamp previous_callback_time = 0;
-
-int period; /* milliseconds per callback */
-
-int histogram[HIST_LEN];
-int max_latency = 0; /* worst latency observed */
-int out_of_range = 0; /* how many points outside of HIST_LEN? */
-
-int test_in, test_out; /* test MIDI in and/or out? */
-int output_period; /* output MIDI every __ iterations if test_out true */
-int iteration = 0;
-PmStream *in, *out;
-int note_on = 0; /* is the note currently on? */
-
-/* callback function for PortTime -- computes histogram */
-void pt_callback(PtTimestamp timestamp, void *userData)
-{
- PtTimestamp difference = timestamp - previous_callback_time - period;
- previous_callback_time = timestamp;
-
- /* allow 5 seconds for the system to settle down */
- if (timestamp < 5000) return;
-
- iteration++;
- /* send a note on/off if user requested it */
- if (test_out && (iteration % output_period == 0)) {
- PmEvent buffer[1];
- buffer[0].timestamp = Pt_Time();
- if (note_on) {
- /* note off */
- buffer[0].message = Pm_Message(0x90, 60, 0);
- note_on = 0;
- } else {
- /* note on */
- buffer[0].message = Pm_Message(0x90, 60, 100);
- note_on = 1;
- }
- Pm_Write(out, buffer, 1);
- iteration = 0;
- }
-
- /* read all waiting events (if user requested) */
- if (test_in) {
- PmError status;
- PmEvent buffer[1];
- do {
- status = Pm_Poll(in);
- if (status == TRUE) {
- Pm_Read(in,buffer,1);
- }
- } while (status == TRUE);
- }
-
- if (difference < 0) return; /* ignore when system is "catching up" */
-
- /* update the histogram */
- if (difference < HIST_LEN) {
- histogram[difference]++;
- } else {
- out_of_range++;
- }
-
- if (max_latency < difference) max_latency = difference;
-}
-
-
-int main()
-{
- int i;
- int len;
- int choice;
- PtTimestamp stop;
- printf("Latency histogram.\n");
- period = 0;
- while (period < 1) {
- period = get_number("Choose timer period (in ms, >= 1): ");
- }
- printf("Benchmark with:\n\t%s\n\t%s\n\t%s\n\t%s\n",
- "1. No MIDI traffic",
- "2. MIDI input",
- "3. MIDI output",
- "4. MIDI input and output");
- choice = get_number("? ");
- switch (choice) {
- case 1: test_in = 0; test_out = 0; break;
- case 2: test_in = 1; test_out = 0; break;
- case 3: test_in = 0; test_out = 1; break;
- case 4: test_in = 1; test_out = 1; break;
- default: assert(0);
- }
- if (test_in || test_out) {
- /* list device information */
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if ((test_in && info->input) ||
- (test_out && info->output)) {
- printf("%d: %s, %s", i, info->interf, info->name);
- if (info->input) printf(" (input)");
- if (info->output) printf(" (output)");
- printf("\n");
- }
- }
- /* open stream(s) */
- if (test_in) {
- int i = get_number("MIDI input device number: ");
- Pm_OpenInput(&in,
- i,
- NULL,
- INPUT_BUFFER_SIZE,
- (PmTimestamp (*)(void *)) Pt_Time,
- NULL);
- /* turn on filtering; otherwise, input might overflow in the
- 5-second period before timer callback starts reading midi */
- Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
- }
- if (test_out) {
- int i = get_number("MIDI output device number: ");
- PmEvent buffer[1];
- Pm_OpenOutput(&out,
- i,
- NULL,
- OUTPUT_BUFFER_SIZE,
- (PmTimestamp (*)(void *)) Pt_Time,
- NULL,
- 0); /* no latency scheduling */
-
- /* send a program change to force a status byte -- this fixes
- a problem with a buggy linux MidiSport driver, and shouldn't
- hurt anything else
- */
- buffer[0].timestamp = 0;
- buffer[0].message = Pm_Message(0xC0, 0, 0); /* program change */
- Pm_Write(out, buffer, 1);
-
- output_period = get_number(
- "MIDI out should be sent every __ callback iterations: ");
-
- assert(output_period >= 1);
- }
- }
-
- printf("Latency measurements will start in 5 seconds. "
- "Type return to stop: ");
- Pt_Start(period, &pt_callback, 0);
- while (getchar() != '\n') ;
- stop = Pt_Time();
- Pt_Stop();
-
- /* courteously turn off the last note, if necessary */
- if (note_on) {
- PmEvent buffer[1];
- buffer[0].timestamp = Pt_Time();
- buffer[0].message = Pm_Message(0x90, 60, 0);
- Pm_Write(out, buffer, 1);
- }
-
- /* print the histogram */
- printf("Duration of test: %g seconds\n\n", max(0, stop - 5000) * 0.001);
- printf("Latency(ms) Number of occurrences\n");
- /* avoid printing beyond last non-zero histogram entry */
- len = min(HIST_LEN, max_latency + 1);
- for (i = 0; i < len; i++) {
- printf("%2d %10d\n", i, histogram[i]);
- }
- printf("Number of points greater than %dms: %d\n",
- HIST_LEN - 1, out_of_range);
- printf("Maximum latency: %d milliseconds\n", max_latency);
- printf("\nNote that due to rounding, actual latency can be 1ms higher\n");
- printf("than the numbers reported here.\n");
- printf("Type return to exit...");
- while (getchar() != '\n') ;
-
- if(choice == 2)
- Pm_Close(in);
- else if(choice == 3)
- Pm_Close(out);
- else if(choice == 4)
- {
- Pm_Close(in);
- Pm_Close(out);
- }
- return 0;
-}
-
-
-/* read a number from console */
-int get_number(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- while (getchar() != '\n') ;
- }
- return i;
-}
diff --git a/portmidi/pm_test/midiclock.c b/portmidi/pm_test/midiclock.c
deleted file mode 100644
index f0a6897..0000000
--- a/portmidi/pm_test/midiclock.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* miditime.c -- a test program that sends midi clock and MTC */
-
-#include "portmidi.h"
-#include "porttime.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-
-#ifndef false
-#define false 0
-#define true 1
-#endif
-
-#define private static
-typedef int boolean;
-
-#define MIDI_TIME_CLOCK 0xf8
-#define MIDI_START 0xfa
-#define MIDI_CONTINUE 0xfb
-#define MIDI_STOP 0xfc
-#define MIDI_Q_FRAME 0xf1
-
-#define OUTPUT_BUFFER_SIZE 0
-#define DRIVER_INFO NULL
-#define TIME_PROC ((PmTimeProcPtr) Pt_Time)
-#define TIME_INFO NULL
-#define LATENCY 0
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-#define STRING_MAX 80 /* used for console input */
-
-/* to determine ms per clock:
- * time per beat in seconds = 60 / tempo
- * multiply by 1000 to get time per beat in ms: 60000 / tempo
- * divide by 24 CLOCKs per beat: (60000/24) / tempo
- * simplify: 2500 / tempo
- */
-#define TEMPO_TO_CLOCK 2500.0
-
-boolean done = false;
-PmStream *midi;
-/* shared flags to control callback output generation: */
-boolean clock_running = false;
-boolean send_start_stop = false;
-boolean time_code_running = false;
-boolean active = false; /* tells callback to do its thing */
-float tempo = 60.0F;
-/* protocol for handing off portmidi to callback thread:
- main owns portmidi
- main sets active = true: ownership transfers to callback
- main sets active = false: main requests ownership
- callback sees active == false, yields ownership back to main
- main waits 2ms to make sure callback has a chance to yield
- (stop making PortMidi calls), then assumes it can close
- PortMidi
- */
-
-/* timer_poll -- the timer callback function */
-/*
- * All MIDI sends take place here
- */
-void timer_poll(PtTimestamp timestamp, void *userData)
-{
- static int callback_owns_portmidi = false;
- static PmTimestamp clock_start_time = 0;
- static double next_clock_time = 0;
- /* SMPTE time */
- static int frames = 0;
- static int seconds = 0;
- static int minutes = 0;
- static int hours = 0;
- static int mtc_count = 0; /* where are we in quarter frame sequence? */
- static int smpte_start_time = 0;
- static double next_smpte_time = 0;
- #define QUARTER_FRAME_PERIOD (1.0 / 120.0) /* 30fps, 1/4 frame */
-
- if (callback_owns_portmidi && !active) {
- /* main is requesting (by setting active to false) that we shut down */
- callback_owns_portmidi = false;
- return;
- }
- if (!active) return; /* main still getting ready or it's closing down */
- callback_owns_portmidi = true; /* main is ready, we have portmidi */
- if (send_start_stop) {
- if (clock_running) {
- Pm_WriteShort(midi, 0, MIDI_STOP);
- } else {
- Pm_WriteShort(midi, 0, MIDI_START);
- clock_start_time = timestamp;
- next_clock_time = TEMPO_TO_CLOCK / tempo;
- }
- clock_running = !clock_running;
- send_start_stop = false; /* until main sets it again */
- /* note that there's a slight race condition here: main could
- set send_start_stop asynchronously, but we assume user is
- typing slower than the clock rate */
- }
- if (clock_running) {
- if ((timestamp - clock_start_time) > next_clock_time) {
- Pm_WriteShort(midi, 0, MIDI_TIME_CLOCK);
- next_clock_time += TEMPO_TO_CLOCK / tempo;
- }
- }
- if (time_code_running) {
- int data = 0; // initialization avoids compiler warning
- if ((timestamp - smpte_start_time) < next_smpte_time)
- return;
- switch (mtc_count) {
- case 0: /* frames low nibble */
- data = frames;
- break;
- case 1: /* frames high nibble */
- data = frames >> 4;
- break;
- case 2: /* frames seconds low nibble */
- data = seconds;
- break;
- case 3: /* frames seconds high nibble */
- data = seconds >> 4;
- break;
- case 4: /* frames minutes low nibble */
- data = minutes;
- break;
- case 5: /* frames minutes high nibble */
- data = minutes >> 4;
- break;
- case 6: /* hours low nibble */
- data = hours;
- break;
- case 7: /* hours high nibble */
- data = hours >> 4;
- break;
- }
- data &= 0xF; /* take only 4 bits */
- Pm_WriteShort(midi, 0,
- Pm_Message(MIDI_Q_FRAME, (mtc_count << 4) + data, 0));
- mtc_count = (mtc_count + 1) & 7; /* wrap around */
- if (mtc_count == 0) { /* update time by two frames */
- frames += 2;
- if (frames >= 30) {
- frames = 0;
- seconds++;
- if (seconds >= 60) {
- seconds = 0;
- minutes++;
- if (minutes >= 60) {
- minutes = 0;
- hours++;
- /* just let hours wrap if it gets that far */
- }
- }
- }
- }
- next_smpte_time += QUARTER_FRAME_PERIOD;
- } else { /* time_code_running is false */
- smpte_start_time = timestamp;
- /* so that when it finally starts, we'll be in sync */
- }
-}
-
-
-/* read a number from console */
-/**/
-int get_number(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- while (getchar() != '\n') ;
- }
- return i;
-}
-
-/****************************************************************************
-* showhelp
-* Effect: print help text
-****************************************************************************/
-
-private void showhelp()
-{
- printf("\n");
- printf("t toggles sending MIDI Time Code (MTC)\n");
- printf("c toggles sending MIDI CLOCK (initially on)\n");
- printf("m to set tempo (from 1bpm to 300bpm)\n");
- printf("q quits\n");
- printf("\n");
-}
-
-/****************************************************************************
-* doascii
-* Inputs:
-* char c: input character
-* Effect: interpret to control output
-****************************************************************************/
-
-private void doascii(char c)
-{
- if (isupper(c)) c = tolower(c);
- if (c == 'q') done = true;
- else if (c == 'c') {
- printf("%s MIDI CLOCKs\n", (clock_running ? "Stopping" : "Starting"));
- send_start_stop = true;
- } else if (c == 't') {
- printf("%s MIDI Time Code\n",
- (time_code_running ? "Stopping" : "Starting"));
- time_code_running = !time_code_running;
- } else if (c == 'm') {
- int input_tempo = get_number("Enter new tempo (bpm): ");
- if (input_tempo >= 1 && input_tempo <= 300) {
- printf("Changing tempo to %d\n", input_tempo);
- tempo = (float) input_tempo;
- } else {
- printf("Tempo range is 1 to 300, current tempo is %g bpm\n",
- tempo);
- }
- } else {
- showhelp();
- }
-}
-
-
-/* main - prompt for parameters, start processing */
-/*
- * Prompt user to type return.
- * Then send START and MIDI CLOCK for 60 beats/min.
- * Commands:
- * t - toggle sending MIDI Time Code (MTC)
- * c - toggle sending MIDI CLOCK
- * m - set tempo
- * q - quit
- */
-int main(int argc, char **argv)
-{
- int outp;
- PmError err;
- int i;
- if (argc > 1) {
- printf("Warning: command line arguments ignored\n");
- }
- showhelp();
- /* use porttime callback to send midi */
- Pt_Start(1, timer_poll, 0);
- /* list device information */
- printf("MIDI output devices:\n");
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if (info->output) printf("%d: %s, %s\n", i, info->interf, info->name);
- }
- outp = get_number("Type output device number: ");
- err = Pm_OpenOutput(&midi, outp, DRIVER_INFO, OUTPUT_BUFFER_SIZE,
- TIME_PROC, TIME_INFO, LATENCY);
- if (err) {
- puts(Pm_GetErrorText(err));
- goto error_exit_no_device;
- }
- active = true;
-
- printf("Type ENTER to start MIDI CLOCK:\n");
- while (getchar() != '\n') ;
- send_start_stop = true; /* send START and then CLOCKs */
-
- while (!done) {
- doascii(getchar());
- while (getchar() != '\n') ;
- }
-
- active = false;
- Pt_Sleep(2); /* this is to allow callback to complete -- it's
- real time, so it's either ok and it runs on
- time, or there's no point to synchronizing
- with it */
- /* now we "own" portmidi again */
- Pm_Close(midi);
- error_exit_no_device:
- Pt_Stop();
- Pm_Terminate();
- exit(0);
-}
-
diff --git a/portmidi/pm_test/midithread.c b/portmidi/pm_test/midithread.c
deleted file mode 100755
index ea0613b..0000000
--- a/portmidi/pm_test/midithread.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/* midithread.c -- example program showing how to do midi processing
- in a preemptive thread
-
- Notes: if you handle midi I/O from your main program, there will be
- some delay before handling midi messages whenever the program is
- doing something like file I/O, graphical interface updates, etc.
-
- To handle midi with minimal delay, you should do all midi processing
- in a separate, high priority thread. A convenient way to get a high
- priority thread in windows is to use the timer callback provided by
- the PortTime library. That is what we show here.
-
- If the high priority thread writes to a file, prints to the console,
- or does just about anything other than midi processing, this may
- create delays, so all this processing should be off-loaded to the
- "main" process or thread. Communication between threads can be tricky.
- If one thread is writing at the same time the other is reading, very
- tricky race conditions can arise, causing programs to behave
- incorrectly, but only under certain timing conditions -- a terrible
- thing to debug. Advanced programmers know this as a synchronization
- problem. See any operating systems textbook for the complete story.
-
- To avoid synchronization problems, a simple, reliable approach is
- to communicate via messages. PortMidi offers a message queue as a
- datatype, and operations to insert and remove messages. Use two
- queues as follows: midi_to_main transfers messages from the midi
- thread to the main thread, and main_to_midi transfers messages from
- the main thread to the midi thread. Queues are safe for use between
- threads as long as ONE thread writes and ONE thread reads. You must
- NEVER allow two threads to write to the same queue.
-
- This program transposes incoming midi data by an amount controlled
- by the main program. To change the transposition, type an integer
- followed by return. The main program sends this via a message queue
- to the midi thread. To quit, type 'q' followed by return.
-
- The midi thread can also send a pitch to the main program on request.
- Type 'm' followed by return to wait for the next midi message and
- print the pitch.
-
- This program illustrates:
- Midi processing in a high-priority thread.
- Communication with a main process via message queues.
-
- */
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "assert.h"
-#include "portmidi.h"
-#include "pmutil.h"
-#include "porttime.h"
-
-/* if INPUT_BUFFER_SIZE is 0, PortMidi uses a default value */
-#define INPUT_BUFFER_SIZE 0
-
-#define OUTPUT_BUFFER_SIZE 100
-#define DRIVER_INFO NULL
-#define TIME_PROC NULL
-#define TIME_INFO NULL
-/* use zero latency because we want output to be immediate */
-#define LATENCY 0
-
-#define STRING_MAX 80
-
-/**********************************/
-/* DATA USED ONLY BY process_midi */
-/* (except during initialization) */
-/**********************************/
-
-int active = FALSE;
-int monitor = FALSE;
-int midi_thru = TRUE;
-
-int transpose;
-PmStream *midi_in;
-PmStream *midi_out;
-
-/****************************/
-/* END OF process_midi DATA */
-/****************************/
-
-/* shared queues */
-PmQueue *midi_to_main;
-PmQueue *main_to_midi;
-
-#define QUIT_MSG 1000
-#define MONITOR_MSG 1001
-#define THRU_MSG 1002
-
-/* timer interrupt for processing midi data */
-void process_midi(PtTimestamp timestamp, void *userData)
-{
- PmError result;
- PmEvent buffer; /* just one message at a time */
- int32_t msg;
-
- /* do nothing until initialization completes */
- if (!active)
- return;
-
- /* check for messages */
- do {
- result = Pm_Dequeue(main_to_midi, &msg);
- if (result) {
- if (msg >= -127 && msg <= 127)
- transpose = msg;
- else if (msg == QUIT_MSG) {
- /* acknowledge receipt of quit message */
- Pm_Enqueue(midi_to_main, &msg);
- active = FALSE;
- return;
- } else if (msg == MONITOR_MSG) {
- /* main has requested a pitch. monitor is a flag that
- * records the request:
- */
- monitor = TRUE;
- } else if (msg == THRU_MSG) {
- /* toggle Thru on or off */
- midi_thru = !midi_thru;
- }
- }
- } while (result);
-
- /* see if there is any midi input to process */
- do {
- result = Pm_Poll(midi_in);
- if (result) {
- int status, data1, data2;
- if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow)
- continue;
- if (midi_thru)
- Pm_Write(midi_out, &buffer, 1);
- /* unless there was overflow, we should have a message now */
- status = Pm_MessageStatus(buffer.message);
- data1 = Pm_MessageData1(buffer.message);
- data2 = Pm_MessageData2(buffer.message);
- if ((status & 0xF0) == 0x90 ||
- (status & 0xF0) == 0x80) {
-
- /* this is a note-on or note-off, so transpose and send */
- data1 += transpose;
-
- /* keep within midi pitch range, keep proper pitch class */
- while (data1 > 127)
- data1 -= 12;
- while (data1 < 0)
- data1 += 12;
-
- /* send the message */
- buffer.message = Pm_Message(status, data1, data2);
- Pm_Write(midi_out, &buffer, 1);
-
- /* if monitor is set, send the pitch to the main thread */
- if (monitor) {
- Pm_Enqueue(midi_to_main, &data1);
- monitor = FALSE; /* only send one pitch per request */
- }
- }
- }
- } while (result);
-}
-
-void exit_with_message(char *msg)
-{
- printf("%s\n", msg);
- while (getchar() != '\n') ;
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- int32_t n;
- const PmDeviceInfo *info;
- char line[STRING_MAX];
- int spin;
- int done = FALSE;
- int i;
- int input = -1, output = -1;
-
- printf("Usage: midithread [-i input] [-o output]\n"
- "where input and output are portmidi device numbers\n");
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-i") == 0) {
- i++;
- input = atoi(argv[i]);
- printf("Input device number: %d\n", input);
- } else if (strcmp(argv[i], "-o") == 0) {
- i++;
- output = atoi(argv[i]);
- printf("Output device number: %d\n", output);
- } else {
- return -1;
- }
- }
- printf("begin PortMidi multithread test...\n");
-
- /* note that it is safe to call PortMidi from the main thread for
- initialization and opening devices. You should not make any
- calls to PortMidi from this thread once the midi thread begins.
- to make PortMidi calls.
- */
-
- /* make the message queues */
- /* messages can be of any size and any type, but all messages in
- * a given queue must have the same size. We'll just use int32_t's
- * for our messages in this simple example
- */
- midi_to_main = Pm_QueueCreate(32, sizeof(int32_t));
- assert(midi_to_main != NULL);
- main_to_midi = Pm_QueueCreate(32, sizeof(int32_t));
- assert(main_to_midi != NULL);
-
- /* a little test of enqueue and dequeue operations. Ordinarily,
- * you would call Pm_Enqueue from one thread and Pm_Dequeue from
- * the other. Since the midi thread is not running, this is safe.
- */
- n = 1234567890;
- Pm_Enqueue(midi_to_main, &n);
- n = 987654321;
- Pm_Enqueue(midi_to_main, &n);
- Pm_Dequeue(midi_to_main, &n);
- if (n != 1234567890) {
- exit_with_message("Pm_Dequeue produced unexpected result.");
- }
- Pm_Dequeue(midi_to_main, &n);
- if(n != 987654321) {
- exit_with_message("Pm_Dequeue produced unexpected result.");
- }
-
- /* always start the timer before you start midi */
- Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */
- /* the timer will call our function, process_midi() every millisecond */
-
- Pm_Initialize();
-
- output = (output < 0 ? Pm_GetDefaultOutputDeviceID() : output);
- info = Pm_GetDeviceInfo(output);
- if (info == NULL) {
- printf("Could not open output device (%d).", output);
- exit_with_message("");
- }
- printf("Opening output device %s %s\n", info->interf, info->name);
-
- /* use zero latency because we want output to be immediate */
- Pm_OpenOutput(&midi_out,
- output,
- DRIVER_INFO,
- OUTPUT_BUFFER_SIZE,
- TIME_PROC,
- TIME_INFO,
- LATENCY);
-
- input = (input < 0 ? Pm_GetDefaultInputDeviceID() : input);
- info = Pm_GetDeviceInfo(input);
- if (info == NULL) {
- printf("Could not open default input device (%d).", input);
- exit_with_message("");
- }
- printf("Opening input device %s %s\n", info->interf, info->name);
- Pm_OpenInput(&midi_in,
- input,
- DRIVER_INFO,
- INPUT_BUFFER_SIZE,
- TIME_PROC,
- TIME_INFO);
-
- active = TRUE; /* enable processing in the midi thread -- yes, this
- is a shared variable without synchronization, but
- this simple assignment is safe */
-
- printf("Enter midi input; it will be transformed as specified by...\n");
- printf("Type 'q' to quit, 'm' to monitor next pitch, t to toggle thru or\n"
- "type a number to specify transposition.\n"
- "Must terminate with [ENTER]\n");
-
- while (!done) {
- int32_t msg;
- int input;
- int len;
- if (!fgets(line, STRING_MAX, stdin)) break; /* no stdin? */
- /* remove the newline: */
- len = (int) strlen(line);
- if (len > 0) line[len - 1] = 0; /* overwrite the newline char */
- if (strcmp(line, "q") == 0) {
- msg = QUIT_MSG;
- Pm_Enqueue(main_to_midi, &msg);
- /* wait for acknowlegement */
- do {
- spin = Pm_Dequeue(midi_to_main, &msg);
- } while (spin == 0); /* spin */ ;
- done = TRUE; /* leave the command loop and wrap up */
- } else if (strcmp(line, "m") == 0) {
- msg = MONITOR_MSG;
- Pm_Enqueue(main_to_midi, &msg);
- printf("Waiting for note...\n");
- do {
- spin = Pm_Dequeue(midi_to_main, &msg);
- } while (spin == 0); /* spin */ ;
- // convert int32_t to long for safe printing
- printf("... pitch is %ld\n", (long) msg);
- } else if (strcmp(line, "t") == 0) {
- /* reading midi_thru asynchronously could give incorrect results,
- e.g. if you type "t" twice before the midi thread responds to
- the first one, but we'll do it this way anyway. Perhaps a more
- correct way would be to wait for an acknowledgement message
- containing the new state. */
- printf("Setting THRU %s\n", (midi_thru ? "off" : "on"));
- msg = THRU_MSG;
- Pm_Enqueue(main_to_midi, &msg);
- } else if (sscanf(line, "%d", &input) == 1) {
- if (input >= -127 && input <= 127) {
- /* send transposition value, make sur */
- printf("Transposing by %d\n", input);
- msg = (int32_t) input;
- Pm_Enqueue(main_to_midi, &msg);
- } else {
- printf("Transposition must be within -127...127\n");
- }
- } else {
- printf("%s\n%s\n",
- "Type 'q[ENTER]' to quit, 'm[ENTER]' to monitor next pitch, or",
- "enter a number to specify transposition.");
- }
- }
-
- /* at this point, midi thread is inactive and we need to shut down
- * the midi input and output
- */
- Pt_Stop(); /* stop the timer */
- Pm_QueueDestroy(midi_to_main);
- Pm_QueueDestroy(main_to_midi);
-
- /* Belinda! if close fails here, some memory is deleted, right??? */
- Pm_Close(midi_in);
- Pm_Close(midi_out);
-
- fputs("finished portMidi multithread test.\n"
- "type ENTER to quit:", stdout);
- while (getchar() != '\n') ;
- return 0;
-}
diff --git a/portmidi/pm_test/midithru.c b/portmidi/pm_test/midithru.c
deleted file mode 100755
index 94b4f13..0000000
--- a/portmidi/pm_test/midithru.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/* midithru.c -- example program implementing background thru processing */
-
-/* suppose you want low-latency midi-thru processing, but your
- application wants to take advantage of the input buffer and
- timestamped data so that it does not have to operate with very low
- latency.
-
- This program illustrates how to use a timer callback from PortTime
- to implement a low-latency process that handles midi thru,
- including correctly merging midi data from the application with
- midi data from the input port.
-
- The main application, which runs in the main program thread, will
- use an interface similar to that of PortMidi, but since PortMidi
- does not allow concurrent threads to share access to a stream, the
- application will call private methods that transfer MIDI messages
- to and from the timer thread using lock-free queues. All PortMidi
- API calls are made from the timer thread.
- */
-
-/* DESIGN
-
-All setup will be done by the main thread. Then, all direct access to
-PortMidi will be handed off to the timer callback thread.
-
-After this hand-off, the main thread will get/send messages via a queue.
-
-The goal is to send incoming messages to the midi output while merging
-any midi data generated by the application. Sysex is a problem here
-because you cannot insert (merge) a midi message while a sysex is in
-progress. There are at least three ways to implement midi thru with
-sysex messages:
-
-1) Turn them off. If your application does not need them, turn them off
- with Pm_SetFilter(midi_in, PM_FILT_ACTIVE | PM_FILT_SYSEX). You will
- not receive sysex (or active sensing messages), so you will not have
- to handle them.
-
-2) Make them atomic. As you receive sysex messages, copy the data into
- a (big) buffer. Ideally, expand the buffer as needed -- sysex messages
- do not have any maximum length. Even more ideally, use a list structure
- and real-time memory allocation to avoid latency in the timer thread.
- When a full sysex message is received, send it to the midi output all
- at once.
-
-3) Process sysex incrementally. Send sysex data to midi output as it
- arrives. Block any non-real-time messages from the application until
- the sysex message completes. There is the risk that an incomplete
- sysex message will block messages forever, so implement a 5-second
- timeout: if no sysex data is seen for 5 seconds, release the block,
- possibly losing the rest of the sysex message.
-
- Application messages must be processed similarly: once started, a
- sysex message will block MIDI THRU processing. We will assume that
- the application will not abort a sysex message, so timeouts are not
- necessary here.
-
-This code implements (3).
-
-Latency is also an issue. PortMidi requires timestamps to be in
-non-decreasing order. Since we'll be operating with a low-latency
-timer thread, we can just set the latency to zero meaning timestamps
-are ignored by PortMidi. This will allow thru to go through with
-minimal latency. The application, however, needs to use timestamps
-because we assume it is high latency (the whole purpose of this
-example is to illustrate how to get low-latency thru with a high-latency
-application.) So the callback thread will implement midi timing by
-observing timestamps. The current timestamp will be available in the
-global variable current_timestamp.
-
-*/
-
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "string.h"
-#include "assert.h"
-#include "portmidi.h"
-#include "pmutil.h"
-#include "porttime.h"
-
-#define MIDI_SYSEX 0xf0
-#define MIDI_EOX 0xf7
-#define STRING_MAX 80 /* used for console input */
-
-/* active is set true when midi processing should start, must be
- * volatile to force thread to check for updates by other thread */
-int active = FALSE;
-/* process_midi_exit_flag is set when the timer thread shuts down;
- * must be volatile so it is re-read in the while loop that waits on it */
-volatile int process_midi_exit_flag;
-
-PmStream *midi_in;
-PmStream *midi_out;
-
-/* shared queues */
-#define IN_QUEUE_SIZE 1024
-#define OUT_QUEUE_SIZE 1024
-PmQueue *in_queue;
-PmQueue *out_queue;
-/* this is volatile because it is set in the process_midi callback and
- * the main thread reads it to sense elapsed time. Without volatile, the
- * optimizer can put it in a register and not see the updates.
- */
-volatile PmTimestamp current_timestamp = 0;
-int thru_sysex_in_progress = FALSE;
-int app_sysex_in_progress = FALSE;
-PmTimestamp last_timestamp = 0;
-
-
-static void prompt_and_exit(void)
-{
- printf("type ENTER...");
- while (getchar() != '\n') ;
- /* this will clean up open ports: */
- exit(-1);
-}
-
-
-static PmError checkerror(PmError err)
-{
- if (err == pmHostError) {
- /* it seems pointless to allocate memory and copy the string,
- * so I will do the work of Pm_GetHostErrorText directly
- */
- char errmsg[80];
- Pm_GetHostErrorText(errmsg, 80);
- printf("PortMidi found host error...\n %s\n", errmsg);
- prompt_and_exit();
- } else if (err < 0) {
- printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
- prompt_and_exit();
- }
- return err;
-}
-
-
-/* time proc parameter for Pm_MidiOpen */
-PmTimestamp midithru_time_proc(void *info)
-{
- return current_timestamp;
-}
-
-
-/* timer interrupt for processing midi data.
- Incoming data is delivered to main program via in_queue.
- Outgoing data from main program is delivered via out_queue.
- Incoming data from midi_in is copied with low latency to midi_out.
- Sysex messages from either source block messages from the other.
- */
-void process_midi(PtTimestamp timestamp, void *userData)
-{
- PmError result;
- PmEvent buffer; /* just one message at a time */
-
- current_timestamp++; /* update every millisecond */
-
- /* do nothing until initialization completes */
- if (!active) {
- /* this flag signals that no more midi processing will be done */
- process_midi_exit_flag = TRUE;
- return;
- }
-
- /* see if there is any midi input to process */
- if (!app_sysex_in_progress) {
- do {
- result = Pm_Poll(midi_in);
- if (result) {
- int status;
- PmError rslt = Pm_Read(midi_in, &buffer, 1);
- if (rslt == pmBufferOverflow)
- continue;
- assert(rslt == 1);
-
- /* record timestamp of most recent data */
- last_timestamp = current_timestamp;
-
- /* the data might be the end of a sysex message that
- has timed out, in which case we must ignore it.
- It's a continuation of a sysex message if status
- is actually a data byte (high-order bit is zero). */
- status = Pm_MessageStatus(buffer.message);
- if (((status & 0x80) == 0) && !thru_sysex_in_progress) {
- continue; /* ignore this data */
- }
-
- /* implement midi thru */
- /* note that you could output to multiple ports or do other
- processing here if you wanted
- */
- /* printf("thru: %x\n", buffer.message); */
- Pm_Write(midi_out, &buffer, 1);
-
- /* send the message to the application */
- /* you might want to filter clock or active sense messages here
- to avoid sending a bunch of junk to the application even if
- you want to send it to MIDI THRU
- */
- Pm_Enqueue(in_queue, &buffer);
-
- /* sysex processing */
- if (status == MIDI_SYSEX) thru_sysex_in_progress = TRUE;
- else if ((status & 0xF8) != 0xF8) {
- /* not MIDI_SYSEX and not real-time, so */
- thru_sysex_in_progress = FALSE;
- }
- if (thru_sysex_in_progress && /* look for EOX */
- (((buffer.message & 0xFF) == MIDI_EOX) ||
- (((buffer.message >> 8) & 0xFF) == MIDI_EOX) ||
- (((buffer.message >> 16) & 0xFF) == MIDI_EOX) ||
- (((buffer.message >> 24) & 0xFF) == MIDI_EOX))) {
- thru_sysex_in_progress = FALSE;
- }
- }
- } while (result);
- }
-
-
- /* see if there is application midi data to process */
- while (!Pm_QueueEmpty(out_queue)) {
- /* see if it is time to output the next message */
- PmEvent *next = (PmEvent *) Pm_QueuePeek(out_queue);
- assert(next); /* must be non-null because queue is not empty */
- if (next->timestamp <= current_timestamp) {
- /* time to send a message, first make sure it's not blocked */
- int status = Pm_MessageStatus(next->message);
- if ((status & 0xF8) == 0xF8) {
- ; /* real-time messages are not blocked */
- } else if (thru_sysex_in_progress) {
- /* maybe sysex has timed out (output becomes unblocked) */
- if (last_timestamp + 5000 < current_timestamp) {
- thru_sysex_in_progress = FALSE;
- } else break; /* output is blocked, so exit loop */
- }
- Pm_Dequeue(out_queue, &buffer);
- Pm_Write(midi_out, &buffer, 1);
-
- /* inspect message to update app_sysex_in_progress */
- if (status == MIDI_SYSEX) app_sysex_in_progress = TRUE;
- else if ((status & 0xF8) != 0xF8) {
- /* not MIDI_SYSEX and not real-time, so */
- app_sysex_in_progress = FALSE;
- }
- if (app_sysex_in_progress && /* look for EOX */
- (((buffer.message & 0xFF) == MIDI_EOX) ||
- (((buffer.message >> 8) & 0xFF) == MIDI_EOX) ||
- (((buffer.message >> 16) & 0xFF) == MIDI_EOX) ||
- (((buffer.message >> 24) & 0xFF) == MIDI_EOX))) {
- app_sysex_in_progress = FALSE;
- }
- } else break; /* wait until indicated timestamp */
- }
-}
-
-
-void exit_with_message(char *msg)
-{
-#define STRING_MAX 80
- printf("%s\nType ENTER...", msg);
- while (getchar() != '\n') ;
- exit(1);
-}
-
-
-void initialize(int input, int output, int virtual)
-/* set up midi processing thread and open midi streams */
-{
- /* note that it is safe to call PortMidi from the main thread for
- initialization and opening devices. You should not make any
- calls to PortMidi from this thread once the midi thread begins.
- to make PortMidi calls.
- */
-
- /* note that this routine provides minimal error checking. If
- you use the PortMidi library compiled with PM_CHECK_ERRORS,
- then error messages will be printed and the program will exit
- if an error is encountered. Otherwise, you should add some
- error checking to this code.
- */
-
- const PmDeviceInfo *info;
-
- /* make the message queues */
- in_queue = Pm_QueueCreate(IN_QUEUE_SIZE, sizeof(PmEvent));
- assert(in_queue != NULL);
- out_queue = Pm_QueueCreate(OUT_QUEUE_SIZE, sizeof(PmEvent));
- assert(out_queue != NULL);
-
- /* always start the timer before you start midi */
- Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */
- /* the timer will call our function, process_midi() every millisecond */
-
- Pm_Initialize();
-
- if (output < 0) {
- if (!virtual) {
- output = Pm_GetDefaultOutputDeviceID();
- }
- }
- if (output >= 0) {
- info = Pm_GetDeviceInfo(output);
- if (info == NULL) {
- printf("Could not open default output device (%d).", output);
- exit_with_message("");
- }
-
- printf("Opening output device %s %s\n", info->interf, info->name);
-
- /* use zero latency because we want output to be immediate */
- Pm_OpenOutput(&midi_out,
- output,
- NULL /* driver info */,
- OUT_QUEUE_SIZE,
- &midithru_time_proc,
- NULL /* time info */,
- 0 /* Latency */);
- } else { /* send to virtual port */
- int id;
- printf("Opening virtual output device \"midithru\"\n");
- id = Pm_CreateVirtualOutput("midithru", NULL, NULL);
- if (id < 0) checkerror(id); /* error reporting */
- checkerror(Pm_OpenOutput(&midi_out, id, NULL, OUT_QUEUE_SIZE,
- &midithru_time_proc, NULL, 0));
- }
- if (input < 0) {
- if (!virtual) {
- input = Pm_GetDefaultInputDeviceID();
- }
- }
- if (input >= 0) {
- info = Pm_GetDeviceInfo(input);
- if (info == NULL) {
- printf("Could not open default input device (%d).", input);
- exit_with_message("");
- }
-
- printf("Opening input device %s %s\n", info->interf, info->name);
- Pm_OpenInput(&midi_in,
- input,
- NULL /* driver info */,
- 0 /* use default input size */,
- &midithru_time_proc,
- NULL /* time info */);
- } else { /* receive from virtual port */
- int id;
- printf("Opening virtual input device \"midithru\"\n");
- id = Pm_CreateVirtualInput("midithru", NULL, NULL);
- if (id < 0) checkerror(id); /* error reporting */
- checkerror(Pm_OpenInput(&midi_in, id, NULL, 0,
- &midithru_time_proc, NULL));
- }
- /* Note: if you set a filter here, then this will filter what goes
- to the MIDI THRU port. You may not want to do this.
- */
- Pm_SetFilter(midi_in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
-
- active = TRUE; /* enable processing in the midi thread -- yes, this
- is a shared variable without synchronization, but
- this simple assignment is safe */
-
-}
-
-
-void finalize()
-{
- /* the timer thread could be in the middle of accessing PortMidi stuff */
- /* to detect that it is done, we first clear process_midi_exit_flag and
- then wait for the timer thread to set it
- */
- process_midi_exit_flag = FALSE;
- active = FALSE;
- /* busy wait for flag from timer thread that it is done */
- while (!process_midi_exit_flag) ;
- /* at this point, midi thread is inactive and we need to shut down
- * the midi input and output
- */
- Pt_Stop(); /* stop the timer */
- Pm_QueueDestroy(in_queue);
- Pm_QueueDestroy(out_queue);
-
- Pm_Close(midi_in);
- Pm_Close(midi_out);
-
- Pm_Terminate();
-}
-
-
-int main(int argc, char *argv[])
-{
- PmTimestamp last_time = 0;
- PmEvent buffer;
- int i;
- int input = -1, output = -1;
- int virtual = FALSE;
- int delay_enable = TRUE;
-
- printf("Usage: midithru [-i input] [-o output] [-v] [-n]\n"
- "where input and output are portmidi device numbers\n"
- "if -v and input and/or output are not specified,\n"
- "then virtual ports are created and used instead.\n"
- "-n turns off the default MIDI delay effect.\n");
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-i") == 0) {
- i++;
- input = atoi(argv[i]);
- printf("Input device number: %d\n", input);
- } else if (strcmp(argv[i], "-o") == 0) {
- i++;
- output = atoi(argv[i]);
- printf("Output device number: %d\n", output);
- } else if (strcmp(argv[i], "-v") == 0) {
- virtual = TRUE;
- } else if (strcmp(argv[i], "-n") == 0) {
- delay_enable = FALSE;
- printf("delay_effect is disabled\n");
- } else {
- return -1;
- }
- }
- printf("begin PortMidi midithru program...\n");
-
- initialize(input, output, virtual); /* set up and start midi processing */
-
- printf("This program will run for 60 seconds, "
- "or until you play B below middle C,\n"
- "All input is sent immediately, implementing software MIDI THRU.\n"
- "Also, all input is echoed with a 2 second delay.\n");
-
- while (current_timestamp < 60000) {
- /* just to make the point that this is not a low-latency process,
- spin until half a second has elapsed */
- last_time = last_time + 500;
- while (last_time > current_timestamp) ;
-
- /* now read data and send it after changing timestamps */
- while (Pm_Dequeue(in_queue, &buffer) == 1) {
- /* printf("timestamp %d\n", buffer.timestamp); */
- /* printf("message %x\n", buffer.message); */
- if (delay_enable) {
- buffer.timestamp = buffer.timestamp + 2000; /* delay */
- Pm_Enqueue(out_queue, &buffer);
- }
- /* play B3 to break out of loop */
- if (Pm_MessageStatus(buffer.message) == 0x90 &&
- Pm_MessageData1(buffer.message) == 59) {
- goto quit_now;
- }
- }
- }
-quit_now:
- finalize();
- exit_with_message("finished PortMidi midithru program.");
- return 0; /* never executed, but keeps the compiler happy */
-}
diff --git a/portmidi/pm_test/mm.c b/portmidi/pm_test/mm.c
deleted file mode 100755
index ab9d32e..0000000
--- a/portmidi/pm_test/mm.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/* mm.c -- midi monitor */
-
-/*****************************************************************************
-* Change Log
-* Date | Change
-*-----------+-----------------------------------------------------------------
-* 7-Apr-86 | Created changelog
-* 31-Jan-90 | GWL : use new cmdline
-* 5-Apr-91 | JDW : Further changes
-* 16-Feb-92 | GWL : eliminate label mmexit:; add error recovery
-* 18-May-92 | GWL : continuous clocks, etc.
-* 17-Jan-94 | GWL : option to display notes
-* 20-Nov-06 | RBD : port mm.c from CMU Midi Toolkit to PortMidi
-* | mm.c -- revealing MIDI secrets for over 20 years!
-*****************************************************************************/
-
-#include "stdlib.h"
-#include "ctype.h"
-#include "string.h"
-#include "stdio.h"
-#include "porttime.h"
-#include "portmidi.h"
-
-#define STRING_MAX 80
-
-#define MIDI_CODE_MASK 0xf0
-#define MIDI_CHN_MASK 0x0f
-/*#define MIDI_REALTIME 0xf8
- #define MIDI_CHAN_MODE 0xfa */
-#define MIDI_OFF_NOTE 0x80
-#define MIDI_ON_NOTE 0x90
-#define MIDI_POLY_TOUCH 0xa0
-#define MIDI_CTRL 0xb0
-#define MIDI_CH_PROGRAM 0xc0
-#define MIDI_TOUCH 0xd0
-#define MIDI_BEND 0xe0
-
-#define MIDI_SYSEX 0xf0
-#define MIDI_Q_FRAME 0xf1
-#define MIDI_SONG_POINTER 0xf2
-#define MIDI_SONG_SELECT 0xf3
-#define MIDI_TUNE_REQ 0xf6
-#define MIDI_EOX 0xf7
-#define MIDI_TIME_CLOCK 0xf8
-#define MIDI_START 0xfa
-#define MIDI_CONTINUE 0xfb
-#define MIDI_STOP 0xfc
-#define MIDI_ACTIVE_SENSING 0xfe
-#define MIDI_SYS_RESET 0xff
-
-#define MIDI_ALL_SOUND_OFF 0x78
-#define MIDI_RESET_CONTROLLERS 0x79
-#define MIDI_LOCAL 0x7a
-#define MIDI_ALL_OFF 0x7b
-#define MIDI_OMNI_OFF 0x7c
-#define MIDI_OMNI_ON 0x7d
-#define MIDI_MONO_ON 0x7e
-#define MIDI_POLY_ON 0x7f
-
-
-#define private static
-
-#ifndef false
-#define false 0
-#define true 1
-#endif
-
-typedef int boolean;
-
-int debug = false; /* never set, but referenced by userio.c */
-PmStream *midi_in; /* midi input */
-boolean active = false; /* set when midi_in is ready for reading */
-boolean in_sysex = false; /* we are reading a sysex message */
-boolean inited = false; /* suppress printing during command line parsing */
-boolean done = false; /* when true, exit */
-boolean notes = true; /* show notes? */
-boolean controls = true; /* show continuous controllers */
-boolean bender = true; /* record pitch bend etc.? */
-boolean excldata = true; /* record system exclusive data? */
-boolean verbose = true; /* show text representation? */
-boolean realdata = true; /* record real time messages? */
-boolean clksencnt = true; /* clock and active sense count on */
-boolean chmode = true; /* show channel mode messages */
-boolean pgchanges = true; /* show program changes */
-boolean flush = false; /* flush all pending MIDI data */
-
-uint32_t filter = 0; /* remember state of midi filter */
-
-uint32_t clockcount = 0; /* count of clocks */
-uint32_t actsensecount = 0; /* cout of active sensing bytes */
-uint32_t notescount = 0; /* #notes since last request */
-uint32_t notestotal = 0; /* total #notes */
-
-char val_format[] = " Val %d\n";
-
-/*****************************************************************************
-* Imported variables
-*****************************************************************************/
-
-extern int abort_flag;
-
-/*****************************************************************************
-* Routines local to this module
-*****************************************************************************/
-
-private void mmexit(int code);
-private void output(PmMessage data);
-private int put_pitch(int p);
-private void showhelp();
-private void showbytes(PmMessage data, int len, boolean newline);
-private void showstatus(boolean flag);
-private void doascii(char c);
-private int get_number(const char *prompt);
-
-
-/* read a number from console */
-/**/
-int get_number(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- while (getchar() != '\n') ;
- }
- return i;
-}
-
-
-void receive_poll(PtTimestamp timestamp, void *userData)
-{
- PmEvent event;
- int count;
- if (!active) return;
- while ((count = Pm_Read(midi_in, &event, 1))) {
- if (count == 1) output(event.message);
- else puts(Pm_GetErrorText(count));
- }
-}
-
-
-/****************************************************************************
-* main
-* Effect: prompts for parameters, starts monitor
-****************************************************************************/
-
-int main(int argc, char **argv)
-{
- char *argument;
- int inp;
- PmError err;
- int i;
- if (argc > 1) { /* first arg can change defaults */
- argument = argv[1];
- while (*argument) doascii(*argument++);
- }
- showhelp();
- /* use porttime callback to empty midi queue and print */
- Pt_Start(1, receive_poll, 0);
- /* list device information */
- puts("MIDI input devices:");
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if (info->input) printf("%d: %s, %s\n", i, info->interf, info->name);
- }
- inp = get_number("Type input device number: ");
- err = Pm_OpenInput(&midi_in, inp, NULL, 512, NULL, NULL);
- if (err) {
- puts(Pm_GetErrorText(err));
- Pt_Stop();
- mmexit(1);
- }
- Pm_SetFilter(midi_in, filter);
- inited = true; /* now can document changes, set filter */
- printf("Midi Monitor ready.\n");
- active = true;
- while (!done) {
- doascii(getchar());
- while (getchar() != '\n') ;
- }
- active = false;
- Pm_Close(midi_in);
- Pt_Stop();
- Pm_Terminate();
- mmexit(0);
- return 0; // make the compiler happy be returning a value
-}
-
-
-/****************************************************************************
-* doascii
-* Inputs:
-* char c: input character
-* Effect: interpret to revise flags
-****************************************************************************/
-
-private void doascii(char c)
-{
- if (isupper(c)) c = tolower(c);
- if (c == 'q') done = true;
- else if (c == 'b') {
- bender = !bender;
- filter ^= PM_FILT_PITCHBEND;
- if (inited)
- printf("Pitch Bend, etc. %s\n", (bender ? "ON" : "OFF"));
- } else if (c == 'c') {
- controls = !controls;
- filter ^= PM_FILT_CONTROL;
- if (inited)
- printf("Control Change %s\n", (controls ? "ON" : "OFF"));
- } else if (c == 'h') {
- pgchanges = !pgchanges;
- filter ^= PM_FILT_PROGRAM;
- if (inited)
- printf("Program Changes %s\n", (pgchanges ? "ON" : "OFF"));
- } else if (c == 'n') {
- notes = !notes;
- filter ^= PM_FILT_NOTE;
- if (inited)
- printf("Notes %s\n", (notes ? "ON" : "OFF"));
- } else if (c == 'x') {
- excldata = !excldata;
- filter ^= PM_FILT_SYSEX;
- if (inited)
- printf("System Exclusive data %s\n", (excldata ? "ON" : "OFF"));
- } else if (c == 'r') {
- realdata = !realdata;
- filter ^= (PM_FILT_PLAY | PM_FILT_RESET | PM_FILT_TICK | PM_FILT_UNDEFINED);
- if (inited)
- printf("Real Time messages %s\n", (realdata ? "ON" : "OFF"));
- } else if (c == 'k') {
- clksencnt = !clksencnt;
- if (inited) {
- printf("Clock and Active Sense Counting %s\n", (clksencnt ? "ON" : "OFF"));
- printf("Resetting Clock and Active Sense counts.\n");
- clockcount = actsensecount = 0;
- }
- } else if (c == 's') {
- if (inited) {
- printf("Clock Count %ld\nActive Sense Count %ld\n",
- (long) clockcount, (long) actsensecount);
- }
- } else if (c == 't') {
- notestotal+=notescount;
- if (inited)
- printf("This Note Count %ld\nTotal Note Count %ld\n",
- (long) notescount, (long) notestotal);
- notescount=0;
- } else if (c == 'v') {
- verbose = !verbose;
- if (inited)
- printf("Verbose %s\n", (verbose ? "ON" : "OFF"));
- } else if (c == 'm') {
- chmode = !chmode;
- if (inited)
- printf("Channel Mode Messages %s", (chmode ? "ON" : "OFF"));
- } else {
- if (inited) {
- if (c == ' ') {
- PmEvent event;
- while (Pm_Read(midi_in, &event, 1)) ; /* flush midi input */
- printf("...FLUSHED MIDI INPUT\n\n");
- } else showhelp();
- }
- }
- if (inited) Pm_SetFilter(midi_in, filter);
-}
-
-
-
-private void mmexit(int code)
-{
- /* if this is not being run from a console, maybe we should wait for
- * the user to read error messages before exiting
- */
- exit(code);
-}
-
-
-/****************************************************************************
-* output
-* Inputs:
-* data: midi message buffer holding one command or 4 bytes of sysex msg
-* Effect: format and print midi data
-****************************************************************************/
-
-char vel_format[] = " Vel %d\n";
-
-private void output(PmMessage data)
-{
- int command; /* the current command */
- int chan; /* the midi channel of the current event */
- int len; /* used to get constant field width */
-
- /* printf("output data %8x; ", data); */
-
- command = Pm_MessageStatus(data) & MIDI_CODE_MASK;
- chan = Pm_MessageStatus(data) & MIDI_CHN_MASK;
-
- if (in_sysex || Pm_MessageStatus(data) == MIDI_SYSEX) {
-#define sysex_max 16
- int i;
- PmMessage data_copy = data;
- in_sysex = true;
- /* look for MIDI_EOX in first 3 bytes
- * if realtime messages are embedded in sysex message, they will
- * be printed as if they are part of the sysex message
- */
- for (i = 0; (i < 4) && ((data_copy & 0xFF) != MIDI_EOX); i++)
- data_copy >>= 8;
- if (i < 4) {
- in_sysex = false;
- i++; /* include the EOX byte in output */
- }
- showbytes(data, i, verbose);
- if (verbose) printf("System Exclusive\n");
- } else if (command == MIDI_ON_NOTE && Pm_MessageData2(data) != 0) {
- notescount++;
- if (notes) {
- showbytes(data, 3, verbose);
- if (verbose) {
- printf("NoteOn Chan %2d Key %3d ", chan, Pm_MessageData1(data));
- len = put_pitch(Pm_MessageData1(data));
- printf(vel_format + len, Pm_MessageData2(data));
- }
- }
- } else if ((command == MIDI_ON_NOTE /* && Pm_MessageData2(data) == 0 */ ||
- command == MIDI_OFF_NOTE)) {
- if (notes) {
- showbytes(data, 3, verbose);
- if (verbose) {
- printf("NoteOff Chan %2d Key %3d ", chan,
- Pm_MessageData1(data));
- len = put_pitch(Pm_MessageData1(data));
- printf(vel_format + len, Pm_MessageData2(data));
- }
- }
- } else if (command == MIDI_CH_PROGRAM) {
- if (pgchanges) {
- showbytes(data, 2, verbose);
- if (verbose) {
- printf(" ProgChg Chan %2d Prog %2d\n", chan,
- Pm_MessageData1(data) + 1);
- }
- }
- } else if (command == MIDI_CTRL) {
- /* controls 121 (MIDI_RESET_CONTROLLER) to 127 are channel
- * mode messages. */
- if (Pm_MessageData1(data) < MIDI_ALL_SOUND_OFF) {
- if (controls) {
- showbytes(data, 3, verbose);
- if (verbose) {
- printf("CtrlChg Chan %2d Ctrl %2d Val %2d\n",
- chan, Pm_MessageData1(data), Pm_MessageData2(data));
- }
- } else /* channel mode */ if (chmode) {
- showbytes(data, 3, verbose);
- if (verbose) {
- switch (Pm_MessageData1(data)) {
- case MIDI_ALL_SOUND_OFF:
- printf("All Sound Off, Chan %2d\n", chan);
- break;
- case MIDI_RESET_CONTROLLERS:
- printf("Reset All Controllers, Chan %2d\n", chan);
- break;
- case MIDI_LOCAL:
- printf("LocCtrl Chan %2d %s\n",
- chan, Pm_MessageData2(data) ? "On" : "Off");
- break;
- case MIDI_ALL_OFF:
- printf("All Off Chan %2d\n", chan);
- break;
- case MIDI_OMNI_OFF:
- printf("OmniOff Chan %2d\n", chan);
- break;
- case MIDI_OMNI_ON:
- printf("Omni On Chan %2d\n", chan);
- break;
- case MIDI_MONO_ON:
- printf("Mono On Chan %2d\n", chan);
- if (Pm_MessageData2(data))
- printf(" to %d received channels\n",
- Pm_MessageData2(data));
- else
- printf(" to all received channels\n");
- break;
- case MIDI_POLY_ON:
- printf("Poly On Chan %2d\n", chan);
- break;
- }
- }
- }
- }
- } else if (command == MIDI_POLY_TOUCH) {
- if (bender) {
- showbytes(data, 3, verbose);
- if (verbose) {
- printf("P.Touch Chan %2d Key %2d ", chan,
- Pm_MessageData1(data));
- len = put_pitch(Pm_MessageData1(data));
- printf(val_format + len, Pm_MessageData2(data));
- }
- }
- } else if (command == MIDI_TOUCH) {
- if (bender) {
- showbytes(data, 2, verbose);
- if (verbose) {
- printf(" A.Touch Chan %2d Val %2d\n", chan,
- Pm_MessageData1(data));
- }
- }
- } else if (command == MIDI_BEND) {
- if (bender) {
- showbytes(data, 3, verbose);
- if (verbose) {
- printf("P.Bend Chan %2d Val %2d\n", chan,
- (Pm_MessageData1(data) + (Pm_MessageData2(data)<<7)));
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_SONG_POINTER) {
- showbytes(data, 3, verbose);
- if (verbose) {
- printf(" Song Position %d\n",
- (Pm_MessageData1(data) + (Pm_MessageData2(data)<<7)));
- }
- } else if (Pm_MessageStatus(data) == MIDI_SONG_SELECT) {
- showbytes(data, 2, verbose);
- if (verbose) {
- printf(" Song Select %d\n", Pm_MessageData1(data));
- }
- } else if (Pm_MessageStatus(data) == MIDI_TUNE_REQ) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" Tune Request\n");
- }
- } else if (Pm_MessageStatus(data) == MIDI_Q_FRAME) {
- if (realdata) {
- showbytes(data, 2, verbose);
- if (verbose) {
- printf(" Time Code Quarter Frame Type %d Values %d\n",
- (Pm_MessageData1(data) & 0x70) >> 4,
- Pm_MessageData1(data) & 0xf);
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_START) {
- if (realdata) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" Start\n");
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_CONTINUE) {
- if (realdata) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" Continue\n");
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_STOP) {
- if (realdata) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" Stop\n");
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_SYS_RESET) {
- if (realdata) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" System Reset\n");
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_TIME_CLOCK) {
- clockcount++;
- if (clksencnt) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" Clock\n");
- }
- }
- } else if (Pm_MessageStatus(data) == MIDI_ACTIVE_SENSING) {
- actsensecount++;
- if (clksencnt) {
- showbytes(data, 1, verbose);
- if (verbose) {
- printf(" Active Sensing\n");
- }
- }
- } else showbytes(data, 3, verbose);
- fflush(stdout);
-}
-
-
-/****************************************************************************
-* put_pitch
-* Inputs:
-* int p: pitch number
-* Effect: write out the pitch name for a given number
-****************************************************************************/
-
-private int put_pitch(int p)
-{
- char result[8];
- static char *ptos[] = {
- "c", "cs", "d", "ef", "e", "f", "fs", "g",
- "gs", "a", "bf", "b" };
- /* note octave correction below */
- sprintf(result, "%s%d", ptos[p % 12], (p / 12) - 1);
- fputs(result, stdout);
- return (int) strlen(result);
-}
-
-
-/****************************************************************************
-* showbytes
-* Effect: print hex data, precede with newline if asked
-****************************************************************************/
-
-char nib_to_hex[] = "0123456789ABCDEF";
-
-private void showbytes(PmMessage data, int len, boolean newline)
-{
- int count = 0;
- int i;
-
-/* if (newline) {
- putchar('\n');
- count++;
- } */
- for (i = 0; i < len; i++) {
- putchar(nib_to_hex[(data >> 4) & 0xF]);
- putchar(nib_to_hex[data & 0xF]);
- count += 2;
- if (count > 72) {
- putchar('.');
- putchar('.');
- putchar('.');
- break;
- }
- data >>= 8;
- }
- putchar(' ');
-}
-
-
-
-/****************************************************************************
-* showhelp
-* Effect: print help text
-****************************************************************************/
-
-private void showhelp()
-{
- printf("\n");
- printf(" Item Reported Range Item Reported Range\n");
- printf(" ------------- ----- ------------- -----\n");
- printf(" Channels 1 - 16 Programs 1 - 128\n");
- printf(" Controllers 0 - 127 After Touch 0 - 127\n");
- printf(" Loudness 0 - 127 Pitch Bend 0 - 16383, "
- "center = 8192\n");
- printf(" Pitches 0 - 127, 60 = c4 = middle C\n");
- printf(" \n");
- printf("n toggles notes");
- showstatus(notes);
- printf("t displays noteon count since last t\n");
- printf("b toggles pitch bend, aftertouch");
- showstatus(bender);
- printf("c toggles continuous control");
- showstatus(controls);
- printf("h toggles program changes");
- showstatus(pgchanges);
- printf("x toggles system exclusive");
- showstatus(excldata);
- printf("k toggles clock and sense messages, clears counts");
- showstatus(clksencnt);
- printf("r toggles other real time messages & SMPTE");
- showstatus(realdata);
- printf("s displays clock and sense count since last k\n");
- printf("m toggles channel mode messages");
- showstatus(chmode);
- printf("v toggles verbose text");
- showstatus(verbose);
- printf("q quits\n");
- printf("\n");
-}
-
-/****************************************************************************
-* showstatus
-* Effect: print status of flag
-****************************************************************************/
-
-private void showstatus(boolean flag)
-{
- printf(", now %s\n", flag ? "ON" : "OFF");
-}
diff --git a/portmidi/pm_test/multivirtual.c b/portmidi/pm_test/multivirtual.c
deleted file mode 100644
index b90d860..0000000
--- a/portmidi/pm_test/multivirtual.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* multivirtual.c -- test for creating two input and two output virtual ports */
-/*
- * Roger B. Dannenberg
- * Oct 2021
- */
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define OUTPUT_BUFFER_SIZE 0
-#define DEVICE_INFO NULL
-#define DRIVER_INFO NULL
-#define TIME_PROC ((PmTimeProcPtr) Pt_Time)
-#define TIME_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-int latency = 0;
-
-static void prompt_and_exit(void)
-{
- printf("type ENTER...");
- while (getchar() != '\n') ;
- /* this will clean up open ports: */
- exit(-1);
-}
-
-
-static PmError checkerror(PmError err)
-{
- if (err == pmHostError) {
- /* it seems pointless to allocate memory and copy the string,
- * so I will do the work of Pm_GetHostErrorText directly
- */
- char errmsg[80];
- Pm_GetHostErrorText(errmsg, 80);
- printf("PortMidi found host error...\n %s\n", errmsg);
- prompt_and_exit();
- } else if (err < 0) {
- printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
- prompt_and_exit();
- }
- return err;
-}
-
-static int msg_count[2] = {0, 0};
-
-void poll_input(PmStream *in, int which)
-{
- PmEvent buffer[1];
- int pitch, expected, length;
- PmError status = Pm_Poll(in);
- if (status == TRUE) {
- length = Pm_Read(in, buffer, 1);
- if (length > 0) {
- printf("Got message %d from portmidi%d: "
- "time %ld, %2x %2x %2x\n",
- msg_count[which], which + 1, (long) buffer[0].timestamp,
- (status = Pm_MessageStatus(buffer[0].message)),
- (pitch = Pm_MessageData1(buffer[0].message)),
- Pm_MessageData2(buffer[0].message));
- if (status == 0x90) { /* 1 & 2 are on/off 60, 3 & 4 are 61, etc. */
- expected = (((msg_count[which] - 1) / 2) % 12) + 60 +
- which * 12;
- if (pitch != expected) {
- printf("WARNING: expected pitch %d, got pitch %d\n",
- expected, pitch);
- }
- }
- msg_count[which]++;
- } else {
- assert(0);
- }
- }
-}
-
-
-void wait_until(PmTimestamp when, PmStream *in1, PmStream *in2)
-{
- while (when > Pt_Time()) {
- poll_input(in1, 0);
- poll_input(in2, 1);
- Pt_Sleep(10);
- }
-}
-
-
-/* create one virtual output device and one input device */
-void init(const char *name, PmStream **midi_out, PmStream **midi_in,
- int *id_out, int *id_in)
-{
- PmEvent buffer[1];
-
- *id_out = checkerror(Pm_CreateVirtualOutput(name, NULL, DEVICE_INFO));
- checkerror(Pm_OpenOutput(midi_out, *id_out, DRIVER_INFO, OUTPUT_BUFFER_SIZE,
- TIME_PROC, TIME_INFO, latency));
- printf("Virtual Output \"%s\" id %d created and opened.\n", name, *id_out);
-
- *id_in = checkerror(Pm_CreateVirtualInput(name, NULL, DRIVER_INFO));
- checkerror(Pm_OpenInput(midi_in, *id_in, NULL, 0, NULL, NULL));
- printf("Virtual Input \"%s\" id %d created and opened.\n", name, *id_in);
- Pm_SetFilter(*midi_in, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
- /* empty the buffer after setting filter, just in case anything
- got through */
- while (Pm_Read(*midi_in, buffer, 1)) ;
-}
-
-
-void main_test(int num)
-{
- PmStream *midi1_out;
- PmStream *midi2_out;
- PmStream *midi1_in;
- PmStream *midi2_in;
- int id1_out;
- int id2_out;
- int id1_in;
- int id2_in;
- int32_t next_time;
- PmEvent buffer[1];
- int pitch = 60;
- int expected_count = num + 1; /* add 1 for MIDI Program message */
-
- /* It is recommended to start timer before Midi; otherwise, PortMidi may
- start the timer with its (default) parameters
- */
- TIME_START;
-
- init("portmidi1", &midi1_out, &midi1_in, &id1_out, &id1_in);
- init("portmidi2", &midi2_out, &midi2_in, &id2_out, &id2_in);
-
- printf("Type ENTER to send messages: ");
- while (getchar() != '\n') ;
-
- buffer[0].timestamp = Pt_Time();
-#define PROGRAM 0
- buffer[0].message = Pm_Message(0xC0, PROGRAM, 0);
- Pm_Write(midi1_out, buffer, 1);
- Pm_Write(midi2_out, buffer, 1);
- next_time = Pt_Time() + 1000; /* wait 1s */
- while (num > 0) {
- wait_until(next_time, midi1_in, midi2_in);
- Pm_WriteShort(midi1_out, next_time, Pm_Message(0x90, pitch, 100));
- Pm_WriteShort(midi2_out, next_time, Pm_Message(0x90, pitch + 12, 100));
- printf("Note On pitch %d\n", pitch);
- num--;
- next_time += 500;
-
- wait_until(next_time, midi1_in, midi2_in);
- Pm_WriteShort(midi1_out, next_time, Pm_Message(0x90, pitch, 0));
- Pm_WriteShort(midi2_out, next_time, Pm_Message(0x90, pitch + 12, 0));
- printf("Note Off pitch %d\n", pitch);
- num--;
- pitch = (pitch + 1) % 12 + 60;
- next_time += 500;
- }
- wait_until(next_time, midi1_in, midi2_in); /* get final note-offs */
-
- printf("Got %d messages from portmidi1 and %d from portmidi2; "
- "expected %d.\n", msg_count[0], msg_count[1], expected_count);
-
- /* close devices (this not explicitly needed in most implementations) */
- printf("ready to close...");
- checkerror(Pm_Close(midi1_out));
- checkerror(Pm_Close(midi2_out));
- checkerror(Pm_Close(midi1_in));
- checkerror(Pm_Close(midi2_in));
- printf("done closing.\nNow delete the virtual devices...");
- checkerror(Pm_DeleteVirtualDevice(id1_out));
- checkerror(Pm_DeleteVirtualDevice(id1_in));
- checkerror(Pm_DeleteVirtualDevice(id2_out));
- checkerror(Pm_DeleteVirtualDevice(id2_in));
- printf("done deleting.\n");
-}
-
-
-void show_usage()
-{
- printf("Usage: multivirtual [-h] [-l latency-in-ms] [n]\n"
- " -h for this message,\n"
- " -l ms designates latency for precise timing (default 0),\n"
- " n is number of message to send each output, not counting\n"
- " initial program change.\n"
- "sends change program to 1, then one note per second with 0.5s on,\n"
- "0.5s off, for n/2 seconds to both output ports portmidi1 and\n"
- "portmidi2. portmidi1 gets pitches from C4 (60). portmidi2 gets\n"
- "pitches an octave higher. Latency >0 uses the device driver for \n"
- "precise timing (see PortMidi documentation). Inputs print what\n"
- "they get and print WARNING if they get something unexpected.\n"
- "The expected test is use two instances of testio to loop\n"
- "portmidi1 back to portmidi1 and portmidi2 back to portmidi2.\n");
- exit(0);
-}
-
-
-int main(int argc, char *argv[])
-{
- int num = 10;
- int i;
- 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 %d\n", latency);
- } else {
- num = atoi(argv[1]);
- if (num <= 0) {
- show_usage();
- }
- printf("Sending %d messages.\n", num);
- }
- }
-
- main_test(num);
-
- printf("finished sendvirtual test...type ENTER to quit...");
- while (getchar() != '\n') ;
- return 0;
-}
diff --git a/portmidi/pm_test/pmlist.c b/portmidi/pm_test/pmlist.c
deleted file mode 100644
index 5e3d1db..0000000
--- a/portmidi/pm_test/pmlist.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* pmlist.c -- list portmidi devices and numbers
- *
- * This program lists devices. When you type return, it
- * restarts portmidi and lists devices again. It is mainly
- * a test for shutting down and restarting.
- *
- * Roger B. Dannenberg, Feb 2022
- */
-
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define DEVICE_INFO NULL
-#define DRIVER_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-#define STRING_MAX 80 /* used for console input */
-
-void show_usage()
-{
- printf("Usage: pmlist [-h]\n -h means help.\n"
- " Type return to rescan and list devices, q<ret> to quit\n");
-}
-
-
-int main(int argc, char *argv[])
-{
- if (argc > 1) {
- show_usage();
- exit(0);
- }
-
- while (1) {
- char input[STRING_MAX];
- const char *deflt;
- const char *in_or_out;
- int default_in, default_out, i;
-
- // Pm_Initialize();
- /* list device information */
- default_in = Pm_GetDefaultInputDeviceID();
- default_out = Pm_GetDefaultOutputDeviceID();
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- printf("%d: %s, %s", i, info->interf, info->name);
- deflt = "";
- if (i == default_out || i == default_in) {
- deflt = "default ";
- }
- in_or_out = (info->input ? "input" : "output");
- printf(" (%s%s)\n", deflt, in_or_out);
- }
- if (fgets(input, STRING_MAX, stdin) && input[0] == 'q') {
- return 0;
- }
- Pm_Terminate();
- }
- return 0;
-}
diff --git a/portmidi/pm_test/qtest.c b/portmidi/pm_test/qtest.c
deleted file mode 100644
index 14d803e..0000000
--- a/portmidi/pm_test/qtest.c
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "portmidi.h"
-#include "pmutil.h"
-#include "stdlib.h"
-#include "stdio.h"
-
-
-/* make_msg -- make a psuedo-random message of length n whose content
- * is purely a function of i
- */
-void make_msg(long msg[], int n, int i)
-{
- int j;
- for (j = 0; j < n; j++) {
- msg[j] = i % (j + 5);
- }
-}
-
-
-/* print_msg -- print the content of msg of length n to stdout */
-/**/
-void print_msg(long msg[], int n)
-{
- int i;
- for (i = 0; i < n; i++) {
- printf(" %li", msg[i]);
- }
-}
-
-
-/* cmp_msg -- compare two messages of length n */
-/**/
-int cmp_msg(long msg[], long msg2[], int n, int i)
-{
- int j;
- for (j = 0; j < n; j++) {
- if (msg[j] != msg2[j]) {
- printf("Received message %d doesn't match sent message\n", i);
- printf("in: "); print_msg(msg, n); printf("\n");
- printf("out:"); print_msg(msg2, n); printf("\n");
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
-int main()
-{
- int msg_len;
- for (msg_len = 4; msg_len < 100; msg_len += 5) {
- PmQueue *queue = Pm_QueueCreate(100, msg_len * sizeof(long));
- int i;
- long msg[100];
- long msg2[100];
-
- printf("msg_len = %d\n", msg_len);
- if (!queue) {
- printf("Could not allocate queue\n");
- return 1;
- }
-
- /* insert/remove 1000 messages */
- printf("test 1\n");
- for (i = 0; i < 1357; i++) {
- make_msg(msg, msg_len, i);
- if (Pm_Enqueue(queue, msg)) {
- printf("Pm_Enqueue error\n");
- return 1;
- }
- if (Pm_Dequeue(queue, msg2) != 1) {
- printf("Pm_Dequeue error\n");
- return 1;
- }
- if (!cmp_msg(msg, msg2, msg_len, i)) {
- return 1;
- }
- }
-
- /* make full */
- printf("test 2\n");
- for (i = 0; i < 100; i++) {
- make_msg(msg, msg_len, i);
- if (Pm_Enqueue(queue, msg)) {
- printf("Pm_Enqueue error\n");
- return 1;
- }
- }
-
- /* alternately remove and insert */
- for (i = 100; i < 1234; i++) {
- make_msg(msg, msg_len, i - 100); /* what we expect */
- if (Pm_Dequeue(queue, msg2) != 1) {
- printf("Pm_Dequeue error\n");
- return 1;
- }
- if (!cmp_msg(msg, msg2, msg_len, i)) {
- return 1;
- }
- make_msg(msg, msg_len, i);
- if (Pm_Enqueue(queue, msg)) {
- printf("Pm_Enqueue error\n");
- return 1;
- }
- }
-
- /* remove all */
- while (!Pm_QueueEmpty(queue)) {
- make_msg(msg, msg_len, i - 100); /* what we expect */
- if (Pm_Dequeue(queue, msg2) != 1) {
- printf("Pm_Dequeue error\n");
- return 1;
- }
- if (!cmp_msg(msg, msg2, msg_len, i)) {
- return 1;
- }
- i++;
- }
- if (i != 1334) {
- printf("Message count error\n");
- return 1;
- }
-
- /* now test overflow */
- printf("test 3\n");
- for (i = 0; i < 110; i++) {
- make_msg(msg, msg_len, i);
- if (Pm_Enqueue(queue, msg) == pmBufferOverflow) {
- break; /* this is supposed to execute after 100 messages */
- }
- }
- for (i = 0; i < 100; i++) {
- make_msg(msg, msg_len, i);
- if (Pm_Dequeue(queue, msg2) != 1) {
- printf("Pm_Dequeue error\n");
- return 1;
- }
- if (!cmp_msg(msg, msg2, msg_len, i)) {
- return 1;
- }
- }
- /* we should detect overflow after removing 100 messages */
- if (Pm_Dequeue(queue, msg2) != pmBufferOverflow) {
- printf("Pm_Dequeue overflow expected\n");
- return 1;
- }
-
- /* after overflow is detected (and cleared), sender can
- * send again
- */
- /* see if function is restored, also test peek */
- printf("test 4\n");
- for (i = 0; i < 1357; i++) {
- long *peek;
- make_msg(msg, msg_len, i);
- if (Pm_Enqueue(queue, msg)) {
- printf("Pm_Enqueue error\n");
- return 1;
- }
- peek = (long *) Pm_QueuePeek(queue);
- if (!cmp_msg(msg, peek, msg_len, i)) {
- return 1;
- }
- if (Pm_Dequeue(queue, msg2) != 1) {
- printf("Pm_Dequeue error\n");
- return 1;
- }
- if (!cmp_msg(msg, msg2, msg_len, i)) {
- return 1;
- }
- }
- Pm_QueueDestroy(queue);
- }
- return 0;
-}
diff --git a/portmidi/pm_test/recvvirtual.c b/portmidi/pm_test/recvvirtual.c
deleted file mode 100644
index f8d9848..0000000
--- a/portmidi/pm_test/recvvirtual.c
+++ /dev/null
@@ -1,175 +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 TIME_PROC ((PmTimeProcPtr) 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 */
-
-char *portname = "portmidi";
-
-PmSysDepInfo *sysdepinfo = NULL;
-char *port_name = "portmidi";
-
-static void set_sysdepinfo(char m_or_p, const char *name)
-{
- if (!sysdepinfo) {
- // allocate some space we will alias with open-ended PmDriverInfo:
- // there is space for 4 parameters:
- static char dimem[sizeof(PmSysDepInfo) + sizeof(void *) * 8];
- sysdepinfo = (PmSysDepInfo *) dimem;
- // build the driver info structure:
- sysdepinfo->structVersion = PM_SYSDEPINFO_VERS;
- sysdepinfo->length = 0;
- }
- if (sysdepinfo->length > 1) {
- printf("Error: sysdepinfo was allocated to hold 2 parameters\n");
- exit(1);
- }
- int i = sysdepinfo->length++;
- enum PmSysDepPropertyKey k = pmKeyNone;
- if (m_or_p == 'm') k = pmKeyCoreMidiManufacturer;
- else if (m_or_p == 'p') k = pmKeyAlsaPortName;
- else if (m_or_p == 'c') k = pmKeyAlsaClientName;
- sysdepinfo->properties[i].key = k;
- sysdepinfo->properties[i].value = name;
-}
-
-
-static void prompt_and_exit(void)
-{
- printf("type ENTER...");
- while (getchar() != '\n') ;
- /* this will clean up open ports: */
- exit(-1);
-}
-
-
-static PmError checkerror(PmError err)
-{
- if (err == pmHostError) {
- /* it seems pointless to allocate memory and copy the string,
- * so I will do the work of Pm_GetHostErrorText directly
- */
- char errmsg[80];
- Pm_GetHostErrorText(errmsg, 80);
- printf("PortMidi found host error...\n %s\n", errmsg);
- prompt_and_exit();
- } else if (err < 0) {
- printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
- prompt_and_exit();
- }
- return err;
-}
-
-
-void main_test_input(int num)
-{
- PmStream *midi;
- PmError status, length;
- PmEvent buffer[1];
- int id;
- int i = 0; /* count messages as they arrive */
- /* It is recommended to start timer before Midi; otherwise, PortMidi may
- start the timer with its (default) parameters
- */
- TIME_START;
-
- /* create a virtual input device */
- id = checkerror(Pm_CreateVirtualInput(port_name, NULL, sysdepinfo));
- checkerror(Pm_OpenInput(&midi, id, sysdepinfo, 0, NULL, NULL));
-
- 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 */
- 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);
- }
- }
- }
-
- /* close device (this not explicitly needed in most implementations) */
- printf("ready to close...");
- Pm_Close(midi);
- printf("done closing.\nNow delete the virtual device...");
- checkerror(Pm_DeleteVirtualDevice(id));
- printf("done deleting.\n");
-}
-
-
-void show_usage()
-{
- printf("Usage: recvvirtual [-h] [-m manufacturer] [-c clientname] "
- "[-p portname] [n]\n"
- " -h for this message,\n"
- " -m name designates a manufacturer name (macOS only),\n"
- " -c name designates a client name (linux only),\n"
- " -p name designates a port name (linux only),\n"
- " n is number of message to wait for.\n");
- exit(0);
-}
-
-
-int main(int argc, char *argv[])
-{
- char line[STRING_MAX];
- int num = 10;
- int i;
- if (argc <= 1) {
- show_usage();
- }
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-h") == 0) {
- show_usage();
- } else if (strcmp(argv[i], "-m") == 0 && (i + 1 < argc)) {
- i = i + 1;
- set_sysdepinfo('m', argv[i]);
- printf("Manufacturer name will be %s\n", argv[i]);
- } else if (strcmp(argv[i], "-p") == 0 && (i + 1 < argc)) {
- i = i + 1;
- port_name = argv[i];
- set_sysdepinfo('p', port_name);
- printf("Port name will be %s\n", port_name);
- } else if (strcmp(argv[i], "-c") == 0 && (i + 1 < argc)) {
- i = i + 1;
- set_sysdepinfo('c', argv[i]);
- printf("Client name will be %s\n", argv[i]);
- } else {
- num = atoi(argv[i]);
- if (num <= 0) {
- printf("Zero value or non-number for n\n");
- show_usage();
- }
- printf("Waiting for %d messages.\n", num);
- }
- }
-
- main_test_input(num);
-
- printf("finished portMidi test...type ENTER to quit...");
- while (getchar() != '\n') ;
- return 0;
-}
diff --git a/portmidi/pm_test/sendvirtual.c b/portmidi/pm_test/sendvirtual.c
deleted file mode 100644
index a60a48f..0000000
--- a/portmidi/pm_test/sendvirtual.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/* sendvirtual.c -- test for creating a virtual device and sending to it */
-/*
- * Roger B. Dannenberg
- * Sep 2021
- */
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define OUTPUT_BUFFER_SIZE 0
-#define TIME_PROC ((PmTimeProcPtr) Pt_Time)
-#define TIME_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-int latency = 0;
-PmSysDepInfo *sysdepinfo = NULL;
-char *port_name = "portmidi";
-
-static void set_sysdepinfo(char m_or_p, const char *name)
-{
- if (!sysdepinfo) {
- // allocate some space we will alias with open-ended PmDriverInfo:
- // there is space for 4 parameters:
- static char dimem[sizeof(PmSysDepInfo) + sizeof(void *) * 8];
- sysdepinfo = (PmSysDepInfo *) dimem;
- // build the driver info structure:
- sysdepinfo->structVersion = PM_SYSDEPINFO_VERS;
- sysdepinfo->length = 0;
- }
- if (sysdepinfo->length > 1) {
- printf("Error: sysdepinfo was allocated to hold 2 parameters\n");
- exit(1);
- }
- int i = sysdepinfo->length++;
- enum PmSysDepPropertyKey k = pmKeyNone;
- if (m_or_p == 'm') k = pmKeyCoreMidiManufacturer;
- else if (m_or_p == 'p') k = pmKeyAlsaPortName;
- else if (m_or_p == 'c') k = pmKeyAlsaClientName;
- sysdepinfo->properties[i].key = k;
- sysdepinfo->properties[i].value = name;
-}
-
-
-static void prompt_and_exit(void)
-{
- printf("type ENTER...");
- while (getchar() != '\n') ;
- /* this will clean up open ports: */
- exit(-1);
-}
-
-
-static PmError checkerror(PmError err)
-{
- if (err == pmHostError) {
- /* it seems pointless to allocate memory and copy the string,
- * so I will do the work of Pm_GetHostErrorText directly
- */
- char errmsg[80];
- Pm_GetHostErrorText(errmsg, 80);
- printf("PortMidi found host error...\n %s\n", errmsg);
- prompt_and_exit();
- } else if (err < 0) {
- printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
- prompt_and_exit();
- }
- return err;
-}
-
-
-void wait_until(PmTimestamp when)
-{
- PtTimestamp now = Pt_Time();
- if (when > now) {
- Pt_Sleep(when - now);
- }
-}
-
-
-void main_test_output(int num)
-{
- PmStream *midi;
- int32_t next_time;
- PmEvent buffer[1];
- PmTimestamp timestamp;
- int pitch = 60;
- int id;
-
- /* It is recommended to start timer before Midi; otherwise, PortMidi may
- start the timer with its (default) parameters
- */
- TIME_START;
-
- /* create a virtual output device */
- id = checkerror(Pm_CreateVirtualOutput(port_name, NULL, sysdepinfo));
- checkerror(Pm_OpenOutput(&midi, id, sysdepinfo, OUTPUT_BUFFER_SIZE,
- TIME_PROC, TIME_INFO, latency));
-
- printf("Midi Output Virtual Device \"%s\" created.\n", port_name);
- printf("Type ENTER to send messages: ");
- while (getchar() != '\n') ;
-
- buffer[0].timestamp = Pt_Time();
-#define PROGRAM 0
- buffer[0].message = Pm_Message(0xC0, PROGRAM, 0);
- Pm_Write(midi, buffer, 1);
- next_time = Pt_Time() + 1000; /* wait 1s */
- while (num > 0) {
- wait_until(next_time);
- Pm_WriteShort(midi, next_time, Pm_Message(0x90, pitch, 100));
- printf("Note On pitch %d\n", pitch);
- num--;
- next_time += 500;
-
- wait_until(next_time);
- Pm_WriteShort(midi, next_time, Pm_Message(0x90, pitch, 0));
- printf("Note Off pitch %d\n", pitch);
- num--;
- pitch = (pitch + 1) % 12 + 60;
- next_time += 500;
- }
-
- /* close device (this not explicitly needed in most implementations) */
- printf("ready to close...");
- Pm_Close(midi);
- printf("done closing.\nNow delete the virtual device...");
- checkerror(Pm_DeleteVirtualDevice(id));
- printf("done deleting.\n");
-}
-
-
-void show_usage()
-{
- printf("Usage: sendvirtual [-h] [-l latency-in-ms] [-m manufacturer] "
- "[-c clientname] [-p portname] [n]\n"
- " -h for this message,\n"
- " -l ms designates latency for precise timing (default 0),\n"
- " -m name designates a manufacturer name (macOS only),\n"
- " -c name designates a client name (linux only),\n"
- " -p name designates a port name (linux only),\n"
- " n is number of message to send.\n"
- "sends change program to 1, then one note per second with 0.5s on,\n"
- "0.5s off, for n/2 seconds. Latency >0 uses the device driver for \n"
- "precise timing (see PortMidi documentation).\n");
- exit(0);
-}
-
-
-int main(int argc, char *argv[])
-{
- int num = 10;
- int i;
- if (argc <= 1) {
- show_usage();
- }
- 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 %d\n", latency);
- } else if (strcmp(argv[i], "-m") == 0 && (i + 1 < argc)) {
- i = i + 1;
- set_sysdepinfo('m', argv[i]);
- printf("Manufacturer name will be %s\n", argv[i]);
- } else if (strcmp(argv[i], "-p") == 0 && (i + 1 < argc)) {
- i = i + 1;
- port_name = argv[i];
- set_sysdepinfo('p', port_name);
- printf("Port name will be %s\n", port_name);
- } else if (strcmp(argv[i], "-c") == 0 && (i + 1 < argc)) {
- i = i + 1;
- set_sysdepinfo('c', argv[i]);
- printf("Client name will be %s\n", argv[i]);
- } else {
- num = atoi(argv[i]);
- if (num <= 0) {
- printf("Zero value or non-number for n\n");
- show_usage();
- }
- printf("Sending %d messages.\n", num);
- }
- }
-
- main_test_output(num);
-
- printf("finished sendvirtual test...type ENTER to quit...");
- while (getchar() != '\n') ;
- return 0;
-}
diff --git a/portmidi/pm_test/sysex.c b/portmidi/pm_test/sysex.c
deleted file mode 100755
index c2c7187..0000000
--- a/portmidi/pm_test/sysex.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/* sysex.c -- example program showing how to send and receive sysex
- messages
-
- Messages are stored in a file using 2-digit hexadecimal numbers,
- one per byte, separated by blanks, with up to 32 numbers per line:
- F0 14 A7 4B ...
-
- */
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "assert.h"
-#include "portmidi.h"
-#include "porttime.h"
-#include "string.h"
-#ifdef WIN32
-// need to get declaration for Sleep()
-#include "windows.h"
-#else
-#include <unistd.h>
-#define Sleep(n) usleep(n * 1000)
-#endif
-
-// enable some extra printing
-#ifndef VERBOSE
-#define VERBOSE 0
-#endif
-
-#define MIDI_SYSEX 0xf0
-#define MIDI_EOX 0xf7
-
-#define STRING_MAX 80
-
-#ifndef true
-#define true 1
-#define false 0
-#endif
-
-int latency = 0;
-
-/* read a number from console */
-/**/
-int get_number(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- while (getchar() != '\n') ;
- }
- return i;
-}
-
-
-/* loopback test -- send/rcv from 2 to 1000 bytes of random midi data */
-/**/
-void loopback_test()
-{
- int outp;
- int inp;
- PmStream *midi_in;
- PmStream *midi_out;
- unsigned char msg[1024];
- int32_t len;
- int i;
- int data;
- PmEvent event;
- int shift;
- long total_bytes = 0;
- int32_t begin_time;
-
- Pt_Start(1, 0, 0);
-
- printf("Connect a midi cable from an output port to an input port.\n");
- printf("This test will send random data via sysex message from output\n");
- printf("to input and check that the correct data was received.\n");
- outp = get_number("Type output device number: ");
- /* Open output with 1ms latency -- when latency is non-zero, the Win32
- implementation supports sending sysex messages incrementally in a
- series of buffers. This is nicer than allocating a big buffer for the
- message, and it also seems to work better. Either way works.
- */
- while ((latency = get_number(
- "Latency in milliseconds (0 to send data immediatedly,\n"
- " >0 to send timestamped messages): ")) < 0);
- Pm_OpenOutput(&midi_out, outp, NULL, 0, NULL, NULL, latency);
- inp = get_number("Type input device number: ");
- /* since we are going to send and then receive, make sure the input buffer
- is large enough for the entire message */
- Pm_OpenInput(&midi_in, inp, NULL, 512, NULL, NULL);
-
- srand((unsigned int) Pt_Time()); /* seed for random numbers */
-
- begin_time = Pt_Time();
- while (total_bytes < 100000) {
- PmError count;
- int32_t start_time;
- int error_position = -1; /* 0; -1; -1 for continuous */
- int expected = 0;
- int actual = 0;
- /* this modification will run until an error is detected */
- /* set error_position above to 0 for interactive, -1 for */
- /* continuous */
- if (error_position >= 0) {
- int c;
- printf("Type return to send message, q to quit: ");
- while ((c = getchar()) != '\n') {
- if (c == 'q') goto cleanup;
- }
- }
-
- /* compose the message */
- len = rand() % 998 + 2; /* len only counts data bytes */
- msg[0] = (char) MIDI_SYSEX; /* start of SYSEX message */
- /* data bytes go from 1 to len */
- for (i = 0; i < len; i++) {
-/* pick whether data is sequential or random... (docs say random) */
-#define DATA_EXPR (i+1)
-// #define DATA_EXPR rand()
- msg[i + 1] = DATA_EXPR & 0x7f; /* MIDI data */
- }
- /* final EOX goes in len+1, total of len+2 bytes in msg */
- msg[len + 1] = (char) MIDI_EOX;
-
- /* sanity check: before we send, there should be no queued data */
- count = Pm_Read(midi_in, &event, 1);
-
- if (count != 0) {
- printf("Before sending anything, a MIDI message was found in\n");
- printf("the input buffer. Please try again.\n");
- break;
- }
-
- /* send the message two ways: 1) Pm_WriteSysEx, 2) Pm_Write */
- if (total_bytes & 1) {
- printf("Sending %d byte sysex msg via Pm_WriteSysEx.\n", len + 2);
- Pm_WriteSysEx(midi_out, 0, msg);
- } else {
- PmEvent event = {0, 0};
- int bits = 0;
- printf("Sending %d byte sysex msg via Pm_Write(s).\n", len + 2);
- for (i = 0; i < len + 2; i++) {
- event.message |= (msg[i] << bits);
- bits += 8;
- if (bits == 32) { /* full message - send it */
- Pm_Write(midi_out, &event, 1);
- bits = 0;
- event.message = 0;
- }
- }
- if (bits > 0) { /* last message is partially full */
- Pm_Write(midi_out, &event, 1);
- }
- }
-
- /* receive the message and compare to msg[] */
- data = 0;
- shift = 0;
- i = 0;
- start_time = Pt_Time();
- if (VERBOSE) {
- printf("start_time %d\n", start_time);
- }
- error_position = -1;
- /* allow up to 2 seconds for transmission */
- while (data != MIDI_EOX && start_time + 2000 > Pt_Time()) {
- count = Pm_Read(midi_in, &event, 1);
- if (count == 0) {
- Sleep(1); /* be nice: give some CPU time to the system */
- continue; /* continue polling for input */
- }
- if (VERBOSE) {
- printf("read %08x ", event.message);
- fflush(stdout);
- }
- /* compare 4 bytes of data until you reach an eox */
- for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) {
- data = (event.message >> shift) & 0xFF;
- if (data != msg[i] && error_position < 0) {
- error_position = i;
- expected = msg[i];
- actual = data;
- }
- i++;
- }
- }
- if (error_position >= 0) {
- printf("Error at time %d byte %d: sent %x recd %x.\n", Pt_Time(),
- error_position, expected, actual);
- break;
- } else if (i != len + 2) {
- printf("Error at time %d: byte %d not received.\n", Pt_Time(), i);
- break;
- } else {
- int seconds = (Pt_Time() - begin_time) / 1000;
- if (seconds == 0) seconds = 1;
- printf("Correctly received %d byte sysex message.\n", i);
- total_bytes += i;
- printf("Cummulative bytes/sec: %d, %d%% done.\n",
- (int) (total_bytes / seconds),
- (int) (100 * total_bytes / 100000));
- }
- }
-cleanup:
- Pm_Close(midi_out);
- Pm_Close(midi_in);
- return;
-}
-
-
-/* send_multiple test -- send many sysex messages */
-/**/
-void send_multiple_test()
-{
- int outp;
- int length;
- int num_msgs;
- PmStream *midi_out;
- unsigned char msg[1024];
- int i;
- PtTimestamp start_time;
- PtTimestamp stop_time;
-
- Pt_Start(1, 0, 0);
-
- printf("This is for performance testing. You should be sending to this\n");
- printf("program running the receive multiple test. Do NOT send to\n");
- printf("a synthesizer or you risk reprogramming it\n");
- outp = get_number("Type output device number: ");
- while ((latency = get_number(
- "Latency in milliseconds (0 to send data immediatedly,\n"
- " >0 to send timestamped messages): ")) < 0);
- Pm_OpenOutput(&midi_out, outp, NULL, 0, NULL, NULL, latency);
- while ((length = get_number("Message length (7 - 1024): ")) < 7 ||
- length > 1024) ;
- while ((num_msgs = get_number("Number of messages: ")) < 1);
- /* latency, length, and num_msgs should now all be valid */
- /* compose the message except for sequence number in first 5 bytes */
- msg[0] = (char) MIDI_SYSEX;
- for (i = 6; i < length - 1; i++) {
- msg[i] = i % 128; /* this is just filler */
- }
- msg[length - 1] = (char) MIDI_EOX;
-
- start_time = Pt_Time();
- /* send the messages */
- for (i = num_msgs; i > 0; i--) {
- /* insert sequence number into first 5 data bytes */
- /* sequence counts down to zero */
- int j;
- int count = i;
- /* 7 bits of message count i goes into each data byte */
- for (j = 1; j <= 5; j++) {
- msg[j] = count & 127;
- count >>= 7;
- }
- /* send the message */
- Pm_WriteSysEx(midi_out, 0, msg);
- }
- stop_time = Pt_Time();
- Pm_Close(midi_out);
- return;
-}
-
-#define MAX_MSG_LEN 1024
-static unsigned char receive_msg[MAX_MSG_LEN];
-static int receive_msg_index;
-static int receive_msg_length;
-static int receive_msg_count;
-static int receive_msg_error;
-static int receive_msg_messages;
-static PmStream *receive_msg_midi_in;
-static int receive_poll_running;
-
-/* receive_poll -- callback function to check for midi input */
-/**/
-void receive_poll(PtTimestamp timestamp, void *userData)
-{
- PmError count;
- PmEvent event;
- int shift;
- int data = 0;
- int i;
-
- if (!receive_poll_running) return; /* wait until midi device is opened */
- shift = 0;
- while (data != MIDI_EOX) {
- count = Pm_Read(receive_msg_midi_in, &event, 1);
- if (count == 0) return;
-
- /* compare 4 bytes of data until you reach an eox */
- for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) {
- receive_msg[receive_msg_index++] = data =
- (event.message >> shift) & 0xFF;
- if (receive_msg_index >= MAX_MSG_LEN) {
- printf("error: incoming sysex too long\n");
- goto error;
- }
- }
- }
- /* check the message */
- if (receive_msg_length == 0) {
- receive_msg_length = receive_msg_index;
- }
- if (receive_msg_length != receive_msg_index) {
- printf("error: incoming sysex wrong length\n");
- goto error;
- }
- if (receive_msg[0] != MIDI_SYSEX) {
- printf("error: incoming sysex missing status byte\n");
- goto error;
- }
- /* get and check the count */
- count = 0;
- for (i = 0; i < 5; i++) {
- count += receive_msg[i + 1] << (7 * i);
- }
- if (receive_msg_count == -1) {
- receive_msg_count = count;
- receive_msg_messages = count;
- }
- if (receive_msg_count != count) {
- printf("error: incoming sysex has wrong count\n");
- goto error;
- }
- for (i = 6; i < receive_msg_index - 1; i++) {
- if (receive_msg[i] != i % 128) {
- printf("error: incoming sysex has bad data\n");
- goto error;
- }
- }
- if (receive_msg[receive_msg_length - 1] != MIDI_EOX) goto error;
- receive_msg_index = 0; /* get ready for next message */
- receive_msg_count--;
- return;
- error:
- receive_msg_error = 1;
- return;
-}
-
-
-/* receive_multiple_test -- send/rcv from 2 to 1000 bytes of random midi data */
-/**/
-void receive_multiple_test()
-{
- PmError err;
- int inp;
-
- printf("This test expects to receive data sent by the send_multiple test\n");
- printf("The test will check that correct data is received.\n");
-
- /* Important: start PortTime first -- if it is not started first, it will
- be started by PortMidi, and then our attempt to open again will fail */
- receive_poll_running = false;
- if ((err = Pt_Start(1, receive_poll, 0))) {
- printf("PortTime error code: %d\n", err);
- goto cleanup;
- }
- inp = get_number("Type input device number: ");
- Pm_OpenInput(&receive_msg_midi_in, inp, NULL, 512, NULL, NULL);
- receive_msg_index = 0;
- receive_msg_length = 0;
- receive_msg_count = -1;
- receive_msg_error = 0;
- receive_poll_running = true;
- while ((!receive_msg_error) && (receive_msg_count != 0)) {
-#ifdef WIN32
- Sleep(1000);
-#else
- sleep(1); /* block and wait */
-#endif
- }
- if (receive_msg_error) {
- printf("Receive_multiple test encountered an error\n");
- } else {
- printf("Receive_multiple test successfully received %d sysex messages\n",
- receive_msg_messages);
- }
-cleanup:
- receive_poll_running = false;
- Pm_Close(receive_msg_midi_in);
- Pt_Stop();
- return;
-}
-
-
-#define is_real_time_msg(msg) ((0xF0 & Pm_MessageStatus(msg)) == 0xF8)
-
-
-void receive_sysex()
-{
- char line[80];
- FILE *f;
- PmStream *midi;
- int shift = 0;
- int data = 0;
- int bytes_on_line = 0;
- PmEvent msg;
-
- /* determine which output device to use */
- int i = get_number("Type input device number: ");
-
- /* open input device */
- Pm_OpenInput(&midi, i, NULL, 512, NULL, NULL);
- printf("Midi Input opened, type file for sysex data: ");
-
- /* open file */
- if (!fgets(line, STRING_MAX, stdin)) return; /* no more stdin? */
- /* remove the newline character */
- if (strlen(line) > 0) line[strlen(line) - 1] = 0;
- f = fopen(line, "w");
- if (!f) {
- printf("Could not open %s\n", line);
- Pm_Close(midi);
- return;
- }
-
- printf("Ready to receive a sysex message\n");
-
- /* read data and write to file */
- while (data != MIDI_EOX) {
- PmError count;
- count = Pm_Read(midi, &msg, 1);
- /* CAUTION: this causes busy waiting. It would be better to
- be in a polling loop to avoid being compute bound. PortMidi
- does not support a blocking read since this is so seldom
- useful.
- */
- if (count == 0) continue;
- /* ignore real-time messages */
- if (is_real_time_msg(Pm_MessageStatus(msg.message))) continue;
-
- /* write 4 bytes of data until you reach an eox */
- for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) {
- data = (msg.message >> shift) & 0xFF;
- /* if this is a status byte that's not MIDI_EOX, the sysex
- message is incomplete and there is no more sysex data */
- if (data & 0x80 && data != MIDI_EOX) break;
- fprintf(f, "%2x ", data);
- if (++bytes_on_line >= 16) {
- fprintf(f, "\n");
- bytes_on_line = 0;
- }
- }
- }
- fclose(f);
- Pm_Close(midi);
-}
-
-
-void send_sysex()
-{
- char line[80];
- FILE *f;
- PmStream *midi;
- int data;
- int shift = 0;
- PmEvent msg;
-
- /* determine which output device to use */
- int i = get_number("Type output device number: ");
- while ((latency = get_number(
- "Latency in milliseconds (0 to send data immediatedly,\n"
- " >0 to send timestamped messages): ")) < 0);
-
- msg.timestamp = 0; /* no need for timestamp */
-
- /* open output device */
- Pm_OpenOutput(&midi, i, NULL, 0, NULL, NULL, latency);
- printf("Midi Output opened, type file with sysex data: ");
-
- /* open file */
- if (!fgets(line, STRING_MAX, stdin)) return; /* no more stdin? */
- /* remove the newline character */
- if (strlen(line) > 0) line[strlen(line) - 1] = 0;
- f = fopen(line, "r");
- if (!f) {
- printf("Could not open %s\n", line);
- Pm_Close(midi);
- return;
- }
-
- /* read file and send data */
- msg.message = 0;
- while (1) {
- /* get next byte from file */
-
- if (fscanf(f, "%x", &data) == 1) {
- /* printf("read %x, ", data); */
- /* OR byte into message at proper offset */
- msg.message |= (data << shift);
- shift += 8;
- }
- /* send the message if it's full (shift == 32) or if we are at end */
- if (shift == 32 || data == MIDI_EOX) {
- /* this will send sysex data 4 bytes at a time -- it would
- be much more efficient to send multiple PmEvents at once
- but this method is simpler. See Pm_WriteSysEx for a more
- efficient code example.
- */
- Pm_Write(midi, &msg, 1);
- msg.message = 0;
- shift = 0;
- }
- if (data == MIDI_EOX) { /* end of message */
- fclose(f);
- Pm_Close(midi);
- return;
- }
- }
-}
-
-
-int main()
-{
- int i;
-
- /* list device information */
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- printf("%d: %s, %s", i, info->interf, info->name);
- if (info->input) printf(" (input)");
- if (info->output) printf(" (output)");
- printf("\n");
- }
- while (1) {
- char cmd;
- printf("Type r to receive sysex, s to send,"
- " l for loopback test, m to send multiple,"
- " n to receive multiple, q to quit: ");
- cmd = getchar();
- while (getchar() != '\n') ;
- switch (cmd) {
- case 'r':
- receive_sysex();
- break;
- case 's':
- send_sysex();
- break;
- case 'l':
- loopback_test();
- break;
- case 'm':
- send_multiple_test();
- break;
- case 'n':
- receive_multiple_test();
- break;
- case 'q':
- exit(0);
- default:
- break;
- }
- }
- return 0;
-}
diff --git a/portmidi/pm_test/testio.c b/portmidi/pm_test/testio.c
deleted file mode 100755
index 2711286..0000000
--- a/portmidi/pm_test/testio.c
+++ /dev/null
@@ -1,594 +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 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 WAIT_FOR_ENTER while (getchar() != '\n') ;
-
-int32_t latency = 0;
-int verbose = FALSE;
-PmSysDepInfo *sysdepinfo = NULL;
-
-/* 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(const char *prompt)
-{
- int n = 0, i;
- fputs(prompt, stdout);
- while (n != 1) {
- n = scanf("%d", &i);
- WAIT_FOR_ENTER
- }
- return i;
-}
-
-
-static void set_sysdepinfo(char m_or_p, const char *name)
-{
- if (!sysdepinfo) {
- // allocate some space we will alias with open-ended PmDriverInfo:
- // there is space for 4 parameters:
- static char dimem[sizeof(PmSysDepInfo) + sizeof(void *) * 8];
- sysdepinfo = (PmSysDepInfo *) dimem;
- // build the driver info structure:
- sysdepinfo->structVersion = PM_SYSDEPINFO_VERS;
- sysdepinfo->length = 0;
- }
- if (sysdepinfo->length > 1) {
- printf("Error: sysdepinfo was allocated to hold 2 parameters\n");
- exit(1);
- }
- int i = sysdepinfo->length++;
- enum PmSysDepPropertyKey k = pmKeyNone;
- if (m_or_p == 'm') k = pmKeyCoreMidiManufacturer;
- else if (m_or_p == 'p') k = pmKeyAlsaPortName;
- else if (m_or_p == 'c') k = pmKeyAlsaClientName;
- sysdepinfo->properties[i].key = k;
- sysdepinfo->properties[i].value = name;
-}
-
-
-/*
- * 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,
- sysdepinfo,
- 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: timestamp %ld, "
- "%2lx %2lx %2lx\n", i, (long) Pt_Time(),
- (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(int isochronous_test)
-{
- PmStream * midi;
- 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,
- sysdepinfo,
- 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 ENTER):");
- WAIT_FOR_ENTER
- /* 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 = Pt_Time();
- /* 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);
-
- if (isochronous_test) { // play 4 notes per sec for 20s
- int count;
- PmTimestamp start;
- if (latency < 100) {
- printf("Warning: latency < 100, but this test sends messages"
- " at times that are jittered by up to 100ms, so you"
- " may hear uneven timing\n");
- }
- printf("Starting in 1s..."); fflush(stdout);
- Pt_Sleep(1000);
- start = Pt_Time();
- for (count = 0; count < 80; count++) {
- PmTimestamp next_time;
- buffer[0].timestamp = start + count * 250;
- buffer[0].message = Pm_Message(0x90, 69, 100);
- buffer[1].timestamp = start + count * 250 + 200;
- buffer[1].message = Pm_Message(0x90, 69, 0);
- Pm_Write(midi, buffer, 2);
- next_time = start + (count + 1) * 250;
- // sleep for a random time up to 100ms to add jitter to
- // the times at which we send messages. PortMidi timing
- // should remove the jitter if latency > 100
- while (Pt_Time() < next_time) {
- Pt_Sleep(rand() % 100);
- }
- }
- printf("Done sending 80 notes at 4 notes per second.\n");
- } else {
- PmError err = 0;
- printf("ready to note-on... (type ENTER):");
- WAIT_FOR_ENTER
- buffer[0].timestamp = Pt_Time();
- buffer[0].message = Pm_Message(0x90, 60, 100);
- if ((err = Pm_Write(midi, buffer, 1))) {
- printf("Pm_Write returns error: %d (%s)\n",
- err, Pm_GetErrorText(err));
- if (err == pmHostError) {
- char errmsg[128];
- Pm_GetHostErrorText(errmsg, 127);
- printf(" Host error: %s\n", errmsg);
- }
- }
- printf("ready to note-off... (type ENTER):");
- WAIT_FOR_ENTER
- buffer[0].timestamp = Pt_Time();
- buffer[0].message = Pm_Message(0x90, 60, 0);
- if ((err = Pm_Write(midi, buffer, 1))) {
- printf("Pm_Write returns error: %d (%s)\n",
- err, Pm_GetErrorText(err));
- if (err == pmHostError) {
- char errmsg[128];
- Pm_GetHostErrorText(errmsg, 127);
- printf(" Host error: %s\n", errmsg);
- }
- }
-
- /* output short note on/off w/latency offset; hold until user prompts */
- printf("ready to note-on (short form)... (type ENTER):");
- WAIT_FOR_ENTER
- Pm_WriteShort(midi, Pt_Time(),
- Pm_Message(0x90, 60, 100));
- printf("ready to note-off (short form)... (type ENTER):");
- WAIT_FOR_ENTER
- Pm_WriteShort(midi, Pt_Time(),
- Pm_Message(0x90, 60, 0));
-
- /* output several note on/offs to test timing.
- Should be 1s between notes */
- if (latency == 0) {
- printf("chord should not arpeggiate, latency == 0\n");
- } else {
- printf("chord should arpeggiate (latency = %ld > 0\n",
- (long) latency);
- }
- printf("ready to chord-on/chord-off... (type ENTER):");
- WAIT_FOR_ENTER
- timestamp = Pt_Time();
- printf("starting timestamp %ld\n", (long) timestamp);
- 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 (Pt_Time() < off_time)
- /* There was a report that Pm_Write with zero length sent last
- * message again, so call Pm_Write here to see if note repeats
- */
- Pm_Write(midi, buffer, 0);
- Pt_Sleep(20); /* 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 ENTER):");
- WAIT_FOR_ENTER
-
- 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 = 11;
-
- 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,
- sysdepinfo,
- 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,
- sysdepinfo,
- 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: timestamp %ld, "
- "%2lx %2lx %2lx\n", i, (long) Pt_Time(),
- (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);
- }
- }
- }
- /* allow time for last message to go out */
- Pt_Sleep(100 + latency);
-
- /* 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;
- 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,
- sysdepinfo,
- 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 ENTER):");
- WAIT_FOR_ENTER
-
- /* 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 = Pt_Time();
- 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 = Pt_Time();
- 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)
- Pt_Sleep(10);
- /* 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 ENTER):");
- WAIT_FOR_ENTER
-
- Pm_Close(midi);
- Pm_Terminate();
- printf("done closing and terminating...\n");
-}
-
-
-void show_usage()
-{
- printf("Usage: test [-h] [-l latency-in-ms] [-c clientname] "
- "[-p portname] [-v]\n"
- " -h for this help message (only)\n"
- " -l for latency\n"
- " -c name designates a client name (linux only),\n"
- " -p name designates a port name (linux only),\n"
- " -v for verbose (enables more output)\n");
-}
-
-int main(int argc, char *argv[])
-{
- int default_in;
- int default_out;
- int i = 0, n = 0;
- int test_input = 0, test_output = 0, test_both = 0, somethingStupid = 0;
- int isochronous_test = 0;
- int stream_test = 0;
- int latency_valid = FALSE;
-
- show_usage();
- 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) {
- exit(0);
- } else if (strcmp(argv[i], "-p") == 0 && (i + 1 < argc)) {
- i = i + 1;
- const char *port_name = argv[i];
- set_sysdepinfo('p', port_name);
- printf("Port name will be %s\n", port_name);
- } else if (strcmp(argv[i], "-c") == 0 && (i + 1 < argc)) {
- i = i + 1;
- set_sysdepinfo('c', argv[i]);
- printf("Client name will be %s\n", argv[i]);
- } 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 if (strcmp(argv[i], "-v") == 0) {
- printf("Verbose is now TRUE\n");
- verbose = TRUE; /* not currently used for anything */
- } else {
- show_usage();
- exit(0);
- }
- }
-
- 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("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 (for WinMM)\n"
- " 7. isochronous out\n");
- while (n != 1) {
- n = scanf("%d", &i);
- WAIT_FOR_ENTER
- 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;
- case 7:
- test_output = 1;
- isochronous_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(isochronous_test);
- } else if (test_both) {
- main_test_both();
- }
-
- printf("finished portMidi test...type ENTER to quit...");
- WAIT_FOR_ENTER
- return 0;
-}
diff --git a/portmidi/pm_test/txdata.syx b/portmidi/pm_test/txdata.syx
deleted file mode 100755
index 1e06e5a..0000000
--- a/portmidi/pm_test/txdata.syx
+++ /dev/null
@@ -1,257 +0,0 @@
-20 0 1d 4 c 6 0 34 1 4d 4 d 1f 7 3 6
- c 5e 4 4d d b 18 5 3 6 0 3d 1 4a 16 18
-1f 8 3 6 d 0 1 63 4 13 3a 23 0 0 0 2
- c 2 4 0 63 32 0 0 0 32 0 47 72 61 6e 64
-50 69 61 6e 6f 63 63 63 32 32 32 0 0 0 0 0
-10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 9 9 f c 27 2 35 37 10 1f 4 3 4
- d 19 4 56 5 16 1f f 8 d c 0 43 60 4 e
-1f c 3 7 e 0 43 63 5 10 3c 14 8 2 1b 56
- 5 2 4 0 63 32 0 0 0 32 0 4c 6f 54 69 6e
-65 38 31 5a 20 63 63 63 32 32 32 0 7f 0 1 0
-18 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f e f e 9 0 3 43 2d e 1f f 5 7
- f 16 43 5a 0 0 1f 12 6 8 d 0 3 63 4 0
-1f 12 6 8 f 0 2 63 4 6 34 14 0 1 2 4e
-18 2 4 0 63 32 0 32 0 32 0 44 79 6e 6f 6d
-69 74 65 45 50 63 63 63 32 32 32 0 70 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f b 1 b 8 18 40 5f a e 1f 1f 0 a
- f 0 40 5f 4 0 1f 1f 0 a f 0 40 63 5 6
-1f 1f 0 a f 0 40 5f 0 8 1f 20 0 3 0 5a
-18 4 4 0 63 32 32 0 0 32 0 50 65 72 63 4f
-72 67 61 6e 20 63 63 63 32 32 32 0 0 0 0 0
- 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f b 7 f 9 0 4 49 13 13 1f 8 7 5
- e 0 2 58 0 c 1f 6 4 6 f 23 3 46 10 a
-1f 7 8 c d 0 2 63 8 b 2 1c 0 0 0 52
-18 4 4 0 63 32 0 32 0 32 0 54 68 69 6e 20
-43 6c 61 76 20 63 63 63 32 32 32 0 70 0 20 0
-10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f c 0 6 1 a 4 50 20 e 1f c 0 6
- 1 a 4 50 1f 8 1f b 9 5 e 0 2 63 5 e
-1f b 9 5 e 0 3 63 4 8 4 1a 0 0 0 52
-1d 2 4 0 63 32 0 32 0 32 0 42 72 69 74 65
-43 65 6c 73 74 63 63 63 32 32 32 0 20 0 26 0
- 1 0 8 4 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 f 1f 4 8 f 0 3a 51 4 b e 1f 0 8
- f 0 22 4b 4 3 f 1a b 8 d 0 3b 36 9 3
-12 1f 0 8 f 0 22 5d 4 b 3a 1e 19 5 0 52
-18 4 4 0 63 32 0 0 0 32 0 54 72 75 6d 70
-65 74 38 31 5a 63 63 63 32 32 32 0 0 0 50 0
-51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 c 5 0 8 0 0 2 4a 4 b f 1f 0 8
- f 0 2 3f 4 3 1f f 0 8 0 23 3 44 b 3
-10 1f 0 9 f 0 2 5e 4 c 3a 1f 19 7 0 52
-18 4 4 0 63 32 0 0 0 32 0 46 6c 75 67 65
-6c 68 6f 72 6e 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 10 1f 0 8 f 0 42 4a 0 3 11 1f 0 8
- f a 43 51 0 3 11 9 0 8 d 0 42 2b 16 6
-10 1f 0 9 f 0 42 63 4 b 3a 1e 9 9 0 5a
-24 4 4 0 63 32 31 0 0 32 0 52 61 73 70 41
-6c 74 6f 20 20 63 63 63 32 32 32 0 10 0 20 0
-54 0 20 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 10 9 2 6 d 0 41 3e 4 15 c b 2 3
- e 0 41 4f 4 12 c e 2 8 d 0 42 4b a 1c
- d b 1 9 e 0 3 63 a 14 0 23 f 2 1b 5e
-18 4 5 0 63 28 50 32 0 32 0 48 61 72 6d 6f
-6e 69 63 61 20 63 63 63 32 32 32 0 50 10 50 0
-50 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1c 2 0 4 e 63 0 4e 4 3 d 5 0 6
- e 63 1 56 a 8 12 7 0 6 9 63 2 47 1b e
- a a 0 5 f 0 1 63 4 b 32 1a 8 d 0 52
- c 4 4 0 63 32 0 0 0 32 0 44 6f 75 62 6c
-65 42 61 73 73 63 63 63 32 32 32 0 10 0 0 0
- 3 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 b 4 0 4 f 14 2 49 9 6 a 7 0 4
- f 14 2 51 a 0 8 1f 0 5 f 0 1 63 9 6
- a 1f 0 5 f 0 1 63 a 0 3c 1f 6 9 0 52
- 5 4 4 0 63 32 0 0 0 32 0 48 69 53 74 72
-69 6e 67 20 31 63 63 63 32 32 32 0 2 0 30 0
-32 0 10 5 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 10 13 f 4 a 0 3 3b 14 14 1f e 8 7
- 9 0 2 42 5 e 18 13 d 9 c 0 2 3c 13 8
-1f 11 7 4 f 0 42 63 4 10 3a 1b 0 0 0 52
-1d 4 4 0 63 32 0 0 0 32 0 48 61 72 70 20
-20 20 20 20 20 63 63 63 32 32 32 8 0 0 21 0
- 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 6 6 4 f 0 40 48 5 0 c 8 7 5
- f 5 0 52 4 0 f 7 3 7 e 8 3 63 4 6
- f 8 4 5 f 0 3 63 4 6 7c 1f 0 6 0 4a
-11 2 4 0 63 32 0 0 0 32 0 46 61 6e 66 61
-72 54 70 74 73 63 63 63 32 32 32 6 1 0 38 0
- 8 0 48 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 d b 0 1 c 0 2 2c 3d 3 d 7 0 1
- c 0 2 1f 3c 3 d 1f 0 5 f 0 2 63 5 6
- d 1f 0 5 f 0 2 63 4 0 3c 63 0 2f 0 53
-11 4 4 0 63 32 0 0 0 32 0 42 72 65 61 74
-68 4f 72 67 6e 63 63 63 32 32 32 4 30 5 50 0
-11 0 18 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 9 0 6 0 27 2 51 19 b 1c 6 0 8
- 0 37 2 47 a 3 1f a 0 9 0 3d 2 4d a e
-1f 12 8 8 f 0 3 61 4 b 28 1f 0 3 0 52
- c 3 4 0 63 32 1 32 0 32 0 4e 79 6c 6f 6e
-47 75 69 74 20 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f e e f f 0 3 48 2d 6 1f f 4 f
- f 25 3 5b 0 0 1f 12 6 c e 1c 3 55 0 10
-1f 13 7 8 e 6 4 62 4 e 3b 14 0 0 0 42
-18 2 4 0 63 32 0 32 0 32 0 47 75 69 74 61
-72 20 23 31 20 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 19 8 a 3 0 3 63 10 18 1f c 5 b
- 5 0 3 52 0 b 1f 19 6 b 5 0 3 63 a 16
-1f f 11 9 7 0 4 63 4 3 3a 14 0 0 0 42
-18 2 4 0 63 32 0 32 0 32 0 46 75 6e 6b 79
-20 50 69 63 6b 63 63 63 32 32 32 0 30 0 0 0
- 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 1 0 8 4 0 3 3d a 1e 1f 1 0 8
- 0 0 0 43 0 10 1f 9 6 8 c 1b 7 46 1c 1e
-1f 9 0 9 9 0 1 63 4 3 3a 1c 0 0 0 52
- c 4 5 0 63 4b 0 0 0 32 0 45 6c 65 63 42
-61 73 73 20 31 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f f f e 9 0 3 46 1d 16 1f f 5 e
- e d 3 63 0 b 1f 13 6 5 d 1c 3 63 0 0
-1f 13 6 8 f 0 4 63 4 6 3b 1f 0 0 0 42
- c 4 4 0 63 32 0 32 0 32 0 53 79 6e 46 75
-6e 6b 42 61 73 63 63 63 32 32 32 d 6c 0 0 0
-70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 10 7 8 3 0 3 4f 4 3 1f 9 0 8
- 0 0 1 4a 0 b 1f 11 0 8 0 0 1 47 4 8
-1f 9 0 8 0 0 0 63 0 b 39 19 0 7 0 52
- c 2 4 0 63 32 0 32 0 32 0 4c 61 74 65 6c
-79 42 61 73 73 63 63 63 32 32 32 2 0 0 0 0
-40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 13 12 0 9 d 22 0 51 0 b 1f 14 0 5
- 8 24 40 5c 0 3 1f 11 0 6 c 2c 0 53 9 0
-10 1f 0 b f 0 0 5c a e 3a 22 11 e 1e 5e
-18 7 4 0 63 32 0 32 0 32 0 53 79 6e 63 20
-4c 65 61 64 20 63 63 63 32 32 32 0 70 0 40 0
- 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 13 1e 0 9 e 0 0 63 3f b 1f 14 0 5
- e 24 1 51 4 3 1f 14 0 f 1 0 41 4d 8 3
- f 1f 0 b f 0 2 63 4 b 3b 20 11 12 33 56
-18 4 4 0 63 37 e 0 0 32 0 4a 61 7a 7a 20
-46 6c 75 74 65 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 15 13 d 3 d 1e 2 50 18 e 15 14 9 4
- c 1e 2 56 11 8 1b 1f f 7 f 0 1 63 4 6
-1a 1f e 6 f 0 2 63 4 0 7c b 0 8 0 62
-18 4 4 0 63 32 0 0 0 32 0 4a 61 76 61 20
-4a 69 76 65 20 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 0 0 4 f 0 40 63 3c 0 b 8 7 7
- f 5 0 63 4 6 f 5 3 7 f 8 0 3b 5 6
- e 8 4 5 f 0 3 63 3 0 7e 1d 6 f 0 4a
-11 0 4 0 63 32 0 0 0 32 0 42 61 61 64 42
-72 65 61 74 68 63 63 63 32 32 32 6 30 0 38 0
- 1 0 46 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 0 0 4 f 0 40 47 2f 0 e 8 7 7
- f 5 0 4c 0 6 13 1c d c 6 8 0 63 5 6
-14 11 d b 0 0 3 63 4 0 7a 10 0 51 0 68
-17 0 4 0 63 32 0 0 0 32 0 56 6f 63 61 6c
-4e 75 74 73 20 63 63 63 32 32 32 6 30 0 30 0
- 1 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 1f 0 5 f 0 0 41 32 3 1f 14 10 5
- 5 1 2 63 7 3 1f b 12 8 f 0 1 63 c 3
-1f 1f f 8 f 0 1 63 4 3 39 23 0 0 0 62
-18 7 4 0 63 32 0 0 0 32 0 57 61 74 65 72
-47 6c 61 73 73 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 16 2 0 4 6 9 1 4f 8 0 19 e 1 4
- 0 20 1 43 19 0 1f 12 10 6 7 0 0 54 3d 3
-16 d 6 6 2 1e 3 61 8 e 3a 20 1 14 0 42
- c 2 4 2 63 63 63 0 0 32 0 46 75 7a 7a 79
-20 4b 6f 74 6f 63 63 63 32 32 32 0 0 0 0 b
-50 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1c 8 0 3 e 0 1 55 12 3 1c 7 0 1
- e 2e 1 58 27 b e 4 0 2 a 0 2 63 4 a
- d 9 0 2 c 1 2 63 10 b 4 54 0 47 0 53
-18 7 4 0 63 32 0 0 0 32 0 42 72 74 68 62
-65 6c 6c 73 20 63 63 63 32 32 32 0 4 0 40 0
-40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1a 4 1 1 b 16 0 47 5 3 15 e 0 1
- d 0 0 4c 5 16 1c 6 4 2 7 0 0 63 4 16
-18 18 3 1 e 0 0 5e 4 10 24 7 0 4 0 62
-24 4 4 0 63 32 0 0 0 32 0 54 75 62 65 20
-42 65 6c 6c 73 63 63 63 32 32 32 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 1f 13 3 0 0 0 5f 3d 6 1f 12 13 2
- 0 0 1 52 5 2 1f 14 13 3 0 0 1 56 28 5
-1e b 13 f 9 0 0 63 6 3 3b 63 0 63 0 73
-23 7 4 0 63 32 0 0 0 32 0 4e 6f 69 73 65
-20 53 68 6f 74 63 63 63 32 32 32 8 0 0 0 8
- 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1f 16 0 3 7 0 1 50 0 3 1f 18 3 3
- 3 22 0 63 0 14 1d 7 6 3 6 0 1 3c 8 3
-1f 5 7 3 0 0 1 63 4 1b 39 23 0 8 0 42
-18 4 4 0 63 32 0 0 0 32 0 48 61 6e 64 20
-44 72 75 6d 20 63 63 63 32 32 32 0 1 0 3 0
- 1 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 7d f7 \ No newline at end of file
diff --git a/portmidi/pm_test/virttest.c b/portmidi/pm_test/virttest.c
deleted file mode 100644
index 1aeb09b..0000000
--- a/portmidi/pm_test/virttest.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* virttest.c -- test for creating/deleting virtual ports */
-/*
- * Roger B. Dannenberg
- * Oct 2021
-
-This test is performed by running 2 instances of the program. The
-first instance makes input and output ports named portmidi and waits
-for a message. The second tries to do the same, but will fail because
-portmidi already exists. It then opens portmidi (both input and
-output). In greater detail:
-
-FIRST INSTANCE SECOND INSTANCE
--------------- ---------------
-
-initialize PortMidi initialize PortMidi
-create portmidi in
-create portmidi out
-wait for input
- create portmidi in -> fails
- open portmidi in/out
- send to portmidi
-recv from portmidi
-send to portmidi
-wait 1s recv from portmidi
- close portmidi in and out
- terminate PortMidi
-list all devices:
- - check for correct number
- - check for good description of portmidi in port (open)
- - check for good description of portmidi out port (open)
-close portmidi in
-list all devices:
- - check for correct number
- - check for good description of portmidi in port (closed)
- - check for good description of portmidi out port (open)
-close portmidi out
-list all devices:
- - check for correct number
- - check for good description of portmidi in port (closed)
- - check for good description of portmidi out port (closed)
-delete portmidi in
- - check for correct number
- - check for NULL description of portmidi in port
- - check for good description of portmidi out port (closed)
-delete portmidi out
- - check for correct number
- - check for NULL description of portmidi in port
- - check for NULL description of portmidi out port
-terminate portmidi
-REPEAT 3 TIMES wait 2 seconds to give head start to other instance
- REPEAT 3 TIMES
- */
-
-#include "portmidi.h"
-#include "porttime.h"
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-
-#define OUTPUT_BUFFER_SIZE 0
-#define INPUT_BUFFER_SIZE 10
-#define DEVICE_INFO NULL
-#define DRIVER_INFO NULL
-#define TIME_PROC ((PmTimeProcPtr) Pt_Time)
-#define TIME_INFO NULL
-#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
-
-
-static void prompt_and_exit(void)
-{
- printf("type ENTER...");
- while (getchar() != '\n') ;
- /* this will clean up open ports: */
- exit(-1);
-}
-
-
-static PmError printerror(PmError err, const char *msg)
-{
- if (err == pmHostError) {
- /* it seems pointless to allocate memory and copy the string,
- * so I will do the work of Pm_GetHostErrorText directly
- */
- char errmsg[80];
- Pm_GetHostErrorText(errmsg, 80);
- printf("%s\n %s\n", msg, errmsg);
- } else if (err < 0) {
- printf("%s\n %s\n", msg, Pm_GetErrorText(err));
- }
- return err;
-}
-
-
-static PmError checkerror(PmError err)
-{
- if (err < 0) {
- printerror(err, "PortMidi call failed...");
- prompt_and_exit();
- }
- return err;
-}
-
-
-void wait_until(PmTimestamp when)
-{
- PtTimestamp now = Pt_Time();
- if (when > now) {
- Pt_Sleep(when - now);
- }
-}
-
-
-void show_usage()
-{
- printf("Usage: virttest\n"
- " run two instances to test virtual port create/delete\n");
-}
-
-
-void check_info(int id, char stat, int input, int virtual)
-{
- const PmDeviceInfo *info = Pm_GetDeviceInfo(id);
- if (stat == 'd') {
- if (info) {
- printf("Expected device %d to be deleted.\n", id);
- prompt_and_exit();
- }
- return;
- }
- if (!info) {
- printf("Expected device %d to not be deleted.\n", id);
- prompt_and_exit();
- }
- if (strcmp("portmidi", info->name) != 0) {
- printf("Device %d name is %s, not \"portmidi\".\n", id, info->name);
- prompt_and_exit();
- }
- if (info->input != input || (!info->output) != input) {
- printf("Device %d input/output fields are wrong.\n", id);
- prompt_and_exit();
- }
- if ((!info->opened && stat == 'o') || (info->opened && stat == 'c')) {
- printf("Device %d opened==%d, status should be %c.\n", id,
- info->opened, stat);
- prompt_and_exit();
- }
- if (info->is_virtual != virtual) {
- printf("Expected device %d to be virtual.\n", id);
- prompt_and_exit();
- }
-}
-
-
-/* stat is 'o' for open, 'c' for closed, 'd' for deleted device */
-void check_ports(int cnt, int in_id, char in_stat,
- int out_id, char out_stat, int virtual)
-{
- if (cnt != Pm_CountDevices()) {
- printf("Device count changed from %d to %d.\n", cnt, Pm_CountDevices());
- prompt_and_exit();
- }
- check_info(in_id, in_stat, TRUE, virtual);
- check_info(out_id, out_stat, FALSE, virtual);
-}
-
-
-void devices_list()
-{
- int i;
- for (i = 0; i < Pm_CountDevices(); i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if (info) {
- printf("%d: %s %s %s %s\n", i, info->name,
- (info->input ? "input" : "output"),
- (info->is_virtual ? "virtual" : "real_device"),
- (info->opened ? "opened" : "closed"));
- }
- }
-}
-
-
-void test2()
-{
- PmStream *out = NULL;
- PmStream *in = NULL;
- int out_id;
- int in_id;
- PmEvent buffer[1];
- PmTimestamp timestamp;
- int pitch = 60;
- int device_count = 0;
- int i;
-
- printf("This must be virttest instance #2\n");
-
- /* find and open portmidi in and out */
- device_count = Pm_CountDevices();
- for (i = 0; i < device_count; i++) {
- const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
- if (info && strcmp(info->name, "portmidi") == 0) {
- if (info->input) {
- checkerror(Pm_OpenInput(&in, i, DRIVER_INFO,
- INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO));
- in_id = i;
- } else {
- checkerror(Pm_OpenOutput(&out, i, DRIVER_INFO,
- OUTPUT_BUFFER_SIZE, NULL, NULL, 0));
- out_id = i;
- }
- }
- }
- if (!in) {
- printf("Did not open portmidi as input (virtual output).\n");
- prompt_and_exit();
- }
- if (!out) {
- printf("Did not open portmidi as output (virtual input).\n");
- prompt_and_exit();
- }
- printf("Input device %d and output device %d are open.\n", in_id, out_id);
-
- /* send a message */
- buffer[0].timestamp = 0;
- buffer[0].message = Pm_Message(0x90, pitch, 100);
- checkerror(Pm_Write(out, buffer, 1));
-
- /* wait for reply */
- printf("Sent message, waiting for reply...\n");
- while (Pm_Read(in, buffer, 1) < 1) Pt_Sleep(10);
-
- printf("********** GOT THE MESSAGE, SHUTTING DOWN ************\n");
-
- /* close in */
- checkerror(Pm_Close(in));
- check_ports(device_count, in_id, 'c', out_id, 'o', FALSE);
- printf("Closed input %d\n", in_id);
-
- /* close out */
- checkerror(Pm_Close(out));
- check_ports(device_count, in_id, 'c', out_id, 'c', FALSE);
- printf("Closed output %d\n", out_id);
-
- Pt_Sleep(1000);
- /* wrap it up */
- Pm_Terminate();
- printf("Got reply and terminated...\n");
- Pt_Sleep(2000); /* 2 seconds because other is waiting 1s. */
- /* 1 more second to make sure other shuts down before test repeats. */
-}
-
-extern int pm_check_errors;
-
-void test()
-{
- PmStream *out;
- PmStream *in;
- int out_id;
- int in_id;
- PmEvent buffer[1];
- PmTimestamp timestamp;
- int device_count = 0;
-
- TIME_START;
-
- printf("******** INITIALIZING PORTMIDI ***********\n");
- timestamp = Pt_Time();
- Pm_Initialize();
- printf("Pm_Initialize took %dms\n", Pt_Time() - timestamp);
- devices_list();
-
- pm_check_errors = FALSE; /* otherwise, PM_CHECK_ERRORS, if defined, */
- /* can cause this program to report an error and exit on pmNameConflict. */
- in_id = Pm_CreateVirtualInput("portmidi", NULL, DEVICE_INFO);
- pm_check_errors = TRUE; /* there should be no other errors */
- if (in_id < 0) {
- printerror(in_id, "Pm_CreateVirtualInput failed...");
- test2();
- return;
- }
- printf("Created portmidi virtual input; this is virttest instance #1\n");
- out_id = checkerror(Pm_CreateVirtualOutput("portmidi", NULL, DRIVER_INFO));
- device_count = Pm_CountDevices();
-
- checkerror(Pm_OpenInput(&in, in_id, NULL, 0, NULL, NULL));
- checkerror(Pm_OpenOutput(&out, out_id, DRIVER_INFO, OUTPUT_BUFFER_SIZE,
- TIME_PROC, TIME_INFO, 0));
- printf("Created/Opened input %d and output %d\n", in_id, out_id);
- Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
- /* empty the buffer after setting filter, just in case anything
- got through */
- while (Pm_Read(in, buffer, 1)) ;
-
- /* wait for input */
- printf("Waiting for input...\n");
- while (Pm_Read(in, buffer, 1) < 1) Pt_Sleep(10);
-
- /* send two replies (only one would be fine) */
- checkerror(Pm_Write(out, buffer, 1));
- printf("Received input, writing output...\n");
-
- /* wait 1s so receiver can get the message before we shut down */
- Pt_Sleep(1000);
- printf("****** Closing everything and shutting down...\n");
-
- /* expect 2 open ports */
- check_ports(device_count, in_id, 'o', out_id, 'o', TRUE);
- /* close in */
- checkerror(Pm_Close(in));
- check_ports(device_count, in_id, 'c', out_id, 'o', TRUE);
-
- /* close out */
- checkerror(Pm_Close(out));
- check_ports(device_count, in_id, 'c', out_id, 'c', TRUE);
-
- /* delete in */
- checkerror(Pm_DeleteVirtualDevice(in_id));
- check_ports(device_count, in_id, 'd', out_id, 'c', TRUE);
-
- /* delete out */
- checkerror(Pm_DeleteVirtualDevice(out_id));
- check_ports(device_count, in_id, 'd', out_id, 'd', TRUE);
-
- /* we are done */
- Pm_Terminate();
-}
-
-
-int main(int argc, char *argv[])
-{
- int i;
- show_usage();
- for (i = 0; i < 3; i++) {
- test();
- }
- printf("finished virttest (SUCCESS). Type ENTER to quit...");
- while (getchar() != '\n') ;
- return 0;
-}