diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2024-10-07 19:30:56 +0200 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2024-10-07 19:30:56 +0200 |
| commit | 40a899bd6ee536eae093337bf2d0dcc8db4e46f1 (patch) | |
| tree | 485ace3e6fd28b91f394efd277732651e10824d8 /portmidi/pm_test/fast.c | |
| parent | 6fc4bddfdf8e056469f316c1a0fe488efbb4253a (diff) | |
| download | ttdaw-40a899bd6ee536eae093337bf2d0dcc8db4e46f1.tar.gz | |
Moved example code examples folder
Diffstat (limited to 'portmidi/pm_test/fast.c')
| -rw-r--r-- | portmidi/pm_test/fast.c | 290 |
1 files changed, 0 insertions, 290 deletions
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; -} |
