summaryrefslogtreecommitdiff
path: root/portmidi/pm_test/fastrcv.c
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-10-07 19:30:56 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-10-07 19:30:56 +0200
commit40a899bd6ee536eae093337bf2d0dcc8db4e46f1 (patch)
tree485ace3e6fd28b91f394efd277732651e10824d8 /portmidi/pm_test/fastrcv.c
parent6fc4bddfdf8e056469f316c1a0fe488efbb4253a (diff)
downloadttdaw-40a899bd6ee536eae093337bf2d0dcc8db4e46f1.tar.gz
Moved example code examples folder
Diffstat (limited to 'portmidi/pm_test/fastrcv.c')
-rw-r--r--portmidi/pm_test/fastrcv.c255
1 files changed, 0 insertions, 255 deletions
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 @@
1/* fastrcv.c -- send many MIDI messages very fast.
2 *
3 * This is a stress test created to explore reports of
4 * pm_write() call blocking (forever) on Linux when
5 * sending very dense MIDI sequences.
6 *
7 * Modified 8 Aug 2017 with -n to send expired timestamps
8 * to test a theory about why Linux ALSA hangs in Audacity.
9 *
10 * Roger B. Dannenberg, Aug 2017
11 */
12
13#include "portmidi.h"
14#include "porttime.h"
15#include "stdlib.h"
16#include "stdio.h"
17#include "string.h"
18#include "assert.h"
19
20#define INPUT_BUFFER_SIZE 1000 /* big to avoid losing any input */
21#define DEVICE_INFO NULL
22#define DRIVER_INFO NULL
23#define TIME_PROC ((PmTimeProcPtr) Pt_Time)
24#define TIME_INFO NULL
25#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
26
27#define STRING_MAX 80 /* used for console input */
28// need to get declaration for Sleep()
29#ifdef WIN32
30#include "windows.h"
31#else
32#include <unistd.h>
33#define Sleep(n) usleep(n * 1000)
34#endif
35
36
37int deviceno = -9999;
38int verbose = FALSE;
39
40
41static void prompt_and_exit(void)
42{
43 printf("type ENTER...");
44 while (getchar() != '\n') ;
45 /* this will clean up open ports: */
46 exit(-1);
47}
48
49
50static PmError checkerror(PmError err)
51{
52 if (err == pmHostError) {
53 /* it seems pointless to allocate memory and copy the string,
54 * so I will do the work of Pm_GetHostErrorText directly
55 */
56 char errmsg[80];
57 Pm_GetHostErrorText(errmsg, 80);
58 printf("PortMidi found host error...\n %s\n", errmsg);
59 prompt_and_exit();
60 } else if (err < 0) {
61 printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
62 prompt_and_exit();
63 }
64 return err;
65}
66
67
68/* read a number from console */
69/**/
70int get_number(const char *prompt)
71{
72 int n = 0, i;
73 fputs(prompt, stdout);
74 while (n != 1) {
75 n = scanf("%d", &i);
76 while (getchar() != '\n') ;
77 }
78 return i;
79}
80
81
82void fastrcv_test()
83{
84 PmStream * midi;
85 PmError status, length;
86 PmEvent buffer[1];
87 PmTimestamp start;
88 /* every 10ms read all messages, keep counts */
89 /* every 1000ms, print report */
90 int msgcnt = 0;
91 /* expect repeating sequence of 60 through 71, alternating on/off */
92 int expected_pitch = 60;
93 int expected_on = TRUE;
94 int report_time;
95 PmTimestamp last_timestamp = -1;
96 PmTimestamp last_delta = -1;
97
98 /* It is recommended to start timer before PortMidi */
99 TIME_START;
100
101 /* open output device */
102 if (deviceno == Pm_CountDevices()) {
103 int id = Pm_CreateVirtualInput("fastrcv", NULL, DEVICE_INFO);
104 if (id < 0) checkerror(id); /* error reporting */
105 checkerror(Pm_OpenInput(&midi, id, DRIVER_INFO,
106 INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO));
107 } else {
108 Pm_OpenInput(&midi, deviceno, DRIVER_INFO, INPUT_BUFFER_SIZE,
109 TIME_PROC, TIME_INFO);
110 }
111 printf("Midi Input opened.\n");
112
113 /* wait a sec after printing previous line */
114 start = Pt_Time() + 1000;
115 while (start > Pt_Time()) {
116 Sleep(10);
117 }
118
119 report_time = Pt_Time() + 1000; /* report every 1s */
120 while (TRUE) {
121 PmTimestamp now = Pt_Time();
122 status = Pm_Poll(midi);
123 if (status == TRUE) {
124 length = Pm_Read(midi, buffer, 1);
125 if (length > 0) {
126 int status = Pm_MessageStatus(buffer[0].message);
127 if (status == 0x80) { /* convert NoteOff to NoteOn, vel=0 */
128 status = 0x90;
129 buffer[0].message = Pm_Message(status,
130 Pm_MessageData1(buffer[0].message), 0);
131 }
132 /* only listen to NOTEON messages */
133 if (status == 0x90) {
134 int pitch = Pm_MessageData1(buffer[0].message);
135 int vel = Pm_MessageData2(buffer[0].message);
136 int is_on = (vel > 0);
137 if (verbose) {
138 printf("Note pitch %d vel %d\n", pitch, vel);
139 }
140 msgcnt++;
141 if (pitch != expected_pitch || expected_on != is_on) {
142 printf("Unexpected note-on: pitch %d vel %d, "
143 "expected: pitch %d Note%s\n", pitch, vel,
144 expected_pitch, (expected_on ? "On" : "Off"));
145 }
146 if (is_on) {
147 expected_on = FALSE;
148 expected_pitch = pitch;
149 } else {
150 expected_on = TRUE;
151 expected_pitch = (pitch + 1) % 72;
152 if (expected_pitch < 60) expected_pitch = 60;
153 }
154 if (last_timestamp >= 0) {
155 last_delta = buffer[0].timestamp - last_timestamp;
156 }
157 last_timestamp = buffer[0].timestamp;
158 }
159 }
160 }
161 if (now >= report_time) {
162 printf("%d msgs/sec", msgcnt);
163 /* if available, print the last timestamp and last delta time */
164 if (last_timestamp >= 0) {
165 printf(" last timestamp %d", (int) last_timestamp);
166 last_timestamp = -1;
167 }
168 if (last_delta >= 0) {
169 printf(" last delta time %d", (int) last_delta);
170 last_delta = -1;
171 }
172 printf("\n");
173 report_time += 1000;
174 msgcnt = 0;
175 }
176 }
177}
178
179
180void show_usage()
181{
182 printf("Usage: fastrcv [-h] [-v] [-d device], where\n"
183 "device is the PortMidi device number,\n"
184 "-h means help,\n"
185 "-v means verbose (print messages)\n");
186}
187
188int main(int argc, char *argv[])
189{
190 int default_in;
191 int default_out;
192 char *deflt;
193
194 int i = 0;
195 int test_input = 0, test_output = 0, test_both = 0;
196 int stream_test = 0;
197 int device_valid = FALSE;
198
199 if (sizeof(void *) == 8)
200 printf("Apparently this is a 64-bit machine.\n");
201 else if (sizeof(void *) == 4)
202 printf ("Apparently this is a 32-bit machine.\n");
203
204 if (argc <= 1) {
205 show_usage();
206 } else {
207 for (i = 1; i < argc; i++) {
208 if (strcmp(argv[i], "-h") == 0) {
209 show_usage();
210 } else if (strcmp(argv[i], "-v") == 0) {
211 verbose = TRUE;
212 } else if (strcmp(argv[i], "-d") == 0) {
213 i = i + 1;
214 deviceno = atoi(argv[i]);
215 printf("Device will be %d\n", deviceno);
216 } else {
217 show_usage();
218 }
219 }
220 }
221
222 /* list device information */
223 default_in = Pm_GetDefaultInputDeviceID();
224 default_out = Pm_GetDefaultOutputDeviceID();
225 for (i = 0; i < Pm_CountDevices(); i++) {
226 const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
227 if (!info->output) {
228 printf("%d: %s, %s", i, info->interf, info->name);
229 if (i == deviceno) {
230 device_valid = TRUE;
231 deflt = "selected ";
232 } else if (i == default_out) {
233 deflt = "default ";
234 } else {
235 deflt = "";
236 }
237 printf(" (%sinput)\n", deflt);
238 }
239 }
240 printf("%d: Create virtual port named \"fastrcv\"", i);
241 if (i == deviceno) {
242 device_valid = TRUE;
243 deflt = "selected ";
244 } else {
245 deflt = "";
246 }
247 printf(" (%sinput)\n", deflt);
248
249 if (!device_valid) {
250 deviceno = get_number("Input device number: ");
251 }
252
253 fastrcv_test();
254 return 0;
255}