diff options
Diffstat (limited to 'portmidi/pm_test/virttest.c')
| -rw-r--r-- | portmidi/pm_test/virttest.c | 339 |
1 files changed, 0 insertions, 339 deletions
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 @@ | |||
| 1 | /* virttest.c -- test for creating/deleting virtual ports */ | ||
| 2 | /* | ||
| 3 | * Roger B. Dannenberg | ||
| 4 | * Oct 2021 | ||
| 5 | |||
| 6 | This test is performed by running 2 instances of the program. The | ||
| 7 | first instance makes input and output ports named portmidi and waits | ||
| 8 | for a message. The second tries to do the same, but will fail because | ||
| 9 | portmidi already exists. It then opens portmidi (both input and | ||
| 10 | output). In greater detail: | ||
| 11 | |||
| 12 | FIRST INSTANCE SECOND INSTANCE | ||
| 13 | -------------- --------------- | ||
| 14 | |||
| 15 | initialize PortMidi initialize PortMidi | ||
| 16 | create portmidi in | ||
| 17 | create portmidi out | ||
| 18 | wait for input | ||
| 19 | create portmidi in -> fails | ||
| 20 | open portmidi in/out | ||
| 21 | send to portmidi | ||
| 22 | recv from portmidi | ||
| 23 | send to portmidi | ||
| 24 | wait 1s recv from portmidi | ||
| 25 | close portmidi in and out | ||
| 26 | terminate PortMidi | ||
| 27 | list all devices: | ||
| 28 | - check for correct number | ||
| 29 | - check for good description of portmidi in port (open) | ||
| 30 | - check for good description of portmidi out port (open) | ||
| 31 | close portmidi in | ||
| 32 | list all devices: | ||
| 33 | - check for correct number | ||
| 34 | - check for good description of portmidi in port (closed) | ||
| 35 | - check for good description of portmidi out port (open) | ||
| 36 | close portmidi out | ||
| 37 | list all devices: | ||
| 38 | - check for correct number | ||
| 39 | - check for good description of portmidi in port (closed) | ||
| 40 | - check for good description of portmidi out port (closed) | ||
| 41 | delete portmidi in | ||
| 42 | - check for correct number | ||
| 43 | - check for NULL description of portmidi in port | ||
| 44 | - check for good description of portmidi out port (closed) | ||
| 45 | delete portmidi out | ||
| 46 | - check for correct number | ||
| 47 | - check for NULL description of portmidi in port | ||
| 48 | - check for NULL description of portmidi out port | ||
| 49 | terminate portmidi | ||
| 50 | REPEAT 3 TIMES wait 2 seconds to give head start to other instance | ||
| 51 | REPEAT 3 TIMES | ||
| 52 | */ | ||
| 53 | |||
| 54 | #include "portmidi.h" | ||
| 55 | #include "porttime.h" | ||
| 56 | #include "stdlib.h" | ||
| 57 | #include "stdio.h" | ||
| 58 | #include "string.h" | ||
| 59 | #include "assert.h" | ||
| 60 | |||
| 61 | #define OUTPUT_BUFFER_SIZE 0 | ||
| 62 | #define INPUT_BUFFER_SIZE 10 | ||
| 63 | #define DEVICE_INFO NULL | ||
| 64 | #define DRIVER_INFO NULL | ||
| 65 | #define TIME_PROC ((PmTimeProcPtr) Pt_Time) | ||
| 66 | #define TIME_INFO NULL | ||
| 67 | #define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */ | ||
| 68 | |||
| 69 | |||
| 70 | static void prompt_and_exit(void) | ||
| 71 | { | ||
| 72 | printf("type ENTER..."); | ||
| 73 | while (getchar() != '\n') ; | ||
| 74 | /* this will clean up open ports: */ | ||
| 75 | exit(-1); | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | static PmError printerror(PmError err, const char *msg) | ||
| 80 | { | ||
| 81 | if (err == pmHostError) { | ||
| 82 | /* it seems pointless to allocate memory and copy the string, | ||
| 83 | * so I will do the work of Pm_GetHostErrorText directly | ||
| 84 | */ | ||
| 85 | char errmsg[80]; | ||
| 86 | Pm_GetHostErrorText(errmsg, 80); | ||
| 87 | printf("%s\n %s\n", msg, errmsg); | ||
| 88 | } else if (err < 0) { | ||
| 89 | printf("%s\n %s\n", msg, Pm_GetErrorText(err)); | ||
| 90 | } | ||
| 91 | return err; | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | static PmError checkerror(PmError err) | ||
| 96 | { | ||
| 97 | if (err < 0) { | ||
| 98 | printerror(err, "PortMidi call failed..."); | ||
| 99 | prompt_and_exit(); | ||
| 100 | } | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | |||
| 105 | void wait_until(PmTimestamp when) | ||
| 106 | { | ||
| 107 | PtTimestamp now = Pt_Time(); | ||
| 108 | if (when > now) { | ||
| 109 | Pt_Sleep(when - now); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | void show_usage() | ||
| 115 | { | ||
| 116 | printf("Usage: virttest\n" | ||
| 117 | " run two instances to test virtual port create/delete\n"); | ||
| 118 | } | ||
| 119 | |||
| 120 | |||
| 121 | void check_info(int id, char stat, int input, int virtual) | ||
| 122 | { | ||
| 123 | const PmDeviceInfo *info = Pm_GetDeviceInfo(id); | ||
| 124 | if (stat == 'd') { | ||
| 125 | if (info) { | ||
| 126 | printf("Expected device %d to be deleted.\n", id); | ||
| 127 | prompt_and_exit(); | ||
| 128 | } | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | if (!info) { | ||
| 132 | printf("Expected device %d to not be deleted.\n", id); | ||
| 133 | prompt_and_exit(); | ||
| 134 | } | ||
| 135 | if (strcmp("portmidi", info->name) != 0) { | ||
| 136 | printf("Device %d name is %s, not \"portmidi\".\n", id, info->name); | ||
| 137 | prompt_and_exit(); | ||
| 138 | } | ||
| 139 | if (info->input != input || (!info->output) != input) { | ||
| 140 | printf("Device %d input/output fields are wrong.\n", id); | ||
| 141 | prompt_and_exit(); | ||
| 142 | } | ||
| 143 | if ((!info->opened && stat == 'o') || (info->opened && stat == 'c')) { | ||
| 144 | printf("Device %d opened==%d, status should be %c.\n", id, | ||
| 145 | info->opened, stat); | ||
| 146 | prompt_and_exit(); | ||
| 147 | } | ||
| 148 | if (info->is_virtual != virtual) { | ||
| 149 | printf("Expected device %d to be virtual.\n", id); | ||
| 150 | prompt_and_exit(); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | |||
| 155 | /* stat is 'o' for open, 'c' for closed, 'd' for deleted device */ | ||
| 156 | void check_ports(int cnt, int in_id, char in_stat, | ||
| 157 | int out_id, char out_stat, int virtual) | ||
| 158 | { | ||
| 159 | if (cnt != Pm_CountDevices()) { | ||
| 160 | printf("Device count changed from %d to %d.\n", cnt, Pm_CountDevices()); | ||
| 161 | prompt_and_exit(); | ||
| 162 | } | ||
| 163 | check_info(in_id, in_stat, TRUE, virtual); | ||
| 164 | check_info(out_id, out_stat, FALSE, virtual); | ||
| 165 | } | ||
| 166 | |||
| 167 | |||
| 168 | void devices_list() | ||
| 169 | { | ||
| 170 | int i; | ||
| 171 | for (i = 0; i < Pm_CountDevices(); i++) { | ||
| 172 | const PmDeviceInfo *info = Pm_GetDeviceInfo(i); | ||
| 173 | if (info) { | ||
| 174 | printf("%d: %s %s %s %s\n", i, info->name, | ||
| 175 | (info->input ? "input" : "output"), | ||
| 176 | (info->is_virtual ? "virtual" : "real_device"), | ||
| 177 | (info->opened ? "opened" : "closed")); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | |||
| 183 | void test2() | ||
| 184 | { | ||
| 185 | PmStream *out = NULL; | ||
| 186 | PmStream *in = NULL; | ||
| 187 | int out_id; | ||
| 188 | int in_id; | ||
| 189 | PmEvent buffer[1]; | ||
| 190 | PmTimestamp timestamp; | ||
| 191 | int pitch = 60; | ||
| 192 | int device_count = 0; | ||
| 193 | int i; | ||
| 194 | |||
| 195 | printf("This must be virttest instance #2\n"); | ||
| 196 | |||
| 197 | /* find and open portmidi in and out */ | ||
| 198 | device_count = Pm_CountDevices(); | ||
| 199 | for (i = 0; i < device_count; i++) { | ||
| 200 | const PmDeviceInfo *info = Pm_GetDeviceInfo(i); | ||
| 201 | if (info && strcmp(info->name, "portmidi") == 0) { | ||
| 202 | if (info->input) { | ||
| 203 | checkerror(Pm_OpenInput(&in, i, DRIVER_INFO, | ||
| 204 | INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO)); | ||
| 205 | in_id = i; | ||
| 206 | } else { | ||
| 207 | checkerror(Pm_OpenOutput(&out, i, DRIVER_INFO, | ||
| 208 | OUTPUT_BUFFER_SIZE, NULL, NULL, 0)); | ||
| 209 | out_id = i; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } | ||
| 213 | if (!in) { | ||
| 214 | printf("Did not open portmidi as input (virtual output).\n"); | ||
| 215 | prompt_and_exit(); | ||
| 216 | } | ||
| 217 | if (!out) { | ||
| 218 | printf("Did not open portmidi as output (virtual input).\n"); | ||
| 219 | prompt_and_exit(); | ||
| 220 | } | ||
| 221 | printf("Input device %d and output device %d are open.\n", in_id, out_id); | ||
| 222 | |||
| 223 | /* send a message */ | ||
| 224 | buffer[0].timestamp = 0; | ||
| 225 | buffer[0].message = Pm_Message(0x90, pitch, 100); | ||
| 226 | checkerror(Pm_Write(out, buffer, 1)); | ||
| 227 | |||
| 228 | /* wait for reply */ | ||
| 229 | printf("Sent message, waiting for reply...\n"); | ||
| 230 | while (Pm_Read(in, buffer, 1) < 1) Pt_Sleep(10); | ||
| 231 | |||
| 232 | printf("********** GOT THE MESSAGE, SHUTTING DOWN ************\n"); | ||
| 233 | |||
| 234 | /* close in */ | ||
| 235 | checkerror(Pm_Close(in)); | ||
| 236 | check_ports(device_count, in_id, 'c', out_id, 'o', FALSE); | ||
| 237 | printf("Closed input %d\n", in_id); | ||
| 238 | |||
| 239 | /* close out */ | ||
| 240 | checkerror(Pm_Close(out)); | ||
| 241 | check_ports(device_count, in_id, 'c', out_id, 'c', FALSE); | ||
| 242 | printf("Closed output %d\n", out_id); | ||
| 243 | |||
| 244 | Pt_Sleep(1000); | ||
| 245 | /* wrap it up */ | ||
| 246 | Pm_Terminate(); | ||
| 247 | printf("Got reply and terminated...\n"); | ||
| 248 | Pt_Sleep(2000); /* 2 seconds because other is waiting 1s. */ | ||
| 249 | /* 1 more second to make sure other shuts down before test repeats. */ | ||
| 250 | } | ||
| 251 | |||
| 252 | extern int pm_check_errors; | ||
| 253 | |||
| 254 | void test() | ||
| 255 | { | ||
| 256 | PmStream *out; | ||
| 257 | PmStream *in; | ||
| 258 | int out_id; | ||
| 259 | int in_id; | ||
| 260 | PmEvent buffer[1]; | ||
| 261 | PmTimestamp timestamp; | ||
| 262 | int device_count = 0; | ||
| 263 | |||
| 264 | TIME_START; | ||
| 265 | |||
| 266 | printf("******** INITIALIZING PORTMIDI ***********\n"); | ||
| 267 | timestamp = Pt_Time(); | ||
| 268 | Pm_Initialize(); | ||
| 269 | printf("Pm_Initialize took %dms\n", Pt_Time() - timestamp); | ||
| 270 | devices_list(); | ||
| 271 | |||
| 272 | pm_check_errors = FALSE; /* otherwise, PM_CHECK_ERRORS, if defined, */ | ||
| 273 | /* can cause this program to report an error and exit on pmNameConflict. */ | ||
| 274 | in_id = Pm_CreateVirtualInput("portmidi", NULL, DEVICE_INFO); | ||
| 275 | pm_check_errors = TRUE; /* there should be no other errors */ | ||
| 276 | if (in_id < 0) { | ||
| 277 | printerror(in_id, "Pm_CreateVirtualInput failed..."); | ||
| 278 | test2(); | ||
| 279 | return; | ||
| 280 | } | ||
| 281 | printf("Created portmidi virtual input; this is virttest instance #1\n"); | ||
| 282 | out_id = checkerror(Pm_CreateVirtualOutput("portmidi", NULL, DRIVER_INFO)); | ||
| 283 | device_count = Pm_CountDevices(); | ||
| 284 | |||
| 285 | checkerror(Pm_OpenInput(&in, in_id, NULL, 0, NULL, NULL)); | ||
| 286 | checkerror(Pm_OpenOutput(&out, out_id, DRIVER_INFO, OUTPUT_BUFFER_SIZE, | ||
| 287 | TIME_PROC, TIME_INFO, 0)); | ||
| 288 | printf("Created/Opened input %d and output %d\n", in_id, out_id); | ||
| 289 | Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX); | ||
| 290 | /* empty the buffer after setting filter, just in case anything | ||
| 291 | got through */ | ||
| 292 | while (Pm_Read(in, buffer, 1)) ; | ||
| 293 | |||
| 294 | /* wait for input */ | ||
| 295 | printf("Waiting for input...\n"); | ||
| 296 | while (Pm_Read(in, buffer, 1) < 1) Pt_Sleep(10); | ||
| 297 | |||
| 298 | /* send two replies (only one would be fine) */ | ||
| 299 | checkerror(Pm_Write(out, buffer, 1)); | ||
| 300 | printf("Received input, writing output...\n"); | ||
| 301 | |||
| 302 | /* wait 1s so receiver can get the message before we shut down */ | ||
| 303 | Pt_Sleep(1000); | ||
| 304 | printf("****** Closing everything and shutting down...\n"); | ||
| 305 | |||
| 306 | /* expect 2 open ports */ | ||
| 307 | check_ports(device_count, in_id, 'o', out_id, 'o', TRUE); | ||
| 308 | /* close in */ | ||
| 309 | checkerror(Pm_Close(in)); | ||
| 310 | check_ports(device_count, in_id, 'c', out_id, 'o', TRUE); | ||
| 311 | |||
| 312 | /* close out */ | ||
| 313 | checkerror(Pm_Close(out)); | ||
| 314 | check_ports(device_count, in_id, 'c', out_id, 'c', TRUE); | ||
| 315 | |||
| 316 | /* delete in */ | ||
| 317 | checkerror(Pm_DeleteVirtualDevice(in_id)); | ||
| 318 | check_ports(device_count, in_id, 'd', out_id, 'c', TRUE); | ||
| 319 | |||
| 320 | /* delete out */ | ||
| 321 | checkerror(Pm_DeleteVirtualDevice(out_id)); | ||
| 322 | check_ports(device_count, in_id, 'd', out_id, 'd', TRUE); | ||
| 323 | |||
| 324 | /* we are done */ | ||
| 325 | Pm_Terminate(); | ||
| 326 | } | ||
| 327 | |||
| 328 | |||
| 329 | int main(int argc, char *argv[]) | ||
| 330 | { | ||
| 331 | int i; | ||
| 332 | show_usage(); | ||
| 333 | for (i = 0; i < 3; i++) { | ||
| 334 | test(); | ||
| 335 | } | ||
| 336 | printf("finished virttest (SUCCESS). Type ENTER to quit..."); | ||
| 337 | while (getchar() != '\n') ; | ||
| 338 | return 0; | ||
| 339 | } | ||
