aboutsummaryrefslogtreecommitdiff
path: root/portmidi/pm_test/recvvirtual.c
diff options
context:
space:
mode:
Diffstat (limited to 'portmidi/pm_test/recvvirtual.c')
-rw-r--r--portmidi/pm_test/recvvirtual.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/portmidi/pm_test/recvvirtual.c b/portmidi/pm_test/recvvirtual.c
new file mode 100644
index 0000000..f8d9848
--- /dev/null
+++ b/portmidi/pm_test/recvvirtual.c
@@ -0,0 +1,175 @@
1#include "portmidi.h"
2#include "porttime.h"
3#include "stdlib.h"
4#include "stdio.h"
5#include "string.h"
6#include "assert.h"
7
8#define INPUT_BUFFER_SIZE 100
9#define TIME_PROC ((PmTimeProcPtr) Pt_Time)
10#define TIME_INFO NULL
11#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
12
13#define STRING_MAX 80 /* used for console input */
14
15char *portname = "portmidi";
16
17PmSysDepInfo *sysdepinfo = NULL;
18char *port_name = "portmidi";
19
20static void set_sysdepinfo(char m_or_p, const char *name)
21{
22 if (!sysdepinfo) {
23 // allocate some space we will alias with open-ended PmDriverInfo:
24 // there is space for 4 parameters:
25 static char dimem[sizeof(PmSysDepInfo) + sizeof(void *) * 8];
26 sysdepinfo = (PmSysDepInfo *) dimem;
27 // build the driver info structure:
28 sysdepinfo->structVersion = PM_SYSDEPINFO_VERS;
29 sysdepinfo->length = 0;
30 }
31 if (sysdepinfo->length > 1) {
32 printf("Error: sysdepinfo was allocated to hold 2 parameters\n");
33 exit(1);
34 }
35 int i = sysdepinfo->length++;
36 enum PmSysDepPropertyKey k = pmKeyNone;
37 if (m_or_p == 'm') k = pmKeyCoreMidiManufacturer;
38 else if (m_or_p == 'p') k = pmKeyAlsaPortName;
39 else if (m_or_p == 'c') k = pmKeyAlsaClientName;
40 sysdepinfo->properties[i].key = k;
41 sysdepinfo->properties[i].value = name;
42}
43
44
45static void prompt_and_exit(void)
46{
47 printf("type ENTER...");
48 while (getchar() != '\n') ;
49 /* this will clean up open ports: */
50 exit(-1);
51}
52
53
54static PmError checkerror(PmError err)
55{
56 if (err == pmHostError) {
57 /* it seems pointless to allocate memory and copy the string,
58 * so I will do the work of Pm_GetHostErrorText directly
59 */
60 char errmsg[80];
61 Pm_GetHostErrorText(errmsg, 80);
62 printf("PortMidi found host error...\n %s\n", errmsg);
63 prompt_and_exit();
64 } else if (err < 0) {
65 printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err));
66 prompt_and_exit();
67 }
68 return err;
69}
70
71
72void main_test_input(int num)
73{
74 PmStream *midi;
75 PmError status, length;
76 PmEvent buffer[1];
77 int id;
78 int i = 0; /* count messages as they arrive */
79 /* It is recommended to start timer before Midi; otherwise, PortMidi may
80 start the timer with its (default) parameters
81 */
82 TIME_START;
83
84 /* create a virtual input device */
85 id = checkerror(Pm_CreateVirtualInput(port_name, NULL, sysdepinfo));
86 checkerror(Pm_OpenInput(&midi, id, sysdepinfo, 0, NULL, NULL));
87
88 printf("Midi Input opened. Reading %d Midi messages...\n", num);
89 Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
90 /* empty the buffer after setting filter, just in case anything
91 got through */
92 while (Pm_Poll(midi)) {
93 Pm_Read(midi, buffer, 1);
94 }
95 /* now start paying attention to messages */
96 while (i < num) {
97 status = Pm_Poll(midi);
98 if (status == TRUE) {
99 length = Pm_Read(midi, buffer, 1);
100 if (length > 0) {
101 printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
102 i,
103 (long) buffer[0].timestamp,
104 (long) Pm_MessageStatus(buffer[0].message),
105 (long) Pm_MessageData1(buffer[0].message),
106 (long) Pm_MessageData2(buffer[0].message));
107 i++;
108 } else {
109 assert(0);
110 }
111 }
112 }
113
114 /* close device (this not explicitly needed in most implementations) */
115 printf("ready to close...");
116 Pm_Close(midi);
117 printf("done closing.\nNow delete the virtual device...");
118 checkerror(Pm_DeleteVirtualDevice(id));
119 printf("done deleting.\n");
120}
121
122
123void show_usage()
124{
125 printf("Usage: recvvirtual [-h] [-m manufacturer] [-c clientname] "
126 "[-p portname] [n]\n"
127 " -h for this message,\n"
128 " -m name designates a manufacturer name (macOS only),\n"
129 " -c name designates a client name (linux only),\n"
130 " -p name designates a port name (linux only),\n"
131 " n is number of message to wait for.\n");
132 exit(0);
133}
134
135
136int main(int argc, char *argv[])
137{
138 char line[STRING_MAX];
139 int num = 10;
140 int i;
141 if (argc <= 1) {
142 show_usage();
143 }
144 for (i = 1; i < argc; i++) {
145 if (strcmp(argv[i], "-h") == 0) {
146 show_usage();
147 } else if (strcmp(argv[i], "-m") == 0 && (i + 1 < argc)) {
148 i = i + 1;
149 set_sysdepinfo('m', argv[i]);
150 printf("Manufacturer name will be %s\n", argv[i]);
151 } else if (strcmp(argv[i], "-p") == 0 && (i + 1 < argc)) {
152 i = i + 1;
153 port_name = argv[i];
154 set_sysdepinfo('p', port_name);
155 printf("Port name will be %s\n", port_name);
156 } else if (strcmp(argv[i], "-c") == 0 && (i + 1 < argc)) {
157 i = i + 1;
158 set_sysdepinfo('c', argv[i]);
159 printf("Client name will be %s\n", argv[i]);
160 } else {
161 num = atoi(argv[i]);
162 if (num <= 0) {
163 printf("Zero value or non-number for n\n");
164 show_usage();
165 }
166 printf("Waiting for %d messages.\n", num);
167 }
168 }
169
170 main_test_input(num);
171
172 printf("finished portMidi test...type ENTER to quit...");
173 while (getchar() != '\n') ;
174 return 0;
175}