summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/pdbox/PDa/extra/OSC-client.h189
-rw-r--r--apps/plugins/pdbox/PDa/extra/OSC.pd14
-rw-r--r--apps/plugins/pdbox/PDa/extra/OSCroute.c628
-rw-r--r--apps/plugins/pdbox/PDa/extra/bandpass-help.pd18
-rw-r--r--apps/plugins/pdbox/PDa/extra/dumpOSC.c1000
-rw-r--r--apps/plugins/pdbox/PDa/extra/fatom.h486
-rw-r--r--apps/plugins/pdbox/PDa/extra/gcanvas-help.pd9
-rw-r--r--apps/plugins/pdbox/PDa/extra/makefile34
-rw-r--r--apps/plugins/pdbox/PDa/extra/sendOSC.c1461
-rw-r--r--apps/plugins/pdbox/PDa/extra/sformat.h56
-rw-r--r--apps/plugins/pdbox/PDa/extra/shell.c312
-rw-r--r--apps/plugins/pdbox/PDa/extra/slider.c54
-rw-r--r--apps/plugins/pdbox/PDa/extra/sliderh.c64
-rw-r--r--apps/plugins/pdbox/PDa/extra/test-clip.pd14
-rw-r--r--apps/plugins/pdbox/PDa/extra/test-vcf.pd19
-rw-r--r--apps/plugins/pdbox/PDa/intern/sig~.c68
-rw-r--r--apps/plugins/pdbox/PDa/src/build.ipod6
-rw-r--r--apps/plugins/pdbox/PDa/src/d_array.c1074
-rw-r--r--apps/plugins/pdbox/PDa/src/d_delay.c319
-rw-r--r--apps/plugins/pdbox/PDa/src/d_filter.c548
-rw-r--r--apps/plugins/pdbox/PDa/src/d_math.c573
-rw-r--r--apps/plugins/pdbox/PDa/src/d_osc.c535
-rw-r--r--apps/plugins/pdbox/PDa/src/delme.pd9
-rw-r--r--apps/plugins/pdbox/PDa/src/makefile176
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio_alsa.c946
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio_mmio.c795
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio_oss.c845
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio_pa.c293
-rw-r--r--apps/plugins/pdbox/PDa/src/s_entry.c52
-rw-r--r--apps/plugins/pdbox/PDa/src/s_inter.c1000
-rw-r--r--apps/plugins/pdbox/PDa/src/s_main.c839
-rw-r--r--apps/plugins/pdbox/PDa/src/s_midi.c642
-rw-r--r--apps/plugins/pdbox/PDa/src/s_midi_oss.c360
-rw-r--r--apps/plugins/pdbox/PDa/src/s_midi_pm.c167
-rw-r--r--apps/plugins/pdbox/PDa/src/s_midi_sgi.c189
-rw-r--r--apps/plugins/pdbox/PDa/src/s_watchdog.c48
-rw-r--r--apps/plugins/pdbox/PDa/src/t_main.c121
-rw-r--r--apps/plugins/pdbox/PDa/src/t_tkcmd.c398
-rw-r--r--apps/plugins/pdbox/PDa/src/u_main.tk3368
-rw-r--r--apps/plugins/pdbox/PDa/src/u_pdreceive.c326
-rw-r--r--apps/plugins/pdbox/PDa/src/u_pdsend.c158
-rw-r--r--apps/plugins/pdbox/PDa/src/x_gui.c378
-rw-r--r--apps/plugins/pdbox/PDa/src/x_midi.c1314
-rw-r--r--apps/plugins/pdbox/SOURCES61
44 files changed, 17 insertions, 19949 deletions
diff --git a/apps/plugins/pdbox/PDa/extra/OSC-client.h b/apps/plugins/pdbox/PDa/extra/OSC-client.h
deleted file mode 100644
index fe2c37b5cb..0000000000
--- a/apps/plugins/pdbox/PDa/extra/OSC-client.h
+++ /dev/null
@@ -1,189 +0,0 @@
1/*
2Written by Matt Wright, The Center for New Music and Audio Technologies,
3University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03
4The Regents of the University of California (Regents).
5
6Permission to use, copy, modify, distribute, and distribute modified versions
7of this software and its documentation without fee and without a signed
8licensing agreement, is hereby granted, provided that the above copyright
9notice, this paragraph and the following two paragraphs appear in all copies,
10modifications, and distributions.
11
12IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
13SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
14OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
15BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
17REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
20HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
21MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
22*/
23
24/*
25
26 OSC-client.h: library for constructing OpenSoundControl messages.
27 Derived from SynthControl.h
28 Author: Matt Wright
29 Version 0.1: 6/13/97
30 Version 0.2: 7/21/2000: Support for type-tagged messages
31
32
33 General notes:
34
35 This library abstracts away the data format for the OpenSoundControl
36 protocol. Users of this library can construct OpenSoundControl packets
37 with a function call interface instead of knowing how to lay out the bits.
38
39 All issues of memory allocation are deferred to the user of this library.
40 There are two data structures that the user must allocate. The first
41 is the actual buffer that the message will be written into. This buffer
42 can be any size, but if it's too small there's a possibility that it
43 will become overfull. The other data structure is called an OSCbuf,
44 and it holds all the state used by the library as it's constructing
45 a buffer.
46
47 All procedures that have the possibility of an error condition return int,
48 with 0 indicating no error and nonzero indicating an error. The variable
49 OSC_errorMessage will be set to point to a string containing an error
50 message explaining what the problem is.
51
52*/
53
54
55
56/* The int4byte type has to be a 4-byte integer. You may have to
57 change this to long or something else on your system. */
58#ifdef __MWERKS__
59 /* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is
60 always 4 bytes */
61 typedef long int4byte;
62#else
63 typedef int int4byte;
64#endif
65
66/* OSC_timetag.h */
67
68 typedef struct {
69 int seconds;
70 int fraction;
71 } OSCTimeTag;
72
73OSCTimeTag OSCTT_Immediately(void);
74OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset);
75OSCTimeTag OSCTT_CurrentTime(void);
76
77
78
79/* The maximum depth of bundles within bundles within bundles within...
80 This is the size of a static array. If you exceed this limit you'll
81 get an error message. */
82#define MAX_BUNDLE_NESTING 32
83
84
85/* Don't ever manipulate the data in the OSCbuf struct directly. (It's
86 declared here in the header file only so your program will be able to
87 declare variables of type OSCbuf and have the right amount of memory
88 be allocated.) */
89
90typedef struct OSCbuf_struct {
91 char *buffer; /* The buffer to hold the OSC packet */
92 int size; /* Size of the buffer */
93 char *bufptr; /* Current position as we fill the buffer */
94 int state; /* State of partially-constructed message */
95 int4byte *thisMsgSize; /* Pointer to count field before
96 currently-being-written message */
97 int4byte *prevCounts[MAX_BUNDLE_NESTING];
98 /* Pointers to count field before each currently
99 open bundle */
100 int bundleDepth; /* How many sub-sub-bundles are we in now? */
101 char *typeStringPtr; /* This pointer advances through the type
102 tag string as you add arguments. */
103 int gettingFirstUntypedArg; /* nonzero if this message doesn't have
104 a type tag and we're waiting for the 1st arg */
105} OSCbuf;
106
107
108
109/* Initialize the given OSCbuf. The user of this module must pass in the
110 block of memory that this OSCbuf will use for a buffer, and the number of
111 bytes in that block. (It's the user's job to allocate the memory because
112 you do it differently in different systems.) */
113void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray);
114
115
116/* Reset the given OSCbuf. Do this after you send out the contents of
117 the buffer and want to start writing new data into it. */
118void OSC_resetBuffer(OSCbuf *buf);
119
120
121/* Is the buffer empty? (I.e., would it be stupid to send the buffer
122 contents to the synth?) */
123int OSC_isBufferEmpty(OSCbuf *buf);
124
125
126/* How much space is left in the buffer? */
127int OSC_freeSpaceInBuffer(OSCbuf *buf);
128
129/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */
130int OSC_isBufferDone(OSCbuf *buf);
131
132/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone()
133 returns true), call these two procedures to get the OSC packet that's been
134 assembled and its size in bytes. (And then call OSC_resetBuffer() if you
135 want to re-use this OSCbuf for the next packet.) */
136char *OSC_getPacket(OSCbuf *buf);
137int OSC_packetSize(OSCbuf *buf);
138
139
140
141/* Here's the basic model for building up OSC messages in an OSCbuf:
142
143 - Make sure the OSCbuf has been initialized with OSC_initBuffer().
144
145 - To open a bundle, call OSC_openBundle(). You can then write
146 messages or open new bundles within the bundle you opened.
147 Call OSC_closeBundle() to close the bundle. Note that a packet
148 does not have to have a bundle; it can instead consist of just a
149 single message.
150
151
152 - For each message you want to send:
153
154 - Call OSC_writeAddress() with the name of your message. (In
155 addition to writing your message name into the buffer, this
156 procedure will also leave space for the size count of this message.)
157
158 - Alternately, call OSC_writeAddressAndTypes() with the name of
159 your message and with a type string listing the types of all the
160 arguments you will be putting in this message.
161
162 - Now write each of the arguments into the buffer, by calling one of:
163 OSC_writeFloatArg()
164 OSC_writeFloatArgs()
165 OSC_writeIntArg()
166 OSC_writeStringArg()
167
168 - Now your message is complete; you can send out the buffer or you can
169 add another message to it.
170*/
171
172int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt);
173int OSC_closeBundle(OSCbuf *buf);
174int OSC_closeAllBundles(OSCbuf *buf);
175
176int OSC_writeAddress(OSCbuf *buf, char *name);
177int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types);
178int OSC_writeFloatArg(OSCbuf *buf, float arg);
179int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args);
180int OSC_writeIntArg(OSCbuf *buf, int4byte arg);
181int OSC_writeStringArg(OSCbuf *buf, char *arg);
182
183extern char *OSC_errorMessage;
184
185/* How many bytes will be needed in the OSC format to hold the given
186 string? The length of the string, plus the null char, plus any padding
187 needed for 4-byte alignment. */
188int OSC_effectiveStringLength(char *string);
189
diff --git a/apps/plugins/pdbox/PDa/extra/OSC.pd b/apps/plugins/pdbox/PDa/extra/OSC.pd
deleted file mode 100644
index 37841ef17a..0000000000
--- a/apps/plugins/pdbox/PDa/extra/OSC.pd
+++ /dev/null
@@ -1,14 +0,0 @@
1#N canvas 0 0 240 300 10;
2#X obj 32 185 dumpOSC 5550;
3#X obj 32 217 OSCroute /hello;
4#X obj 32 239 print;
5#X obj 133 238 print;
6#X obj 26 87 sendOSC;
7#X msg 50 43 connect localhost 5550;
8#X msg 21 13 send /hello PDa;
9#X connect 0 0 1 0;
10#X connect 1 0 2 0;
11#X connect 1 1 3 0;
12#X connect 5 0 4 0;
13#X connect 6 0 4 0;
14
diff --git a/apps/plugins/pdbox/PDa/extra/OSCroute.c b/apps/plugins/pdbox/PDa/extra/OSCroute.c
deleted file mode 100644
index 64edbc777f..0000000000
--- a/apps/plugins/pdbox/PDa/extra/OSCroute.c
+++ /dev/null
@@ -1,628 +0,0 @@
1/*
2Written by Adrian Freed, The Center for New Music and Audio Technologies,
3University of California, Berkeley. Copyright (c) 1992,93,94,95,96,97,98,99,2000,01,02,03,04
4The Regents of the University of California (Regents).
5
6Permission to use, copy, modify, distribute, and distribute modified versions
7of this software and its documentation without fee and without a signed
8licensing agreement, is hereby granted, provided that the above copyright
9notice, this paragraph and the following two paragraphs appear in all copies,
10modifications, and distributions.
11
12IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
13SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
14OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
15BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
17REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
20HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
21MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
22
23
24The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
25*/
26
27 /* OSC-route.c
28 Max object for OSC-style dispatching
29
30 To-do:
31
32 Match a pattern against a pattern?
33 Declare outlet types / distinguish leaf nodes from other children
34 More sophisticated (2-pass?) allmessages scheme
35 set message?
36
37
38 pd
39 -------------
40 -- tweaks for Win32 www.zeggz.com/raf 13-April-2002
41
42
43 */
44
45#ifdef ROCKBOX
46#include "plugin.h"
47#include "../../pdbox.h"
48#else /* ROCKBOX */
49#ifdef WIN32
50 #include <stdlib.h>
51 #include <string.h>
52#endif
53#ifdef __APPLE__
54 #include <stdio.h>
55#endif
56#ifdef UNIX
57 #include <stdio.h>
58#endif
59#endif /* ROCKBOX */
60
61/* structure definition of your object */
62
63#define MAX_NUM 20
64#define OSC_ROUTE_VERSION "1.05"
65#define OSCWarning(x...) post(x)
66
67/* the required include files */
68#include "../src/m_pd.h"
69
70
71#ifndef TRUE
72typedef int Boolean;
73#define TRUE 1
74#define FALSE 0
75#endif
76
77
78/* Fixed byte width types */
79typedef int int4; /* 4 byte int */
80
81Boolean PatternMatch (const char *pattern, const char *test);
82
83
84
85/* Version 1.04: Allows #1 thru #9 as typed-in arguments
86 Version 1.05: Allows "list" messages as well as "message" messages.
87*/
88
89static t_class *OSCroute_class;
90
91typedef struct _OSCroute
92{
93 t_object x_obj; // required header
94 t_int x_num; // Number of address prefixes we store
95 t_int x_complainmode; // Do we print a message if no match?
96 t_int x_sendmode; // use pd internal sends instead of outlets
97 char *x_prefixes[MAX_NUM];
98 void *x_outlets[MAX_NUM+1];
99} t_OSCroute;
100
101t_symbol *ps_list, *ps_complain, *ps_emptySymbol;
102
103/* prototypes */
104
105void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
106void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
107void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
108/* //void *OSCroute_new(t_symbol *s, int argc, atom *argv); */
109void *OSCroute_new(t_symbol *s, int argc, t_atom *argv);
110void OSCroute_version (t_OSCroute *x);
111/* void OSCroute_assist (OSCroute *x, void *box, long msg, long arg, */
112/* char *dstString); */
113void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
114
115static char *NextSlashOrNull(char *p);
116static void StrCopyUntilSlash(char *target, const char *source);
117
118
119// free
120static void OSCroute_free(t_OSCroute *x)
121{
122#ifdef ROCKBOX
123 (void) x;
124#endif
125 // freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
126}
127
128/* initialization routine */
129
130// setup
131#ifdef WIN32
132 OSC_API void OSCroute_setup(void) {
133#else
134void OSCroute_setup(void) {
135#endif
136 OSCroute_class = class_new(gensym("OSCroute"), (t_newmethod)OSCroute_new,
137 (t_method)OSCroute_free,sizeof(t_OSCroute), 0, A_GIMME, 0);
138 class_addlist(OSCroute_class, OSCroute_list);
139 class_addanything(OSCroute_class, OSCroute_anything);
140 class_addmethod(OSCroute_class, (t_method)OSCroute_version, gensym("version"), A_NULL, 0, 0);
141 class_sethelpsymbol(OSCroute_class, gensym("OSCroute-help.pd"));
142
143 /*
144 class_addmethod(OSCroute_class, (t_method)OSCroute_connect,
145 gensym("connect"), A_SYMBOL, A_FLOAT, 0);
146 class_addmethod(OSCroute_class, (t_method)OSCroute_disconnect,
147 gensym("disconnect"), 0);
148 class_addmethod(OSCroute_class, (t_method)OSCroute_send, gensym("send"),
149 A_GIMME, 0);
150 */
151/* ps_list = gensym("list"); */
152/* ps_complain = gensym("complain"); */
153 ps_emptySymbol = gensym("");
154
155 post("OSCroute object version " OSC_ROUTE_VERSION " by Matt Wright. pd: jdl Win32 raf.");
156 post("OSCroute Copyright © 1999 Regents of the University of California. All Rights Reserved.");
157}
158
159
160
161/* instance creation routine */
162
163void *OSCroute_new(t_symbol *s, int argc, t_atom *argv)
164{
165#ifdef ROCKBOX
166 (void) s;
167#endif
168 t_OSCroute *x = (t_OSCroute *)pd_new(OSCroute_class); // get memory for a new object & initialize
169
170 int i; //{{raf}} n not used
171
172 // EnterCallback();
173
174 if (argc > MAX_NUM) {
175 post("* OSC-route: too many arguments: %ld (max %ld)", argc, MAX_NUM);
176 // ExitCallback();
177 return 0;
178 }
179
180 x->x_complainmode = 0;
181 x->x_num = 0;
182 for (i = 0; i < argc; ++i) {
183 if (argv[i].a_type == A_SYMBOL) {
184 if (argv[i].a_w.w_symbol->s_name[0] == '/') {
185 /* Now that's a nice prefix */
186 x->x_prefixes[i] = argv[i].a_w.w_symbol->s_name;
187 ++(x->x_num);
188 } else if (argv[i].a_w.w_symbol->s_name[0] == '#' &&
189 argv[i].a_w.w_symbol->s_name[1] >= '1' &&
190 argv[i].a_w.w_symbol->s_name[1] <= '9') {
191 /* The Max programmer is trying to make a patch that will be
192 a subpatch with arguments. We have to make an outlet for this
193 argument. */
194 x->x_prefixes[i] = "dummy";
195 ++(x->x_num);
196 } else {
197 /* Maybe this is an option we support */
198
199/* if (argv[i].a_w.w_sym == ps_complain) { */
200/* x->x_complainmode = 1; */
201/* } else { */
202/* post("* OSC-route: Unrecognized argument %s", argv[i].a_w.w_sym->s_name); */
203/* } */
204
205 }
206
207 // no LONG
208
209/* } else if (argv[i].a_type == A_FLOAD) { */
210/* // Convert to a numeral. Max ints are -2147483648 to 2147483647 */
211/* char *string = getbytes(12); */
212/* // I can't be bothered to plug this 12 byte memory leak */
213/* if (string == 0) { */
214/* post("* OSC-route: out of memory!"); */
215/* // ExitCallback(); */
216/* return 0; */
217/* } */
218/* sprintf(string, "%d", argv[i].a_w.w_long); */
219/* x->x_prefixes[i] = string; */
220/* ++(x->x_num); */
221
222 } else if (argv[i].a_type == A_FLOAT) {
223 post("* OSC-route: float arguments are not OK.");
224 // ExitCallback();
225 return 0;
226 } else {
227 post("* OSC-route: unrecognized argument type!");
228 // ExitCallback();
229 return 0;
230 }
231 }
232
233
234 /* Have to create the outlets in reverse order */
235 /* well, not in pd ? */
236 // for (i = x->x_num-1; i >= 0; --i) {
237 // for (i = 0; i <= x->x_num-1; i++) {
238 for (i = 0; i <= x->x_num; i++) {
239 // x->x_outlets[i] = listout(x);
240 x->x_outlets[i] = outlet_new(&x->x_obj, &s_list);
241 }
242
243 // ExitCallback();
244 return (x);
245}
246
247
248void OSCroute_version (t_OSCroute *x) {
249#ifdef ROCKBOX
250 (void) x;
251#endif
252 // EnterCallback();
253 post("OSCroute Version " OSC_ROUTE_VERSION
254 ", by Matt Wright. pd jdl, win32: raf.\nOSCroute Compiled " __TIME__ " " __DATE__);
255 // ExitCallback();
256}
257
258/* I don't know why these aren't defined in some Max #include file. */
259#define ASSIST_INLET 1
260#define ASSIST_OUTLET 2
261
262void OSCroute_assist (t_OSCroute *x, void *box, long msg, long arg,
263 char *dstString) {
264#ifdef ROCKBOX
265 (void) box;
266#endif
267 // EnterCallback();
268
269 if (msg==ASSIST_INLET) {
270#ifdef ROCKBOX
271 strcpy(dstString, "Incoming OSC messages");
272#else
273 sprintf(dstString, "Incoming OSC messages");
274#endif
275 } else if (msg==ASSIST_OUTLET) {
276 if (arg < 0 || arg >= x->x_num) {
277 post("* OSCroute_assist: No outlet corresponds to arg %ld!", arg);
278 } else {
279#ifdef ROCKBOX
280 strcpy(dstString, "subaddress + args for prefix ");
281 strcat(dstString, x->x_prefixes[arg]);
282#else
283 sprintf(dstString, "subaddress + args for prefix %s", x->x_prefixes[arg]);
284#endif
285 }
286 } else {
287 post("* OSCroute_assist: unrecognized message %ld", msg);
288 }
289
290 // ExitCallback();
291}
292
293void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
294#ifdef ROCKBOX
295 (void) s;
296#endif
297 // EnterCallback();
298 if (argc > 0 && argv[0].a_type == A_SYMBOL) {
299 /* Ignore the fact that this is a "list" */
300 OSCroute_doanything(x, argv[0].a_w.w_symbol, argc-1, argv+1);
301 } else {
302 // post("* OSC-route: invalid list beginning with a number");
303 // output on unmatched outlet jdl 20020908
304 if (argv[0].a_type == A_FLOAT) {
305 outlet_float(x->x_outlets[x->x_num], argv[0].a_w.w_float);
306 } else {
307 post("* OSC-route: unrecognized atom type!");
308 }
309 }
310 // ExitCallback();
311}
312
313
314void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
315 // EnterCallback();
316 OSCroute_doanything(x, s, argc, argv);
317 // ExitCallback();
318}
319
320
321
322
323void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
324 char *pattern, *nextSlash;
325 int i;
326 int matchedAnything;
327 // post("*** OSCroute_anything(s %s, argc %ld)", s->s_name, (long) argc);
328
329 pattern = s->s_name;
330 if (pattern[0] != '/') {
331 post("* OSC-route: invalid message pattern %s does not begin with /", s->s_name);
332 outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
333 return;
334 }
335
336 matchedAnything = 0;
337
338 nextSlash = NextSlashOrNull(pattern+1);
339 if (*nextSlash == '\0') {
340 /* last level of the address, so we'll output the argument list */
341
342
343#ifdef NULL_IS_DIFFERENT_FROM_BANG
344 if (argc==0) {
345 post("* OSC-route: why are you matching one level pattern %s with no args?",
346 pattern);
347 return;
348 }
349#endif
350
351 for (i = 0; i < x->x_num; ++i) {
352 if (PatternMatch(pattern+1, x->x_prefixes[i]+1)) {
353 ++matchedAnything;
354
355 // I hate stupid Max lists with a special first element
356 if (argc == 0) {
357 outlet_bang(x->x_outlets[i]);
358 } else if (argv[0].a_type == A_SYMBOL) {
359 // Promote the symbol that was argv[0] to the special symbol
360 outlet_anything(x->x_outlets[i], argv[0].a_w.w_symbol, argc-1, argv+1);
361 } else if (argc > 1) {
362 // Multiple arguments starting with a number, so naturally we have
363 // to use a special function to output this "list", since it's what
364 // Max originally meant by "list".
365 outlet_list(x->x_outlets[i], 0L, argc, argv);
366 } else {
367 // There was only one argument, and it was a number, so we output it
368 // not as a list
369/* if (argv[0].a_type == A_LONG) { */
370
371/* outlet_int(x->x_outlets[i], argv[0].a_w.w_long); */
372 // } else
373 if (argv[0].a_type == A_FLOAT) {
374
375 outlet_float(x->x_outlets[i], argv[0].a_w.w_float);
376 } else {
377 post("* OSC-route: unrecognized atom type!");
378 }
379 }
380 }
381 }
382 } else {
383 /* There's more address after this part, so our output list will begin with
384 the next slash. */
385 t_symbol *restOfPattern = 0; /* avoid the gensym unless we have to output */
386 char patternBegin[1000];
387
388
389 /* Get the first level of the incoming pattern to match against all our prefixes */
390 StrCopyUntilSlash(patternBegin, pattern+1);
391
392 for (i = 0; i < x->x_num; ++i) {
393 if (PatternMatch(patternBegin, x->x_prefixes[i]+1)) {
394 ++matchedAnything;
395 if (restOfPattern == 0) {
396 restOfPattern = gensym(nextSlash);
397 }
398 outlet_anything(x->x_outlets[i], restOfPattern, argc, argv);
399 }
400 }
401 }
402
403 if (x->x_complainmode) {
404 if (!matchedAnything) {
405 post("* OSC-route: pattern %s did not match any prefixes", pattern);
406 }
407 }
408
409 // output unmatched data on rightmost outlet a la normal 'route' object, jdl 20020908
410 if (!matchedAnything) {
411 outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
412 }
413
414
415}
416
417static char *NextSlashOrNull(char *p) {
418 while (*p != '/' && *p != '\0') {
419 p++;
420 }
421 return p;
422}
423
424static void StrCopyUntilSlash(char *target, const char *source) {
425 while (*source != '/' && *source != '\0') {
426 *target = *source;
427 ++target;
428 ++source;
429 }
430 *target = 0;
431}
432
433static int MyStrCopy(char *target, const char *source) {
434 int i = 0;
435 while (*source != '\0') {
436 *target = *source;
437 ++target;
438 ++source;
439 ++i;
440 }
441 *target = 0;
442 return i;
443}
444
445
446
447void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
448 int i;
449 t_symbol *prefixSymbol = 0;
450 char prefixBuf[1000];
451 char *endOfPrefix;
452 t_atom a[1];
453
454 if (argc >= 1 && argv[0].a_type == A_SYMBOL) {
455 prefixSymbol = argv[0].a_w.w_symbol;
456 endOfPrefix = prefixBuf + MyStrCopy(prefixBuf,
457 prefixSymbol->s_name);
458 } else {
459 prefixSymbol = ps_emptySymbol;
460 prefixBuf[0] = '\0';
461 endOfPrefix = prefixBuf;
462 }
463
464
465 for (i = 0; i < x->x_num; ++i) {
466 post("OSC: %s%s", prefixSymbol->s_name, x->x_prefixes[i]);
467 MyStrCopy(endOfPrefix, x->x_prefixes[i]);
468 SETSYMBOL(a, gensym(prefixBuf));
469 outlet_anything(x->x_outlets[i], s, 1, a);
470 }
471}
472
473
474/* --------------------------------------------------- */
475
476
477
478static const char *theWholePattern; /* Just for warning messages */
479
480static Boolean MatchBrackets (const char *pattern, const char *test);
481static Boolean MatchList (const char *pattern, const char *test);
482
483Boolean PatternMatch (const char * pattern, const char * test) {
484 theWholePattern = pattern;
485
486 if (pattern == 0 || pattern[0] == 0) {
487 return test[0] == 0;
488 }
489
490 if (test[0] == 0) {
491 if (pattern[0] == '*')
492 return PatternMatch (pattern+1,test);
493 else
494 return FALSE;
495 }
496
497 switch (pattern[0]) {
498 case 0 : return test[0] == 0;
499 case '?' : return PatternMatch (pattern + 1, test + 1);
500 case '*' :
501 if (PatternMatch (pattern+1, test)) {
502 return TRUE;
503 } else {
504 return PatternMatch (pattern, test+1);
505 }
506 case ']' :
507 case '}' :
508 OSCWarning("Spurious %c in pattern \".../%s/...\"",pattern[0], theWholePattern);
509 return FALSE;
510 case '[' :
511 return MatchBrackets (pattern,test);
512 case '{' :
513 return MatchList (pattern,test);
514 case '\\' :
515 if (pattern[1] == 0) {
516 return test[0] == 0;
517 } else if (pattern[1] == test[0]) {
518 return PatternMatch (pattern+2,test+1);
519 } else {
520 return FALSE;
521 }
522 default :
523 if (pattern[0] == test[0]) {
524 return PatternMatch (pattern+1,test+1);
525 } else {
526 return FALSE;
527 }
528 }
529}
530
531
532/* we know that pattern[0] == '[' and test[0] != 0 */
533
534static Boolean MatchBrackets (const char *pattern, const char *test) {
535 Boolean result;
536 Boolean negated = FALSE;
537 const char *p = pattern;
538
539 if (pattern[1] == 0) {
540 OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
541 return FALSE;
542 }
543
544 if (pattern[1] == '!') {
545 negated = TRUE;
546 p++;
547 }
548
549 while (*p != ']') {
550 if (*p == 0) {
551 OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
552 return FALSE;
553 }
554 if (p[1] == '-' && p[2] != 0) {
555 if (test[0] >= p[0] && test[0] <= p[2]) {
556 result = !negated;
557 goto advance;
558 }
559 }
560 if (p[0] == test[0]) {
561 result = !negated;
562 goto advance;
563 }
564 p++;
565 }
566
567 result = negated;
568
569advance:
570
571 if (!result)
572 return FALSE;
573
574 while (*p != ']') {
575 if (*p == 0) {
576 OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
577 return FALSE;
578 }
579 p++;
580 }
581
582 return PatternMatch (p+1,test+1);
583}
584
585static Boolean MatchList (const char *pattern, const char *test) {
586
587 const char *restOfPattern, *tp = test;
588
589
590 for(restOfPattern = pattern; *restOfPattern != '}'; restOfPattern++) {
591 if (*restOfPattern == 0) {
592 OSCWarning("Unterminated { in pattern \".../%s/...\"", theWholePattern);
593 return FALSE;
594 }
595 }
596
597 restOfPattern++; /* skip close curly brace */
598
599
600 pattern++; /* skip open curly brace */
601
602 while (1) {
603
604 if (*pattern == ',') {
605 if (PatternMatch (restOfPattern, tp)) {
606 return TRUE;
607 } else {
608 tp = test;
609 ++pattern;
610 }
611 } else if (*pattern == '}') {
612 return PatternMatch (restOfPattern, tp);
613 } else if (*pattern == *tp) {
614 ++pattern;
615 ++tp;
616 } else {
617 tp = test;
618 while (*pattern != ',' && *pattern != '}') {
619 pattern++;
620 }
621 if (*pattern == ',') {
622 pattern++;
623 }
624 }
625 }
626
627}
628
diff --git a/apps/plugins/pdbox/PDa/extra/bandpass-help.pd b/apps/plugins/pdbox/PDa/extra/bandpass-help.pd
deleted file mode 100644
index 52feeb16c2..0000000000
--- a/apps/plugins/pdbox/PDa/extra/bandpass-help.pd
+++ /dev/null
@@ -1,18 +0,0 @@
1#N canvas 428 285 240 300 8;
2#X obj 24 78 noise~;
3#X obj 15 215 dac~;
4#X obj 24 167 biquad~;
5#X floatatom 67 76 5 0 0 0 - - -;
6#X floatatom 83 111 5 0 0 0 - - -;
7#X obj 67 138 bandpass 600 10;
8#X text 77 97 bandwidth: 100 = 1 octave;
9#X text 67 58 frequency;
10#X text 8 11 Calculation of biquad coefficients;
11#X text 7 21 ==================================;
12#X connect 0 0 2 0;
13#X connect 2 0 1 0;
14#X connect 2 0 1 1;
15#X connect 3 0 5 0;
16#X connect 4 0 5 1;
17#X connect 5 0 2 0;
18
diff --git a/apps/plugins/pdbox/PDa/extra/dumpOSC.c b/apps/plugins/pdbox/PDa/extra/dumpOSC.c
deleted file mode 100644
index b4ef97d7d1..0000000000
--- a/apps/plugins/pdbox/PDa/extra/dumpOSC.c
+++ /dev/null
@@ -1,1000 +0,0 @@
1/*
2Written by Matt Wright and Adrian Freed, The Center for New Music and
3Audio Technologies, University of California, Berkeley. Copyright (c)
41992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of
5California (Regents).
6
7Permission to use, copy, modify, distribute, and distribute modified versions
8of this software and its documentation without fee and without a signed
9licensing agreement, is hereby granted, provided that the above copyright
10notice, this paragraph and the following two paragraphs appear in all copies,
11modifications, and distributions.
12
13IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
14SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
15OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
16BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17
18REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
21HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
22MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
24
25The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
26*/
27
28
29 /*
30
31 dumpOSC.c
32 server that displays OpenSoundControl messages sent to it
33 for debugging client udp and UNIX protocol
34
35 by Matt Wright, 6/3/97
36 modified from dumpSC.c, by Matt Wright and Adrian Freed
37
38 version 0.2: Added "-silent" option a.k.a. "-quiet"
39
40 version 0.3: Incorporated patches from Nicola Bernardini to make
41 things Linux-friendly. Also added ntohl() in the right places
42 to support little-endian architectures.
43
44
45
46 compile:
47 cc -o dumpOSC dumpOSC.c
48
49 to-do:
50
51 More robustness in saying exactly what's wrong with ill-formed
52 messages. (If they don't make sense, show exactly what was
53 received.)
54
55 Time-based features: print time-received for each packet
56
57 Clean up to separate OSC parsing code from socket/select stuff
58
59 pd: branched from http://www.cnmat.berkeley.edu/OpenSoundControl/src/dumpOSC/dumpOSC.c
60 -------------
61 -- added pd functions
62 -- socket is made differently than original via pd mechanisms
63 -- tweaks for Win32 www.zeggz.com/raf 13-April-2002
64 -- the OSX changes from cnmat didnt make it here yet but this compiles
65 on OSX anyway.
66
67*/
68
69#if HAVE_CONFIG_H
70#include <config.h>
71#endif
72
73#include "../src/m_pd.h"
74//#include "m_imp.h"
75#include "s_stuff.h"
76
77/* declarations */
78
79// typedef void (*t_fdpollfn)(void *ptr, int fd);
80void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
81
82
83#if defined(__sgi) || defined(__linux) || defined(WIN32) || defined(__APPLE__)
84
85#ifdef WIN32
86 #include "OSC-common.h"
87 #include <winsock2.h>
88 #include <string.h>
89 #include <stdlib.h>
90 #include <fcntl.h>
91 #include <sys/types.h>
92 #include <sys/stat.h>
93 #include <ctype.h>
94 #include <signal.h>
95#else
96 #include <stdio.h>
97 #include <string.h>
98 #include <stdlib.h>
99 #include <unistd.h>
100 #include <fcntl.h>
101 #include <sys/types.h>
102 #include <sys/stat.h>
103 #include <netinet/in.h>
104 #include <rpc/rpc.h>
105 #include <sys/socket.h>
106 #include <sys/un.h>
107 #include <sys/times.h>
108 #include <sys/param.h>
109 #include <sys/time.h>
110 #include <sys/ioctl.h>
111 #include <ctype.h>
112 #include <arpa/inet.h>
113 #include <netdb.h>
114 #include <pwd.h>
115 #include <signal.h>
116 #include <grp.h>
117 #include <sys/file.h>
118 //#include <sys/prctl.h>
119
120 #ifdef NEED_SCHEDCTL_AND_LOCK
121 #include <sys/schedctl.h>
122 #include <sys/lock.h>
123 #endif
124#endif
125
126
127char *htm_error_string;
128typedef int Boolean;
129typedef void *OBJ;
130
131typedef struct ClientAddressStruct {
132 struct sockaddr_in cl_addr;
133 int clilen;
134 int sockfd;
135} *ClientAddr;
136
137typedef unsigned long long osc_time_t;
138
139Boolean ShowBytes = FALSE;
140Boolean Silent = FALSE;
141
142/* Declarations */
143#ifndef WIN32
144static int unixinitudp(int chan);
145#endif
146
147static int initudp(int chan);
148static void closeudp(int sockfd);
149Boolean ClientReply(int packetsize, void *packet, int socketfd,
150 void *clientaddresspointer, int clientaddressbufferlength);
151void sgi_CleanExit(void);
152Boolean sgi_HaveToQuit(void);
153int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy);
154static void catch_sigint();
155static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ;
156char *DataAfterAlignedString(char *string, char *boundary) ;
157Boolean IsNiceString(char *string, char *boundary) ;
158void complain(char *s, ...);
159
160#define MAXMESG 32768
161static char mbuf[MAXMESG];
162
163/* ----------------------------- dumpOSC ------------------------- */
164
165#define MAXOUTAT 50
166
167static t_class *dumpOSC_class;
168
169typedef struct _dumpOSC
170{
171 t_object x_obj;
172 t_outlet *x_msgout;
173 t_outlet *x_connectout;
174 t_atom x_outat[MAXOUTAT];
175 int x_outatc;
176 t_binbuf *x_b;
177 int x_connectsocket;
178 int x_nconnections;
179 int x_udp;
180 struct sockaddr_in x_server;
181 int x_clilen;
182} t_dumpOSC;
183
184void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr);
185Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd);
186static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr);
187static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n);
188static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma);
189
190static void dumpOSC_read(t_dumpOSC *x, int sockfd) {
191 int clilen = x->x_clilen;
192 int n;
193 struct ClientAddressStruct ras;
194 ClientAddr ra = &ras;
195
196 //catchupflag= FALSE;
197
198/* if (ShowBytes) { */
199/* int i; */
200/* printf("%d byte message:\n", n); */
201/* for (i = 0; i < n; ++i) { */
202/* printf(" %x (%c)\t", m[i], m[i]); */
203/* if (i%4 == 3) printf("\n"); */
204/* } */
205/* printf("\n"); */
206/* } */
207
208 // return catchupflag;
209 //struct sockaddr_in x->x_server;
210 //while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0)
211 // while((
212
213 #ifdef WIN32
214 if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (SOCKADDR*)&x->x_server, &clilen)) >0)
215 #else
216 if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (struct sockaddr *)&x->x_server, &clilen)) >0)
217 #endif
218 {
219 //int r;
220 ras.cl_addr = *((struct sockaddr_in *) &x->x_server);
221 ras.clilen = x->x_clilen;
222 ras.sockfd = x->x_connectsocket;
223
224 #ifdef DEBUG
225 printf("dumpOSC_read: received UDP packet of length %d\n", n);
226 #endif
227
228 if(!dumpOSC_SendReply(mbuf, n, &x->x_server, clilen, sockfd))
229 {
230 dumpOSC_ParsePacket(x, mbuf, n, ra);
231 }
232 //r = Synthmessage(mbuf, n, &x->x_server, clilen, sockfd);
233 //post ("%d", r);
234 //outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
235 // emsg-msg-1, at + msg + 1);
236 // outlet_list(x->x_msgout, 0, n, mbuf);
237 //if( sgi_HaveToQuit()) goto out;
238 //if(r>0) goto back;
239 //clilen = maxclilen;
240 }
241}
242
243static void *dumpOSC_new(t_symbol *compatflag,
244 t_floatarg fportno) {
245 t_dumpOSC *x;
246 struct sockaddr_in server;
247 int clilen=sizeof(server);
248 int sockfd;
249 int portno=fportno;
250 int udp = 1;
251
252 //x->x_b = binbuf_new();
253 //x->x_outat = binbuf_getvec(x->x_b);
254
255 //{{raf}} pointer not valid yet...moving this down
256 //x->x_outatc = 0; {{raf}}
257
258 /* create a socket */
259 if ((sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1)
260 {
261 sys_sockerror("socket");
262 return (0);
263 }
264
265 server.sin_family = AF_INET;
266 server.sin_addr.s_addr = INADDR_ANY;
267 /* assign server port number */
268 server.sin_port = htons((u_short)portno);
269 /* name the socket */
270 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
271 {
272 sys_sockerror("bind");
273 sys_closesocket(sockfd);
274 return (0);
275 }
276
277 x = (t_dumpOSC *)pd_new(dumpOSC_class);
278 x->x_outatc = 0; // {{raf}} now pointer is valid (less invalid)
279
280 x->x_msgout = outlet_new(&x->x_obj, &s_anything);
281
282 // if (udp) /* datagram protocol */
283 {
284
285 sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_read, x);
286 x->x_connectout = 0;
287 }
288 // else /* streaming protocol */
289 /* { */
290 /* if (listen(sockfd, 5) < 0) */
291 /* { */
292 /* sys_sockerror("listen"); */
293 /* sys_closesocket(sockfd); */
294 /* sockfd = -1; */
295 /* } */
296 /* else */
297 /* { */
298 /* sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_connectpoll, x); */
299 /* x->x_connectout = outlet_new(&x->x_obj, &s_float); */
300 /* } */
301 /* } */
302
303 x->x_connectsocket = sockfd;
304 x->x_server = server;
305 x->x_clilen = clilen;
306 x->x_nconnections = 0;
307 x->x_udp = udp;
308
309 return (x);
310}
311
312static void dumpOSC_free(t_dumpOSC *x)
313{
314 /* LATER make me clean up open connections */
315 if (x->x_connectsocket >= 0)
316 {
317 sys_rmpollfn(x->x_connectsocket);
318 sys_closesocket(x->x_connectsocket);
319 }
320}
321
322#ifdef WIN32
323OSC_API void dumpOSC_setup(void)
324#else
325void dumpOSC_setup(void)
326#endif
327{
328 dumpOSC_class = class_new(gensym("dumpOSC"),
329 (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free,
330 sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT,
331 A_DEFSYM, 0);
332 class_sethelpsymbol(dumpOSC_class, gensym("dumpOSC-help.pd"));
333}
334
335
336#ifndef WIN32
337 #define UNIXDG_PATH "/tmp/htm"
338 #define UNIXDG_TMP "/tmp/htm.XXXXXX"
339 static int unixinitudp(int chan)
340 {
341 struct sockaddr_un serv_addr;
342 int sockfd;
343
344 if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
345 return sockfd;
346
347 bzero((char *)&serv_addr, sizeof(serv_addr));
348 serv_addr.sun_family = AF_UNIX;
349 strcpy(serv_addr.sun_path, UNIXDG_PATH);
350 sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan);
351 unlink(serv_addr.sun_path);
352 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0)
353 {
354 perror("unable to bind\n");
355 return -1;
356 }
357
358 fcntl(sockfd, F_SETFL, FNDELAY);
359 return sockfd;
360 }
361#endif // #ifndef WIN32
362
363
364
365static int initudp(int chan)
366{
367
368#ifdef WIN32
369 struct sockaddr_in serv_addr;
370 unsigned int sockfd;
371 ULONG nonBlocking = (ULONG) TRUE;
372
373 if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET ) {
374 ZeroMemory((char *)&serv_addr, sizeof(serv_addr));
375 serv_addr.sin_family = AF_INET;
376 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
377 serv_addr.sin_port = htons(chan);
378 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) {
379 // set for non-blocking mode
380 if(ioctlsocket(sockfd, FIONBIO, &nonBlocking) == SOCKET_ERROR) {
381 perror("unable to set non-blocking\n");
382 return -1;
383 }
384 }
385 else { perror("unable to bind\n"); return -1; }
386 }
387 return (sockfd == INVALID_SOCKET ? -1 : (int)sockfd);
388#else
389 struct sockaddr_in serv_addr;
390 int sockfd;
391
392 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
393 return sockfd;
394
395 bzero((char *)&serv_addr, sizeof(serv_addr));
396 serv_addr.sin_family = AF_INET;
397 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
398 serv_addr.sin_port = htons(chan);
399
400 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
401 {
402 perror("unable to bind\n");
403 return -1;
404 }
405
406 fcntl(sockfd, F_SETFL, FNDELAY);
407 return sockfd;
408#endif
409}
410
411
412
413
414
415
416
417
418static void closeudp(int sockfd) {
419 #ifdef WIN32
420 closesocket(sockfd);
421 #else
422 close(sockfd);
423 #endif
424}
425
426static Boolean catchupflag=FALSE;
427Boolean ClientReply(int packetsize, void *packet, int socketfd,
428 void *clientaddresspointer, int clientaddressbufferlength)
429{
430 if(!clientaddresspointer) return FALSE;
431 catchupflag= TRUE;
432 return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength);
433}
434
435static Boolean exitflag= FALSE;
436void sgi_CleanExit(void) {
437 exitflag = TRUE;
438}
439
440Boolean sgi_HaveToQuit(void) {
441 return exitflag;
442}
443
444
445/* file descriptor poll table */
446static int npolldevs =0;
447typedef struct polldev
448{
449 int fd;
450 void (*callbackfunction)(int , void *);
451 void *dummy;
452} polldev;
453#define TABMAX 8
454static polldev polldevs[TABMAX];
455
456
457/* Register a device (referred to by a file descriptor that the caller
458 should have already successfully obtained from a system call) to be
459 polled as real-time constraints allowed.
460
461 When a select(2) call indicates activity on the file descriptor, the
462 callback function is called with the file descripter as first
463 argument and the given dummy argument (presumably a pointer to the
464 instance variables associated with the device).
465*/
466int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy)
467{
468 if(npolldevs<TABMAX)
469 {
470 polldevs[npolldevs].fd = fd;
471 polldevs[npolldevs].callbackfunction = callbackfunction;
472 polldevs[npolldevs].dummy = dummy;
473 }
474 else return -1;
475 return npolldevs++;
476}
477
478static int caught_sigint;
479
480static void catch_sigint() {
481 caught_sigint = 1;
482}
483static int sockfd, usockfd;
484
485
486void PrintClientAddr(ClientAddr CA) {
487 unsigned long addr = CA->cl_addr.sin_addr.s_addr;
488 printf("Client address %p:\n", CA);
489 printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd);
490 printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family,
491 CA->cl_addr.sin_port);
492 printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr));
493
494 printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n",
495 CA->cl_addr.sin_zero[0],
496 CA->cl_addr.sin_zero[1],
497 CA->cl_addr.sin_zero[2],
498 CA->cl_addr.sin_zero[3],
499 CA->cl_addr.sin_zero[4],
500 CA->cl_addr.sin_zero[5],
501 CA->cl_addr.sin_zero[6],
502 CA->cl_addr.sin_zero[7]);
503
504 printf("\n");
505}
506
507//*******************
508
509void WriteTime(char* dst, osc_time_t osctime)
510{
511 *(int32_t*)dst = htonl((int32_t)(osctime >> 32));
512 *(int32_t*)(dst+4) = htonl((int32_t)osctime);
513}
514
515void WriteMode(char* dst)
516{
517 *(int32_t*)dst = htonl(0);
518}
519
520osc_time_t ReadTime(const char* src)
521{
522 osc_time_t osctime = ntohl(*(int32_t*)src);
523 return (osctime << 32) + ntohl(*(int32_t*)(src+4));
524}
525
526double TimeToSeconds(osc_time_t osctime)
527{
528 return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */;
529}
530
531int timeRound(double x)
532{
533 return x >= 0.0 ? x+0.5 : x-0.5;
534}
535/*
536void WriteLogicalTime(char* dst)
537{
538 static double startTime = -1.0;
539 double sTime;
540
541 // Initialisierung der Startzeit.
542 // Knnte effizienter (ohne 'if') auch irgendwo vorher passieren.
543 // Knnte wahrscheinlich auch 0.0 sein.
544 if (startTime < 0.0) {
545 startTime = clock_getlogicaltime();
546 }
547
548 sTime = clock_gettimesince(startTime) * 0.001;
549 *(int32_t*)dst = hton'K l((int32_t)sTime);
550 *(int32_t*)(dst+4) = htonl((int32_t)(4294967296.0 * sTime));
551}
552*/
553
554void WriteLogicalTime(char* dst)
555{
556 double sTime = clock_gettimesince(19230720) / 1000.0;
557 double tau = sTime - timeRound(sTime);
558
559 //fprintf(stderr, "sSec = %f tau = %f\n", sTime, tau);
560
561 *(int32_t*)dst = htonl((int32_t)(sTime));
562 *(int32_t*)(dst+4) = htonl((int32_t)(4294967296 * tau));
563}
564
565Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd)
566{
567 if((n == 24) && (strcmp(buf, "#time") == 0))
568 {
569 osc_time_t t0, t1, t2;
570 double dt0, dt1, dt2;
571
572 WriteMode(buf+6);
573
574 t0 = ReadTime(buf+8);
575
576 WriteLogicalTime(buf+16);
577 t1 = ReadTime(buf+16); // reverse
578 dt0 = TimeToSeconds(t0); // client time
579 dt1 = TimeToSeconds(t1); // server time
580
581 // fprintf(stderr, "%f\t%f\t%f\n", dt0, dt1, dt0 - dt1);
582
583 sendto(fd, buf, n, 0, (struct sockaddr *)clientDesc, clientDescLenght);
584 return TRUE;
585 }
586 else
587 {
588 return FALSE;
589 }
590}
591
592//**********************
593
594void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr) {
595 // t_dumpOSC *x;
596 int size, messageLen, i;
597 char *messageName;
598 char *args;
599
600 //#ifdef PRINTADDRS
601 #ifdef DEBUG
602 //PrintClientAddr(returnAddr);
603 #endif
604
605
606 if ((n%4) != 0) {
607 complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", n);
608 return;
609 }
610
611 if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) {
612 /* This is a bundle message. */
613 #ifdef DEBUG
614 printf("dumpOSC_ParsePacket: bundle msg: bundles not yet supported\n");
615 #endif
616
617 if (n < 16) {
618 complain("Bundle message too small (%d bytes) for time tag", n);
619 return;
620 }
621
622 /* Print the time tag */
623 #ifdef DEBUG
624 printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), ntohl(*((unsigned long *)(buf+12))));
625 #endif
626
627 /* Note: if we wanted to actually use the time tag as a little-endian
628 64-bit int, we'd have to word-swap the two 32-bit halves of it */
629
630 i = 16; /* Skip "#group\0" and time tag */
631
632 while(i<n) {
633 size = ntohl(*((int *) (buf + i)));
634 if ((size % 4) != 0) {
635 complain("Bad size count %d in bundle (not a multiple of 4)", size);
636 return;
637 }
638 if ((size + i + 4) > n) {
639 complain("Bad size count %d in bundle (only %d bytes left in entire bundle)",
640 size, n-i-4);
641 return;
642 }
643
644 /* Recursively handle element of bundle */
645 dumpOSC_ParsePacket(x, buf+i+4, size, returnAddr);
646 i += 4 + size;
647 }
648
649 if (i != n) {
650 complain("This can't happen");
651 }
652 #ifdef DEBUG
653 printf("]\n");
654 #endif
655
656 }
657 else if ((n == 24) && (strcmp(buf, "#time") == 0))
658 {
659 complain("Time message: %s\n :).\n", htm_error_string);
660 return;
661
662 }
663 else
664 {
665 /* This is not a bundle message */
666
667 messageName = buf;
668 args = DataAfterAlignedString(messageName, buf+n);
669 if (args == 0) {
670 complain("Bad message name string: %s\nDropping entire message.\n",
671 htm_error_string);
672 return;
673 }
674 messageLen = args-messageName;
675 dumpOSC_Smessage(x, messageName, (void *)args, n-messageLen, returnAddr);
676 }
677}
678
679#define SMALLEST_POSITIVE_FLOAT 0.000001f
680
681static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr) {
682 char *chars = v;
683 t_atom at;
684 //t_atom myargv[50];
685
686 int myargc = x->x_outatc;
687 t_atom* mya = x->x_outat;
688 int myi;
689
690#ifdef DEBUG
691 printf("%s ", address);
692#endif
693
694 // ztoln+cvt from envgen.c, ggee-0.18 ..
695 // outlet_anything's 'symbol' gets set to address
696 // so we dont need to append address to the atomlist
697 /*
698 SETSYMBOL(mya,gensym(address));myargc++;
699 x->x_outatc = myargc;
700 */
701
702 if (n != 0) {
703 if (chars[0] == ',') {
704 if (chars[1] != ',') {
705 /* This message begins with a type-tag string */
706 dumpOSC_PrintTypeTaggedArgs(x, v, n);
707 } else {
708 /* Double comma means an escaped real comma, not a type string */
709 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 1);
710 }
711 } else {
712 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0);
713 }
714 }
715
716 outlet_anything(x->x_msgout,gensym(address),x->x_outatc,(t_atom*)&x->x_outat);
717 x->x_outatc = 0;
718#ifdef DEBUG
719 printf("\n");
720#endif
721 fflush(stdout); /* Added for Sami 5/21/98 */
722}
723
724static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n) {
725 char *typeTags, *thisType;
726 char *p;
727
728 int myargc = x->x_outatc;
729 t_atom* mya = x->x_outat;
730 int myi;
731
732 typeTags = v;
733
734 if (!IsNiceString(typeTags, typeTags+n)) {
735 /* No null-termination, so maybe it wasn't a type tag
736 string after all */
737 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0);
738 return;
739 }
740
741 p = DataAfterAlignedString(typeTags, typeTags+n);
742
743
744 for (thisType = typeTags + 1; *thisType != 0; ++thisType) {
745 switch (*thisType) {
746 case 'i': case 'r': case 'm': case 'c':
747#ifdef DEBUG
748 //post("integer: %d", ntohl(*((int *) p)));
749#endif
750 /* Martin Peach fix for negative floats:
751 * was: SETFLOAT(mya+myargc,ntohl(*((int *) p)));
752 * now is:
753 */
754 SETFLOAT(mya+myargc,(signed)ntohl(*((int *) p)));
755 myargc++;
756
757 p += 4;
758 break;
759
760 case 'f': {
761 int i = ntohl(*((int *) p));
762 float *floatp = ((float *) (&i));
763#ifdef DEBUG
764 post("float: %f", *floatp);
765#endif
766 SETFLOAT(mya+myargc,*floatp);
767 myargc++;
768
769 p += 4;
770 }
771 break;
772
773 case 'h': case 't':
774#ifdef DEBUG
775 printf("[A 64-bit int] ");
776#endif
777 post("[A 64-bit int] not implemented");
778
779 p += 8;
780 break;
781
782 case 'd':
783#ifdef DEBUG
784 printf("[A 64-bit float] ");
785#endif
786 post("[A 64-bit float] not implemented");
787
788 p += 8;
789 break;
790
791 case 's': case 'S':
792 if (!IsNiceString(p, typeTags+n)) {
793 post("Type tag said this arg is a string but it's not!\n");
794 return;
795 } else {
796#ifdef DEBUG
797 post("string: \"%s\"", p);
798#endif
799 SETSYMBOL(mya+myargc,gensym(p));
800 myargc++;
801 //outlet_list(x->x_msgout, 0,sizeof(p), p);
802 //outlet_anything(x->x_msgout, 0, sizeof(p), p);
803 p = DataAfterAlignedString(p, typeTags+n);
804 // append to output vector ..
805 }
806 break;
807
808 case 'T':
809#ifdef DEBUG
810 printf("[True] ");
811#endif
812 SETFLOAT(mya+myargc,1.);
813 myargc++;
814 break;
815 case 'F':
816#ifdef DEBUG
817 printf("[False] ");
818#endif
819 SETFLOAT(mya+myargc,0.);
820 myargc++;
821 break;
822 case 'N':
823#ifdef DEBUG
824 printf("[Nil]");
825#endif
826 post("sendOSC: [Nil] not implemented");
827 break;
828 case 'I':
829#ifdef DEBUG
830 printf("[Infinitum]");
831#endif
832 post("sendOSC: [Infinitum] not implemented");
833 break;
834
835 default:
836 post("sendOSC: [Unrecognized type tag %c]", *thisType);
837 // return;
838 }
839 }
840 x->x_outatc = myargc;
841}
842
843static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma) {
844 int i, thisi;
845 float thisf;
846 int *ints;
847 char *chars;
848 char *string, *nextString;
849
850 int myargc= x->x_outatc;
851 t_atom* mya = x->x_outat;
852 int myi;
853
854
855 /* Go through the arguments 32 bits at a time */
856 ints = v;
857 chars = v;
858
859 for (i = 0; i<n/4; ) {
860 string = &chars[i*4];
861 thisi = ntohl(ints[i]);
862 /* Reinterpret the (potentially byte-reversed) thisi as a float */
863 thisf = *(((float *) (&thisi)));
864
865 if (thisi >= -1000 && thisi <= 1000000) {
866#ifdef DEBUG
867 printf("%d ", thisi);
868#endif
869 // append to output vector ..
870 SETFLOAT(mya+myargc,(t_float) (thisi));
871 myargc++;
872 // outlet_float(x->x_msgout, thisi);
873 i++;
874 } else if (thisf >= -1000.f && thisf <= 1000000.f &&
875 (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) {
876#ifdef DEBUG
877 printf("%f ", thisf);
878#endif
879 // append to output vector ..
880 SETFLOAT(mya+myargc,thisf);
881 myargc++;
882 //outlet_float(x->x_msgout, thisf);
883 i++;
884 } else if (IsNiceString(string, chars+n)) {
885 nextString = DataAfterAlignedString(string, chars+n);
886#ifdef DEBUG
887 printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string);
888#endif
889 // append to output vector ..
890 SETSYMBOL(mya+myargc,gensym(string));
891 myargc++;
892 //outlet_symbol(x->x_msgout, gensym((i == 0 && skipComma) ? string +1 : string));
893 i += (nextString-string) / 4;
894 } else {
895 // unhandled .. ;)
896#ifdef DEBUG
897 printf("0x%x xx", ints[i]);
898#endif
899 i++;
900 }
901 x->x_outatc = myargc;
902 }
903}
904
905
906#define STRING_ALIGN_PAD 4
907
908char *DataAfterAlignedString(char *string, char *boundary)
909{
910 /* The argument is a block of data beginning with a string. The
911 string has (presumably) been padded with extra null characters
912 so that the overall length is a multiple of STRING_ALIGN_PAD
913 bytes. Return a pointer to the next byte after the null
914 byte(s). The boundary argument points to the character after
915 the last valid character in the buffer---if the string hasn't
916 ended by there, something's wrong.
917
918 If the data looks wrong, return 0, and set htm_error_string */
919
920 int i;
921
922 if ((boundary - string) %4 != 0) {
923 fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n");
924 return 0;
925 }
926
927 for (i = 0; string[i] != '\0'; i++) {
928 if (string + i >= boundary) {
929 htm_error_string = "DataAfterAlignedString: Unreasonably long string";
930 return 0;
931 }
932 }
933
934 /* Now string[i] is the first null character */
935 i++;
936
937 for (; (i % STRING_ALIGN_PAD) != 0; i++) {
938 if (string + i >= boundary) {
939 htm_error_string = "DataAfterAlignedString: Unreasonably long string";
940 return 0;
941 }
942 if (string[i] != '\0') {
943 htm_error_string = "DataAfterAlignedString: Incorrectly padded string.";
944 return 0;
945 }
946 }
947
948 return string+i;
949}
950
951Boolean IsNiceString(char *string, char *boundary)
952{
953 /* Arguments same as DataAfterAlignedString(). Is the given "string"
954 really a string? I.e., is it a sequence of isprint() characters
955 terminated with 1-4 null characters to align on a 4-byte boundary? */
956
957 int i;
958
959 if ((boundary - string) %4 != 0) {
960 fprintf(stderr, "Internal error: IsNiceString: bad boundary\n");
961 return 0;
962 }
963
964 for (i = 0; string[i] != '\0'; i++) {
965 if (!isprint(string[i])) return FALSE;
966 if (string + i >= boundary) return FALSE;
967 }
968
969 /* If we made it this far, it's a null-terminated sequence of printing characters
970 in the given boundary. Now we just make sure it's null padded... */
971
972 /* Now string[i] is the first null character */
973 i++;
974 for (; (i % STRING_ALIGN_PAD) != 0; i++) {
975 if (string[i] != '\0') return FALSE;
976 }
977
978 return TRUE;
979}
980
981
982
983
984
985
986
987
988
989#include <stdarg.h>
990void complain(char *s, ...) {
991 va_list ap;
992 va_start(ap, s);
993 fprintf(stderr, "*** ERROR: ");
994 vfprintf(stderr, s, ap);
995 fprintf(stderr, "\n");
996 va_end(ap);
997}
998
999#endif /* __sgi or LINUX or WIN32 */
1000
diff --git a/apps/plugins/pdbox/PDa/extra/fatom.h b/apps/plugins/pdbox/PDa/extra/fatom.h
deleted file mode 100644
index a7a153fad3..0000000000
--- a/apps/plugins/pdbox/PDa/extra/fatom.h
+++ /dev/null
@@ -1,486 +0,0 @@
1/* ------------------------ fatom ----------------------------- */
2
3#define x_val a_pos.a_w.w_float
4#define DEBUG(x)
5
6#include <string.h>
7#include <stdio.h>
8
9typedef struct _fatom
10{
11 t_object x_obj;
12 t_atom a_pos; /* the value of the fatom */
13
14 t_symbol* x_send;
15 t_symbol* x_receive;
16 t_glist * x_glist; /* value of the current canvas, intialized in _new */
17 int x_rect_width; /* width of the widget */
18 int x_rect_height; /* height of the widget */
19 t_symbol* x_sym; /* symbol for receiving callbacks from GUI */
20 t_symbol* x_type; /* type of fatom (vslider, hslider, checkbutton) */
21
22 t_symbol* x_text; /* associated widget text */
23 int x_max; /* maximum value of a_pos (x_val) */
24 int x_min; /* minimum value of a_pos (x_val) */
25 int x_width; /* width of widget (e.g x_rect_height + 15 for hslider, x_rect_width + 15 for slider) */
26 t_symbol* x_color;
27 t_symbol* x_bgcolor;
28} t_fatom;
29
30/* widget helper functions */
31
32
33
34
35static void draw_inlets(t_fatom *x, t_glist *glist, int firsttime, int nin, int nout)
36{
37 int n = nin;
38 int nplus, i;
39 nplus = (n == 1 ? 1 : n-1);
40 DEBUG(post("draw inlet");)
41 for (i = 0; i < n; i++)
42 {
43 int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH) * i / nplus;
44 if (firsttime)
45 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
46 glist_getcanvas(glist),
47 onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 1,
48 onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height,
49 x, i);
50 else
51 sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
52 glist_getcanvas(glist), x, i,
53 onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 1,
54 onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height);
55 }
56 n = nout;
57 nplus = (n == 1 ? 1 : n-1);
58 for (i = 0; i < n; i++)
59 {
60 int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH) * i / nplus;
61 if (firsttime)
62 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
63 glist_getcanvas(glist),
64 onset, text_ypix(&x->x_obj, glist),
65 onset + IOWIDTH, text_ypix(&x->x_obj, glist) + 1,
66 x, i);
67 else
68 sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
69 glist_getcanvas(glist), x, i,
70 onset, text_ypix(&x->x_obj, glist),
71 onset + IOWIDTH, text_ypix(&x->x_obj, glist) + 1);
72
73 }
74 DEBUG(post("draw inlet end");)
75}
76
77
78static void draw_handle(t_fatom *x, t_glist *glist, int firsttime) {
79 int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH+2);
80
81 if (firsttime)
82 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xhandle\n",
83 glist_getcanvas(glist),
84 onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 12,
85 onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height-4,
86 x);
87 else
88 sys_vgui(".x%x.c coords %xhandle %d %d %d %d\n",
89 glist_getcanvas(glist), x,
90 onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 12,
91 onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height-4);
92}
93
94static void create_widget(t_fatom *x, t_glist *glist)
95{
96 t_canvas *canvas=glist_getcanvas(glist);
97
98 if (!strcmp(x->x_type->s_name,"vslider")) {
99 x->x_rect_width = x->x_width+15;
100 x->x_rect_height = x->x_max-x->x_min+26;
101
102 sys_vgui("scale .x%x.c.s%x \
103 -sliderlength 10 \
104 -showvalue 0 \
105 -length %d \
106 -resolution 0.01 \
107 -repeatinterval 20 \
108 -from %d -to %d \
109 -width %d \
110 -bg %s \
111 -activebackground %s \
112 -troughcolor %s \
113 -command fatom_cb%x\n",canvas,x,
114 x->x_max-x->x_min+14,
115 x->x_max,
116 x->x_min,
117 x->x_width,
118 x->x_color->s_name,
119 x->x_color->s_name,
120 x->x_bgcolor->s_name,
121 x);
122 } else if (!strcmp(x->x_type->s_name,"hslider")) {
123 x->x_rect_width = x->x_max-x->x_min + 24;
124 x->x_rect_height = x->x_width + 15;
125 sys_vgui("scale .x%x.c.s%x \
126 -sliderlength 10 \
127 -showvalue 0 \
128 -length %d \
129 -resolution 0.01 \
130 -orient horizontal \
131 -repeatinterval 20 \
132 -from %d -to %d \
133 -width %d \
134 -bg %s \
135 -activebackground %s \
136 -troughcolor %s \
137 -command fatom_cb%x\n",canvas,x,
138 x->x_max-x->x_min+14,
139 x->x_min,
140 x->x_max,
141 x->x_width,
142 x->x_color->s_name,
143 x->x_color->s_name,
144 x->x_bgcolor->s_name,
145 x);
146 } else if (!strcmp(x->x_type->s_name,"checkbutton")) {
147 x->x_rect_width = 32;
148 x->x_rect_height = 28;
149 sys_vgui("checkbutton .x%x.c.s%x \
150 -command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -text \"%s\" \
151 -bg %s \
152 -activebackground %s \
153 \n",canvas,x,x,x,x,
154 x->x_text->s_name,
155 x->x_color->s_name,
156 x->x_bgcolor->s_name);
157 } else if (!strcmp(x->x_type->s_name,"hradio")) {
158 int i;
159 x->x_rect_width = 8*20;
160 x->x_rect_height = 25;
161 for (i=0;i<8;i++) {
162 sys_vgui("radiobutton .x%x.c.s%x%d \
163 -command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -value %d\n",canvas,x,i,x,x,x,i);
164 }
165 /* TODO pack them */
166 } else if (!strcmp(x->x_type->s_name,"vradio")) {
167 int i;
168 x->x_rect_width = 30;
169 x->x_rect_height = 20*8+5;
170 for (i=0;i<8;i++) {
171 sys_vgui("radiobutton .x%x.c.s%x%d \
172 -command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -value %d\n",canvas,x,i,x,x,x,i);
173 }
174 /* TODO pack them */
175 } else {
176 x->x_rect_width = 32;
177 x->x_rect_height = 140;
178 sys_vgui("scale .x%x.c.s%x \
179 -sliderlength 10 \
180 -showvalue 0 \
181 -length 131 \
182 -from 127 -to 0 \
183 -command fatom_cb%x\n",canvas,x,x);
184 }
185
186 /* set the start value */
187 if (!strcmp(x->x_type->s_name,"checkbutton")) {
188 if (x->x_val)
189 sys_vgui(".x%x.c.s%x select\n",canvas,x,x->x_val);
190 else
191 sys_vgui(".x%x.c.s%x deselect\n",canvas,x,x->x_val);
192 } else
193 sys_vgui(".x%x.c.s%x set %f\n",canvas,x,x->x_val);
194
195}
196
197
198
199
200
201static void fatom_drawme(t_fatom *x, t_glist *glist, int firsttime)
202{
203 t_canvas *canvas=glist_getcanvas(glist);// x->x_glist;//glist_getcanvas(glist);
204 DEBUG(post("drawme %d",firsttime);)
205 if (firsttime) {
206 DEBUG(post("glist %x canvas %x",x->x_glist,canvas));
207 create_widget(x,glist);
208 x->x_glist = canvas;
209 sys_vgui(".x%x.c create window %d %d -anchor nw -window .x%x.c.s%x -tags %xS\n",
210 canvas,text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist)+2,x->x_glist,x,x);
211
212 }
213 else {
214 sys_vgui(".x%x.c coords %xS \
215%d %d\n",
216 canvas, x,
217 text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist)+2);
218 }
219 draw_inlets(x, glist, firsttime, 1,1);
220 // draw_handle(x, glist, firsttime);
221
222}
223
224
225static void fatom_erase(t_fatom* x,t_glist* glist)
226{
227 int n;
228
229 DEBUG(post("erase");)
230 sys_vgui("destroy .x%x.c.s%x\n",glist_getcanvas(glist),x);
231
232 sys_vgui(".x%x.c delete %xS\n",glist_getcanvas(glist), x);
233
234 /* inlets and outlets */
235
236 sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,0);
237 sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,0);
238 sys_vgui(".x%x.c delete %xhandle\n",glist_getcanvas(glist),x,0);
239}
240
241
242
243/* ------------------------ fatom widgetbehaviour----------------------------- */
244
245
246static void fatom_getrect(t_gobj *z, t_glist *owner,
247 int *xp1, int *yp1, int *xp2, int *yp2)
248{
249 int width, height;
250 t_fatom* s = (t_fatom*)z;
251
252 width = s->x_rect_width;
253 height = s->x_rect_height;
254 *xp1 = text_xpix(&s->x_obj, owner);
255 *yp1 = text_ypix(&s->x_obj, owner);
256 *xp2 = text_xpix(&s->x_obj, owner) + width;
257 *yp2 = text_ypix(&s->x_obj, owner) + height;
258}
259
260static void fatom_displace(t_gobj *z, t_glist *glist,
261 int dx, int dy)
262{
263 t_fatom *x = (t_fatom *)z;
264 DEBUG(post("displace");)
265 x->x_obj.te_xpix += dx;
266 x->x_obj.te_ypix += dy;
267 if (glist_isvisible(glist))
268 {
269 sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
270 glist_getcanvas(glist), x,
271 text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
272 text_xpix(&x->x_obj, glist) + x->x_rect_width, text_ypix(&x->x_obj, glist) + x->x_rect_height);
273
274 fatom_drawme(x, glist, 0);
275 canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
276 }
277 DEBUG(post("displace end");)
278}
279
280static void fatom_select(t_gobj *z, t_glist *glist, int state)
281{
282 t_fatom *x = (t_fatom *)z;
283 if (state) {
284 sys_vgui(".x%x.c create rectangle \
285%d %d %d %d -tags %xSEL -outline blue\n",
286 glist_getcanvas(glist),
287 text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
288 text_xpix(&x->x_obj, glist) + x->x_rect_width, text_ypix(&x->x_obj, glist) + x->x_rect_height,
289 x);
290 }
291 else {
292 sys_vgui(".x%x.c delete %xSEL\n",
293 glist_getcanvas(glist), x);
294 }
295
296
297
298}
299
300
301static void fatom_activate(t_gobj *z, t_glist *glist, int state)
302{
303/* t_text *x = (t_text *)z;
304 t_rtext *y = glist_findrtext(glist, x);
305 if (z->g_pd != gatom_class) rtext_activate(y, state);*/
306}
307
308static void fatom_delete(t_gobj *z, t_glist *glist)
309{
310 t_text *x = (t_text *)z;
311 canvas_deletelinesfor(glist_getcanvas(glist), x);
312}
313
314
315static void fatom_vis(t_gobj *z, t_glist *glist, int vis)
316{
317 t_fatom* s = (t_fatom*)z;
318 t_rtext *y;
319 DEBUG(post("vis: %d",vis);)
320 if (vis) {
321#ifdef PD_MINOR_VERSION
322 y = (t_rtext *) rtext_new(glist, (t_text *)z);
323#else
324 y = (t_rtext *) rtext_new(glist, (t_text *)z,0,0);
325#endif
326 fatom_drawme(s, glist, 1);
327 }
328 else {
329 y = glist_findrtext(glist, (t_text *)z);
330 fatom_erase(s,glist);
331 rtext_free(y);
332 }
333}
334
335static void fatom_save(t_gobj *z, t_binbuf *b);
336
337t_widgetbehavior fatom_widgetbehavior;
338
339
340
341
342static void fatom_size(t_fatom* x,t_floatarg w,t_floatarg h) {
343 x->x_rect_width = w;
344 x->x_rect_height = h;
345}
346
347static void fatom_color(t_fatom* x,t_symbol* col)
348{
349
350}
351
352
353static void fatom_f(t_fatom* x,t_floatarg f)
354{
355 x->x_val = f;
356 if (x->x_send == &s_)
357 outlet_float(x->x_obj.ob_outlet,f);
358 else
359 if (x->x_send->s_thing) pd_float(x->x_send->s_thing,f);
360}
361
362
363static void fatom_float(t_fatom* x,t_floatarg f)
364{
365 if (glist_isvisible(x->x_glist)) {
366 if (!strcmp(x->x_type->s_name,"checkbutton")) {
367 if (x->x_val)
368 sys_vgui(".x%x.c.s%x select\n",x->x_glist,x,f);
369 else
370 sys_vgui(".x%x.c.s%x deselect\n",x->x_glist,x,f);
371 } else
372 sys_vgui(".x%x.c.s%x set %f\n",x->x_glist,x,f);
373 }
374 fatom_f(x,f);
375}
376
377
378static void fatom_bang(t_fatom* x,t_floatarg f)
379{
380 outlet_float(x->x_obj.ob_outlet,x->x_val);
381}
382
383
384static void fatom_properties(t_gobj *z, t_glist *owner)
385{
386 post("N/I");
387}
388
389
390static void fatom_save(t_gobj *z, t_binbuf *b)
391{
392
393 t_fatom *x = (t_fatom *)z;
394
395 binbuf_addv(b, "ssiiss", gensym("#X"),gensym("obj"),
396 x->x_obj.te_xpix, x->x_obj.te_ypix ,
397 gensym("fatom"),x->x_type);
398 binbuf_addv(b, ";");
399}
400
401
402static void *fatom_new(t_fatom* x,int argc,t_atom* argv)
403{
404 char buf[256];
405 int n = 0;
406 x->x_glist = canvas_getcurrent();
407
408 x->x_text = gensym("");
409 x->x_max = 127;
410 x->x_min = 0;
411 x->x_width = 15;
412 x->x_color = gensym("grey");
413 x->x_bgcolor = gensym("grey");
414 x->x_send = &s_;
415
416 while (argc) {
417 if (argv->a_type == A_FLOAT) {
418 if (n==0) x->x_max = atom_getfloat(argv);
419 if (n==1) x->x_min = atom_getfloat(argv);
420 if (n==2) x->x_width = atom_getfloat(argv);
421 }
422
423 if (argv->a_type == A_SYMBOL) {
424 post("%d: symbol value %s",n,atom_getsymbol(argv)->s_name);
425 if (n==3) x->x_send = atom_getsymbol(argv);
426 if (n==4) x->x_color = atom_getsymbol(argv);
427 if (n==5) x->x_bgcolor = atom_getsymbol(argv);
428 }
429 argv++;
430 argc--;
431 n++;
432 }
433
434 /* bind to a symbol for slider callback (later make this based on the
435 filepath ??) */
436
437 sprintf(buf,"fatom%x",(t_int)x);
438 x->x_sym = gensym(buf);
439 pd_bind(&x->x_obj.ob_pd, x->x_sym);
440
441 /* pipe startup code to tk */
442
443 sys_vgui("proc fatom_cb%x {v} {\n pd [concat fatom%x f $v \\;]\n }\n",x,x);
444
445 outlet_new(&x->x_obj, &s_float);
446 return (x);
447}
448
449static void fatom_setup_common(t_class* class)
450{
451
452 fatom_widgetbehavior.w_getrectfn = fatom_getrect;
453 fatom_widgetbehavior.w_displacefn = fatom_displace;
454 fatom_widgetbehavior.w_selectfn = fatom_select;
455 fatom_widgetbehavior.w_activatefn = fatom_activate;
456 fatom_widgetbehavior.w_deletefn = fatom_delete;
457 fatom_widgetbehavior.w_visfn = fatom_vis;
458#if PD_MINOR_VERSION < 37
459 fatom_widgetbehavior.w_savefn = fatom_save;
460 fatom_widgetbehavior.w_propertiesfn = NULL;
461#endif
462 fatom_widgetbehavior.w_clickfn = NULL;
463
464 class_addfloat(class, (t_method)fatom_float);
465 class_addbang(class, (t_method)fatom_bang);
466 class_addmethod(class, (t_method)fatom_f, gensym("f"),
467 A_FLOAT, 0);
468
469/*
470 class_addmethod(class, (t_method)fatom_size, gensym("size"),
471 A_FLOAT, A_FLOAT, 0);
472
473 class_addmethod(class, (t_method)fatom_color, gensym("color"),
474 A_SYMBOL, 0);
475*/
476/*
477 class_addmethod(class, (t_method)fatom_open, gensym("open"),
478 A_SYMBOL, 0);
479*/
480
481 class_setwidget(class,&fatom_widgetbehavior);
482#if PD_MINOR_VERSION >= 37
483 class_setsavefn(class,&fatom_save);
484#endif
485}
486
diff --git a/apps/plugins/pdbox/PDa/extra/gcanvas-help.pd b/apps/plugins/pdbox/PDa/extra/gcanvas-help.pd
deleted file mode 100644
index 2844911261..0000000000
--- a/apps/plugins/pdbox/PDa/extra/gcanvas-help.pd
+++ /dev/null
@@ -1,9 +0,0 @@
1#N canvas 0 0 240 300 8;
2#X obj 21 61 gcanvas 80 80;
3#X text 14 9 gcanvas .. mouse coordinate enabled canvas;
4#X text 13 22 ==========================================;
5#X floatatom 21 148 5 0 0 0 - - -;
6#X floatatom 94 147 5 0 0 0 - - -;
7#X connect 0 0 3 0;
8#X connect 0 1 4 0;
9
diff --git a/apps/plugins/pdbox/PDa/extra/makefile b/apps/plugins/pdbox/PDa/extra/makefile
deleted file mode 100644
index 4bd6ed0960..0000000000
--- a/apps/plugins/pdbox/PDa/extra/makefile
+++ /dev/null
@@ -1,34 +0,0 @@
1
2VERSION = 0.2
3SOURCE = $(shell ls *.c)
4TARGETS = $(SOURCE:.c=.pd_linux)
5
6EXT= pd_linux
7
8AFLAGS = -g -O2 -I./ -DFIXEDPOINT
9EFLAGS = -shared -Wl,-export-dynamic
10PREFIX = /usr
11
12
13all: $(TARGETS)
14
15clean:
16 -rm $(TARGETS)
17 -rm *.o *~
18
19tar: clean
20 cd ..;tar czvf PDa-externals-$(VERSION).tgz PDa-externals
21
22upload: tar
23 scp ../PDa-externals-$(VERSION).tgz gige@xdv.org:~/www/pda/release
24
25install:
26 install -d $(DESTDIR)/$(PREFIX)/lib/pd/extra
27 cp $(TARGETS) $(DESTDIR)/$(PREFIX)/lib/pd/extra
28
29%.$(EXT) : %.o
30 $(CC) -o $@ $(EFLAGS) $+
31
32%.o : %.c
33 $(CC) -c $(AFLAGS) $(CFLAGS) $+
34
diff --git a/apps/plugins/pdbox/PDa/extra/sendOSC.c b/apps/plugins/pdbox/PDa/extra/sendOSC.c
deleted file mode 100644
index 6bb809d68f..0000000000
--- a/apps/plugins/pdbox/PDa/extra/sendOSC.c
+++ /dev/null
@@ -1,1461 +0,0 @@
1/*
2Written by Matt Wright, The Center for New Music and Audio Technologies,
3University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03
4The Regents of the University of California (Regents).
5
6Permission to use, copy, modify, distribute, and distribute modified versions
7of this software and its documentation without fee and without a signed
8licensing agreement, is hereby granted, provided that the above copyright
9notice, this paragraph and the following two paragraphs appear in all copies,
10modifications, and distributions.
11
12IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
13SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
14OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
15BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
17REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
20HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
21MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
22
23
24The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
25*/
26
27
28/* sendOSC.c
29
30 Matt Wright, 6/3/97
31 based on sendOSC.c, which was based on a version by Adrian Freed
32
33 Text-based OpenSoundControl client. User can enter messages via command
34 line arguments or standard input.
35
36 Version 0.1: "play" feature
37 Version 0.2: Message type tags.
38
39 pd version branched from http://www.cnmat.berkeley.edu/OpenSoundControl/src/sendOSC/sendOSC.c
40 -------------
41 -- added bundle stuff to send. jdl 20020416
42 -- tweaks for Win32 www.zeggz.com/raf 13-April-2002
43 -- ost_at_test.at + i22_at_test.at, 2000-2002
44 modified to compile as pd externel
45*/
46
47#define MAX_ARGS 2000
48#define SC_BUFFER_SIZE 64000
49
50#include "../src/m_pd.h"
51#include "OSC-client.h"
52
53#include <string.h>
54#include <sys/types.h>
55#include <stdlib.h>
56#include <stdio.h>
57#include <sys/stat.h>
58#include <sys/types.h>
59
60#ifdef WIN32
61#include <winsock2.h>
62#include <io.h>
63#include <errno.h>
64#include <fcntl.h>
65#include <winsock2.h>
66#include <ctype.h>
67#include <signal.h>
68#else
69#include <sys/socket.h>
70#include <netinet/in.h>
71#include <rpc/rpc.h>
72#include <sys/times.h>
73#include <sys/param.h>
74#include <sys/time.h>
75#include <sys/ioctl.h>
76#include <netdb.h>
77#endif
78
79#ifdef __APPLE__
80 #include <string.h>
81#endif
82
83#define UNIXDG_PATH "/tmp/htm"
84#define UNIXDG_TMP "/tmp/htm.XXXXXX"
85
86
87
88OSCTimeTag OSCTT_Immediately(void) {
89 OSCTimeTag result;
90 result.seconds = 0;
91 result.fraction = 1;
92 return result;
93}
94
95
96OSCTimeTag OSCTT_CurrentTime(void) {
97 OSCTimeTag result;
98 result.seconds = 0;
99 result.fraction = 1;
100 return result;
101}
102
103OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) {
104 OSCTimeTag result;
105 result.seconds = 0;
106 result.fraction = 1;
107 return result;
108}
109
110
111typedef int bool;
112
113typedef struct
114{
115 float srate;
116
117 struct sockaddr_in serv_addr; /* udp socket */
118 #ifndef WIN32
119 struct sockaddr_un userv_addr; /* UNIX socket */
120 #endif
121 int sockfd; /* socket file descriptor */
122 int index, len,uservlen;
123 void *addr;
124 int id;
125} desc;
126
127
128/* open a socket for HTM communication to given host on given portnumber */
129/* if host is 0 then UNIX protocol is used (i.e. local communication */
130void *OpenHTMSocket(char *host, int portnumber)
131{
132 struct sockaddr_in cl_addr;
133 #ifndef WIN32
134 int sockfd;
135 struct sockaddr_un ucl_addr;
136 #else
137 unsigned int sockfd;
138 #endif
139
140 desc *o;
141 int oval = 1;
142 o = malloc(sizeof(*o));
143 if(!o) return 0;
144
145 #ifndef WIN32
146
147 if(!host)
148 {
149 char *mktemp(char *);
150 int clilen;
151 o->len = sizeof(ucl_addr);
152 /*
153 * Fill in the structure "userv_addr" with the address of the
154 * server that we want to send to.
155 */
156
157 bzero((char *) &o->userv_addr, sizeof(o->userv_addr));
158 o->userv_addr.sun_family = AF_UNIX;
159 strcpy(o->userv_addr.sun_path, UNIXDG_PATH);
160 sprintf(o->userv_addr.sun_path+strlen(o->userv_addr.sun_path), "%d", portnumber);
161 o->uservlen = sizeof(o->userv_addr.sun_family) + strlen(o->userv_addr.sun_path);
162 o->addr = &(o->userv_addr);
163 /*
164 * Open a socket (a UNIX domain datagram socket).
165 */
166
167 if ( (sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) >= 0)
168 {
169 /*
170 * Bind a local address for us.
171 * In the UNIX domain we have to choose our own name (that
172 * should be unique). We'll use mktemp() to create a unique
173 * pathname, based on our process id.
174 */
175
176 bzero((char *) &ucl_addr, sizeof(ucl_addr)); /* zero out */
177 ucl_addr.sun_family = AF_UNIX;
178 strcpy(ucl_addr.sun_path, UNIXDG_TMP);
179
180 mktemp(ucl_addr.sun_path);
181 clilen = sizeof(ucl_addr.sun_family) + strlen(ucl_addr.sun_path);
182
183 if (bind(sockfd, (struct sockaddr *) &ucl_addr, clilen) < 0)
184 {
185 perror("client: can't bind local address");
186 close(sockfd);
187 sockfd = -1;
188 }
189 }
190 else
191 perror("unable to make socket\n");
192
193 }else
194
195 #endif
196
197 {
198 /*
199 * Fill in the structure "serv_addr" with the address of the
200 * server that we want to send to.
201 */
202 o->len = sizeof(cl_addr);
203
204 #ifdef WIN32
205 ZeroMemory((char *)&o->serv_addr, sizeof(o->serv_addr));
206 #else
207 bzero((char *)&o->serv_addr, sizeof(o->serv_addr));
208 #endif
209
210 o->serv_addr.sin_family = AF_INET;
211
212 /* MW 6/6/96: Call gethostbyname() instead of inet_addr(),
213 so that host can be either an Internet host name (e.g.,
214 "les") or an Internet address in standard dot notation
215 (e.g., "128.32.122.13") */
216 {
217 struct hostent *hostsEntry;
218 unsigned long address;
219
220 hostsEntry = gethostbyname(host);
221 if (hostsEntry == NULL) {
222 fprintf(stderr, "Couldn't decipher host name \"%s\"\n", host);
223 #ifndef WIN32
224 herror(NULL);
225 #endif
226 return 0;
227 }
228 address = *((unsigned long *) hostsEntry->h_addr_list[0]);
229 o->serv_addr.sin_addr.s_addr = address;
230 }
231
232 /* was: o->serv_addr.sin_addr.s_addr = inet_addr(host); */
233
234 /* End MW changes */
235
236 /*
237 * Open a socket (a UDP domain datagram socket).
238 */
239
240
241 #ifdef WIN32
242 o->serv_addr.sin_port = htons((USHORT)portnumber);
243 o->addr = &(o->serv_addr);
244 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET) {
245 ZeroMemory((char *)&cl_addr, sizeof(cl_addr));
246 cl_addr.sin_family = AF_INET;
247 cl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
248 cl_addr.sin_port = htons(0);
249
250 // enable broadcast: jdl ~2003
251 if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &oval, sizeof(int)) == -1) {
252 perror("setsockopt");
253 }
254
255 if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) {
256 perror("could not bind\n");
257 closesocket(sockfd);
258 sockfd = -1;
259 }
260 }
261 else { perror("unable to make socket\n");}
262 #else
263 o->serv_addr.sin_port = htons(portnumber);
264 o->addr = &(o->serv_addr);
265 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
266 bzero((char *)&cl_addr, sizeof(cl_addr));
267 cl_addr.sin_family = AF_INET;
268 cl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
269 cl_addr.sin_port = htons(0);
270
271 // enable broadcast: jdl ~2003
272 if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &oval, sizeof(int)) == -1) {
273 perror("setsockopt");
274 }
275
276 if(bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0) {
277 perror("could not bind\n");
278 close(sockfd);
279 sockfd = -1;
280 }
281 }
282 else { perror("unable to make socket\n");}
283 #endif
284 }
285 #ifdef WIN32
286 if(sockfd == INVALID_SOCKET) {
287 #else
288 if(sockfd < 0) {
289 #endif
290 free(o);
291 o = 0;
292 }
293 else
294 o->sockfd = sockfd;
295 return o;
296}
297
298static bool sendudp(const struct sockaddr *sp, int sockfd,int length, int count, void *b)
299{
300 int rcount;
301 if((rcount=sendto(sockfd, b, count, 0, sp, length)) != count)
302 {
303 printf("sockfd %d count %d rcount %dlength %d\n", sockfd,count,rcount,length);
304 return FALSE;
305 }
306 return TRUE;
307}
308
309bool SendHTMSocket(void *htmsendhandle, int length_in_bytes, void *buffer)
310{
311 desc *o = (desc *)htmsendhandle;
312 return sendudp(o->addr, o->sockfd, o->len, length_in_bytes, buffer);
313}
314void CloseHTMSocket(void *htmsendhandle)
315{
316 desc *o = (desc *)htmsendhandle;
317 #ifdef WIN32
318 if(SOCKET_ERROR == closesocket(o->sockfd)) {
319 perror("CloseHTMSocket::closesocket failed\n");
320 return;
321 }
322 #else
323 if(close(o->sockfd) == -1)
324 {
325 perror("CloseHTMSocket::closesocket failed");
326 return;
327 }
328 #endif
329
330 free(o);
331}
332
333
334///////////////////////
335// from sendOSC
336
337typedef struct {
338 //enum {INT, FLOAT, STRING} type;
339 enum {INT_osc, FLOAT_osc, STRING_osc} type;
340 union {
341 int i;
342 float f;
343 char *s;
344 } datum;
345} typedArg;
346
347void CommandLineMode(int argc, char *argv[], void *htmsocket);
348OSCTimeTag ParseTimeTag(char *s);
349void ParseInteractiveLine(OSCbuf *buf, char *mesg);
350typedArg ParseToken(char *token);
351int WriteMessage(OSCbuf *buf, char *messageName, int numArgs, typedArg *args);
352void SendBuffer(void *htmsocket, OSCbuf *buf);
353void SendData(void *htmsocket, int size, char *data);
354/* defined in OSC-system-dependent.c now */
355
356//static void *htmsocket;
357static int exitStatus = 0;
358static int useTypeTags = 0;
359
360static char bufferForOSCbuf[SC_BUFFER_SIZE];
361
362
363/////////
364// end from sendOSC
365
366static t_class *sendOSC_class;
367
368typedef struct _sendOSC
369{
370 t_object x_obj;
371 int x_protocol; // UDP/TCP (udp only atm)
372 t_int x_typetags; // typetag flag
373 void *x_htmsocket; // sending socket
374 int x_bundle; // bundle open flag
375 OSCbuf x_oscbuf[1]; // OSCbuffer
376 t_outlet *x_bdpthout;// bundle-depth floatoutlet
377} t_sendOSC;
378
379static void *sendOSC_new(t_floatarg udpflag)
380{
381 t_sendOSC *x = (t_sendOSC *)pd_new(sendOSC_class);
382 outlet_new(&x->x_obj, &s_float);
383 x->x_htmsocket = 0; // {{raf}}
384 // set udp
385 x->x_protocol = SOCK_STREAM;
386 // set typetags to 1 by default
387 x->x_typetags = 1;
388 // bunlde is closed
389 x->x_bundle = 0;
390 OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf);
391 x->x_bdpthout = outlet_new(&x->x_obj, 0); // outlet_float();
392 //x->x_oscbuf =
393 return (x);
394}
395
396
397void sendOSC_openbundle(t_sendOSC *x)
398{
399 if (x->x_oscbuf->bundleDepth + 1 >= MAX_BUNDLE_NESTING ||
400 OSC_openBundle(x->x_oscbuf, OSCTT_Immediately()))
401 {
402 post("Problem opening bundle: %s\n", OSC_errorMessage);
403 return;
404 }
405 x->x_bundle = 1;
406 outlet_float(x->x_bdpthout, (float)x->x_oscbuf->bundleDepth);
407}
408
409static void sendOSC_closebundle(t_sendOSC *x)
410{
411 if (OSC_closeBundle(x->x_oscbuf)) {
412 post("Problem closing bundle: %s\n", OSC_errorMessage);
413 return;
414 }
415 outlet_float(x->x_bdpthout, (float)x->x_oscbuf->bundleDepth);
416 // in bundle mode we send when bundle is closed?
417 if(!OSC_isBufferEmpty(x->x_oscbuf) > 0 && OSC_isBufferDone(x->x_oscbuf)) {
418 // post("x_oscbuf: something inside me?");
419 if (x->x_htmsocket) {
420 SendBuffer(x->x_htmsocket, x->x_oscbuf);
421 } else {
422 post("sendOSC: not connected");
423 }
424 OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf);
425 x->x_bundle = 0;
426 return;
427 }
428 // post("x_oscbuf: something went wrong");
429}
430
431static void sendOSC_settypetags(t_sendOSC *x, t_float *f)
432 {
433 x->x_typetags = (int)f;
434 post("sendOSC.c: setting typetags %d",x->x_typetags);
435 }
436
437
438static void sendOSC_connect(t_sendOSC *x, t_symbol *hostname,
439 t_floatarg fportno)
440{
441 int portno = fportno;
442 /* create a socket */
443
444 // make sure handle is available
445 if(x->x_htmsocket == 0) {
446 //
447 x->x_htmsocket = OpenHTMSocket(hostname->s_name, portno);
448 if (!x->x_htmsocket)
449 post("Couldn't open socket: ");
450 else {
451 post("connected to port %s:%d (hSock=%d)", hostname->s_name, portno, x->x_htmsocket);
452 outlet_float(x->x_obj.ob_outlet, 1);
453 }
454 }
455 else
456 perror("call to sendOSC_connect() against UNavailable socket handle");
457}
458
459void sendOSC_disconnect(t_sendOSC *x)
460{
461 if (x->x_htmsocket)
462 {
463 post("disconnecting htmsock (hSock=%d)...", x->x_htmsocket);
464 CloseHTMSocket(x->x_htmsocket);
465 x->x_htmsocket = 0; // {{raf}} semi-quasi-semaphorize this
466 outlet_float(x->x_obj.ob_outlet, 0);
467 }
468 else {
469 perror("call to sendOSC_disconnect() against unused socket handle");
470 }
471}
472
473void sendOSC_senduntyped(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv)
474{
475 char* targv[MAXPDARG];
476 char tmparg[MAXPDSTRING];
477 char* tmp = tmparg;
478 //char testarg[MAXPDSTRING];
479 int c;
480
481 post("sendOSC: use typetags 0/1 message and plain send method so send untypetagged...");
482 return;
483
484 //atom_string(argv,testarg, MAXPDSTRING);
485 for (c=0;c<argc;c++) {
486 atom_string(argv+c,tmp, 80);
487 targv[c] = tmp;
488 tmp += strlen(tmp)+1;
489 }
490
491 // this sock needs to be larger than 0, not >= ..
492 if (x->x_htmsocket)
493 {
494 CommandLineMode(argc, targv, x->x_htmsocket);
495 // post("test %d", c);
496 }
497 else {
498 post("sendOSC: not connected");
499 }
500}
501
502//////////////////////////////////////////////////////////////////////
503// this is the real and only sending routine now, for both typed and
504// undtyped mode.
505
506static void sendOSC_sendtyped(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv)
507{
508 char* targv[MAX_ARGS];
509 char tmparg[MAXPDSTRING];
510 char* tmp = tmparg;
511 int c;
512
513 char *messageName;
514 char *token;
515 typedArg args[MAX_ARGS];
516 int i,j;
517 int numArgs = 0;
518
519 messageName = "";
520#ifdef DEBUG
521 post ("sendOSC: messageName: %s", messageName);
522#endif
523
524
525
526 for (c=0;c<argc;c++) {
527 atom_string(argv+c,tmp, 80);
528
529#ifdef DEBUG
530 // post ("sendOSC: %d, %s",c, tmp);
531#endif
532
533 targv[c] = tmp;
534 tmp += strlen(tmp)+1;
535
536#ifdef DEBUG
537 // post ("sendOSC: %d, %s",c, targv[c]);
538#endif
539 }
540
541 // this sock needs to be larger than 0, not >= ..
542 if (x->x_htmsocket > 0)
543 {
544#ifdef DEBUG
545 post ("sendOSC: type tags? %d", useTypeTags);
546#endif
547
548 messageName = strtok(targv[0], ",");
549 j = 1;
550 for (i = j; i < argc; i++) {
551 token = strtok(targv[i],",");
552 args[i-j] = ParseToken(token);
553#ifdef DEBUG
554 printf("cell-cont: %s\n", targv[i]);
555 printf(" type-id: %d\n", args[i-j]);
556#endif
557 numArgs = i;
558 }
559
560
561 if(WriteMessage(x->x_oscbuf, messageName, numArgs, args)) {
562 post("sendOSC: usage error, write-msg failed: %s", OSC_errorMessage);
563 return;
564 }
565
566 if(!x->x_bundle) {
567 SendBuffer(x->x_htmsocket, x->x_oscbuf);
568 OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf);
569 }
570
571 //CommandLineMode(argc, targv, x->x_htmsocket);
572 //useTypeTags = 0;
573 }
574 else {
575 post("sendOSC: not connected");
576 }
577}
578
579void sendOSC_send(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv)
580{
581 if(!argc) {
582 post("not sending empty message.");
583 return;
584 }
585 if(x->x_typetags) {
586 useTypeTags = 1;
587 sendOSC_sendtyped(x,s,argc,argv);
588 useTypeTags = 0;
589 } else {
590 sendOSC_sendtyped(x,s,argc,argv);
591 }
592}
593
594static void sendOSC_free(t_sendOSC *x)
595{
596 sendOSC_disconnect(x);
597}
598
599#ifdef WIN32
600 OSC_API void sendOSC_setup(void) {
601#else
602 void sendOSC_setup(void) {
603#endif
604 sendOSC_class = class_new(gensym("sendOSC"), (t_newmethod)sendOSC_new,
605 (t_method)sendOSC_free,
606 sizeof(t_sendOSC), 0, A_DEFFLOAT, 0);
607 class_addmethod(sendOSC_class, (t_method)sendOSC_connect,
608 gensym("connect"), A_SYMBOL, A_FLOAT, 0);
609 class_addmethod(sendOSC_class, (t_method)sendOSC_disconnect,
610 gensym("disconnect"), 0);
611 class_addmethod(sendOSC_class, (t_method)sendOSC_settypetags,
612 gensym("typetags"),
613 A_FLOAT, 0);
614 class_addmethod(sendOSC_class, (t_method)sendOSC_send,
615 gensym("send"),
616 A_GIMME, 0);
617 class_addmethod(sendOSC_class, (t_method)sendOSC_send,
618 gensym("senduntyped"),
619 A_GIMME, 0);
620 class_addmethod(sendOSC_class, (t_method)sendOSC_send,
621 gensym("sendtyped"),
622 A_GIMME, 0);
623 class_addmethod(sendOSC_class, (t_method)sendOSC_openbundle,
624 gensym("["),
625 0, 0);
626 class_addmethod(sendOSC_class, (t_method)sendOSC_closebundle,
627 gensym("]"),
628 0, 0);
629 class_sethelpsymbol(sendOSC_class, gensym("sendOSC-help.pd"));
630}
631
632
633
634
635
636/* Exit status codes:
637 0: successful
638 2: Message(s) dropped because of buffer overflow
639 3: Socket error
640 4: Usage error
641 5: Internal error
642*/
643
644void CommandLineMode(int argc, char *argv[], void *htmsocket) {
645 char *messageName;
646 char *token;
647 typedArg args[MAX_ARGS];
648 int i,j, numArgs;
649 OSCbuf buf[1];
650
651 OSC_initBuffer(buf, SC_BUFFER_SIZE, bufferForOSCbuf);
652
653 if (argc > 1) {
654 post("argc (%d) > 1", argc);
655 }
656
657 // ParseInteractiveLine(buf, argv);
658 messageName = strtok(argv[0], ",");
659
660 j = 1;
661 for (i = j; i < argc; i++) {
662 token = strtok(argv[i],",");
663 args[i-j] = ParseToken(token);
664#ifdef DEBUG
665 printf("cell-cont: %s\n", argv[i]);
666 printf(" type-id: %d\n", args[i-j]);
667#endif
668 numArgs = i;
669 }
670
671 if(WriteMessage(buf, messageName, numArgs, args)) {
672 post("sendOSC: usage error. write-msg failed: %s", OSC_errorMessage);
673 return;
674 }
675
676 SendBuffer(htmsocket, buf);
677}
678
679#define MAXMESG 2048
680
681void InteractiveMode(void *htmsocket) {
682 char mesg[MAXMESG];
683 OSCbuf buf[1];
684 int bundleDepth = 0; /* At first, we haven't seen "[". */
685
686 OSC_initBuffer(buf, SC_BUFFER_SIZE, bufferForOSCbuf);
687
688 while (fgets(mesg, MAXMESG, stdin) != NULL) {
689 if (mesg[0] == '\n') {
690 if (bundleDepth > 0) {
691 /* Ignore blank lines inside a group. */
692 } else {
693 /* blank line => repeat previous send */
694 SendBuffer(htmsocket, buf);
695 }
696 continue;
697 }
698
699 if (bundleDepth == 0) {
700 OSC_resetBuffer(buf);
701 }
702
703 if (mesg[0] == '[') {
704 OSCTimeTag tt = ParseTimeTag(mesg+1);
705 if (OSC_openBundle(buf, tt)) {
706 post("Problem opening bundle: %s\n", OSC_errorMessage);
707 OSC_resetBuffer(buf);
708 bundleDepth = 0;
709 continue;
710 }
711 bundleDepth++;
712 } else if (mesg[0] == ']' && mesg[1] == '\n' && mesg[2] == '\0') {
713 if (bundleDepth == 0) {
714 post("Unexpected ']': not currently in a bundle.\n");
715 } else {
716 if (OSC_closeBundle(buf)) {
717 post("Problem closing bundle: %s\n", OSC_errorMessage);
718 OSC_resetBuffer(buf);
719 bundleDepth = 0;
720 continue;
721 }
722
723 bundleDepth--;
724 if (bundleDepth == 0) {
725 SendBuffer(htmsocket, buf);
726 }
727 }
728 } else {
729 ParseInteractiveLine(buf, mesg);
730 if (bundleDepth != 0) {
731 /* Don't send anything until we close all bundles */
732 } else {
733 SendBuffer(htmsocket, buf);
734 }
735 }
736 }
737}
738
739OSCTimeTag ParseTimeTag(char *s) {
740 char *p, *newline;
741 typedArg arg;
742
743 p = s;
744 while (isspace(*p)) p++;
745 if (*p == '\0') return OSCTT_Immediately();
746
747 if (*p == '+') {
748 /* Time tag is for some time in the future. It should be a
749 number of seconds as an int or float */
750
751 newline = strchr(s, '\n');
752 if (newline != NULL) *newline = '\0';
753
754 p++; /* Skip '+' */
755 while (isspace(*p)) p++;
756
757 arg = ParseToken(p);
758 if (arg.type == STRING_osc) {
759 post("warning: inscrutable time tag request: %s\n", s);
760 return OSCTT_Immediately();
761 } else if (arg.type == INT_osc) {
762 return OSCTT_PlusSeconds(OSCTT_CurrentTime(),
763 (float) arg.datum.i);
764 } else if (arg.type == FLOAT_osc) {
765 return OSCTT_PlusSeconds(OSCTT_CurrentTime(), arg.datum.f);
766 } else {
767 error("This can't happen!");
768 }
769 }
770
771 if (isdigit(*p) || (*p >= 'a' && *p <='f') || (*p >= 'A' && *p <='F')) {
772 /* They specified the 8-byte tag in hex */
773 OSCTimeTag tt;
774 if (sscanf(p, "%llx", &tt) != 1) {
775 post("warning: couldn't parse time tag %s\n", s);
776 return OSCTT_Immediately();
777 }
778#ifndef HAS8BYTEINT
779 if (ntohl(1) != 1) {
780 /* tt is a struct of seconds and fractional part,
781 and this machine is little-endian, so sscanf
782 wrote each half of the time tag in the wrong half
783 of the struct. */
784 int temp;
785 temp = tt.seconds;
786 tt.seconds = tt.fraction ;
787 tt.fraction = temp;
788 }
789#endif
790 return tt;
791 }
792
793 post("warning: invalid time tag: %s\n", s);
794 return OSCTT_Immediately();
795}
796
797
798void ParseInteractiveLine(OSCbuf *buf, char *mesg) {
799 char *messageName, *token, *p;
800 typedArg args[MAX_ARGS];
801 int thisArg;
802
803 p = mesg;
804 while (isspace(*p)) p++;
805 if (*p == '\0') return;
806
807 messageName = p;
808
809 if (strcmp(messageName, "play\n") == 0) {
810 /* Special kludge feature to save typing */
811 typedArg arg;
812
813 if (OSC_openBundle(buf, OSCTT_Immediately())) {
814 post("Problem opening bundle: %s\n", OSC_errorMessage);
815 return;
816 }
817
818 arg.type = INT_osc;
819 arg.datum.i = 0;
820 WriteMessage(buf, "/voices/0/tp/timbre_index", 1, &arg);
821
822 arg.type = FLOAT_osc;
823 arg.datum.i = 0.0f;
824 WriteMessage(buf, "/voices/0/tm/goto", 1, &arg);
825
826 if (OSC_closeBundle(buf)) {
827 post("Problem closing bundle: %s\n", OSC_errorMessage);
828 }
829
830 return;
831 }
832
833 while (!isspace(*p) && *p != '\0') p++;
834 if (isspace(*p)) {
835 *p = '\0';
836 p++;
837 }
838
839 thisArg = 0;
840 while (*p != '\0') {
841 /* flush leading whitespace */
842 while (isspace(*p)) p++;
843 if (*p == '\0') break;
844
845 if (*p == '"') {
846 /* A string argument: scan for close quotes */
847 p++;
848 args[thisArg].type = STRING_osc;
849 args[thisArg].datum.s = p;
850
851 while (*p != '"') {
852 if (*p == '\0') {
853 post("Unterminated quote mark: ignoring line\n");
854 return;
855 }
856 p++;
857 }
858 *p = '\0';
859 p++;
860 } else {
861 token = p;
862 while (!isspace(*p) && (*p != '\0')) p++;
863 if (isspace(*p)) {
864 *p = '\0';
865 p++;
866 }
867 args[thisArg] = ParseToken(token);
868 }
869 thisArg++;
870 if (thisArg >= MAX_ARGS) {
871 post("Sorry, your message has more than MAX_ARGS (%d) arguments; ignoring the rest.\n",
872 MAX_ARGS);
873 break;
874 }
875 }
876
877 if (WriteMessage(buf, messageName, thisArg, args) != 0) {
878 post("Problem sending message: %s\n", OSC_errorMessage);
879 }
880}
881
882typedArg ParseToken(char *token) {
883 char *p = token;
884 typedArg returnVal;
885
886 /* It might be an int, a float, or a string */
887
888 if (*p == '-') p++;
889
890 if (isdigit(*p) || *p == '.') {
891 while (isdigit(*p)) p++;
892 if (*p == '\0') {
893 returnVal.type = INT_osc;
894 returnVal.datum.i = atoi(token);
895 return returnVal;
896 }
897 if (*p == '.') {
898 p++;
899 while (isdigit(*p)) p++;
900 if (*p == '\0') {
901 returnVal.type = FLOAT_osc;
902 returnVal.datum.f = atof(token);
903 return returnVal;
904 }
905 }
906 }
907
908 returnVal.type = STRING_osc;
909 returnVal.datum.s = token;
910 return returnVal;
911}
912
913int WriteMessage(OSCbuf *buf, char *messageName, int numArgs, typedArg *args) {
914 int j, returnVal;
915 const int wmERROR = -1;
916
917 returnVal = 0;
918
919#ifdef DEBUG
920 printf("WriteMessage: %s ", messageName);
921
922 for (j = 0; j < numArgs; j++) {
923 switch (args[j].type) {
924 case INT_osc:
925 printf("%d ", args[j].datum.i);
926 break;
927
928 case FLOAT_osc:
929 printf("%f ", args[j].datum.f);
930 break;
931
932 case STRING_osc:
933 printf("%s ", args[j].datum.s);
934 break;
935
936 default:
937 error("Unrecognized arg type, (not exiting)");
938 return(wmERROR);
939 }
940 }
941 printf("\n");
942#endif
943
944 if (!useTypeTags) {
945 returnVal = OSC_writeAddress(buf, messageName);
946 if (returnVal) {
947 post("Problem writing address: %s\n", OSC_errorMessage);
948 }
949 } else {
950 /* First figure out the type tags */
951 char typeTags[MAX_ARGS+2];
952 int i;
953
954 typeTags[0] = ',';
955
956 for (i = 0; i < numArgs; ++i) {
957 switch (args[i].type) {
958 case INT_osc:
959 typeTags[i+1] = 'i';
960 break;
961
962 case FLOAT_osc:
963 typeTags[i+1] = 'f';
964 break;
965
966 case STRING_osc:
967 typeTags[i+1] = 's';
968 break;
969
970 default:
971 error("Unrecognized arg type (not exiting)");
972 return(wmERROR);
973 }
974 }
975 typeTags[i+1] = '\0';
976
977 returnVal = OSC_writeAddressAndTypes(buf, messageName, typeTags);
978 if (returnVal) {
979 post("Problem writing address: %s\n", OSC_errorMessage);
980 }
981 }
982
983 for (j = 0; j < numArgs; j++) {
984 switch (args[j].type) {
985 case INT_osc:
986 if ((returnVal = OSC_writeIntArg(buf, args[j].datum.i)) != 0) {
987 return returnVal;
988 }
989 break;
990
991 case FLOAT_osc:
992 if ((returnVal = OSC_writeFloatArg(buf, args[j].datum.f)) != 0) {
993 return returnVal;
994 }
995 break;
996
997 case STRING_osc:
998 if ((returnVal = OSC_writeStringArg(buf, args[j].datum.s)) != 0) {
999 return returnVal;
1000 }
1001 break;
1002
1003 default:
1004 error("Unrecognized arg type (not exiting)");
1005 returnVal = wmERROR;
1006 }
1007 }
1008 return returnVal;
1009}
1010
1011void SendBuffer(void *htmsocket, OSCbuf *buf) {
1012#ifdef DEBUG
1013 printf("Sending buffer...\n");
1014#endif
1015 if (OSC_isBufferEmpty(buf)) {
1016 post("SendBuffer() called but buffer empty");
1017 return;
1018 }
1019 if (!OSC_isBufferDone(buf)) {
1020 error("SendBuffer() called but buffer not ready!, not exiting");
1021 return; //{{raf}}
1022 }
1023 SendData(htmsocket, OSC_packetSize(buf), OSC_getPacket(buf));
1024}
1025
1026void SendData(void *htmsocket, int size, char *data) {
1027 if (!SendHTMSocket(htmsocket, size, data)) {
1028 post("SendData::SendHTMSocket()failure -- not connected");
1029 CloseHTMSocket(htmsocket);
1030 }
1031}
1032
1033
1034
1035/* ----------------------
1036 OSC-client code
1037
1038 */
1039
1040/* Here are the possible values of the state field: */
1041
1042#define EMPTY 0 /* Nothing written to packet yet */
1043#define ONE_MSG_ARGS 1 /* Packet has a single message; gathering arguments */
1044#define NEED_COUNT 2 /* Just opened a bundle; must write message name or
1045 open another bundle */
1046#define GET_ARGS 3 /* Getting arguments to a message. If we see a message
1047 name or a bundle open/close then the current message
1048 will end. */
1049#define DONE 4 /* All open bundles have been closed, so can't write
1050 anything else */
1051
1052#ifdef WIN32
1053 #include <winsock2.h>
1054 #include <io.h>
1055 #include <stdio.h>
1056 #include <errno.h>
1057 #include <fcntl.h>
1058 #include <sys/types.h>
1059 #include <sys/stat.h>
1060#endif
1061
1062#ifdef __APPLE__
1063 #include <sys/types.h>
1064#endif
1065
1066#ifdef unix
1067 #include <netinet/in.h>
1068 #include <stdio.h>
1069#endif
1070
1071
1072char *OSC_errorMessage;
1073
1074static int OSC_padString(char *dest, char *str);
1075static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str);
1076static int OSC_WritePadding(char *dest, int i);
1077static int CheckTypeTag(OSCbuf *buf, char expectedType);
1078
1079void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) {
1080 buf->buffer = byteArray;
1081 buf->size = size;
1082 OSC_resetBuffer(buf);
1083}
1084
1085void OSC_resetBuffer(OSCbuf *buf) {
1086 buf->bufptr = buf->buffer;
1087 buf->state = EMPTY;
1088 buf->bundleDepth = 0;
1089 buf->prevCounts[0] = 0;
1090 buf->gettingFirstUntypedArg = 0;
1091 buf->typeStringPtr = 0;
1092}
1093
1094int OSC_isBufferEmpty(OSCbuf *buf) {
1095 return buf->bufptr == buf->buffer;
1096}
1097
1098int OSC_freeSpaceInBuffer(OSCbuf *buf) {
1099 return buf->size - (buf->bufptr - buf->buffer);
1100}
1101
1102int OSC_isBufferDone(OSCbuf *buf) {
1103 return (buf->state == DONE || buf->state == ONE_MSG_ARGS);
1104}
1105
1106char *OSC_getPacket(OSCbuf *buf) {
1107#ifdef ERROR_CHECK_GETPACKET
1108 if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
1109 return buf->buffer;
1110 } else {
1111 OSC_errorMessage = "Packet has unterminated bundles";
1112 return 0;
1113 }
1114#else
1115 return buf->buffer;
1116#endif
1117}
1118
1119int OSC_packetSize(OSCbuf *buf) {
1120#ifdef ERROR_CHECK_PACKETSIZE
1121 if (buf->state == DONE || buf->state == ONE_MSG_ARGS) {
1122 return (buf->bufptr - buf->buffer);
1123 } else {
1124 OSC_errorMessage = "Packet has unterminated bundles";
1125 return 0;
1126 }
1127#else
1128 return (buf->bufptr - buf->buffer);
1129#endif
1130}
1131
1132#define CheckOverflow(buf, bytesNeeded) { if ((bytesNeeded) > OSC_freeSpaceInBuffer(buf)) {OSC_errorMessage = "buffer overflow"; return 1;}}
1133
1134static void PatchMessageSize(OSCbuf *buf) {
1135 int4byte size;
1136 size = buf->bufptr - ((char *) buf->thisMsgSize) - 4;
1137 *(buf->thisMsgSize) = htonl(size);
1138}
1139
1140int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt) {
1141 if (buf->state == ONE_MSG_ARGS) {
1142 OSC_errorMessage = "Can't open a bundle in a one-message packet";
1143 return 3;
1144 }
1145
1146 if (buf->state == DONE) {
1147 OSC_errorMessage = "This packet is finished; can't open a new bundle";
1148 return 4;
1149 }
1150
1151 if (++(buf->bundleDepth) >= MAX_BUNDLE_NESTING) {
1152 OSC_errorMessage = "Bundles nested too deeply; change MAX_BUNDLE_NESTING in OpenSoundControl.h";
1153 return 2;
1154 }
1155
1156 if (CheckTypeTag(buf, '\0')) return 9;
1157
1158 if (buf->state == GET_ARGS) {
1159 PatchMessageSize(buf);
1160 }
1161
1162 if (buf->state == EMPTY) {
1163 /* Need 16 bytes for "#bundle" and time tag */
1164 CheckOverflow(buf, 16);
1165 } else {
1166 /* This bundle is inside another bundle, so we need to leave
1167 a blank size count for the size of this current bundle. */
1168 CheckOverflow(buf, 20);
1169 *((int4byte *)buf->bufptr) = 0xaaaaaaaa;
1170 buf->prevCounts[buf->bundleDepth] = (int4byte *)buf->bufptr;
1171
1172 buf->bufptr += 4;
1173 }
1174
1175 buf->bufptr += OSC_padString(buf->bufptr, "#bundle");
1176
1177
1178 *((OSCTimeTag *) buf->bufptr) = tt;
1179
1180 if (htonl(1) != 1) {
1181 /* Byte swap the 8-byte integer time tag */
1182 int4byte *intp = (int4byte *)buf->bufptr;
1183 intp[0] = htonl(intp[0]);
1184 intp[1] = htonl(intp[1]);
1185
1186#ifdef HAS8BYTEINT
1187 { /* tt is a 64-bit int so we have to swap the two 32-bit words.
1188 (Otherwise tt is a struct of two 32-bit words, and even though
1189 each word was wrong-endian, they were in the right order
1190 in the struct.) */
1191 int4byte temp = intp[0];
1192 intp[0] = intp[1];
1193 intp[1] = temp;
1194 }
1195#endif
1196 }
1197
1198 buf->bufptr += sizeof(OSCTimeTag);
1199
1200 buf->state = NEED_COUNT;
1201
1202 buf->gettingFirstUntypedArg = 0;
1203 buf->typeStringPtr = 0;
1204 return 0;
1205}
1206
1207
1208int OSC_closeBundle(OSCbuf *buf) {
1209 if (buf->bundleDepth == 0) {
1210 /* This handles EMPTY, ONE_MSG, ARGS, and DONE */
1211 OSC_errorMessage = "Can't close bundle; no bundle is open!";
1212 return 5;
1213 }
1214
1215 if (CheckTypeTag(buf, '\0')) return 9;
1216
1217 if (buf->state == GET_ARGS) {
1218 PatchMessageSize(buf);
1219 }
1220
1221 if (buf->bundleDepth == 1) {
1222 /* Closing the last bundle: No bundle size to patch */
1223 buf->state = DONE;
1224 } else {
1225 /* Closing a sub-bundle: patch bundle size */
1226 int size = buf->bufptr - ((char *) buf->prevCounts[buf->bundleDepth]) - 4;
1227 *(buf->prevCounts[buf->bundleDepth]) = htonl(size);
1228 buf->state = NEED_COUNT;
1229 }
1230
1231 --buf->bundleDepth;
1232 buf->gettingFirstUntypedArg = 0;
1233 buf->typeStringPtr = 0;
1234 return 0;
1235}
1236
1237
1238int OSC_closeAllBundles(OSCbuf *buf) {
1239 if (buf->bundleDepth == 0) {
1240 /* This handles EMPTY, ONE_MSG, ARGS, and DONE */
1241 OSC_errorMessage = "Can't close all bundles; no bundle is open!";
1242 return 6;
1243 }
1244
1245 if (CheckTypeTag(buf, '\0')) return 9;
1246
1247 while (buf->bundleDepth > 0) {
1248 OSC_closeBundle(buf);
1249 }
1250 buf->typeStringPtr = 0;
1251 return 0;
1252}
1253
1254int OSC_writeAddress(OSCbuf *buf, char *name) {
1255 int4byte paddedLength;
1256
1257 if (buf->state == ONE_MSG_ARGS) {
1258 OSC_errorMessage = "This packet is not a bundle, so you can't write another address";
1259 return 7;
1260 }
1261
1262 if (buf->state == DONE) {
1263 OSC_errorMessage = "This packet is finished; can't write another address";
1264 return 8;
1265 }
1266
1267 if (CheckTypeTag(buf, '\0')) return 9;
1268
1269 paddedLength = OSC_effectiveStringLength(name);
1270
1271 if (buf->state == EMPTY) {
1272 /* This will be a one-message packet, so no sizes to worry about */
1273 CheckOverflow(buf, paddedLength);
1274 buf->state = ONE_MSG_ARGS;
1275 } else {
1276 /* GET_ARGS or NEED_COUNT */
1277 CheckOverflow(buf, 4+paddedLength);
1278 if (buf->state == GET_ARGS) {
1279 /* Close the old message */
1280 PatchMessageSize(buf);
1281 }
1282 buf->thisMsgSize = (int4byte *)buf->bufptr;
1283 *(buf->thisMsgSize) = 0xbbbbbbbb;
1284 buf->bufptr += 4;
1285 buf->state = GET_ARGS;
1286 }
1287
1288 /* Now write the name */
1289 buf->bufptr += OSC_padString(buf->bufptr, name);
1290 buf->typeStringPtr = 0;
1291 buf->gettingFirstUntypedArg = 1;
1292
1293 return 0;
1294}
1295
1296int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types) {
1297 int result;
1298 int4byte paddedLength;
1299
1300 if (CheckTypeTag(buf, '\0')) return 9;
1301
1302 result = OSC_writeAddress(buf, name);
1303
1304 if (result) return result;
1305
1306 paddedLength = OSC_effectiveStringLength(types);
1307
1308 CheckOverflow(buf, paddedLength);
1309
1310 buf->typeStringPtr = buf->bufptr + 1; /* skip comma */
1311 buf->bufptr += OSC_padString(buf->bufptr, types);
1312
1313 buf->gettingFirstUntypedArg = 0;
1314 return 0;
1315}
1316
1317static int CheckTypeTag(OSCbuf *buf, char expectedType) {
1318 if (buf->typeStringPtr) {
1319 if (*(buf->typeStringPtr) != expectedType) {
1320 if (expectedType == '\0') {
1321 OSC_errorMessage =
1322 "According to the type tag I expected more arguments.";
1323 } else if (*(buf->typeStringPtr) == '\0') {
1324 OSC_errorMessage =
1325 "According to the type tag I didn't expect any more arguments.";
1326 } else {
1327 OSC_errorMessage =
1328 "According to the type tag I expected an argument of a different type.";
1329 printf("* Expected %c, string now %s\n", expectedType, buf->typeStringPtr);
1330 }
1331 return 9;
1332 }
1333 ++(buf->typeStringPtr);
1334 }
1335 return 0;
1336}
1337
1338
1339int OSC_writeFloatArg(OSCbuf *buf, float arg) {
1340 int4byte *intp;
1341 //int result;
1342
1343 CheckOverflow(buf, 4);
1344
1345 if (CheckTypeTag(buf, 'f')) return 9;
1346
1347 /* Pretend arg is a long int so we can use htonl() */
1348 intp = ((int4byte *) &arg);
1349 *((int4byte *) buf->bufptr) = htonl(*intp);
1350
1351 buf->bufptr += 4;
1352
1353 buf->gettingFirstUntypedArg = 0;
1354 return 0;
1355}
1356
1357
1358
1359int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args) {
1360 int i;
1361 int4byte *intp;
1362
1363 CheckOverflow(buf, 4 * numFloats);
1364
1365 /* Pretend args are long ints so we can use htonl() */
1366 intp = ((int4byte *) args);
1367
1368 for (i = 0; i < numFloats; i++) {
1369 if (CheckTypeTag(buf, 'f')) return 9;
1370 *((int4byte *) buf->bufptr) = htonl(intp[i]);
1371 buf->bufptr += 4;
1372 }
1373
1374 buf->gettingFirstUntypedArg = 0;
1375 return 0;
1376}
1377
1378int OSC_writeIntArg(OSCbuf *buf, int4byte arg) {
1379 CheckOverflow(buf, 4);
1380 if (CheckTypeTag(buf, 'i')) return 9;
1381
1382 *((int4byte *) buf->bufptr) = htonl(arg);
1383 buf->bufptr += 4;
1384
1385 buf->gettingFirstUntypedArg = 0;
1386 return 0;
1387}
1388
1389int OSC_writeStringArg(OSCbuf *buf, char *arg) {
1390 int len;
1391
1392 if (CheckTypeTag(buf, 's')) return 9;
1393
1394 len = OSC_effectiveStringLength(arg);
1395
1396 if (buf->gettingFirstUntypedArg && arg[0] == ',') {
1397 /* This un-type-tagged message starts with a string
1398 that starts with a comma, so we have to escape it
1399 (with a double comma) so it won't look like a type
1400 tag string. */
1401
1402 CheckOverflow(buf, len+4); /* Too conservative */
1403 buf->bufptr +=
1404 OSC_padStringWithAnExtraStupidComma(buf->bufptr, arg);
1405
1406 } else {
1407 CheckOverflow(buf, len);
1408 buf->bufptr += OSC_padString(buf->bufptr, arg);
1409 }
1410
1411 buf->gettingFirstUntypedArg = 0;
1412 return 0;
1413
1414}
1415
1416/* String utilities */
1417
1418#define STRING_ALIGN_PAD 4
1419int OSC_effectiveStringLength(char *string) {
1420 int len = strlen(string) + 1; /* We need space for the null char. */
1421
1422 /* Round up len to next multiple of STRING_ALIGN_PAD to account for alignment padding */
1423 if ((len % STRING_ALIGN_PAD) != 0) {
1424 len += STRING_ALIGN_PAD - (len % STRING_ALIGN_PAD);
1425 }
1426 return len;
1427}
1428
1429static int OSC_padString(char *dest, char *str) {
1430 int i;
1431
1432 for (i = 0; str[i] != '\0'; i++) {
1433 dest[i] = str[i];
1434 }
1435
1436 return OSC_WritePadding(dest, i);
1437}
1438
1439static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str) {
1440 int i;
1441
1442 dest[0] = ',';
1443 for (i = 0; str[i] != '\0'; i++) {
1444 dest[i+1] = str[i];
1445 }
1446
1447 return OSC_WritePadding(dest, i+1);
1448}
1449
1450static int OSC_WritePadding(char *dest, int i) {
1451 dest[i] = '\0';
1452 i++;
1453
1454 for (; (i % STRING_ALIGN_PAD) != 0; i++) {
1455 dest[i] = '\0';
1456 }
1457
1458 return i;
1459}
1460
1461
diff --git a/apps/plugins/pdbox/PDa/extra/sformat.h b/apps/plugins/pdbox/PDa/extra/sformat.h
deleted file mode 100644
index 93d353785b..0000000000
--- a/apps/plugins/pdbox/PDa/extra/sformat.h
+++ /dev/null
@@ -1,56 +0,0 @@
1
2#ifndef SFORMAT_H__
3#define SFORMAT_H__
4
5typedef unsigned short uint16;
6typedef unsigned long uint32;
7
8#define FORMAT_WAVE 0
9#define FORMAT_AIFF 1
10#define FORMAT_NEXT 2
11
12/* the NeXTStep sound header structure; can be big or little endian */
13
14typedef struct _nextstep
15{
16 char ns_fileid[4]; /* magic number '.snd' if file is big-endian */
17 uint32 ns_onset; /* byte offset of first sample */
18 uint32 ns_length; /* length of sound in bytes */
19 uint32 ns_format; /* format; see below */
20 uint32 ns_sr; /* sample rate */
21 uint32 ns_nchans; /* number of channels */
22 char ns_info[4]; /* comment */
23} t_nextstep;
24
25#define NS_FORMAT_LINEAR_16 3
26#define NS_FORMAT_LINEAR_24 4
27#define NS_FORMAT_FLOAT 6
28#define SCALE (1./(1024. * 1024. * 1024. * 2.))
29
30/* the WAVE header. All Wave files are little endian. We assume
31 the "fmt" chunk comes first which is usually the case but perhaps not
32 always; same for AIFF and the "COMM" chunk. */
33
34typedef unsigned word;
35typedef unsigned long dword;
36
37typedef struct _wave
38{
39 char w_fileid[4]; /* chunk id 'RIFF' */
40 uint32 w_chunksize; /* chunk size */
41 char w_waveid[4]; /* wave chunk id 'WAVE' */
42 char w_fmtid[4]; /* format chunk id 'fmt ' */
43 uint32 w_fmtchunksize; /* format chunk size */
44 uint16 w_fmttag; /* format tag, 1 for PCM */
45 uint16 w_nchannels; /* number of channels */
46 uint32 w_samplespersec; /* sample rate in hz */
47 uint32 w_navgbytespersec; /* average bytes per second */
48 uint16 w_nblockalign; /* number of bytes per sample */
49 uint16 w_nbitspersample; /* number of bits in a sample */
50 char w_datachunkid[4]; /* data chunk id 'data' */
51 uint32 w_datachunksize; /* length of data chunk */
52} t_wave;
53
54
55#endif
56
diff --git a/apps/plugins/pdbox/PDa/extra/shell.c b/apps/plugins/pdbox/PDa/extra/shell.c
deleted file mode 100644
index 8653c63ff4..0000000000
--- a/apps/plugins/pdbox/PDa/extra/shell.c
+++ /dev/null
@@ -1,312 +0,0 @@
1/* (C) Guenter Geiger <geiger@epy.co.at> */
2
3#include "../src/m_pd.h"
4#ifdef NT
5#pragma warning( disable : 4244 )
6#pragma warning( disable : 4305 )
7#endif
8
9#include <unistd.h>
10#include <stdlib.h>
11#include <string.h>
12#include <stdio.h>
13#include <sys/types.h>
14#include <sys/wait.h>
15#include <signal.h>
16#include <sched.h>
17
18void sys_rmpollfn(int fd);
19void sys_addpollfn(int fd, void* fn, void *ptr);
20
21/* ------------------------ shell ----------------------------- */
22
23#define INBUFSIZE 1024
24
25static t_class *shell_class;
26
27
28static void drop_priority(void)
29{
30#ifdef _POSIX_PRIORITY_SCHEDULING
31 struct sched_param par;
32 int p1 ,p2, p3;
33 par.sched_priority = 0;
34 sched_setscheduler(0,SCHED_OTHER,&par);
35#endif
36}
37
38
39typedef struct _shell
40{
41 t_object x_obj;
42 int x_echo;
43 char *sr_inbuf;
44 int sr_inhead;
45 int sr_intail;
46 void* x_binbuf;
47 int fdpipe[2];
48 int fdinpipe[2];
49 int pid;
50 int x_del;
51 t_outlet* x_done;
52 t_clock* x_clock;
53} t_shell;
54
55static int shell_pid;
56
57
58void shell_cleanup(t_shell* x)
59{
60 sys_rmpollfn(x->fdpipe[0]);
61
62 if (x->fdpipe[0]>0) close(x->fdpipe[0]);
63 if (x->fdpipe[1]>0) close(x->fdpipe[1]);
64 if (x->fdinpipe[0]>0) close(x->fdinpipe[0]);
65 if (x->fdinpipe[1]>0) close(x->fdinpipe[1]);
66
67 x->fdpipe[0] = -1;
68 x->fdpipe[1] = -1;
69 x->fdinpipe[0] = -1;
70 x->fdinpipe[1] = -1;
71 clock_unset(x->x_clock);
72}
73
74void shell_check(t_shell* x)
75{
76 int ret;
77 int status;
78 ret = waitpid(x->pid,&status,WNOHANG);
79 if (ret == x->pid) {
80 shell_cleanup(x);
81 if (WIFEXITED(status)) {
82 outlet_float(x->x_done,WEXITSTATUS(status));
83 }
84 else outlet_float(x->x_done,0);
85 }
86 else {
87 if (x->x_del < 100) x->x_del+=2; /* increment poll times */
88 clock_delay(x->x_clock,x->x_del);
89 }
90}
91
92
93void shell_bang(t_shell *x)
94{
95 post("bang");
96}
97
98/* snippet from pd's code */
99static void shell_doit(void *z, t_binbuf *b)
100{
101 t_shell *x = (t_shell *)z;
102 int msg, natom = binbuf_getnatom(b);
103 t_atom *at = binbuf_getvec(b);
104
105 for (msg = 0; msg < natom;)
106 {
107 int emsg;
108 for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
109 && at[emsg].a_type != A_SEMI; emsg++)
110 ;
111 if (emsg > msg)
112 {
113 int i;
114 for (i = msg; i < emsg; i++)
115 if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
116 {
117 pd_error(x, "netreceive: got dollar sign in message");
118 goto nodice;
119 }
120 if (at[msg].a_type == A_FLOAT)
121 {
122 if (emsg > msg + 1)
123 outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
124 else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
125 }
126 else if (at[msg].a_type == A_SYMBOL)
127 outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
128 emsg-msg-1, at + msg + 1);
129 }
130 nodice:
131 msg = emsg + 1;
132 }
133}
134
135
136void shell_read(t_shell *x, int fd)
137{
138 char buf[INBUFSIZE];
139 t_binbuf* bbuf = binbuf_new();
140 int i;
141 int readto =
142 (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
143 int ret;
144
145 ret = read(fd, buf,INBUFSIZE-1);
146 buf[ret] = '\0';
147
148 for (i=0;i<ret;i++)
149 if (buf[i] == '\n') buf[i] = ';';
150 if (ret < 0)
151 {
152 error("shell: pipe read error");
153 sys_rmpollfn(fd);
154 x->fdpipe[0] = -1;
155 close(fd);
156 return;
157 }
158 else if (ret == 0)
159 {
160 post("EOF on socket %d\n", fd);
161 sys_rmpollfn(fd);
162 x->fdpipe[0] = -1;
163 close(fd);
164 return;
165 }
166 else
167 {
168 int natom;
169 t_atom *at;
170 binbuf_text(bbuf, buf, strlen(buf));
171
172 natom = binbuf_getnatom(bbuf);
173 at = binbuf_getvec(bbuf);
174 shell_doit(x,bbuf);
175 }
176 binbuf_free(bbuf);
177}
178
179
180static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at)
181{
182 int i;
183 char tmp[MAXPDSTRING];
184 int size = 0;
185
186 if (x->fdinpipe[0] == -1) return; /* nothing to send to */
187
188 for (i=0;i<ac;i++) {
189 atom_string(at,tmp+size,MAXPDSTRING - size);
190 at++;
191 size=strlen(tmp);
192 tmp[size++] = ' ';
193 }
194 tmp[size-1] = '\0';
195 post("sending %s",tmp);
196 write(x->fdinpipe[0],tmp,strlen(tmp));
197}
198
199static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
200{
201 int i;
202 char* argv[20];
203 t_symbol* sym;
204
205 if (!strcmp(s->s_name,"send")) {
206 post("send");
207 shell_send(x,s,ac,at);
208 return;
209 }
210
211 argv[0] = s->s_name;
212
213 if (x->fdpipe[0] != -1) {
214 post("shell: old process still running");
215 kill(x->pid,SIGKILL);
216 shell_cleanup(x);
217 }
218
219
220 if (pipe(x->fdpipe) < 0) {
221 error("unable to create pipe");
222 return;
223 }
224
225 if (pipe(x->fdinpipe) < 0) {
226 error("unable to create input pipe");
227 return;
228 }
229
230
231 sys_addpollfn(x->fdpipe[0],shell_read,x);
232
233 if (!(x->pid = fork())) {
234 int status;
235 char* cmd = getbytes(1024);
236 char* tcmd = getbytes(1024);
237 strcpy(cmd,s->s_name);
238
239#if 0
240 for (i=1;i<=ac;i++) {
241 argv[i] = getbytes(255);
242 atom_string(at,argv[i],255);
243/* post("argument %s",argv[i]); */
244 at++;
245 }
246 argv[i] = 0;
247#endif
248 for (i=1;i<=ac;i++) {
249 atom_string(at,tcmd,255);
250 strcat(cmd," ");
251 strcat(cmd,tcmd);
252 at++;
253 }
254
255
256 /* reassign stdout */
257 dup2(x->fdpipe[1],1);
258 dup2(x->fdinpipe[1],0);
259
260 /* drop privileges */
261 drop_priority();
262 seteuid(getuid()); /* lose setuid priveliges */
263
264 post("executing %s",cmd);
265 system(cmd);
266// execvp(s->s_name,argv);
267 exit(0);
268 }
269 x->x_del = 4;
270 clock_delay(x->x_clock,x->x_del);
271
272 if (x->x_echo)
273 outlet_anything(x->x_obj.ob_outlet, s, ac, at);
274}
275
276
277
278void shell_free(t_shell* x)
279{
280 binbuf_free(x->x_binbuf);
281}
282
283static void *shell_new(void)
284{
285 t_shell *x = (t_shell *)pd_new(shell_class);
286
287 x->x_echo = 0;
288 x->fdpipe[0] = -1;
289 x->fdpipe[1] = -1;
290 x->fdinpipe[0] = -1;
291 x->fdinpipe[1] = -1;
292
293 x->sr_inhead = x->sr_intail = 0;
294 if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
295
296 x->x_binbuf = binbuf_new();
297
298 outlet_new(&x->x_obj, &s_list);
299 x->x_done = outlet_new(&x->x_obj, &s_bang);
300 x->x_clock = clock_new(x, (t_method) shell_check);
301 return (x);
302}
303
304void shell_setup(void)
305{
306 shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
307 (t_method)shell_free,sizeof(t_shell), 0,0);
308 class_addbang(shell_class,shell_bang);
309 class_addanything(shell_class, shell_anything);
310}
311
312
diff --git a/apps/plugins/pdbox/PDa/extra/slider.c b/apps/plugins/pdbox/PDa/extra/slider.c
deleted file mode 100644
index 9c49eeb17a..0000000000
--- a/apps/plugins/pdbox/PDa/extra/slider.c
+++ /dev/null
@@ -1,54 +0,0 @@
1#include <stdio.h>
2#include "../src/m_pd.h"
3#include "g_canvas.h" /* for widgetbehaviour */
4#include "fatom.h"
5
6static t_class *slider_class;
7
8static void slider_save(t_gobj *z, t_binbuf *b)
9{
10 t_fatom *x = (t_fatom *)z;
11
12 binbuf_addv(b, "ssiisiiisss", gensym("#X"),gensym("obj"),
13 x->x_obj.te_xpix, x->x_obj.te_ypix ,
14 gensym("slider"),x->x_max,x->x_min,x->x_width,x->x_send,x->x_color,x->x_bgcolor);
15 binbuf_addv(b, ";");
16}
17
18
19static void *slider_new(t_symbol* s,t_int argc, t_atom* argv)
20{
21 t_fatom *x = (t_fatom *)pd_new(slider_class);
22 x->x_type = gensym("vslider");
23 return fatom_new(x,argc,argv);
24}
25
26
27t_widgetbehavior slider_widgetbehavior;
28
29
30void slider_setup(void) {
31 slider_class = class_new(gensym("slider"), (t_newmethod)slider_new, 0,
32 sizeof(t_fatom),0,A_GIMME,0);
33
34 slider_widgetbehavior.w_getrectfn = fatom_getrect;
35 slider_widgetbehavior.w_displacefn = fatom_displace;
36 slider_widgetbehavior.w_selectfn = fatom_select;
37 slider_widgetbehavior.w_activatefn = fatom_activate;
38 slider_widgetbehavior.w_deletefn = fatom_delete;
39 slider_widgetbehavior.w_visfn= fatom_vis;
40 slider_widgetbehavior.w_clickfn = NULL;
41
42 fatom_setup_common(slider_class);
43 class_setwidget(slider_class,&slider_widgetbehavior);
44
45#if PD_MINOR_VERSION < 37
46 slider_widgetbehavior.w_savefn = slider_save;
47 slider_widgetbehavior.w_propertiesfn = NULL;
48#else
49 class_setsavefn(slider_class,&slider_save);
50 class_setpropertiesfn(slider_class,&fatom_properties);
51#endif
52
53}
54
diff --git a/apps/plugins/pdbox/PDa/extra/sliderh.c b/apps/plugins/pdbox/PDa/extra/sliderh.c
deleted file mode 100644
index ef3d096cf6..0000000000
--- a/apps/plugins/pdbox/PDa/extra/sliderh.c
+++ /dev/null
@@ -1,64 +0,0 @@
1#include "../src/m_pd.h"
2#include "g_canvas.h"
3
4
5#ifdef NT
6#pragma warning( disable : 4244 )
7#pragma warning( disable : 4305 )
8#endif
9
10#include "fatom.h"
11
12/* can we use the normal text save function ?? */
13
14static t_class *sliderh_class;
15
16static void sliderh_save(t_gobj *z, t_binbuf *b)
17{
18
19 t_fatom *x = (t_fatom *)z;
20
21 binbuf_addv(b, "ssiisiiisss", gensym("#X"),gensym("obj"),
22 x->x_obj.te_xpix, x->x_obj.te_ypix ,
23 gensym("sliderh"),x->x_max,x->x_min,x->x_width,x->x_send,x->x_color,x->x_bgcolor);
24 binbuf_addv(b, ";");
25}
26
27
28static void *sliderh_new(t_symbol* s, int argc, t_atom* argv)
29{
30 t_fatom *x = (t_fatom *)pd_new(sliderh_class);
31 x->x_type = gensym("hslider");
32 return fatom_new(x,argc,argv);
33}
34
35
36t_widgetbehavior sliderh_widgetbehavior;
37
38
39
40
41void sliderh_setup(void) {
42 sliderh_class = class_new(gensym("sliderh"), (t_newmethod)sliderh_new, 0,
43 sizeof(t_fatom),0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
44
45 fatom_setup_common(sliderh_class);
46
47 sliderh_widgetbehavior.w_getrectfn = fatom_getrect;
48 sliderh_widgetbehavior.w_displacefn= fatom_displace;
49 sliderh_widgetbehavior.w_selectfn= fatom_select;
50 sliderh_widgetbehavior.w_activatefn=fatom_activate;
51 sliderh_widgetbehavior.w_deletefn= fatom_delete;
52 sliderh_widgetbehavior.w_visfn= fatom_vis;
53#if PD_MINOR_VERSION < 37
54 sliderh_widgetbehavior.w_savefn= sliderh_save;
55 sliderh_widgetbehavior.w_propertiesfn= NULL;
56#endif
57 sliderh_widgetbehavior.w_clickfn= NULL;
58
59 class_setwidget(sliderh_class,&sliderh_widgetbehavior);
60#if PD_MINOR_VERSION >= 37
61 class_setsavefn(sliderh_class,&sliderh_save);
62#endif
63}
64
diff --git a/apps/plugins/pdbox/PDa/extra/test-clip.pd b/apps/plugins/pdbox/PDa/extra/test-clip.pd
deleted file mode 100644
index ed6c0c8396..0000000000
--- a/apps/plugins/pdbox/PDa/extra/test-clip.pd
+++ /dev/null
@@ -1,14 +0,0 @@
1#N canvas 0 0 240 300 10;
2#X obj 57 84 clip~ -0.1 0.1;
3#X obj 58 61 sig~;
4#X obj 57 111 snapshot~;
5#X floatatom 58 19 5 0 0 0 - - -;
6#X floatatom 57 144 5 0 0 0 - - -;
7#X obj 58 37 t f b;
8#X connect 0 0 2 0;
9#X connect 1 0 0 0;
10#X connect 2 0 4 0;
11#X connect 3 0 5 0;
12#X connect 5 0 1 0;
13#X connect 5 1 2 0;
14
diff --git a/apps/plugins/pdbox/PDa/extra/test-vcf.pd b/apps/plugins/pdbox/PDa/extra/test-vcf.pd
deleted file mode 100644
index 5f1b29381a..0000000000
--- a/apps/plugins/pdbox/PDa/extra/test-vcf.pd
+++ /dev/null
@@ -1,19 +0,0 @@
1#N canvas 0 0 240 300 10;
2#X obj 38 93 noise~;
3#X obj 44 161 vcf~;
4#X obj 48 191 dac~;
5#X floatatom 138 33 5 0 0 0 - - -;
6#X obj 44 18 osc~ 1;
7#X obj 46 75 *~ 800;
8#X obj 48 48 +~ 2;
9#X obj 106 125 sig~;
10#X floatatom 132 77 5 0 0 0 - - -;
11#X connect 0 0 1 0;
12#X connect 1 0 2 0;
13#X connect 1 0 2 1;
14#X connect 3 0 1 2;
15#X connect 4 0 6 0;
16#X connect 6 0 5 0;
17#X connect 7 0 1 1;
18#X connect 8 0 7 0;
19
diff --git a/apps/plugins/pdbox/PDa/intern/sig~.c b/apps/plugins/pdbox/PDa/intern/sig~.c
deleted file mode 100644
index 1cff614f7c..0000000000
--- a/apps/plugins/pdbox/PDa/intern/sig~.c
+++ /dev/null
@@ -1,68 +0,0 @@
1#include "../src/m_pd.h"
2#include <../src/m_fixed.h>
3
4static t_class *sig_tilde_class;
5
6typedef struct _sig
7{
8 t_object x_obj;
9 t_sample x_f;
10} t_sig;
11
12static t_int *sig_tilde_perform(t_int *w)
13{
14 t_sample f = *(t_sample *)(w[1]);
15 t_sample *out = (t_sample *)(w[2]);
16 int n = (int)(w[3]);
17 while (n--)
18 *out++ = f;
19 return (w+4);
20}
21
22static t_int *sig_tilde_perf8(t_int *w)
23{
24 t_sample f = *(t_sample *)(w[1]);
25 t_sample *out = (t_sample *)(w[2]);
26 int n = (int)(w[3]);
27
28 for (; n; n -= 8, out += 8)
29 {
30 out[0] = f;
31 out[1] = f;
32 out[2] = f;
33 out[3] = f;
34 out[4] = f;
35 out[5] = f;
36 out[6] = f;
37 out[7] = f;
38 }
39 return (w+4);
40}
41
42
43static void sig_tilde_float(t_sig *x, t_float f)
44{
45 x->x_f = ftofix(f);
46}
47
48static void sig_tilde_dsp(t_sig *x, t_signal **sp)
49{
50 dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n);
51}
52
53static void *sig_tilde_new(t_floatarg f)
54{
55 t_sig *x = (t_sig *)pd_new(sig_tilde_class);
56 x->x_f = ftofix(f);
57 outlet_new(&x->x_obj, gensym("signal"));
58 return (x);
59}
60
61void sig_tilde_setup(void)
62{
63 sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0,
64 sizeof(t_sig), 0, A_DEFFLOAT, 0);
65 class_addfloat(sig_tilde_class, (t_method)sig_tilde_float);
66 class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0);
67}
68
diff --git a/apps/plugins/pdbox/PDa/src/build.ipod b/apps/plugins/pdbox/PDa/src/build.ipod
deleted file mode 100644
index 5d940bf56e..0000000000
--- a/apps/plugins/pdbox/PDa/src/build.ipod
+++ /dev/null
@@ -1,6 +0,0 @@
1
2# The compiler for iPod has a bug with -O6, thats why we try to compile twice
3
4make CFLAGS="-O6 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi " -k ipod
5make CFLAGS="-O2 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi" ipod
6
diff --git a/apps/plugins/pdbox/PDa/src/d_array.c b/apps/plugins/pdbox/PDa/src/d_array.c
deleted file mode 100644
index 7139e4dc3d..0000000000
--- a/apps/plugins/pdbox/PDa/src/d_array.c
+++ /dev/null
@@ -1,1074 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* sampling */
6
7/* LATER make tabread4 and tabread~ */
8
9#include "m_pd.h"
10
11
12/* ------------------------- tabwrite~ -------------------------- */
13
14static t_class *tabwrite_tilde_class;
15
16typedef struct _tabwrite_tilde
17{
18 t_object x_obj;
19 int x_phase;
20 int x_nsampsintab;
21 float *x_vec;
22 t_symbol *x_arrayname;
23 t_clock *x_clock;
24 float x_f;
25} t_tabwrite_tilde;
26
27static void tabwrite_tilde_tick(t_tabwrite_tilde *x);
28
29static void *tabwrite_tilde_new(t_symbol *s)
30{
31 t_tabwrite_tilde *x = (t_tabwrite_tilde *)pd_new(tabwrite_tilde_class);
32 x->x_clock = clock_new(x, (t_method)tabwrite_tilde_tick);
33 x->x_phase = 0x7fffffff;
34 x->x_arrayname = s;
35 x->x_f = 0;
36 return (x);
37}
38
39static t_int *tabwrite_tilde_perform(t_int *w)
40{
41 t_tabwrite_tilde *x = (t_tabwrite_tilde *)(w[1]);
42 t_float *in = (t_float *)(w[2]);
43 int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
44 if (!x->x_vec) goto bad;
45
46 if (endphase > phase)
47 {
48 int nxfer = endphase - phase;
49 float *fp = x->x_vec + phase;
50 if (nxfer > n) nxfer = n;
51 phase += nxfer;
52 while (nxfer--)
53 {
54 float f = *in++;
55 if (PD_BIGORSMALL(f))
56 f = 0;
57 *fp++ = f;
58 }
59 if (phase >= endphase)
60 {
61 clock_delay(x->x_clock, 0);
62 phase = 0x7fffffff;
63 }
64 x->x_phase = phase;
65 }
66bad:
67 return (w+4);
68}
69
70void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s)
71{
72 t_garray *a;
73
74 x->x_arrayname = s;
75 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
76 {
77 if (*s->s_name) pd_error(x, "tabwrite~: %s: no such array",
78 x->x_arrayname->s_name);
79 x->x_vec = 0;
80 }
81 else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
82 {
83 pd_error(x, "%s: bad template for tabwrite~", x->x_arrayname->s_name);
84 x->x_vec = 0;
85 }
86 else garray_usedindsp(a);
87}
88
89static void tabwrite_tilde_dsp(t_tabwrite_tilde *x, t_signal **sp)
90{
91 tabwrite_tilde_set(x, x->x_arrayname);
92 dsp_add(tabwrite_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
93}
94
95static void tabwrite_tilde_bang(t_tabwrite_tilde *x)
96{
97 x->x_phase = 0;
98}
99
100static void tabwrite_tilde_stop(t_tabwrite_tilde *x)
101{
102 if (x->x_phase != 0x7fffffff)
103 {
104 tabwrite_tilde_tick(x);
105 x->x_phase = 0x7fffffff;
106 }
107}
108
109static void tabwrite_tilde_tick(t_tabwrite_tilde *x)
110{
111 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
112 if (!a) bug("tabwrite_tilde_tick");
113 else garray_redraw(a);
114}
115
116static void tabwrite_tilde_free(t_tabwrite_tilde *x)
117{
118 clock_free(x->x_clock);
119}
120
121static void tabwrite_tilde_setup(void)
122{
123 tabwrite_tilde_class = class_new(gensym("tabwrite~"),
124 (t_newmethod)tabwrite_tilde_new, (t_method)tabwrite_tilde_free,
125 sizeof(t_tabwrite_tilde), 0, A_DEFSYM, 0);
126 CLASS_MAINSIGNALIN(tabwrite_tilde_class, t_tabwrite_tilde, x_f);
127 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_dsp,
128 gensym("dsp"), 0);
129 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_set,
130 gensym("set"), A_SYMBOL, 0);
131 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_stop,
132 gensym("stop"), 0);
133 class_addbang(tabwrite_tilde_class, tabwrite_tilde_bang);
134}
135
136/* ------------ tabplay~ - non-transposing sample playback --------------- */
137
138static t_class *tabplay_tilde_class;
139
140typedef struct _tabplay_tilde
141{
142 t_object x_obj;
143 t_outlet *x_bangout;
144 int x_phase;
145 int x_nsampsintab;
146 int x_limit;
147 float *x_vec;
148 t_symbol *x_arrayname;
149 t_clock *x_clock;
150} t_tabplay_tilde;
151
152static void tabplay_tilde_tick(t_tabplay_tilde *x);
153
154static void *tabplay_tilde_new(t_symbol *s)
155{
156 t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class);
157 x->x_clock = clock_new(x, (t_method)tabplay_tilde_tick);
158 x->x_phase = 0x7fffffff;
159 x->x_limit = 0;
160 x->x_arrayname = s;
161 outlet_new(&x->x_obj, &s_signal);
162 x->x_bangout = outlet_new(&x->x_obj, &s_bang);
163 return (x);
164}
165
166static t_int *tabplay_tilde_perform(t_int *w)
167{
168 t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]);
169 t_float *out = (t_float *)(w[2]), *fp;
170 int n = (int)(w[3]), phase = x->x_phase,
171 endphase = (x->x_nsampsintab < x->x_limit ?
172 x->x_nsampsintab : x->x_limit), nxfer, n3;
173 if (!x->x_vec || phase >= endphase)
174 goto zero;
175
176 nxfer = endphase - phase;
177 fp = x->x_vec + phase;
178 if (nxfer > n)
179 nxfer = n;
180 n3 = n - nxfer;
181 phase += nxfer;
182 while (nxfer--)
183 *out++ = *fp++;
184 if (phase >= endphase)
185 {
186 clock_delay(x->x_clock, 0);
187 x->x_phase = 0x7fffffff;
188 while (n3--)
189 *out++ = 0;
190 }
191 else x->x_phase = phase;
192
193 return (w+4);
194zero:
195 while (n--) *out++ = 0;
196 return (w+4);
197}
198
199void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s)
200{
201 t_garray *a;
202
203 x->x_arrayname = s;
204 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
205 {
206 if (*s->s_name) pd_error(x, "tabplay~: %s: no such array",
207 x->x_arrayname->s_name);
208 x->x_vec = 0;
209 }
210 else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
211 {
212 pd_error(x, "%s: bad template for tabplay~", x->x_arrayname->s_name);
213 x->x_vec = 0;
214 }
215 else garray_usedindsp(a);
216}
217
218static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp)
219{
220 tabplay_tilde_set(x, x->x_arrayname);
221 dsp_add(tabplay_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
222}
223
224static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s,
225 int argc, t_atom *argv)
226{
227 long start = atom_getfloatarg(0, argc, argv);
228 long length = atom_getfloatarg(1, argc, argv);
229 if (start < 0) start = 0;
230 if (length <= 0)
231 x->x_limit = 0x7fffffff;
232 else
233 x->x_limit = start + length;
234 x->x_phase = start;
235}
236
237static void tabplay_tilde_stop(t_tabplay_tilde *x)
238{
239 x->x_phase = 0x7fffffff;
240}
241
242static void tabplay_tilde_tick(t_tabplay_tilde *x)
243{
244 outlet_bang(x->x_bangout);
245}
246
247static void tabplay_tilde_free(t_tabplay_tilde *x)
248{
249 clock_free(x->x_clock);
250}
251
252static void tabplay_tilde_setup(void)
253{
254 tabplay_tilde_class = class_new(gensym("tabplay~"),
255 (t_newmethod)tabplay_tilde_new, (t_method)tabplay_tilde_free,
256 sizeof(t_tabplay_tilde), 0, A_DEFSYM, 0);
257 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_dsp,
258 gensym("dsp"), 0);
259 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_stop,
260 gensym("stop"), 0);
261 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_set,
262 gensym("set"), A_DEFSYM, 0);
263 class_addlist(tabplay_tilde_class, tabplay_tilde_list);
264}
265
266/******************** tabread~ ***********************/
267
268static t_class *tabread_tilde_class;
269
270typedef struct _tabread_tilde
271{
272 t_object x_obj;
273 int x_npoints;
274 float *x_vec;
275 t_symbol *x_arrayname;
276 float x_f;
277} t_tabread_tilde;
278
279static void *tabread_tilde_new(t_symbol *s)
280{
281 t_tabread_tilde *x = (t_tabread_tilde *)pd_new(tabread_tilde_class);
282 x->x_arrayname = s;
283 x->x_vec = 0;
284 outlet_new(&x->x_obj, gensym("signal"));
285 x->x_f = 0;
286 return (x);
287}
288
289static t_int *tabread_tilde_perform(t_int *w)
290{
291 t_tabread_tilde *x = (t_tabread_tilde *)(w[1]);
292 t_float *in = (t_float *)(w[2]);
293 t_float *out = (t_float *)(w[3]);
294 int n = (int)(w[4]);
295 int maxindex;
296 float *buf = x->x_vec, *fp;
297 int i;
298
299 maxindex = x->x_npoints - 1;
300 if (!buf) goto zero;
301
302 for (i = 0; i < n; i++)
303 {
304 int index = *in++;
305 if (index < 0)
306 index = 0;
307 else if (index > maxindex)
308 index = maxindex;
309 *out++ = buf[index];
310 }
311 return (w+5);
312 zero:
313 while (n--) *out++ = 0;
314
315 return (w+5);
316}
317
318void tabread_tilde_set(t_tabread_tilde *x, t_symbol *s)
319{
320 t_garray *a;
321
322 x->x_arrayname = s;
323 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
324 {
325 if (*s->s_name)
326 pd_error(x, "tabread~: %s: no such array", x->x_arrayname->s_name);
327 x->x_vec = 0;
328 }
329 else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
330 {
331 pd_error(x, "%s: bad template for tabread~", x->x_arrayname->s_name);
332 x->x_vec = 0;
333 }
334 else garray_usedindsp(a);
335}
336
337static void tabread_tilde_dsp(t_tabread_tilde *x, t_signal **sp)
338{
339 tabread_tilde_set(x, x->x_arrayname);
340
341 dsp_add(tabread_tilde_perform, 4, x,
342 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
343
344}
345
346static void tabread_tilde_free(t_tabread_tilde *x)
347{
348}
349
350static void tabread_tilde_setup(void)
351{
352 tabread_tilde_class = class_new(gensym("tabread~"),
353 (t_newmethod)tabread_tilde_new, (t_method)tabread_tilde_free,
354 sizeof(t_tabread_tilde), 0, A_DEFSYM, 0);
355 CLASS_MAINSIGNALIN(tabread_tilde_class, t_tabread_tilde, x_f);
356 class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_dsp,
357 gensym("dsp"), 0);
358 class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_set,
359 gensym("set"), A_SYMBOL, 0);
360}
361
362/******************** tabread4~ ***********************/
363
364static t_class *tabread4_tilde_class;
365
366typedef struct _tabread4_tilde
367{
368 t_object x_obj;
369 int x_npoints;
370 float *x_vec;
371 t_symbol *x_arrayname;
372 float x_f;
373} t_tabread4_tilde;
374
375static void *tabread4_tilde_new(t_symbol *s)
376{
377 t_tabread4_tilde *x = (t_tabread4_tilde *)pd_new(tabread4_tilde_class);
378 x->x_arrayname = s;
379 x->x_vec = 0;
380 outlet_new(&x->x_obj, gensym("signal"));
381 x->x_f = 0;
382 return (x);
383}
384
385static t_int *tabread4_tilde_perform(t_int *w)
386{
387 t_tabread4_tilde *x = (t_tabread4_tilde *)(w[1]);
388 t_float *in = (t_float *)(w[2]);
389 t_float *out = (t_float *)(w[3]);
390 int n = (int)(w[4]);
391 int maxindex;
392 float *buf = x->x_vec, *fp;
393 int i;
394
395 maxindex = x->x_npoints - 3;
396
397 if (!buf) goto zero;
398
399#if 0 /* test for spam -- I'm not ready to deal with this */
400 for (i = 0, xmax = 0, xmin = maxindex, fp = in1; i < n; i++, fp++)
401 {
402 float f = *in1;
403 if (f < xmin) xmin = f;
404 else if (f > xmax) xmax = f;
405 }
406 if (xmax < xmin + x->c_maxextent) xmax = xmin + x->c_maxextent;
407 for (i = 0, splitlo = xmin+ x->c_maxextent, splithi = xmax - x->c_maxextent,
408 fp = in1; i < n; i++, fp++)
409 {
410 float f = *in1;
411 if (f > splitlo && f < splithi) goto zero;
412 }
413#endif
414
415 for (i = 0; i < n; i++)
416 {
417 float findex = *in++;
418 int index = findex;
419 float frac, a, b, c, d, cminusb;
420 static int count;
421 if (index < 1)
422 index = 1, frac = 0;
423 else if (index > maxindex)
424 index = maxindex, frac = 1;
425 else frac = findex - index;
426 fp = buf + index;
427 a = fp[-1];
428 b = fp[0];
429 c = fp[1];
430 d = fp[2];
431 /* if (!i && !(count++ & 1023))
432 post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */
433 cminusb = c-b;
434 *out++ = b + frac * (
435 cminusb - 0.1666667f * (1.-frac) * (
436 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
437 )
438 );
439 }
440 return (w+5);
441 zero:
442 while (n--) *out++ = 0;
443
444 return (w+5);
445}
446
447void tabread4_tilde_set(t_tabread4_tilde *x, t_symbol *s)
448{
449 t_garray *a;
450
451 x->x_arrayname = s;
452 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
453 {
454 if (*s->s_name)
455 pd_error(x, "tabread4~: %s: no such array", x->x_arrayname->s_name);
456 x->x_vec = 0;
457 }
458 else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
459 {
460 pd_error(x, "%s: bad template for tabread4~", x->x_arrayname->s_name);
461 x->x_vec = 0;
462 }
463 else garray_usedindsp(a);
464}
465
466static void tabread4_tilde_dsp(t_tabread4_tilde *x, t_signal **sp)
467{
468 tabread4_tilde_set(x, x->x_arrayname);
469
470 dsp_add(tabread4_tilde_perform, 4, x,
471 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
472
473}
474
475static void tabread4_tilde_free(t_tabread4_tilde *x)
476{
477}
478
479static void tabread4_tilde_setup(void)
480{
481 tabread4_tilde_class = class_new(gensym("tabread4~"),
482 (t_newmethod)tabread4_tilde_new, (t_method)tabread4_tilde_free,
483 sizeof(t_tabread4_tilde), 0, A_DEFSYM, 0);
484 CLASS_MAINSIGNALIN(tabread4_tilde_class, t_tabread4_tilde, x_f);
485 class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_dsp,
486 gensym("dsp"), 0);
487 class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_set,
488 gensym("set"), A_SYMBOL, 0);
489}
490
491/******************** tabosc4~ ***********************/
492
493/* this is all copied from d_osc.c... what include file could this go in? */
494#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
495
496 /* machine-dependent definitions. These ifdefs really
497 should have been by CPU type and not by operating system! */
498#ifdef IRIX
499 /* big-endian. Most significant byte is at low address in memory */
500#define HIOFFSET 0 /* word offset to find MSB */
501#define LOWOFFSET 1 /* word offset to find LSB */
502#define int32 long /* a data type that has 32 bits */
503#else
504#ifdef MSW
505 /* little-endian; most significant byte is at highest address */
506#define HIOFFSET 1
507#define LOWOFFSET 0
508#define int32 long
509#else
510#ifdef __FreeBSD__
511#include <machine/endian.h>
512#if BYTE_ORDER == LITTLE_ENDIAN
513#define HIOFFSET 1
514#define LOWOFFSET 0
515#else
516#define HIOFFSET 0 /* word offset to find MSB */
517#define LOWOFFSET 1 /* word offset to find LSB */
518#endif /* BYTE_ORDER */
519#include <sys/types.h>
520#define int32 int32_t
521#endif
522
523#ifdef __linux__
524#include <endian.h>
525#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
526#error No byte order defined
527#endif
528
529#if __BYTE_ORDER == __LITTLE_ENDIAN
530#define HIOFFSET 1
531#define LOWOFFSET 0
532#else
533#define HIOFFSET 0 /* word offset to find MSB */
534#define LOWOFFSET 1 /* word offset to find LSB */
535#endif /* __BYTE_ORDER */
536
537#include <sys/types.h>
538#define int32 int32_t
539
540#else
541#ifdef MACOSX
542#define HIOFFSET 0 /* word offset to find MSB */
543#define LOWOFFSET 1 /* word offset to find LSB */
544#define int32 int /* a data type that has 32 bits */
545
546#endif /* MACOSX */
547#endif /* __linux__ */
548#endif /* MSW */
549#endif /* SGI */
550
551union tabfudge
552{
553 double tf_d;
554 int32 tf_i[2];
555};
556
557static t_class *tabosc4_tilde_class;
558
559typedef struct _tabosc4_tilde
560{
561 t_object x_obj;
562 float x_fnpoints;
563 float x_finvnpoints;
564 float *x_vec;
565 t_symbol *x_arrayname;
566 float x_f;
567 double x_phase;
568 float x_conv;
569} t_tabosc4_tilde;
570
571static void *tabosc4_tilde_new(t_symbol *s)
572{
573 t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class);
574 x->x_arrayname = s;
575 x->x_vec = 0;
576 x->x_fnpoints = 512.;
577 x->x_finvnpoints = (1./512.);
578 outlet_new(&x->x_obj, gensym("signal"));
579 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
580 x->x_f = 0;
581 return (x);
582}
583
584static t_int *tabosc4_tilde_perform(t_int *w)
585{
586 t_tabosc4_tilde *x = (t_tabosc4_tilde *)(w[1]);
587 t_float *in = (t_float *)(w[2]);
588 t_float *out = (t_float *)(w[3]);
589 int n = (int)(w[4]);
590 int normhipart;
591 union tabfudge tf;
592 float fnpoints = x->x_fnpoints;
593 int mask = fnpoints - 1;
594 float conv = fnpoints * x->x_conv;
595 int maxindex;
596 float *tab = x->x_vec, *addr;
597 int i;
598 double dphase = fnpoints * x->x_phase + UNITBIT32;
599
600 if (!tab) goto zero;
601 tf.tf_d = UNITBIT32;
602 normhipart = tf.tf_i[HIOFFSET];
603
604#if 1
605 while (n--)
606 {
607 float frac, a, b, c, d, cminusb;
608 tf.tf_d = dphase;
609 dphase += *in++ * conv;
610 addr = tab + (tf.tf_i[HIOFFSET] & mask);
611 tf.tf_i[HIOFFSET] = normhipart;
612 frac = tf.tf_d - UNITBIT32;
613 a = addr[0];
614 b = addr[1];
615 c = addr[2];
616 d = addr[3];
617 cminusb = c-b;
618 *out++ = b + frac * (
619 cminusb - 0.1666667f * (1.-frac) * (
620 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
621 )
622 );
623 }
624#endif
625
626 tf.tf_d = UNITBIT32 * fnpoints;
627 normhipart = tf.tf_i[HIOFFSET];
628 tf.tf_d = dphase + (UNITBIT32 * fnpoints - UNITBIT32);
629 tf.tf_i[HIOFFSET] = normhipart;
630 x->x_phase = (tf.tf_d - UNITBIT32 * fnpoints) * x->x_finvnpoints;
631 return (w+5);
632 zero:
633 while (n--) *out++ = 0;
634
635 return (w+5);
636}
637
638void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s)
639{
640 t_garray *a;
641 int npoints, pointsinarray;
642
643 x->x_arrayname = s;
644 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
645 {
646 if (*s->s_name)
647 pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name);
648 x->x_vec = 0;
649 }
650 else if (!garray_getfloatarray(a, &pointsinarray, &x->x_vec))
651 {
652 pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name);
653 x->x_vec = 0;
654 }
655 else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3)))
656 {
657 pd_error(x, "%s: number of points (%d) not a power of 2 plus three",
658 x->x_arrayname->s_name, pointsinarray);
659 x->x_vec = 0;
660 garray_usedindsp(a);
661 }
662 else
663 {
664 x->x_fnpoints = npoints;
665 x->x_finvnpoints = 1./npoints;
666 garray_usedindsp(a);
667 }
668}
669
670static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f)
671{
672 x->x_phase = f;
673}
674
675static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp)
676{
677 x->x_conv = 1. / sp[0]->s_sr;
678 tabosc4_tilde_set(x, x->x_arrayname);
679
680 dsp_add(tabosc4_tilde_perform, 4, x,
681 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
682}
683
684static void tabosc4_tilde_setup(void)
685{
686 tabosc4_tilde_class = class_new(gensym("tabosc4~"),
687 (t_newmethod)tabosc4_tilde_new, 0,
688 sizeof(t_tabosc4_tilde), 0, A_DEFSYM, 0);
689 CLASS_MAINSIGNALIN(tabosc4_tilde_class, t_tabosc4_tilde, x_f);
690 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_dsp,
691 gensym("dsp"), 0);
692 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_set,
693 gensym("set"), A_SYMBOL, 0);
694 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_ft1,
695 gensym("ft1"), A_FLOAT, 0);
696}
697
698/* ------------------------ tabsend~ ------------------------- */
699
700static t_class *tabsend_class;
701
702typedef struct _tabsend
703{
704 t_object x_obj;
705 float *x_vec;
706 int x_graphperiod;
707 int x_graphcount;
708 t_symbol *x_arrayname;
709 t_clock *x_clock;
710 float x_f;
711} t_tabsend;
712
713static void tabsend_tick(t_tabsend *x);
714
715static void *tabsend_new(t_symbol *s)
716{
717 t_tabsend *x = (t_tabsend *)pd_new(tabsend_class);
718 x->x_graphcount = 0;
719 x->x_arrayname = s;
720 x->x_clock = clock_new(x, (t_method)tabsend_tick);
721 x->x_f = 0;
722 return (x);
723}
724
725static t_int *tabsend_perform(t_int *w)
726{
727 t_tabsend *x = (t_tabsend *)(w[1]);
728 t_float *in = (t_float *)(w[2]);
729 int n = w[3];
730 t_float *dest = x->x_vec;
731 int i = x->x_graphcount;
732 if (!x->x_vec) goto bad;
733
734 while (n--)
735 {
736 float f = *in++;
737 if (PD_BIGORSMALL(f))
738 f = 0;
739 *dest++ = f;
740 }
741 if (!i--)
742 {
743 clock_delay(x->x_clock, 0);
744 i = x->x_graphperiod;
745 }
746 x->x_graphcount = i;
747bad:
748 return (w+4);
749}
750
751static void tabsend_dsp(t_tabsend *x, t_signal **sp)
752{
753 int i, vecsize;
754 t_garray *a;
755
756 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
757 {
758 if (*x->x_arrayname->s_name)
759 pd_error(x, "tabsend~: %s: no such array", x->x_arrayname->s_name);
760 }
761 else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
762 pd_error(x, "%s: bad template for tabsend~", x->x_arrayname->s_name);
763 else
764 {
765 int n = sp[0]->s_n;
766 int ticksper = sp[0]->s_sr/n;
767 if (ticksper < 1) ticksper = 1;
768 x->x_graphperiod = ticksper;
769 if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
770 if (n < vecsize) vecsize = n;
771 garray_usedindsp(a);
772 dsp_add(tabsend_perform, 3, x, sp[0]->s_vec, vecsize);
773 }
774}
775
776static void tabsend_tick(t_tabsend *x)
777{
778 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
779 if (!a) bug("tabsend_tick");
780 else garray_redraw(a);
781}
782
783static void tabsend_free(t_tabsend *x)
784{
785 clock_free(x->x_clock);
786}
787
788static void tabsend_setup(void)
789{
790 tabsend_class = class_new(gensym("tabsend~"), (t_newmethod)tabsend_new,
791 (t_method)tabsend_free, sizeof(t_tabsend), 0, A_DEFSYM, 0);
792 CLASS_MAINSIGNALIN(tabsend_class, t_tabsend, x_f);
793 class_addmethod(tabsend_class, (t_method)tabsend_dsp, gensym("dsp"), 0);
794}
795
796/* ------------------------ tabreceive~ ------------------------- */
797
798static t_class *tabreceive_class;
799
800typedef struct _tabreceive
801{
802 t_object x_obj;
803 float *x_vec;
804 t_symbol *x_arrayname;
805} t_tabreceive;
806
807static t_int *tabreceive_perform(t_int *w)
808{
809 t_tabreceive *x = (t_tabreceive *)(w[1]);
810 t_float *out = (t_float *)(w[2]);
811 int n = w[3];
812 t_float *from = x->x_vec;
813 if (from) while (n--) *out++ = *from++;
814 else while (n--) *out++ = 0;
815 return (w+4);
816}
817
818static void tabreceive_dsp(t_tabreceive *x, t_signal **sp)
819{
820 t_garray *a;
821 int vecsize;
822
823 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
824 {
825 if (*x->x_arrayname->s_name)
826 pd_error(x, "tabsend~: %s: no such array", x->x_arrayname->s_name);
827 }
828 else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
829 pd_error(x, "%s: bad template for tabreceive~", x->x_arrayname->s_name);
830 else
831 {
832 int n = sp[0]->s_n;
833 if (n < vecsize) vecsize = n;
834 garray_usedindsp(a);
835 dsp_add(tabreceive_perform, 3, x, sp[0]->s_vec, vecsize);
836 }
837}
838
839static void *tabreceive_new(t_symbol *s)
840{
841 t_tabreceive *x = (t_tabreceive *)pd_new(tabreceive_class);
842 x->x_arrayname = s;
843 outlet_new(&x->x_obj, &s_signal);
844 return (x);
845}
846
847static void tabreceive_setup(void)
848{
849 tabreceive_class = class_new(gensym("tabreceive~"),
850 (t_newmethod)tabreceive_new, 0,
851 sizeof(t_tabreceive), 0, A_DEFSYM, 0);
852 class_addmethod(tabreceive_class, (t_method)tabreceive_dsp,
853 gensym("dsp"), 0);
854}
855
856
857/* ---------- tabread: control, non-interpolating ------------------------ */
858
859static t_class *tabread_class;
860
861typedef struct _tabread
862{
863 t_object x_obj;
864 t_symbol *x_arrayname;
865} t_tabread;
866
867static void tabread_float(t_tabread *x, t_float f)
868{
869 t_garray *a;
870 int npoints;
871 t_float *vec;
872
873 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
874 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
875 else if (!garray_getfloatarray(a, &npoints, &vec))
876 pd_error(x, "%s: bad template for tabread", x->x_arrayname->s_name);
877 else
878 {
879 int n = f;
880 if (n < 0) n = 0;
881 else if (n >= npoints) n = npoints - 1;
882 outlet_float(x->x_obj.ob_outlet, (npoints ? vec[n] : 0));
883 }
884}
885
886static void tabread_set(t_tabread *x, t_symbol *s)
887{
888 x->x_arrayname = s;
889}
890
891static void *tabread_new(t_symbol *s)
892{
893 t_tabread *x = (t_tabread *)pd_new(tabread_class);
894 x->x_arrayname = s;
895 outlet_new(&x->x_obj, &s_float);
896 return (x);
897}
898
899static void tabread_setup(void)
900{
901 tabread_class = class_new(gensym("tabread"), (t_newmethod)tabread_new,
902 0, sizeof(t_tabread), 0, A_DEFSYM, 0);
903 class_addfloat(tabread_class, (t_method)tabread_float);
904 class_addmethod(tabread_class, (t_method)tabread_set, gensym("set"),
905 A_SYMBOL, 0);
906}
907
908/* ---------- tabread4: control, non-interpolating ------------------------ */
909
910static t_class *tabread4_class;
911
912typedef struct _tabread4
913{
914 t_object x_obj;
915 t_symbol *x_arrayname;
916} t_tabread4;
917
918static void tabread4_float(t_tabread4 *x, t_float f)
919{
920 t_garray *a;
921 int npoints;
922 t_float *vec;
923
924 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
925 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
926 else if (!garray_getfloatarray(a, &npoints, &vec))
927 pd_error(x, "%s: bad template for tabread4", x->x_arrayname->s_name);
928 else if (npoints < 4)
929 outlet_float(x->x_obj.ob_outlet, 0);
930 else if (f <= 1)
931 outlet_float(x->x_obj.ob_outlet, vec[1]);
932 else if (f >= npoints - 2)
933 outlet_float(x->x_obj.ob_outlet, vec[npoints - 2]);
934 else
935 {
936 int n = f;
937 float a, b, c, d, cminusb, frac, *fp;
938 if (n >= npoints - 2)
939 n = npoints - 3;
940 fp = vec + n;
941 frac = f - n;
942 a = fp[-1];
943 b = fp[0];
944 c = fp[1];
945 d = fp[2];
946 cminusb = c-b;
947 outlet_float(x->x_obj.ob_outlet, b + frac * (
948 cminusb - 0.1666667f * (1.-frac) * (
949 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b))));
950 }
951}
952
953static void tabread4_set(t_tabread4 *x, t_symbol *s)
954{
955 x->x_arrayname = s;
956}
957
958static void *tabread4_new(t_symbol *s)
959{
960 t_tabread4 *x = (t_tabread4 *)pd_new(tabread4_class);
961 x->x_arrayname = s;
962 outlet_new(&x->x_obj, &s_float);
963 return (x);
964}
965
966static void tabread4_setup(void)
967{
968 tabread4_class = class_new(gensym("tabread4"), (t_newmethod)tabread4_new,
969 0, sizeof(t_tabread4), 0, A_DEFSYM, 0);
970 class_addfloat(tabread4_class, (t_method)tabread4_float);
971 class_addmethod(tabread4_class, (t_method)tabread4_set, gensym("set"),
972 A_SYMBOL, 0);
973}
974
975/* ------------------ tabwrite: control ------------------------ */
976
977static t_class *tabwrite_class;
978
979typedef struct _tabwrite
980{
981 t_object x_obj;
982 t_symbol *x_arrayname;
983 t_clock *x_clock;
984 float x_ft1;
985 double x_updtime;
986 int x_set;
987} t_tabwrite;
988
989static void tabwrite_tick(t_tabwrite *x)
990{
991 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
992 if (!a) bug("tabwrite_tick");
993 else garray_redraw(a);
994 x->x_set = 0;
995 x->x_updtime = clock_getsystime();
996}
997
998static void tabwrite_float(t_tabwrite *x, t_float f)
999{
1000 int i, vecsize;
1001 t_garray *a;
1002 t_float *vec;
1003
1004 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1005 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
1006 else if (!garray_getfloatarray(a, &vecsize, &vec))
1007 pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name);
1008 else
1009 {
1010 int n = x->x_ft1;
1011 double timesince = clock_gettimesince(x->x_updtime);
1012 if (n < 0) n = 0;
1013 else if (n >= vecsize) n = vecsize-1;
1014 vec[n] = f;
1015 if (timesince > 1000)
1016 {
1017 tabwrite_tick(x);
1018 }
1019 else
1020 {
1021 if (x->x_set == 0)
1022 {
1023 clock_delay(x->x_clock, 1000 - timesince);
1024 x->x_set = 1;
1025 }
1026 }
1027 }
1028}
1029
1030static void tabwrite_set(t_tabwrite *x, t_symbol *s)
1031{
1032 x->x_arrayname = s;
1033}
1034
1035static void tabwrite_free(t_tabwrite *x)
1036{
1037 clock_free(x->x_clock);
1038}
1039
1040static void *tabwrite_new(t_symbol *s)
1041{
1042 t_tabwrite *x = (t_tabwrite *)pd_new(tabwrite_class);
1043 x->x_ft1 = 0;
1044 x->x_arrayname = s;
1045 x->x_updtime = clock_getsystime();
1046 x->x_clock = clock_new(x, (t_method)tabwrite_tick);
1047 floatinlet_new(&x->x_obj, &x->x_ft1);
1048 return (x);
1049}
1050
1051void tabwrite_setup(void)
1052{
1053 tabwrite_class = class_new(gensym("tabwrite"), (t_newmethod)tabwrite_new,
1054 (t_method)tabwrite_free, sizeof(t_tabwrite), 0, A_DEFSYM, 0);
1055 class_addfloat(tabwrite_class, (t_method)tabwrite_float);
1056 class_addmethod(tabwrite_class, (t_method)tabwrite_set, gensym("set"), A_SYMBOL, 0);
1057}
1058
1059/* ------------------------ global setup routine ------------------------- */
1060
1061void d_array_setup(void)
1062{
1063 tabwrite_tilde_setup();
1064 tabplay_tilde_setup();
1065 tabread_tilde_setup();
1066 tabread4_tilde_setup();
1067 tabosc4_tilde_setup();
1068 tabsend_setup();
1069 tabreceive_setup();
1070 tabread_setup();
1071 tabread4_setup();
1072 tabwrite_setup();
1073}
1074
diff --git a/apps/plugins/pdbox/PDa/src/d_delay.c b/apps/plugins/pdbox/PDa/src/d_delay.c
deleted file mode 100644
index d04ded9e90..0000000000
--- a/apps/plugins/pdbox/PDa/src/d_delay.c
+++ /dev/null
@@ -1,319 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* send~, delread~, throw~, catch~ */
6
7#include "m_pd.h"
8extern int ugen_getsortno(void);
9
10#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
11static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
12
13/* ----------------------------- delwrite~ ----------------------------- */
14static t_class *sigdelwrite_class;
15
16typedef struct delwritectl
17{
18 int c_n;
19 float *c_vec;
20 int c_phase;
21} t_delwritectl;
22
23typedef struct _sigdelwrite
24{
25 t_object x_obj;
26 t_symbol *x_sym;
27 t_delwritectl x_cspace;
28 int x_sortno; /* DSP sort number at which this was last put on chain */
29 int x_rsortno; /* DSP sort # for first delread or write in chain */
30 int x_vecsize; /* vector size for delread~ to use */
31 float x_f;
32} t_sigdelwrite;
33
34#define XTRASAMPS 4
35#define SAMPBLK 4
36
37 /* routine to check that all delwrites/delreads/vds have same vecsize */
38static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
39{
40 /*
41 LATER this should really check sample rate and blocking, once that is
42 supported. Probably we don't actually care about vecsize.
43 For now just suppress this check... */
44#if 0
45 if (x->x_rsortno != ugen_getsortno())
46 {
47 x->x_vecsize = vecsize;
48 x->x_rsortno = ugen_getsortno();
49 }
50 else if (vecsize != x->x_vecsize)
51 pd_error(x, "delread/delwrite/vd vector size mismatch");
52#endif
53}
54
55static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
56{
57 int nsamps;
58 t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
59 if (!*s->s_name) s = gensym("delwrite~");
60 pd_bind(&x->x_obj.ob_pd, s);
61 x->x_sym = s;
62 nsamps = msec * sys_getsr() * (float)(0.001f);
63 if (nsamps < 1) nsamps = 1;
64 nsamps += ((- nsamps) & (SAMPBLK - 1));
65 nsamps += DEFDELVS;
66 x->x_cspace.c_n = nsamps;
67 x->x_cspace.c_vec =
68 (float *)getbytes((nsamps + XTRASAMPS) * sizeof(float));
69 x->x_cspace.c_phase = XTRASAMPS;
70 x->x_sortno = 0;
71 x->x_vecsize = 0;
72 x->x_f = 0;
73 return (x);
74}
75
76static t_int *sigdelwrite_perform(t_int *w)
77{
78 t_float *in = (t_float *)(w[1]);
79 t_delwritectl *c = (t_delwritectl *)(w[2]);
80 int n = (int)(w[3]);
81 int phase = c->c_phase, nsamps = c->c_n;
82 float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
83 phase += n;
84 while (n--)
85 {
86 float f = *in++;
87 if (PD_BIGORSMALL(f))
88 f = 0;
89 *bp++ = f;
90 if (bp == ep)
91 {
92 vp[0] = ep[-4];
93 vp[1] = ep[-3];
94 vp[2] = ep[-2];
95 vp[3] = ep[-1];
96 bp = vp + XTRASAMPS;
97 phase -= nsamps;
98 }
99 }
100 c->c_phase = phase;
101 return (w+4);
102}
103
104static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
105{
106 dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
107 x->x_sortno = ugen_getsortno();
108 sigdelwrite_checkvecsize(x, sp[0]->s_n);
109}
110
111static void sigdelwrite_free(t_sigdelwrite *x)
112{
113 pd_unbind(&x->x_obj.ob_pd, x->x_sym);
114 freebytes(x->x_cspace.c_vec,
115 (x->x_cspace.c_n + XTRASAMPS) * sizeof(float));
116}
117
118static void sigdelwrite_setup(void)
119{
120 sigdelwrite_class = class_new(gensym("delwrite~"),
121 (t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
122 sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
123 CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
124 class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
125 gensym("dsp"), 0);
126}
127
128/* ----------------------------- delread~ ----------------------------- */
129static t_class *sigdelread_class;
130
131typedef struct _sigdelread
132{
133 t_object x_obj;
134 t_symbol *x_sym;
135 t_float x_deltime; /* delay in msec */
136 int x_delsamps; /* delay in samples */
137 t_float x_sr; /* samples per msec */
138 t_float x_n; /* vector size */
139 int x_zerodel; /* 0 or vecsize depending on read/write order */
140} t_sigdelread;
141
142static void sigdelread_float(t_sigdelread *x, t_float f);
143
144static void *sigdelread_new(t_symbol *s, t_floatarg f)
145{
146 t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
147 x->x_sym = s;
148 x->x_sr = 1;
149 x->x_n = 1;
150 x->x_zerodel = 0;
151 sigdelread_float(x, f);
152 outlet_new(&x->x_obj, &s_signal);
153 return (x);
154}
155
156static void sigdelread_float(t_sigdelread *x, t_float f)
157{
158 int samps;
159 t_sigdelwrite *delwriter =
160 (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
161 x->x_deltime = f;
162 if (delwriter)
163 {
164 int delsize = delwriter->x_cspace.c_n;
165 x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
166 + x->x_n - x->x_zerodel;
167 if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
168 else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
169 x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
170 }
171}
172
173static t_int *sigdelread_perform(t_int *w)
174{
175 t_float *out = (t_float *)(w[1]);
176 t_delwritectl *c = (t_delwritectl *)(w[2]);
177 int delsamps = *(int *)(w[3]);
178 int n = (int)(w[4]);
179 int phase = c->c_phase - delsamps, nsamps = c->c_n;
180 float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
181
182 if (phase < 0) phase += nsamps;
183 bp = vp + phase;
184 while (n--)
185 {
186 *out++ = *bp++;
187 if (bp == ep) bp -= nsamps;
188 }
189 return (w+5);
190}
191
192static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
193{
194 t_sigdelwrite *delwriter =
195 (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
196 x->x_sr = sp[0]->s_sr * 0.001;
197 x->x_n = sp[0]->s_n;
198 if (delwriter)
199 {
200 sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
201 x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
202 0 : delwriter->x_vecsize);
203 sigdelread_float(x, x->x_deltime);
204 dsp_add(sigdelread_perform, 4,
205 sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
206 }
207 else if (*x->x_sym->s_name)
208 error("delread~: %s: no such delwrite~",x->x_sym->s_name);
209}
210
211static void sigdelread_setup(void)
212{
213 sigdelread_class = class_new(gensym("delread~"),
214 (t_newmethod)sigdelread_new, 0,
215 sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
216 class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
217 gensym("dsp"), 0);
218 class_addfloat(sigdelread_class, (t_method)sigdelread_float);
219}
220
221
222/* ----------------------------- vd~ ----------------------------- */
223static t_class *sigvd_class;
224
225typedef struct _sigvd
226{
227 t_object x_obj;
228 t_symbol *x_sym;
229 t_float x_sr; /* samples per msec */
230 int x_zerodel; /* 0 or vecsize depending on read/write order */
231 float x_f;
232} t_sigvd;
233
234static void *sigvd_new(t_symbol *s)
235{
236 t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
237 if (!*s->s_name) s = gensym("vd~");
238 x->x_sym = s;
239 x->x_sr = 1;
240 x->x_zerodel = 0;
241 outlet_new(&x->x_obj, &s_signal);
242 x->x_f = 0;
243 return (x);
244}
245
246static t_int *sigvd_perform(t_int *w)
247{
248 t_float *in = (t_float *)(w[1]);
249 t_float *out = (t_float *)(w[2]);
250 t_delwritectl *ctl = (t_delwritectl *)(w[3]);
251 t_sigvd *x = (t_sigvd *)(w[4]);
252 int n = (int)(w[5]);
253
254 int nsamps = ctl->c_n;
255 float limit = nsamps - n - 1;
256 float fn = n-1;
257 float *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
258 float zerodel = x->x_zerodel;
259 while (n--)
260 {
261 float delsamps = x->x_sr * *in++ - zerodel, frac;
262 int idelsamps;
263 float a, b, c, d, cminusb;
264 if (delsamps < 1.00001f) delsamps = 1.00001f;
265 if (delsamps > limit) delsamps = limit;
266 delsamps += fn;
267 fn = fn - 1.0f;
268 idelsamps = delsamps;
269 frac = delsamps - (float)idelsamps;
270 bp = wp - idelsamps;
271 if (bp < vp + 4) bp += nsamps;
272 d = bp[-3];
273 c = bp[-2];
274 b = bp[-1];
275 a = bp[0];
276 cminusb = c-b;
277 *out++ = b + frac * (
278 cminusb - 0.1666667f * (1.-frac) * (
279 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
280 )
281 );
282 }
283 return (w+6);
284}
285
286static void sigvd_dsp(t_sigvd *x, t_signal **sp)
287{
288 t_sigdelwrite *delwriter =
289 (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
290 x->x_sr = sp[0]->s_sr * 0.001;
291 if (delwriter)
292 {
293 sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
294 x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
295 0 : delwriter->x_vecsize);
296 dsp_add(sigvd_perform, 5,
297 sp[0]->s_vec, sp[1]->s_vec,
298 &delwriter->x_cspace, x, sp[0]->s_n);
299 }
300 else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
301}
302
303static void sigvd_setup(void)
304{
305 sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
306 sizeof(t_sigvd), 0, A_DEFSYM, 0);
307 class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
308 CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
309}
310
311/* ----------------------- global setup routine ---------------- */
312
313void d_delay_setup(void)
314{
315 sigdelwrite_setup();
316 sigdelread_setup();
317 sigvd_setup();
318}
319
diff --git a/apps/plugins/pdbox/PDa/src/d_filter.c b/apps/plugins/pdbox/PDa/src/d_filter.c
deleted file mode 100644
index 8b81a3a0d3..0000000000
--- a/apps/plugins/pdbox/PDa/src/d_filter.c
+++ /dev/null
@@ -1,548 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* "filters", both linear and nonlinear.
6*/
7#include "m_pd.h"
8#include <math.h>
9
10/* ---------------- hip~ - 1-pole 1-zero hipass filter. ----------------- */
11
12typedef struct hipctl
13{
14 float c_x;
15 float c_coef;
16} t_hipctl;
17
18typedef struct sighip
19{
20 t_object x_obj;
21 float x_sr;
22 float x_hz;
23 t_hipctl x_cspace;
24 t_hipctl *x_ctl;
25 float x_f;
26} t_sighip;
27
28t_class *sighip_class;
29static void sighip_ft1(t_sighip *x, t_floatarg f);
30
31static void *sighip_new(t_floatarg f)
32{
33 t_sighip *x = (t_sighip *)pd_new(sighip_class);
34 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
35 outlet_new(&x->x_obj, gensym("signal"));
36 x->x_sr = 44100;
37 x->x_ctl = &x->x_cspace;
38 x->x_cspace.c_x = 0;
39 sighip_ft1(x, f);
40 x->x_f = 0;
41 return (x);
42}
43
44static void sighip_ft1(t_sighip *x, t_floatarg f)
45{
46 if (f < 0) f = 0;
47 x->x_hz = f;
48 x->x_ctl->c_coef = 1 - f * (2 * 3.14159) / x->x_sr;
49 if (x->x_ctl->c_coef < 0)
50 x->x_ctl->c_coef = 0;
51 else if (x->x_ctl->c_coef > 1)
52 x->x_ctl->c_coef = 1;
53}
54
55static t_int *sighip_perform(t_int *w)
56{
57 float *in = (float *)(w[1]);
58 float *out = (float *)(w[2]);
59 t_hipctl *c = (t_hipctl *)(w[3]);
60 int n = (t_int)(w[4]);
61 int i;
62 float last = c->c_x;
63 float coef = c->c_coef;
64 if (coef < 1)
65 {
66 for (i = 0; i < n; i++)
67 {
68 float new = *in++ + coef * last;
69 *out++ = new - last;
70 last = new;
71 }
72 if (PD_BIGORSMALL(last))
73 last = 0;
74 c->c_x = last;
75 }
76 else
77 {
78 for (i = 0; i < n; i++)
79 *out++ = *in++;
80 c->c_x = 0;
81 }
82 return (w+5);
83}
84
85static void sighip_dsp(t_sighip *x, t_signal **sp)
86{
87 x->x_sr = sp[0]->s_sr;
88 sighip_ft1(x, x->x_hz);
89 dsp_add(sighip_perform, 4,
90 sp[0]->s_vec, sp[1]->s_vec,
91 x->x_ctl, sp[0]->s_n);
92
93}
94
95static void sighip_clear(t_sighip *x, t_floatarg q)
96{
97 x->x_cspace.c_x = 0;
98}
99
100void sighip_setup(void)
101{
102 sighip_class = class_new(gensym("hip~"), (t_newmethod)sighip_new, 0,
103 sizeof(t_sighip), 0, A_DEFFLOAT, 0);
104 CLASS_MAINSIGNALIN(sighip_class, t_sighip, x_f);
105 class_addmethod(sighip_class, (t_method)sighip_dsp, gensym("dsp"), 0);
106 class_addmethod(sighip_class, (t_method)sighip_ft1,
107 gensym("ft1"), A_FLOAT, 0);
108 class_addmethod(sighip_class, (t_method)sighip_clear, gensym("clear"), 0);
109}
110
111/* ---------------- lop~ - 1-pole lopass filter. ----------------- */
112
113typedef struct lopctl
114{
115 float c_x;
116 float c_coef;
117} t_lopctl;
118
119typedef struct siglop
120{
121 t_object x_obj;
122 float x_sr;
123 float x_hz;
124 t_lopctl x_cspace;
125 t_lopctl *x_ctl;
126 float x_f;
127} t_siglop;
128
129t_class *siglop_class;
130
131static void siglop_ft1(t_siglop *x, t_floatarg f);
132
133static void *siglop_new(t_floatarg f)
134{
135 t_siglop *x = (t_siglop *)pd_new(siglop_class);
136 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
137 outlet_new(&x->x_obj, gensym("signal"));
138 x->x_sr = 44100;
139 x->x_ctl = &x->x_cspace;
140 x->x_cspace.c_x = 0;
141 siglop_ft1(x, f);
142 x->x_f = 0;
143 return (x);
144}
145
146static void siglop_ft1(t_siglop *x, t_floatarg f)
147{
148 if (f < 0) f = 0;
149 x->x_hz = f;
150 x->x_ctl->c_coef = f * (2 * 3.14159) / x->x_sr;
151 if (x->x_ctl->c_coef > 1)
152 x->x_ctl->c_coef = 1;
153 else if (x->x_ctl->c_coef < 0)
154 x->x_ctl->c_coef = 0;
155}
156
157static void siglop_clear(t_siglop *x, t_floatarg q)
158{
159 x->x_cspace.c_x = 0;
160}
161
162static t_int *siglop_perform(t_int *w)
163{
164 float *in = (float *)(w[1]);
165 float *out = (float *)(w[2]);
166 t_lopctl *c = (t_lopctl *)(w[3]);
167 int n = (t_int)(w[4]);
168 int i;
169 float last = c->c_x;
170 float coef = c->c_coef;
171 float feedback = 1 - coef;
172 for (i = 0; i < n; i++)
173 last = *out++ = coef * *in++ + feedback * last;
174 if (PD_BIGORSMALL(last))
175 last = 0;
176 c->c_x = last;
177 return (w+5);
178}
179
180static void siglop_dsp(t_siglop *x, t_signal **sp)
181{
182 x->x_sr = sp[0]->s_sr;
183 siglop_ft1(x, x->x_hz);
184 dsp_add(siglop_perform, 4,
185 sp[0]->s_vec, sp[1]->s_vec,
186 x->x_ctl, sp[0]->s_n);
187
188}
189
190void siglop_setup(void)
191{
192 siglop_class = class_new(gensym("lop~"), (t_newmethod)siglop_new, 0,
193 sizeof(t_siglop), 0, A_DEFFLOAT, 0);
194 CLASS_MAINSIGNALIN(siglop_class, t_siglop, x_f);
195 class_addmethod(siglop_class, (t_method)siglop_dsp, gensym("dsp"), 0);
196 class_addmethod(siglop_class, (t_method)siglop_ft1,
197 gensym("ft1"), A_FLOAT, 0);
198 class_addmethod(siglop_class, (t_method)siglop_clear, gensym("clear"), 0);
199}
200
201/* ---------------- bp~ - 2-pole bandpass filter. ----------------- */
202
203typedef struct bpctl
204{
205 float c_x1;
206 float c_x2;
207 float c_coef1;
208 float c_coef2;
209 float c_gain;
210} t_bpctl;
211
212typedef struct sigbp
213{
214 t_object x_obj;
215 float x_sr;
216 float x_freq;
217 float x_q;
218 t_bpctl x_cspace;
219 t_bpctl *x_ctl;
220 float x_f;
221} t_sigbp;
222
223t_class *sigbp_class;
224
225static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q);
226
227static void *sigbp_new(t_floatarg f, t_floatarg q)
228{
229 t_sigbp *x = (t_sigbp *)pd_new(sigbp_class);
230 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
231 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
232 outlet_new(&x->x_obj, gensym("signal"));
233 x->x_sr = 44100;
234 x->x_ctl = &x->x_cspace;
235 x->x_cspace.c_x1 = 0;
236 x->x_cspace.c_x2 = 0;
237 sigbp_docoef(x, f, q);
238 x->x_f = 0;
239 return (x);
240}
241
242static float sigbp_qcos(float f)
243{
244 if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f)
245 {
246 float g = f*f;
247 return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
248 }
249 else return (0);
250}
251
252static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q)
253{
254 float r, oneminusr, omega;
255 if (f < 0.001) f = 10;
256 if (q < 0) q = 0;
257 x->x_freq = f;
258 x->x_q = q;
259 omega = f * (2.0f * 3.14159f) / x->x_sr;
260 if (q < 0.001) oneminusr = 1.0f;
261 else oneminusr = omega/q;
262 if (oneminusr > 1.0f) oneminusr = 1.0f;
263 r = 1.0f - oneminusr;
264 x->x_ctl->c_coef1 = 2.0f * sigbp_qcos(omega) * r;
265 x->x_ctl->c_coef2 = - r * r;
266 x->x_ctl->c_gain = 2 * oneminusr * (oneminusr + r * omega);
267 /* post("r %f, omega %f, coef1 %f, coef2 %f",
268 r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
269}
270
271static void sigbp_ft1(t_sigbp *x, t_floatarg f)
272{
273 sigbp_docoef(x, f, x->x_q);
274}
275
276static void sigbp_ft2(t_sigbp *x, t_floatarg q)
277{
278 sigbp_docoef(x, x->x_freq, q);
279}
280
281static void sigbp_clear(t_sigbp *x, t_floatarg q)
282{
283 x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0;
284}
285
286static t_int *sigbp_perform(t_int *w)
287{
288 float *in = (float *)(w[1]);
289 float *out = (float *)(w[2]);
290 t_bpctl *c = (t_bpctl *)(w[3]);
291 int n = (t_int)(w[4]);
292 int i;
293 float last = c->c_x1;
294 float prev = c->c_x2;
295 float coef1 = c->c_coef1;
296 float coef2 = c->c_coef2;
297 float gain = c->c_gain;
298 for (i = 0; i < n; i++)
299 {
300 float output = *in++ + coef1 * last + coef2 * prev;
301 *out++ = gain * output;
302 prev = last;
303 last = output;
304 }
305 if (PD_BIGORSMALL(last))
306 last = 0;
307 if (PD_BIGORSMALL(prev))
308 prev = 0;
309 c->c_x1 = last;
310 c->c_x2 = prev;
311 return (w+5);
312}
313
314static void sigbp_dsp(t_sigbp *x, t_signal **sp)
315{
316 x->x_sr = sp[0]->s_sr;
317 sigbp_docoef(x, x->x_freq, x->x_q);
318 dsp_add(sigbp_perform, 4,
319 sp[0]->s_vec, sp[1]->s_vec,
320 x->x_ctl, sp[0]->s_n);
321
322}
323
324void sigbp_setup(void)
325{
326 sigbp_class = class_new(gensym("bp~"), (t_newmethod)sigbp_new, 0,
327 sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
328 CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, x_f);
329 class_addmethod(sigbp_class, (t_method)sigbp_dsp, gensym("dsp"), 0);
330 class_addmethod(sigbp_class, (t_method)sigbp_ft1,
331 gensym("ft1"), A_FLOAT, 0);
332 class_addmethod(sigbp_class, (t_method)sigbp_ft2,
333 gensym("ft2"), A_FLOAT, 0);
334 class_addmethod(sigbp_class, (t_method)sigbp_clear, gensym("clear"), 0);
335}
336
337/* ---------------- biquad~ - raw biquad filter ----------------- */
338
339typedef struct biquadctl
340{
341 float c_x1;
342 float c_x2;
343 float c_fb1;
344 float c_fb2;
345 float c_ff1;
346 float c_ff2;
347 float c_ff3;
348} t_biquadctl;
349
350typedef struct sigbiquad
351{
352 t_object x_obj;
353 float x_f;
354 t_biquadctl x_cspace;
355 t_biquadctl *x_ctl;
356} t_sigbiquad;
357
358t_class *sigbiquad_class;
359
360static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv);
361
362static void *sigbiquad_new(t_symbol *s, int argc, t_atom *argv)
363{
364 t_sigbiquad *x = (t_sigbiquad *)pd_new(sigbiquad_class);
365 outlet_new(&x->x_obj, gensym("signal"));
366 x->x_ctl = &x->x_cspace;
367 x->x_cspace.c_x1 = x->x_cspace.c_x2 = 0;
368 sigbiquad_list(x, s, argc, argv);
369 x->x_f = 0;
370 return (x);
371}
372
373static t_int *sigbiquad_perform(t_int *w)
374{
375 float *in = (float *)(w[1]);
376 float *out = (float *)(w[2]);
377 t_biquadctl *c = (t_biquadctl *)(w[3]);
378 int n = (t_int)(w[4]);
379 int i;
380 float last = c->c_x1;
381 float prev = c->c_x2;
382 float fb1 = c->c_fb1;
383 float fb2 = c->c_fb2;
384 float ff1 = c->c_ff1;
385 float ff2 = c->c_ff2;
386 float ff3 = c->c_ff3;
387 for (i = 0; i < n; i++)
388 {
389 float output = *in++ + fb1 * last + fb2 * prev;
390 if (PD_BIGORSMALL(output))
391 output = 0;
392 *out++ = ff1 * output + ff2 * last + ff3 * prev;
393 prev = last;
394 last = output;
395 }
396 c->c_x1 = last;
397 c->c_x2 = prev;
398 return (w+5);
399}
400
401static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
402{
403 float fb1 = atom_getfloatarg(0, argc, argv);
404 float fb2 = atom_getfloatarg(1, argc, argv);
405 float ff1 = atom_getfloatarg(2, argc, argv);
406 float ff2 = atom_getfloatarg(3, argc, argv);
407 float ff3 = atom_getfloatarg(4, argc, argv);
408 float discriminant = fb1 * fb1 + 4 * fb2;
409 t_biquadctl *c = x->x_ctl;
410 if (discriminant < 0) /* imaginary roots -- resonant filter */
411 {
412 /* they're conjugates so we just check that the product
413 is less than one */
414 if (fb2 >= -1.0f) goto stable;
415 }
416 else /* real roots */
417 {
418 /* check that the parabola 1 - fb1 x - fb2 x^2 has a
419 vertex between -1 and 1, and that it's nonnegative
420 at both ends, which implies both roots are in [1-,1]. */
421 if (fb1 <= 2.0f && fb1 >= -2.0f &&
422 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
423 goto stable;
424 }
425 /* if unstable, just bash to zero */
426 fb1 = fb2 = ff1 = ff2 = ff3 = 0;
427stable:
428 c->c_fb1 = fb1;
429 c->c_fb2 = fb2;
430 c->c_ff1 = ff1;
431 c->c_ff2 = ff2;
432 c->c_ff3 = ff3;
433}
434
435static void sigbiquad_set(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
436{
437 t_biquadctl *c = x->x_ctl;
438 c->c_x1 = atom_getfloatarg(0, argc, argv);
439 c->c_x2 = atom_getfloatarg(1, argc, argv);
440}
441
442static void sigbiquad_dsp(t_sigbiquad *x, t_signal **sp)
443{
444 dsp_add(sigbiquad_perform, 4,
445 sp[0]->s_vec, sp[1]->s_vec,
446 x->x_ctl, sp[0]->s_n);
447
448}
449
450void sigbiquad_setup(void)
451{
452 sigbiquad_class = class_new(gensym("biquad~"), (t_newmethod)sigbiquad_new,
453 0, sizeof(t_sigbiquad), 0, A_GIMME, 0);
454 CLASS_MAINSIGNALIN(sigbiquad_class, t_sigbiquad, x_f);
455 class_addmethod(sigbiquad_class, (t_method)sigbiquad_dsp, gensym("dsp"), 0);
456 class_addlist(sigbiquad_class, sigbiquad_list);
457 class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("set"),
458 A_GIMME, 0);
459 class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("clear"),
460 A_GIMME, 0);
461}
462
463/* ---------------- samphold~ - sample and hold ----------------- */
464
465typedef struct sigsamphold
466{
467 t_object x_obj;
468 float x_f;
469 float x_lastin;
470 float x_lastout;
471} t_sigsamphold;
472
473t_class *sigsamphold_class;
474
475static void *sigsamphold_new(void)
476{
477 t_sigsamphold *x = (t_sigsamphold *)pd_new(sigsamphold_class);
478 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
479 outlet_new(&x->x_obj, gensym("signal"));
480 x->x_lastin = 0;
481 x->x_lastout = 0;
482 x->x_f = 0;
483 return (x);
484}
485
486static t_int *sigsamphold_perform(t_int *w)
487{
488 float *in1 = (float *)(w[1]);
489 float *in2 = (float *)(w[2]);
490 float *out = (float *)(w[3]);
491 t_sigsamphold *x = (t_sigsamphold *)(w[4]);
492 int n = (t_int)(w[5]);
493 int i;
494 float lastin = x->x_lastin;
495 float lastout = x->x_lastout;
496 for (i = 0; i < n; i++, *in1++)
497 {
498 float next = *in2++;
499 if (next < lastin) lastout = *in1;
500 *out++ = lastout;
501 lastin = next;
502 }
503 x->x_lastin = lastin;
504 x->x_lastout = lastout;
505 return (w+6);
506}
507
508static void sigsamphold_dsp(t_sigsamphold *x, t_signal **sp)
509{
510 dsp_add(sigsamphold_perform, 5,
511 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
512 x, sp[0]->s_n);
513}
514
515static void sigsamphold_reset(t_sigsamphold *x)
516{
517 x->x_lastin = 1e20;
518}
519
520static void sigsamphold_set(t_sigsamphold *x, t_float f)
521{
522 x->x_lastout = f;
523}
524
525void sigsamphold_setup(void)
526{
527 sigsamphold_class = class_new(gensym("samphold~"),
528 (t_newmethod)sigsamphold_new, 0, sizeof(t_sigsamphold), 0, 0);
529 CLASS_MAINSIGNALIN(sigsamphold_class, t_sigsamphold, x_f);
530 class_addmethod(sigsamphold_class, (t_method)sigsamphold_set,
531 gensym("set"), A_FLOAT, 0);
532 class_addmethod(sigsamphold_class, (t_method)sigsamphold_reset,
533 gensym("reset"), 0);
534 class_addmethod(sigsamphold_class, (t_method)sigsamphold_dsp,
535 gensym("dsp"), 0);
536}
537
538/* ------------------------ setup routine ------------------------- */
539
540void d_filter_setup(void)
541{
542 sighip_setup();
543 siglop_setup();
544 sigbp_setup();
545 sigbiquad_setup();
546 sigsamphold_setup();
547}
548
diff --git a/apps/plugins/pdbox/PDa/src/d_math.c b/apps/plugins/pdbox/PDa/src/d_math.c
deleted file mode 100644
index d64e2e3483..0000000000
--- a/apps/plugins/pdbox/PDa/src/d_math.c
+++ /dev/null
@@ -1,573 +0,0 @@
1/* Copyright (c) 1997-2001 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* mathematical functions and other transfer functions, including tilde
6 versions of stuff from x_acoustics.c.
7*/
8
9#include "m_pd.h"
10#include <math.h>
11#define LOGTEN 2.302585092994
12
13/* ------------------------- clip~ -------------------------- */
14static t_class *clip_class;
15
16typedef struct _clip
17{
18 t_object x_obj;
19 float x_f;
20 t_sample x_lo;
21 t_sample x_hi;
22} t_clip;
23
24static void *clip_new(t_floatarg lo, t_floatarg hi)
25{
26 t_clip *x = (t_clip *)pd_new(clip_class);
27 x->x_lo = lo;
28 x->x_hi = hi;
29 outlet_new(&x->x_obj, gensym("signal"));
30 floatinlet_new(&x->x_obj, &x->x_lo);
31 floatinlet_new(&x->x_obj, &x->x_hi);
32 x->x_f = 0;
33 return (x);
34}
35
36static t_int *clip_perform(t_int *w)
37{
38 t_clip *x = (t_clip *)(w[1]);
39 t_float *in = (t_float *)(w[2]);
40 t_float *out = (t_float *)(w[3]);
41 int n = (int)(w[4]);
42 while (n--)
43 {
44 float f = *in++;
45 if (f < x->x_lo) f = x->x_lo;
46 if (f > x->x_hi) f = x->x_hi;
47 *out++ = f;
48 }
49 return (w+5);
50}
51
52static void clip_dsp(t_clip *x, t_signal **sp)
53{
54 dsp_add(clip_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
55}
56
57static void clip_setup(void)
58{
59 clip_class = class_new(gensym("clip~"), (t_newmethod)clip_new, 0,
60 sizeof(t_clip), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
61 CLASS_MAINSIGNALIN(clip_class, t_clip, x_f);
62 class_addmethod(clip_class, (t_method)clip_dsp, gensym("dsp"), 0);
63}
64
65/* sigrsqrt - reciprocal square root good to 8 mantissa bits */
66
67#define DUMTAB1SIZE 256
68#define DUMTAB2SIZE 1024
69
70static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE];
71
72static void init_rsqrt(void)
73{
74 int i;
75 for (i = 0; i < DUMTAB1SIZE; i++)
76 {
77 float f;
78 long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23;
79 *(long *)(&f) = l;
80 rsqrt_exptab[i] = 1./sqrt(f);
81 }
82 for (i = 0; i < DUMTAB2SIZE; i++)
83 {
84 float f = 1 + (1./DUMTAB2SIZE) * i;
85 rsqrt_mantissatab[i] = 1./sqrt(f);
86 }
87}
88
89 /* these are used in externs like "bonk" */
90
91float q8_rsqrt(float f)
92{
93 long l = *(long *)(&f);
94 if (f < 0) return (0);
95 else return (rsqrt_exptab[(l >> 23) & 0xff] *
96 rsqrt_mantissatab[(l >> 13) & 0x3ff]);
97}
98
99float q8_sqrt(float f)
100{
101 long l = *(long *)(&f);
102 if (f < 0) return (0);
103 else return (f * rsqrt_exptab[(l >> 23) & 0xff] *
104 rsqrt_mantissatab[(l >> 13) & 0x3ff]);
105}
106
107 /* the old names are OK unless we're in IRIX N32 */
108
109#ifndef N32
110float qsqrt(float f) {return (q8_sqrt(f)); }
111float qrsqrt(float f) {return (q8_rsqrt(f)); }
112#endif
113
114
115
116typedef struct sigrsqrt
117{
118 t_object x_obj;
119 float x_f;
120} t_sigrsqrt;
121
122static t_class *sigrsqrt_class;
123
124static void *sigrsqrt_new(void)
125{
126 t_sigrsqrt *x = (t_sigrsqrt *)pd_new(sigrsqrt_class);
127 outlet_new(&x->x_obj, gensym("signal"));
128 x->x_f = 0;
129 return (x);
130}
131
132static t_int *sigrsqrt_perform(t_int *w)
133{
134 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
135 t_int n = *(t_int *)(w+3);
136 while (n--)
137 {
138 float f = *in;
139 long l = *(long *)(in++);
140 if (f < 0) *out++ = 0;
141 else
142 {
143 float g = rsqrt_exptab[(l >> 23) & 0xff] *
144 rsqrt_mantissatab[(l >> 13) & 0x3ff];
145 *out++ = 1.5 * g - 0.5 * g * g * g * f;
146 }
147 }
148 return (w + 4);
149}
150
151static void sigrsqrt_dsp(t_sigrsqrt *x, t_signal **sp)
152{
153 dsp_add(sigrsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
154}
155
156void sigrsqrt_setup(void)
157{
158 init_rsqrt();
159 sigrsqrt_class = class_new(gensym("rsqrt~"), (t_newmethod)sigrsqrt_new, 0,
160 sizeof(t_sigrsqrt), 0, 0);
161 /* an old name for it: */
162 class_addcreator(sigrsqrt_new, gensym("q8_rsqrt~"), 0);
163 CLASS_MAINSIGNALIN(sigrsqrt_class, t_sigrsqrt, x_f);
164 class_addmethod(sigrsqrt_class, (t_method)sigrsqrt_dsp, gensym("dsp"), 0);
165}
166
167
168/* sigsqrt - square root good to 8 mantissa bits */
169
170typedef struct sigsqrt
171{
172 t_object x_obj;
173 float x_f;
174} t_sigsqrt;
175
176static t_class *sigsqrt_class;
177
178static void *sigsqrt_new(void)
179{
180 t_sigsqrt *x = (t_sigsqrt *)pd_new(sigsqrt_class);
181 outlet_new(&x->x_obj, gensym("signal"));
182 x->x_f = 0;
183 return (x);
184}
185
186t_int *sigsqrt_perform(t_int *w) /* not static; also used in d_fft.c */
187{
188 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
189 t_int n = *(t_int *)(w+3);
190 while (n--)
191 {
192 float f = *in;
193 long l = *(long *)(in++);
194 if (f < 0) *out++ = 0;
195 else
196 {
197 float g = rsqrt_exptab[(l >> 23) & 0xff] *
198 rsqrt_mantissatab[(l >> 13) & 0x3ff];
199 *out++ = f * (1.5 * g - 0.5 * g * g * g * f);
200 }
201 }
202 return (w + 4);
203}
204
205static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp)
206{
207 dsp_add(sigsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
208}
209
210void sigsqrt_setup(void)
211{
212 sigsqrt_class = class_new(gensym("sqrt~"), (t_newmethod)sigsqrt_new, 0,
213 sizeof(t_sigsqrt), 0, 0);
214 class_addcreator(sigsqrt_new, gensym("q8_sqrt~"), 0); /* old name */
215 CLASS_MAINSIGNALIN(sigsqrt_class, t_sigsqrt, x_f);
216 class_addmethod(sigsqrt_class, (t_method)sigsqrt_dsp, gensym("dsp"), 0);
217}
218
219/* ------------------------------ wrap~ -------------------------- */
220
221typedef struct wrap
222{
223 t_object x_obj;
224 float x_f;
225} t_sigwrap;
226
227t_class *sigwrap_class;
228
229static void *sigwrap_new(void)
230{
231 t_sigwrap *x = (t_sigwrap *)pd_new(sigwrap_class);
232 outlet_new(&x->x_obj, gensym("signal"));
233 x->x_f = 0;
234 return (x);
235}
236
237static t_int *sigwrap_perform(t_int *w)
238{
239 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
240 t_int n = *(t_int *)(w+3);
241 while (n--)
242 {
243 float f = *in++;
244 int k = f;
245 if (f > 0) *out++ = f-k;
246 else *out++ = f - (k-1);
247 }
248 return (w + 4);
249}
250
251static void sigwrap_dsp(t_sigwrap *x, t_signal **sp)
252{
253 dsp_add(sigwrap_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
254}
255
256void sigwrap_setup(void)
257{
258 sigwrap_class = class_new(gensym("wrap~"), (t_newmethod)sigwrap_new, 0,
259 sizeof(t_sigwrap), 0, 0);
260 CLASS_MAINSIGNALIN(sigwrap_class, t_sigwrap, x_f);
261 class_addmethod(sigwrap_class, (t_method)sigwrap_dsp, gensym("dsp"), 0);
262}
263
264/* ------------------------------ mtof_tilde~ -------------------------- */
265
266typedef struct mtof_tilde
267{
268 t_object x_obj;
269 float x_f;
270} t_mtof_tilde;
271
272t_class *mtof_tilde_class;
273
274static void *mtof_tilde_new(void)
275{
276 t_mtof_tilde *x = (t_mtof_tilde *)pd_new(mtof_tilde_class);
277 outlet_new(&x->x_obj, gensym("signal"));
278 x->x_f = 0;
279 return (x);
280}
281
282static t_int *mtof_tilde_perform(t_int *w)
283{
284 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
285 t_int n = *(t_int *)(w+3);
286 for (; n--; in++, out++)
287 {
288 float f = *in;
289 if (f <= -1500) *out = 0;
290 else
291 {
292 if (f > 1499) f = 1499;
293 *out = 8.17579891564 * exp(.0577622650 * f);
294 }
295 }
296 return (w + 4);
297}
298
299static void mtof_tilde_dsp(t_mtof_tilde *x, t_signal **sp)
300{
301 dsp_add(mtof_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
302}
303
304void mtof_tilde_setup(void)
305{
306 mtof_tilde_class = class_new(gensym("mtof~"), (t_newmethod)mtof_tilde_new, 0,
307 sizeof(t_mtof_tilde), 0, 0);
308 CLASS_MAINSIGNALIN(mtof_tilde_class, t_mtof_tilde, x_f);
309 class_addmethod(mtof_tilde_class, (t_method)mtof_tilde_dsp, gensym("dsp"), 0);
310}
311
312/* ------------------------------ ftom_tilde~ -------------------------- */
313
314typedef struct ftom_tilde
315{
316 t_object x_obj;
317 float x_f;
318} t_ftom_tilde;
319
320t_class *ftom_tilde_class;
321
322static void *ftom_tilde_new(void)
323{
324 t_ftom_tilde *x = (t_ftom_tilde *)pd_new(ftom_tilde_class);
325 outlet_new(&x->x_obj, gensym("signal"));
326 x->x_f = 0;
327 return (x);
328}
329
330static t_int *ftom_tilde_perform(t_int *w)
331{
332 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
333 t_int n = *(t_int *)(w+3);
334 for (; n--; *in++, out++)
335 {
336 float f = *in;
337 *out = (f > 0 ? 17.3123405046 * log(.12231220585 * f) : -1500);
338 }
339 return (w + 4);
340}
341
342static void ftom_tilde_dsp(t_ftom_tilde *x, t_signal **sp)
343{
344 dsp_add(ftom_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
345}
346
347void ftom_tilde_setup(void)
348{
349 ftom_tilde_class = class_new(gensym("ftom~"), (t_newmethod)ftom_tilde_new, 0,
350 sizeof(t_ftom_tilde), 0, 0);
351 CLASS_MAINSIGNALIN(ftom_tilde_class, t_ftom_tilde, x_f);
352 class_addmethod(ftom_tilde_class, (t_method)ftom_tilde_dsp, gensym("dsp"), 0);
353}
354
355/* ------------------------------ dbtorms~ -------------------------- */
356
357typedef struct dbtorms_tilde
358{
359 t_object x_obj;
360 float x_f;
361} t_dbtorms_tilde;
362
363t_class *dbtorms_tilde_class;
364
365static void *dbtorms_tilde_new(void)
366{
367 t_dbtorms_tilde *x = (t_dbtorms_tilde *)pd_new(dbtorms_tilde_class);
368 outlet_new(&x->x_obj, gensym("signal"));
369 x->x_f = 0;
370 return (x);
371}
372
373static t_int *dbtorms_tilde_perform(t_int *w)
374{
375 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
376 t_int n = *(t_int *)(w+3);
377 for (; n--; in++, out++)
378 {
379 float f = *in;
380 if (f <= 0) *out = 0;
381 else
382 {
383 if (f > 485)
384 f = 485;
385 *out = exp((LOGTEN * 0.05) * (f-100.));
386 }
387 }
388 return (w + 4);
389}
390
391static void dbtorms_tilde_dsp(t_dbtorms_tilde *x, t_signal **sp)
392{
393 dsp_add(dbtorms_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
394}
395
396void dbtorms_tilde_setup(void)
397{
398 dbtorms_tilde_class = class_new(gensym("dbtorms~"), (t_newmethod)dbtorms_tilde_new, 0,
399 sizeof(t_dbtorms_tilde), 0, 0);
400 CLASS_MAINSIGNALIN(dbtorms_tilde_class, t_dbtorms_tilde, x_f);
401 class_addmethod(dbtorms_tilde_class, (t_method)dbtorms_tilde_dsp, gensym("dsp"), 0);
402}
403
404/* ------------------------------ rmstodb~ -------------------------- */
405
406typedef struct rmstodb_tilde
407{
408 t_object x_obj;
409 float x_f;
410} t_rmstodb_tilde;
411
412t_class *rmstodb_tilde_class;
413
414static void *rmstodb_tilde_new(void)
415{
416 t_rmstodb_tilde *x = (t_rmstodb_tilde *)pd_new(rmstodb_tilde_class);
417 outlet_new(&x->x_obj, gensym("signal"));
418 x->x_f = 0;
419 return (x);
420}
421
422static t_int *rmstodb_tilde_perform(t_int *w)
423{
424 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
425 t_int n = *(t_int *)(w+3);
426 for (; n--; in++, out++)
427 {
428 float f = *in;
429 if (f <= 0) *out = 0;
430 else
431 {
432 float g = 100 + 20./LOGTEN * log(f);
433 *out = (g < 0 ? 0 : g);
434 }
435 }
436 return (w + 4);
437}
438
439static void rmstodb_tilde_dsp(t_rmstodb_tilde *x, t_signal **sp)
440{
441 dsp_add(rmstodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
442}
443
444void rmstodb_tilde_setup(void)
445{
446 rmstodb_tilde_class = class_new(gensym("rmstodb~"), (t_newmethod)rmstodb_tilde_new, 0,
447 sizeof(t_rmstodb_tilde), 0, 0);
448 CLASS_MAINSIGNALIN(rmstodb_tilde_class, t_rmstodb_tilde, x_f);
449 class_addmethod(rmstodb_tilde_class, (t_method)rmstodb_tilde_dsp, gensym("dsp"), 0);
450}
451
452/* ------------------------------ dbtopow~ -------------------------- */
453
454typedef struct dbtopow_tilde
455{
456 t_object x_obj;
457 float x_f;
458} t_dbtopow_tilde;
459
460t_class *dbtopow_tilde_class;
461
462static void *dbtopow_tilde_new(void)
463{
464 t_dbtopow_tilde *x = (t_dbtopow_tilde *)pd_new(dbtopow_tilde_class);
465 outlet_new(&x->x_obj, gensym("signal"));
466 x->x_f = 0;
467 return (x);
468}
469
470static t_int *dbtopow_tilde_perform(t_int *w)
471{
472 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
473 t_int n = *(t_int *)(w+3);
474 for (; n--; in++, out++)
475 {
476 float f = *in;
477 if (f <= 0) *out = 0;
478 else
479 {
480 if (f > 870)
481 f = 870;
482 *out = exp((LOGTEN * 0.1) * (f-100.));
483 }
484 }
485 return (w + 4);
486}
487
488static void dbtopow_tilde_dsp(t_dbtopow_tilde *x, t_signal **sp)
489{
490 dsp_add(dbtopow_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
491}
492
493void dbtopow_tilde_setup(void)
494{
495 dbtopow_tilde_class = class_new(gensym("dbtopow~"), (t_newmethod)dbtopow_tilde_new, 0,
496 sizeof(t_dbtopow_tilde), 0, 0);
497 CLASS_MAINSIGNALIN(dbtopow_tilde_class, t_dbtopow_tilde, x_f);
498 class_addmethod(dbtopow_tilde_class, (t_method)dbtopow_tilde_dsp, gensym("dsp"), 0);
499}
500
501/* ------------------------------ powtodb~ -------------------------- */
502
503typedef struct powtodb_tilde
504{
505 t_object x_obj;
506 float x_f;
507} t_powtodb_tilde;
508
509t_class *powtodb_tilde_class;
510
511static void *powtodb_tilde_new(void)
512{
513 t_powtodb_tilde *x = (t_powtodb_tilde *)pd_new(powtodb_tilde_class);
514 outlet_new(&x->x_obj, gensym("signal"));
515 x->x_f = 0;
516 return (x);
517}
518
519static t_int *powtodb_tilde_perform(t_int *w)
520{
521 float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
522 t_int n = *(t_int *)(w+3);
523 for (; n--; in++, out++)
524 {
525 float f = *in;
526 if (f <= 0) *out = 0;
527 else
528 {
529 float g = 100 + 10./LOGTEN * log(f);
530 *out = (g < 0 ? 0 : g);
531 }
532 }
533 return (w + 4);
534}
535
536static void powtodb_tilde_dsp(t_powtodb_tilde *x, t_signal **sp)
537{
538 dsp_add(powtodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
539}
540
541void powtodb_tilde_setup(void)
542{
543 powtodb_tilde_class = class_new(gensym("powtodb~"), (t_newmethod)powtodb_tilde_new, 0,
544 sizeof(t_powtodb_tilde), 0, 0);
545 CLASS_MAINSIGNALIN(powtodb_tilde_class, t_powtodb_tilde, x_f);
546 class_addmethod(powtodb_tilde_class, (t_method)powtodb_tilde_dsp, gensym("dsp"), 0);
547}
548
549
550/* ------------------------ global setup routine ------------------------- */
551
552void d_math_setup(void)
553{
554 t_symbol *s = gensym("acoustics~.pd");
555 clip_setup();
556 sigrsqrt_setup();
557 sigsqrt_setup();
558 sigwrap_setup();
559 mtof_tilde_setup();
560 ftom_tilde_setup();
561 dbtorms_tilde_setup();
562 rmstodb_tilde_setup();
563 dbtopow_tilde_setup();
564 powtodb_tilde_setup();
565
566 class_sethelpsymbol(mtof_tilde_class, s);
567 class_sethelpsymbol(ftom_tilde_class, s);
568 class_sethelpsymbol(dbtorms_tilde_class, s);
569 class_sethelpsymbol(rmstodb_tilde_class, s);
570 class_sethelpsymbol(dbtopow_tilde_class, s);
571 class_sethelpsymbol(powtodb_tilde_class, s);
572}
573
diff --git a/apps/plugins/pdbox/PDa/src/d_osc.c b/apps/plugins/pdbox/PDa/src/d_osc.c
deleted file mode 100644
index 35b43b82c6..0000000000
--- a/apps/plugins/pdbox/PDa/src/d_osc.c
+++ /dev/null
@@ -1,535 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* sinusoidal oscillator and table lookup; see also tabosc4~ in d_array.c.
6*/
7
8#include "m_pd.h"
9#include "math.h"
10
11#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
12
13 /* machine-dependent definitions. These ifdefs really
14 should have been by CPU type and not by operating system! */
15#ifdef IRIX
16 /* big-endian. Most significant byte is at low address in memory */
17#define HIOFFSET 0 /* word offset to find MSB */
18#define LOWOFFSET 1 /* word offset to find LSB */
19#define int32 long /* a data type that has 32 bits */
20#else
21#ifdef MSW
22 /* little-endian; most significant byte is at highest address */
23#define HIOFFSET 1
24#define LOWOFFSET 0
25#define int32 long
26#else
27#ifdef __FreeBSD__
28#include <machine/endian.h>
29#if BYTE_ORDER == LITTLE_ENDIAN
30#define HIOFFSET 1
31#define LOWOFFSET 0
32#else
33#define HIOFFSET 0 /* word offset to find MSB */
34#define LOWOFFSET 1 /* word offset to find LSB */
35#endif /* BYTE_ORDER */
36#include <sys/types.h>
37#define int32 int32_t
38#endif
39#ifdef __linux__
40
41#include <endian.h>
42
43#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
44#error No byte order defined
45#endif
46
47#if __BYTE_ORDER == __LITTLE_ENDIAN
48#define HIOFFSET 1
49#define LOWOFFSET 0
50#else
51#define HIOFFSET 0 /* word offset to find MSB */
52#define LOWOFFSET 1 /* word offset to find LSB */
53#endif /* __BYTE_ORDER */
54
55#include <sys/types.h>
56#define int32 int32_t
57
58#else
59#ifdef MACOSX
60#define HIOFFSET 0 /* word offset to find MSB */
61#define LOWOFFSET 1 /* word offset to find LSB */
62#define int32 int /* a data type that has 32 bits */
63
64#endif /* MACOSX */
65#endif /* __linux__ */
66#endif /* MSW */
67#endif /* SGI */
68
69union tabfudge
70{
71 double tf_d;
72 int32 tf_i[2];
73};
74
75
76/* -------------------------- phasor~ ------------------------------ */
77static t_class *phasor_class, *scalarphasor_class;
78
79#if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */
80
81typedef struct _phasor
82{
83 t_object x_obj;
84 double x_phase;
85 float x_conv;
86 float x_f; /* scalar frequency */
87} t_phasor;
88
89static void *phasor_new(t_floatarg f)
90{
91 t_phasor *x = (t_phasor *)pd_new(phasor_class);
92 x->x_f = f;
93 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
94 x->x_phase = 0;
95 x->x_conv = 0;
96 outlet_new(&x->x_obj, gensym("signal"));
97 return (x);
98}
99
100static t_int *phasor_perform(t_int *w)
101{
102 t_phasor *x = (t_phasor *)(w[1]);
103 t_float *in = (t_float *)(w[2]);
104 t_float *out = (t_float *)(w[3]);
105 int n = (int)(w[4]);
106 double dphase = x->x_phase + UNITBIT32;
107 union tabfudge tf;
108 int normhipart;
109 float conv = x->x_conv;
110
111 tf.tf_d = UNITBIT32;
112 normhipart = tf.tf_i[HIOFFSET];
113 tf.tf_d = dphase;
114
115 while (n--)
116 {
117 tf.tf_i[HIOFFSET] = normhipart;
118 dphase += *in++ * conv;
119 *out++ = tf.tf_d - UNITBIT32;
120 tf.tf_d = dphase;
121 }
122 tf.tf_i[HIOFFSET] = normhipart;
123 x->x_phase = tf.tf_d - UNITBIT32;
124 return (w+5);
125}
126
127static void phasor_dsp(t_phasor *x, t_signal **sp)
128{
129 x->x_conv = 1./sp[0]->s_sr;
130 dsp_add(phasor_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
131}
132
133static void phasor_ft1(t_phasor *x, t_float f)
134{
135 x->x_phase = f;
136}
137
138static void phasor_setup(void)
139{
140 phasor_class = class_new(gensym("phasor~"), (t_newmethod)phasor_new, 0,
141 sizeof(t_phasor), 0, A_DEFFLOAT, 0);
142 CLASS_MAINSIGNALIN(phasor_class, t_phasor, x_f);
143 class_addmethod(phasor_class, (t_method)phasor_dsp, gensym("dsp"), 0);
144 class_addmethod(phasor_class, (t_method)phasor_ft1,
145 gensym("ft1"), A_FLOAT, 0);
146}
147
148#endif /* Hoeldrich version */
149
150/* ------------------------ cos~ ----------------------------- */
151
152float *cos_table;
153
154static t_class *cos_class;
155
156typedef struct _cos
157{
158 t_object x_obj;
159 float x_f;
160} t_cos;
161
162static void *cos_new(void)
163{
164 t_cos *x = (t_cos *)pd_new(cos_class);
165 outlet_new(&x->x_obj, gensym("signal"));
166 x->x_f = 0;
167 return (x);
168}
169
170static t_int *cos_perform(t_int *w)
171{
172 t_float *in = (t_float *)(w[1]);
173 t_float *out = (t_float *)(w[2]);
174 int n = (int)(w[3]);
175 float *tab = cos_table, *addr, f1, f2, frac;
176 double dphase;
177 int normhipart;
178 union tabfudge tf;
179
180 tf.tf_d = UNITBIT32;
181 normhipart = tf.tf_i[HIOFFSET];
182
183#if 0 /* this is the readable version of the code. */
184 while (n--)
185 {
186 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
187 tf.tf_d = dphase;
188 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
189 tf.tf_i[HIOFFSET] = normhipart;
190 frac = tf.tf_d - UNITBIT32;
191 f1 = addr[0];
192 f2 = addr[1];
193 *out++ = f1 + frac * (f2 - f1);
194 }
195#endif
196#if 1 /* this is the same, unwrapped by hand. */
197 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
198 tf.tf_d = dphase;
199 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
200 tf.tf_i[HIOFFSET] = normhipart;
201 while (--n)
202 {
203 dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
204 frac = tf.tf_d - UNITBIT32;
205 tf.tf_d = dphase;
206 f1 = addr[0];
207 f2 = addr[1];
208 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
209 *out++ = f1 + frac * (f2 - f1);
210 tf.tf_i[HIOFFSET] = normhipart;
211 }
212 frac = tf.tf_d - UNITBIT32;
213 f1 = addr[0];
214 f2 = addr[1];
215 *out++ = f1 + frac * (f2 - f1);
216#endif
217 return (w+4);
218}
219
220static void cos_dsp(t_cos *x, t_signal **sp)
221{
222 dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
223}
224
225static void cos_maketable(void)
226{
227 int i;
228 float *fp, phase, phsinc = (2. * 3.14159) / COSTABSIZE;
229 union tabfudge tf;
230
231 if (cos_table) return;
232 cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
233 for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
234 fp++, phase += phsinc)
235 *fp = cos(phase);
236
237 /* here we check at startup whether the byte alignment
238 is as we declared it. If not, the code has to be
239 recompiled the other way. */
240 tf.tf_d = UNITBIT32 + 0.5;
241 if ((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
242 bug("cos~: unexpected machine alignment");
243}
244
245static void cos_setup(void)
246{
247 cos_class = class_new(gensym("cos~"), (t_newmethod)cos_new, 0,
248 sizeof(t_cos), 0, A_DEFFLOAT, 0);
249 CLASS_MAINSIGNALIN(cos_class, t_cos, x_f);
250 class_addmethod(cos_class, (t_method)cos_dsp, gensym("dsp"), 0);
251 cos_maketable();
252}
253
254/* ------------------------ osc~ ----------------------------- */
255
256static t_class *osc_class, *scalarosc_class;
257
258typedef struct _osc
259{
260 t_object x_obj;
261 double x_phase;
262 float x_conv;
263 float x_f; /* frequency if scalar */
264} t_osc;
265
266static void *osc_new(t_floatarg f)
267{
268 t_osc *x = (t_osc *)pd_new(osc_class);
269 x->x_f = f;
270 outlet_new(&x->x_obj, gensym("signal"));
271 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
272 x->x_phase = 0;
273 x->x_conv = 0;
274 return (x);
275}
276
277static t_int *osc_perform(t_int *w)
278{
279 t_osc *x = (t_osc *)(w[1]);
280 t_float *in = (t_float *)(w[2]);
281 t_float *out = (t_float *)(w[3]);
282 int n = (int)(w[4]);
283 float *tab = cos_table, *addr, f1, f2, frac;
284 double dphase = x->x_phase + UNITBIT32;
285 int normhipart;
286 union tabfudge tf;
287 float conv = x->x_conv;
288
289 tf.tf_d = UNITBIT32;
290 normhipart = tf.tf_i[HIOFFSET];
291#if 0
292 while (n--)
293 {
294 tf.tf_d = dphase;
295 dphase += *in++ * conv;
296 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
297 tf.tf_i[HIOFFSET] = normhipart;
298 frac = tf.tf_d - UNITBIT32;
299 f1 = addr[0];
300 f2 = addr[1];
301 *out++ = f1 + frac * (f2 - f1);
302 }
303#endif
304#if 1
305 tf.tf_d = dphase;
306 dphase += *in++ * conv;
307 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
308 tf.tf_i[HIOFFSET] = normhipart;
309 frac = tf.tf_d - UNITBIT32;
310 while (--n)
311 {
312 tf.tf_d = dphase;
313 f1 = addr[0];
314 dphase += *in++ * conv;
315 f2 = addr[1];
316 addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
317 tf.tf_i[HIOFFSET] = normhipart;
318 *out++ = f1 + frac * (f2 - f1);
319 frac = tf.tf_d - UNITBIT32;
320 }
321 f1 = addr[0];
322 f2 = addr[1];
323 *out++ = f1 + frac * (f2 - f1);
324#endif
325
326 tf.tf_d = UNITBIT32 * COSTABSIZE;
327 normhipart = tf.tf_i[HIOFFSET];
328 tf.tf_d = dphase + (UNITBIT32 * COSTABSIZE - UNITBIT32);
329 tf.tf_i[HIOFFSET] = normhipart;
330 x->x_phase = tf.tf_d - UNITBIT32 * COSTABSIZE;
331 return (w+5);
332}
333
334static void osc_dsp(t_osc *x, t_signal **sp)
335{
336 x->x_conv = COSTABSIZE/sp[0]->s_sr;
337 dsp_add(osc_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
338}
339
340static void osc_ft1(t_osc *x, t_float f)
341{
342 x->x_phase = COSTABSIZE * f;
343}
344
345static void osc_setup(void)
346{
347 osc_class = class_new(gensym("osc~"), (t_newmethod)osc_new, 0,
348 sizeof(t_osc), 0, A_DEFFLOAT, 0);
349 CLASS_MAINSIGNALIN(osc_class, t_osc, x_f);
350 class_addmethod(osc_class, (t_method)osc_dsp, gensym("dsp"), 0);
351 class_addmethod(osc_class, (t_method)osc_ft1, gensym("ft1"), A_FLOAT, 0);
352
353 cos_maketable();
354}
355
356/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
357
358typedef struct vcfctl
359{
360 float c_re;
361 float c_im;
362 float c_q;
363 float c_isr;
364} t_vcfctl;
365
366typedef struct sigvcf
367{
368 t_object x_obj;
369 t_vcfctl x_cspace;
370 t_vcfctl *x_ctl;
371 float x_f;
372} t_sigvcf;
373
374t_class *sigvcf_class;
375
376static void *sigvcf_new(t_floatarg q)
377{
378 t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class);
379 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
380 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
381 outlet_new(&x->x_obj, gensym("signal"));
382 outlet_new(&x->x_obj, gensym("signal"));
383 x->x_ctl = &x->x_cspace;
384 x->x_cspace.c_re = 0;
385 x->x_cspace.c_im = 0;
386 x->x_cspace.c_q = q;
387 x->x_cspace.c_isr = 0;
388 x->x_f = 0;
389 return (x);
390}
391
392static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
393{
394 x->x_ctl->c_q = (f > 0 ? f : 0.f);
395}
396
397static t_int *sigvcf_perform(t_int *w)
398{
399 float *in1 = (float *)(w[1]);
400 float *in2 = (float *)(w[2]);
401 float *out1 = (float *)(w[3]);
402 float *out2 = (float *)(w[4]);
403 t_vcfctl *c = (t_vcfctl *)(w[5]);
404 int n = (t_int)(w[6]);
405 int i;
406 float re = c->c_re, re2;
407 float im = c->c_im;
408 float q = c->c_q;
409 float qinv = (q > 0? 1.0f/q : 0);
410 float ampcorrect = 2.0f - 2.0f / (q + 2.0f);
411 float isr = c->c_isr;
412 float coefr, coefi;
413 float *tab = cos_table, *addr, f1, f2, frac;
414 double dphase;
415 int normhipart, tabindex;
416 union tabfudge tf;
417
418 tf.tf_d = UNITBIT32;
419 normhipart = tf.tf_i[HIOFFSET];
420
421 for (i = 0; i < n; i++)
422 {
423 float cf, cfindx, r, oneminusr;
424 cf = *in2++ * isr;
425 if (cf < 0) cf = 0;
426 cfindx = cf * (float)(COSTABSIZE/6.28318f);
427 r = (qinv > 0 ? 1 - cf * qinv : 0);
428 if (r < 0) r = 0;
429 oneminusr = 1.0f - r;
430 dphase = ((double)(cfindx)) + UNITBIT32;
431 tf.tf_d = dphase;
432 tabindex = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
433 addr = tab + tabindex;
434 tf.tf_i[HIOFFSET] = normhipart;
435 frac = tf.tf_d - UNITBIT32;
436 f1 = addr[0];
437 f2 = addr[1];
438 coefr = r * (f1 + frac * (f2 - f1));
439
440 addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1));
441 f1 = addr[0];
442 f2 = addr[1];
443 coefi = r * (f1 + frac * (f2 - f1));
444
445 f1 = *in1++;
446 re2 = re;
447 *out1++ = re = ampcorrect * oneminusr * f1
448 + coefr * re2 - coefi * im;
449 *out2++ = im = coefi * re2 + coefr * im;
450 }
451 if (PD_BIGORSMALL(re))
452 re = 0;
453 if (PD_BIGORSMALL(im))
454 im = 0;
455 c->c_re = re;
456 c->c_im = im;
457 return (w+7);
458}
459
460static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
461{
462 x->x_ctl->c_isr = 6.28318f/sp[0]->s_sr;
463 dsp_add(sigvcf_perform, 6,
464 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
465 x->x_ctl, sp[0]->s_n);
466
467}
468
469void sigvcf_setup(void)
470{
471 sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0,
472 sizeof(t_sigvcf), 0, A_DEFFLOAT, 0);
473 CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f);
474 class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0);
475 class_addmethod(sigvcf_class, (t_method)sigvcf_ft1,
476 gensym("ft1"), A_FLOAT, 0);
477}
478
479/* -------------------------- noise~ ------------------------------ */
480static t_class *noise_class;
481
482typedef struct _noise
483{
484 t_object x_obj;
485 int x_val;
486} t_noise;
487
488static void *noise_new(void)
489{
490 t_noise *x = (t_noise *)pd_new(noise_class);
491 static int init = 307;
492 x->x_val = (init *= 1319);
493 outlet_new(&x->x_obj, gensym("signal"));
494 return (x);
495}
496
497static t_int *noise_perform(t_int *w)
498{
499 t_float *out = (t_float *)(w[1]);
500 int *vp = (int *)(w[2]);
501 int n = (int)(w[3]);
502 int val = *vp;
503 while (n--)
504 {
505 *out++ = ((float)((val & 0x7fffffff) - 0x40000000)) *
506 (float)(1.0 / 0x40000000);
507 val = val * 435898247 + 382842987;
508 }
509 *vp = val;
510 return (w+4);
511}
512
513static void noise_dsp(t_noise *x, t_signal **sp)
514{
515 dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
516}
517
518static void noise_setup(void)
519{
520 noise_class = class_new(gensym("noise~"), (t_newmethod)noise_new, 0,
521 sizeof(t_noise), 0, 0);
522 class_addmethod(noise_class, (t_method)noise_dsp, gensym("dsp"), 0);
523}
524
525
526/* ----------------------- global setup routine ---------------- */
527void d_osc_setup(void)
528{
529 phasor_setup();
530 cos_setup();
531 osc_setup();
532 sigvcf_setup();
533 noise_setup();
534}
535
diff --git a/apps/plugins/pdbox/PDa/src/delme.pd b/apps/plugins/pdbox/PDa/src/delme.pd
deleted file mode 100644
index 1d4b9fa031..0000000000
--- a/apps/plugins/pdbox/PDa/src/delme.pd
+++ /dev/null
@@ -1,9 +0,0 @@
1#N canvas 0 0 236 296 10;
2#X obj 79 77 gcanvas 80 80 0 0;
3#X floatatom 42 209 5 0 0 0 - - -;
4#X floatatom 107 205 5 0 0 0 - - -;
5#X floatatom 149 210 5 0 0 0 - - -;
6#X connect 0 0 1 0;
7#X connect 0 1 2 0;
8#X connect 0 2 3 0;
9
diff --git a/apps/plugins/pdbox/PDa/src/makefile b/apps/plugins/pdbox/PDa/src/makefile
deleted file mode 100644
index 3f074c4a74..0000000000
--- a/apps/plugins/pdbox/PDa/src/makefile
+++ /dev/null
@@ -1,176 +0,0 @@
1PREFIX = /usr/
2EXT = pd_linux
3
4# pd specific
5
6VPATH = ../obj:./
7OBJ_DIR = ../obj
8BIN_DIR = ../bin
9
10BROOT=/usr
11X11LIB = $(BROOT)/X11R6/lib
12
13DEFINES = -DPD -DUNIX
14
15pd-gui_INCLUDES = -I$(BROOT)/include/tcl8.4 -I$(BROOT)/X11R6/include
16pd-gui_LIBS = -ltk8.4 -ltcl8.4 -lX11 -ldl
17pd-gui_LDFLAGS = -L$(X11LIB)
18pd-gui_DEFINES = $(DEFINES)
19
20pd_LIBS = -lm -lpthread -ldl
21pd_LDFLAGS = -Wl,-export-dynamic
22pd_DEFINES = $(DEFINES) -DINSTALL_PREFIX=\"$(PREFIX)\" \
23 -DFIXEDPOINT -DUSEAPI_OSS -DDL_OPEN
24
25extra_DEFINES = $(DEFINES) -DFIXEDPOINT
26extra_INCLUDES = -I../src
27extra_LDFLAGS = -shared
28
29# IPOD toolchain
30
31ifeq ($(CC), arm-elf-gcc)
32pd_LDFLAGS += -elf2flt
33pd_LIBS = -lm -lpthread
34pd_DEFINES = $(DEFINES) -DINSTALL_PREFIX=\"$(PREFIX)\" \
35 -DFIXEDPOINT -DUSEAPI_OSS -D__linux__ -Dfork=getpid
36extra_DEFINES += -D__linux__ -Dfork=getpid
37endif
38
39# BLACKFIN toolchain
40
41ifeq ($(CC), bfin-uclinux-gcc)
42pd_LIBS = -lm -lpthread
43pd_DEFINES = $(DEFINES) -DINSTALL_PREFIX=\"$(PREFIX)\" \
44 -DFIXEDPOINT -DUSEAPI_OSS -D__linux__
45extra_DEFINES += -D__linux__
46endif
47
48# the sources
49
50pd_SRC = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_io.c \
51 g_scalar.c g_traversal.c g_guiconnect.c g_readwrite.c g_editor.c \
52 g_all_guis.c g_bang.c g_hdial.c g_hslider.c g_mycanvas.c g_numbox.c \
53 g_toggle.c g_vdial.c g_vslider.c g_vumeter.c \
54 m_pd.c m_class.c m_obj.c m_atom.c m_memory.c m_binbuf.c \
55 m_conf.c m_glob.c m_sched.c \
56 s_main.c s_inter.c s_file.c s_print.c \
57 s_loader.c s_path.c s_entry.c s_audio.c s_midi.c \
58 d_ugen.c d_arithmetic.c d_dac.c d_misc.c \
59 d_fft.c d_mayer_fft.c d_fftroutine.c d_global.c \
60 d_resample.c d_ctl.c d_soundfile.c \
61 x_arithmetic.c x_connective.c x_interface.c x_midi.c x_misc.c \
62 x_time.c x_acoustics.c x_net.c x_qlist.c x_gui.c \
63 s_midi_oss.c s_audio_oss.c
64
65pd_SRC += d_imayer_fft.c m_fixed.c
66
67pd_OBJ = $(pd_SRC:.c=.o)
68
69pd-gui_SRC = t_main.c t_tkcmd.c
70pd-gui_OBJ = $(pd-gui_SRC:.c=.o)
71
72extra_SRC = $(shell ls ../intern/*.c) $(shell ls ../extra/*.c)
73extra_OBJ = $(extra_SRC:.c=.o)
74extra_EXT = $(extra_SRC:.c=.pd_linux)
75
76#
77# ------------------ targets ------------------------------------
78#
79
80all: $(BIN_DIR)/pd \
81 $(BIN_DIR)/pd-gui \
82 $(BIN_DIR)/pd-watchdog \
83 $(BIN_DIR)/pdsend \
84 $(BIN_DIR)/pdreceive \
85 $(BIN_DIR)/pd.tk \
86 extra
87
88pd: $(BIN_DIR)/pd
89pd-gui: $(BIN_DIR)/pd-gui
90pd-watchdog: $(BIN_DIR)/pd-watchdog
91
92static:
93 make pd_SRC="$(pd_SRC) $(extra_SRC)" DEFINES="-DPD -DUNIX -DSTATIC" \
94 pd pd-gui pd-watchdog $(BIN_DIR)/pdsend \
95 $(BIN_DIR)/pdreceive $(BIN_DIR)/pd.tk
96
97extra: $(extra_EXT)
98
99ipod:
100 make CC=arm-elf-gcc static
101
102blackfin:
103 make CC=bfin-uclinux-gcc static
104
105$(pd_OBJ) : %.o : %.c
106 $(CC) $(CFLAGS) $(pd_DEFINES) $(pd_INCLUDES) -c -o $(OBJ_DIR)/$@ $+
107
108$(pd-gui_OBJ) : %.o : %.c
109 $(CC) $(CFLAGS) $(pd-gui_DEFINES) $(pd-gui_INCLUDES) -c -o $(OBJ_DIR)/$@ $+
110
111$(extra_OBJ) : %.o : %.c
112 $(CC) $(CFLAGS) $(extra_DEFINES) $(extra_INCLUDES) -c -o $@ $*.c
113
114$(extra_EXT) : %.$(EXT) : %.o
115 $(CC) -o $@ $(extra_LDFLAGS) $+
116
117$(BIN_DIR)/pd-watchdog: s_watchdog.c
118 $(CC) $(CFLAGS) $(DEFINES) -o $@ s_watchdog.c
119
120$(BIN_DIR)/pdsend: u_pdsend.c
121 $(CC) $(CFLAGS) $(DEFINES) -o $@ u_pdsend.c
122
123$(BIN_DIR)/pdreceive: u_pdreceive.c
124 $(CC) $(CFLAGS) $(DEFINES) -o $@ u_pdreceive.c
125
126$(BIN_DIR)/pd: $(pd_OBJ)
127 cd ../obj; $(CC) $(pd_LDFLAGS) -o $@ $(pd_OBJ) $(pd_LIBS)
128
129$(BIN_DIR)/pd-gui: $(pd-gui_OBJ)
130 cd ../obj; $(CC) -o $@ $(pd-gui_OBJ) $(pd-gui_LDFLAGS) $(pd-gui_LIBS)
131
132$(BIN_DIR)/pd.tk: u_main.tk
133 echo set pd_nt 0 > $(BIN_DIR)/pd.tk
134 grep -v "set pd_nt" < u_main.tk >> $@
135
136INSTDIR = $(DESTDIR)/$(PREFIX)
137
138install: all
139# Create the directory structure
140
141 install -d $(INSTDIR)/lib/pd/bin
142 install -d $(INSTDIR)/lib/pd/extra
143 install -d $(INSTDIR)/lib/pd/intern
144 install -d $(INSTDIR)/lib/pd/doc
145 install -d $(INSTDIR)/bin
146 install -d $(INSTDIR)/include
147
148 install $(BIN_DIR)/pd-gui $(INSTDIR)/lib/pd/bin/
149 install $(BIN_DIR)/pd-watchdog $(INSTDIR)/lib/pd/bin/
150 install -m 644 $(BIN_DIR)/pd.tk $(INSTDIR)/lib/pd/bin/
151 install -m 755 $(BIN_DIR)/pd $(INSTDIR)/bin/
152 install -m 755 $(BIN_DIR)/pdsend $(INSTDIR)/bin/pdsend
153 install -m 755 $(BIN_DIR)/pdreceive $(INSTDIR)/bin/pdreceive
154 cp -r ../doc/7.stuff $(INSTDIR)/lib/pd/doc
155 cp -r ../doc/5.reference $(INSTDIR)/lib/pd/doc
156 install -m 644 m_pd.h $(INSTDIR)/include/m_pd.h
157
158# Install the externals if possible
159 cp ../extra/*.pd_linux $(INSTDIR)/lib/pd/extra
160 cp ../intern/*.pd_linux $(INSTDIR)/lib/pd/intern
161
162# Install the ICON and desktop file
163 install -d $(INSTDIR)/share/pixmaps
164 install -d $(INSTDIR)/share/applications
165 cp ../ipkg/pd-icon.png $(INSTDIR)/share/pixmaps
166 cp ../ipkg/pd.desktop $(INSTDIR)/share/applications/
167
168
169
170clean:
171 -rm -f `find ../extra/ -name "*.pd_*"`
172 -rm -f tags
173 -rm -f ../obj/* $(BIN_DIR)/* ../extra/*.{o,$(EXT)} ../intern/*.{o,$(EXT)}
174 -rm -f *~
175 -rm -f $(BIN_DIR)/pdsend $(BIN_DIR)/pdreceive
176
diff --git a/apps/plugins/pdbox/PDa/src/s_audio_alsa.c b/apps/plugins/pdbox/PDa/src/s_audio_alsa.c
deleted file mode 100644
index b8e8535dc9..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_audio_alsa.c
+++ /dev/null
@@ -1,946 +0,0 @@
1/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler,
2* Winfried Ritsch, Karl MacMillan, and others.
3* For information on usage and redistribution, and for a DISCLAIMER OF ALL
4* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5
6/* this file inputs and outputs audio using the ALSA API available on linux. */
7
8#include <alsa/asoundlib.h>
9
10#include "m_pd.h"
11#include "s_stuff.h"
12#include <errno.h>
13#include <stdio.h>
14#include <unistd.h>
15#include <stdlib.h>
16#include <string.h>
17#include <sys/types.h>
18#include <sys/time.h>
19#include <sys/stat.h>
20#include <sys/ioctl.h>
21#include <fcntl.h>
22#include <sched.h>
23#include <sys/mman.h>
24
25typedef int16_t t_alsa_sample16;
26typedef int32_t t_alsa_sample32;
27#define ALSA_SAMPLEWIDTH_16 sizeof(t_alsa_sample16)
28#define ALSA_SAMPLEWIDTH_32 sizeof(t_alsa_sample32)
29#define ALSA_XFERSIZE16 (signed int)(sizeof(t_alsa_sample16) * DEFDACBLKSIZE)
30#define ALSA_XFERSIZE32 (signed int)(sizeof(t_alsa_sample32) * DEFDACBLKSIZE)
31#define ALSA_MAXDEV 1
32#define ALSA_JITTER 1024
33#define ALSA_EXTRABUFFER 2048
34#define ALSA_DEFFRAGSIZE 64
35#define ALSA_DEFNFRAG 12
36
37#ifndef INT32_MAX
38#define INT32_MAX 0x7fffffff
39#endif
40
41#if (SND_LIB_MAJOR < 1)
42#define ALSAAPI9
43#endif
44
45typedef struct _alsa_dev
46{
47 snd_pcm_t *inhandle;
48 snd_pcm_t *outhandle;
49 int innoninterleave; /* true if we're set for noninterleaved read */
50 int outnoninterleave; /* same for write */
51} t_alsa_dev;
52
53t_alsa_dev alsa_device;
54static void *alsa_snd_buf = 0;
55static void **alsa_buf_ptrs;
56static int alsa_samplewidth;
57static snd_pcm_status_t* in_status;
58static snd_pcm_status_t* out_status;
59
60static int alsa_mode;
61static int alsa_buf_samps; /* believed actual ALSA bufsize in sample frames */
62static int alsa_inchannels;
63static int alsa_outchannels;
64
65/* Defines */
66#define DEBUG(x) x
67#define DEBUG2(x) {x;}
68
69static void alsa_checkiosync( void);
70static void alsa_numbertoname(int devno, char *devname, int nchar);
71
72 /* don't assume we can turn all 31 bits when doing float-to-fix;
73 otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */
74#define FMAX 0x7ffff000
75#define CLIP32(x) (((x)>FMAX)?FMAX:((x) < -FMAX)?-FMAX:(x))
76
77/* support for ALSA pcmv2 api by Karl MacMillan<karlmac@peabody.jhu.edu> */
78
79static void check_error(int err, const char *why)
80{
81 if (err < 0)
82 fprintf(stderr, "%s: %s\n", why, snd_strerror(err));
83}
84
85/* was: alsa_open_audio(int wantinchans, int wantoutchans, int srate) */
86
87int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
88 int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
89 int *choutdev, int rate)
90{
91 int err, inchans = 0, outchans = 0, subunitdir;
92 char devname[512];
93 snd_pcm_hw_params_t* hw_params;
94 snd_pcm_sw_params_t* sw_params;
95 snd_output_t* out;
96 int frag_size = (sys_blocksize ? sys_blocksize : ALSA_DEFFRAGSIZE);
97 int nfrags, i;
98 short* tmp_buf;
99 unsigned int tmp_uint;
100 snd_pcm_uframes_t tmp_snd_pcm_uframes;
101 int wantinchans, wantoutchans, devno;
102
103 if (naudioindev >= 2 || naudiooutdev >= 2)
104 post("alsa: only one input and output device allowed (extras ignored");
105 if (naudioindev >= 1 && naudiooutdev >= 1 &&
106 audioindev[0] != audiooutdev[0])
107 post("alsa: changing output device to agree with input device");
108 if (nchindev)
109 wantinchans = chindev[0];
110 else wantinchans = (naudioindev ? 2 : 0);
111 if (nchoutdev)
112 wantoutchans = choutdev[0];
113 else wantoutchans = (naudiooutdev ? 2 : 0);
114 devno = (naudioindev > 0 ? audioindev[0] :
115 (naudiooutdev > 0 ? audiooutdev[0] : 0));
116
117 alsa_numbertoname(devno, devname, 512);
118
119 if (sys_verbose)
120 post("device name %s; channels in %d, out %d", devname, wantinchans,
121 wantoutchans);
122
123 nfrags = sys_schedadvance * (float)rate / (1e6 * frag_size);
124 /* save our belief as to ALSA's buffer size for later */
125 alsa_buf_samps = nfrags * frag_size;
126
127 if (sys_verbose)
128 post("audio buffer set to %d", (int)(0.001 * sys_schedadvance));
129
130 alsa_device.innoninterleave = alsa_device.outnoninterleave = 0;
131 if (wantinchans)
132 {
133 err = snd_pcm_open(&alsa_device.inhandle, devname,
134 SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
135
136 check_error(err, "snd_pcm_open (input)");
137 if (err < 0)
138 inchans = 0;
139 else
140 {
141 inchans = wantinchans;
142 snd_pcm_nonblock(alsa_device.inhandle, 1);
143 }
144 }
145 if (wantoutchans)
146 {
147 err = snd_pcm_open(&alsa_device.outhandle, devname,
148 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
149
150 check_error(err, "snd_pcm_open (output)");
151 if (err < 0)
152 outchans = 0;
153 else
154 {
155 outchans = wantoutchans;
156 snd_pcm_nonblock(alsa_device.outhandle, 1);
157 }
158 }
159 if (inchans)
160 {
161 if (sys_verbose)
162 post("opening sound input...");
163 err = snd_pcm_hw_params_malloc(&hw_params);
164 check_error(err, "snd_pcm_hw_params_malloc (input)");
165
166 // get the default params
167 err = snd_pcm_hw_params_any(alsa_device.inhandle, hw_params);
168 check_error(err, "snd_pcm_hw_params_any (input)");
169
170 /* try to set interleaved access */
171 err = snd_pcm_hw_params_set_access(alsa_device.inhandle,
172 hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
173 if (err < 0)
174 {
175 /* OK, so try non-interleaved */
176 err = snd_pcm_hw_params_set_access(alsa_device.inhandle,
177 hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED);
178 if (err >= 0)
179 {
180 post("using non-interleaved audio input");
181 alsa_device.innoninterleave = 1;
182 }
183 }
184 check_error(err, "snd_pcm_hw_params_set_access (input)");
185 // Try to set 32 bit format first
186 err = snd_pcm_hw_params_set_format(alsa_device.inhandle, hw_params,
187 SND_PCM_FORMAT_S32);
188 if (err < 0)
189 {
190 /* fprintf(stderr,
191 "PD-ALSA: 32 bit format not available - using 16\n"); */
192 err = snd_pcm_hw_params_set_format(alsa_device.inhandle, hw_params,
193 SND_PCM_FORMAT_S16);
194 check_error(err, "snd_pcm_hw_params_set_format (input)");
195 alsa_samplewidth = 2;
196 }
197 else
198 {
199 alsa_samplewidth = 4;
200 }
201 post("Sample width set to %d bytes", alsa_samplewidth);
202 // set the subformat
203 err = snd_pcm_hw_params_set_subformat(alsa_device.inhandle, hw_params,
204 SND_PCM_SUBFORMAT_STD);
205 check_error(err, "snd_pcm_hw_params_set_subformat (input)");
206 // set the number of channels
207 tmp_uint = inchans;
208 err = snd_pcm_hw_params_set_channels_min(alsa_device.inhandle,
209 hw_params, &tmp_uint);
210 check_error(err, "snd_pcm_hw_params_set_channels (input)");
211 if (tmp_uint != (unsigned)inchans)
212 post("ALSA: set input channels to %d", tmp_uint);
213 inchans = tmp_uint;
214 // set the sampling rate
215 err = snd_pcm_hw_params_set_rate_min(alsa_device.inhandle, hw_params,
216 &rate, 0);
217 check_error(err, "snd_pcm_hw_params_set_rate_min (input)");
218#if 0
219 err = snd_pcm_hw_params_get_rate(hw_params, &subunitdir);
220 post("input sample rate %d", err);
221#endif
222 // set the period - ie frag size
223 // post("fragsize a %d", frag_size);
224
225 /* LATER try this to get a recommended period size...
226 right now, it trips an assertion failure in ALSA lib */
227#if 0
228 post("input period was %d, min %d, max %d\n",
229 snd_pcm_hw_params_get_period_size(hw_params, 0),
230 snd_pcm_hw_params_get_period_size_min(hw_params, 0),
231 snd_pcm_hw_params_get_period_size_max(hw_params, 0));
232#endif
233#ifdef ALSAAPI9
234 err = snd_pcm_hw_params_set_period_size_near(alsa_device.inhandle,
235 hw_params,
236 (snd_pcm_uframes_t)
237 frag_size, 0);
238#else
239 tmp_snd_pcm_uframes = frag_size;
240 err = snd_pcm_hw_params_set_period_size_near(alsa_device.inhandle,
241 hw_params, &tmp_snd_pcm_uframes, 0);
242#endif
243 check_error(err, "snd_pcm_hw_params_set_period_size_near (input)");
244 // post("fragsize b %d", frag_size);
245 // set the number of periods - ie numfrags
246 // post("nfrags a %d", nfrags);
247#ifdef ALSAAPI9
248 err = snd_pcm_hw_params_set_periods_near(alsa_device.inhandle,
249 hw_params, nfrags, 0);
250#else
251 tmp_uint = nfrags;
252 err = snd_pcm_hw_params_set_periods_near(alsa_device.inhandle,
253 hw_params, &tmp_uint, 0);
254#endif
255 check_error(err, "snd_pcm_hw_params_set_periods_near (input)");
256 // set the buffer size
257#ifdef ALSAAPI9
258 err = snd_pcm_hw_params_set_buffer_size_near(alsa_device.inhandle,
259 hw_params, nfrags * frag_size);
260#else
261 tmp_snd_pcm_uframes = nfrags * frag_size;
262 err = snd_pcm_hw_params_set_buffer_size_near(alsa_device.inhandle,
263 hw_params, &tmp_snd_pcm_uframes);
264#endif
265 check_error(err, "snd_pcm_hw_params_set_buffer_size_near (input)");
266
267 err = snd_pcm_hw_params(alsa_device.inhandle, hw_params);
268 check_error(err, "snd_pcm_hw_params (input)");
269
270 snd_pcm_hw_params_free(hw_params);
271
272 err = snd_pcm_sw_params_malloc(&sw_params);
273 check_error(err, "snd_pcm_sw_params_malloc (input)");
274 err = snd_pcm_sw_params_current(alsa_device.inhandle, sw_params);
275 check_error(err, "snd_pcm_sw_params_current (input)");
276 err = snd_pcm_sw_params_set_start_threshold(alsa_device.inhandle,
277 sw_params, nfrags * frag_size);
278 check_error(err, "snd_pcm_sw_params_set_start_threshold (input)");
279 err = snd_pcm_sw_params_set_stop_threshold(alsa_device.inhandle,
280 sw_params, 0x7fffffff);
281 check_error(err, "snd_pcm_sw_params_set_stop_threshold (input)");
282 err = snd_pcm_sw_params_set_avail_min(alsa_device.inhandle, sw_params,
283 frag_size);
284 check_error(err, "snd_pcm_sw_params_set_avail_min (input)");
285 err = snd_pcm_sw_params(alsa_device.inhandle, sw_params);
286 check_error(err, "snd_pcm_sw_params (input)");
287
288 snd_pcm_sw_params_free(sw_params);
289
290 snd_output_stdio_attach(&out, stderr, 0);
291#if 0
292 if (sys_verbose)
293 {
294 snd_pcm_dump_hw_setup(alsa_device.inhandle, out);
295 snd_pcm_dump_sw_setup(alsa_device.inhandle, out);
296 }
297#endif
298 }
299
300 if (outchans)
301 {
302 int foo;
303 if (sys_verbose)
304 post("opening sound output...");
305 err = snd_pcm_hw_params_malloc(&hw_params);
306 check_error(err, "snd_pcm_sw_params (output)");
307
308 // get the default params
309 err = snd_pcm_hw_params_any(alsa_device.outhandle, hw_params);
310 check_error(err, "snd_pcm_hw_params_any (output)");
311 // set interleaved access - FIXME deal with other access types
312 err = snd_pcm_hw_params_set_access(alsa_device.outhandle, hw_params,
313 SND_PCM_ACCESS_RW_INTERLEAVED);
314 check_error(err, "snd_pcm_hw_params_set_access (output)");
315
316 /* try to set interleaved access */
317 err = snd_pcm_hw_params_set_access(alsa_device.outhandle,
318 hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
319 if (err < 0)
320 {
321 /* OK, so try non-interleaved */
322 err = snd_pcm_hw_params_set_access(alsa_device.outhandle,
323 hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED);
324 if (err >= 0)
325 {
326 post("using non-interleaved audio");
327 alsa_device.outnoninterleave = 1;
328 }
329 }
330 check_error(err, "snd_pcm_hw_params_set_access (output)");
331
332
333 // Try to set 32 bit format first
334 err = snd_pcm_hw_params_set_format(alsa_device.outhandle, hw_params,
335 SND_PCM_FORMAT_S32);
336 if (err < 0)
337 {
338 err = snd_pcm_hw_params_set_format(alsa_device.outhandle,
339 hw_params,SND_PCM_FORMAT_S16);
340 check_error(err, "snd_pcm_hw_params_set_format (output)");
341 /* fprintf(stderr,
342 "PD-ALSA: 32 bit format not available - using 16\n"); */
343 alsa_samplewidth = 2;
344 }
345 else
346 {
347 alsa_samplewidth = 4;
348 }
349 // set the subformat
350 err = snd_pcm_hw_params_set_subformat(alsa_device.outhandle, hw_params,
351 SND_PCM_SUBFORMAT_STD);
352 check_error(err, "snd_pcm_hw_params_set_subformat (output)");
353 // set the number of channels
354 tmp_uint = outchans;
355 err = snd_pcm_hw_params_set_channels_min(alsa_device.outhandle,
356 hw_params, &tmp_uint);
357 check_error(err, "snd_pcm_hw_params_set_channels (output)");
358 if (tmp_uint != (unsigned)outchans)
359 post("alsa: set output channels to %d", tmp_uint);
360 outchans = tmp_uint;
361 // set the sampling rate
362 err = snd_pcm_hw_params_set_rate_min(alsa_device.outhandle, hw_params,
363 &rate, 0);
364 check_error(err, "snd_pcm_hw_params_set_rate_min (output)");
365#if 0
366 err = snd_pcm_hw_params_get_rate(hw_params, &subunitdir);
367 post("output sample rate %d", err);
368#endif
369 // set the period - ie frag size
370#if 0
371 post("output period was %d, min %d, max %d\n",
372 snd_pcm_hw_params_get_period_size(hw_params, 0),
373 snd_pcm_hw_params_get_period_size_min(hw_params, 0),
374 snd_pcm_hw_params_get_period_size_max(hw_params, 0));
375#endif
376 // post("fragsize c %d", frag_size);
377#ifdef ALSAAPI9
378 err = snd_pcm_hw_params_set_period_size_near(alsa_device.outhandle,
379 hw_params,
380 (snd_pcm_uframes_t)
381 frag_size, 0);
382#else
383 tmp_snd_pcm_uframes = frag_size;
384 err = snd_pcm_hw_params_set_period_size_near(alsa_device.outhandle,
385 hw_params, &tmp_snd_pcm_uframes, 0);
386#endif
387 // post("fragsize d %d", frag_size);
388 check_error(err, "snd_pcm_hw_params_set_period_size_near (output)");
389 // set the number of periods - ie numfrags
390#ifdef ALSAAPI9
391 err = snd_pcm_hw_params_set_periods_near(alsa_device.outhandle,
392 hw_params, nfrags, 0);
393#else
394 tmp_uint = nfrags;
395 err = snd_pcm_hw_params_set_periods_near(alsa_device.outhandle,
396 hw_params, &tmp_uint, 0);
397#endif
398 check_error(err, "snd_pcm_hw_params_set_periods_near (output)");
399 // set the buffer size
400#ifdef ALSAAPI9
401 err = snd_pcm_hw_params_set_buffer_size_near(alsa_device.outhandle,
402 hw_params, nfrags * frag_size);
403#else
404 tmp_snd_pcm_uframes = nfrags * frag_size;
405 err = snd_pcm_hw_params_set_buffer_size_near(alsa_device.outhandle,
406 hw_params, &tmp_snd_pcm_uframes);
407#endif
408 check_error(err, "snd_pcm_hw_params_set_buffer_size_near (output)");
409
410 err = snd_pcm_hw_params(alsa_device.outhandle, hw_params);
411 check_error(err, "snd_pcm_hw_params (output)");
412
413 snd_pcm_hw_params_free(hw_params);
414
415 err = snd_pcm_sw_params_malloc(&sw_params);
416 check_error(err, "snd_pcm_sw_params_malloc (output)");
417 err = snd_pcm_sw_params_current(alsa_device.outhandle, sw_params);
418 check_error(err, "snd_pcm_sw_params_current (output)");
419 err = snd_pcm_sw_params_set_start_threshold(alsa_device.outhandle,
420 sw_params, nfrags * frag_size);
421 check_error(err, "snd_pcm_sw_params_set_start_threshold (output)");
422 err = snd_pcm_sw_params_set_stop_threshold(alsa_device.outhandle,
423 sw_params, 0x7fffffff);
424 check_error(err, "snd_pcm_sw_params_set_stop_threshold (output)");
425 err = snd_pcm_sw_params_set_avail_min(alsa_device.outhandle, sw_params,
426 frag_size);
427 check_error(err, "snd_pcm_sw_params_set_avail_min (output)");
428 err = snd_pcm_sw_params(alsa_device.outhandle, sw_params);
429 check_error(err, "snd_pcm_sw_params (output)");
430 snd_pcm_sw_params_free(sw_params);
431
432 snd_output_stdio_attach(&out, stderr, 0);
433#if 0
434 if (sys_verbose)
435 {
436 snd_pcm_dump_hw_setup(alsa_device.outhandle, out);
437 snd_pcm_dump_sw_setup(alsa_device.outhandle, out);
438 }
439#endif
440 }
441
442 if (inchans)
443 snd_pcm_prepare(alsa_device.inhandle);
444 if (outchans)
445 snd_pcm_prepare(alsa_device.outhandle);
446
447 // if duplex we can link the channels so they start together
448 if (inchans && outchans)
449 snd_pcm_link(alsa_device.inhandle, alsa_device.outhandle);
450
451 // set up the status variables
452 err = snd_pcm_status_malloc(&in_status);
453 check_error(err, "snd_pcm_status_malloc");
454 err = snd_pcm_status_malloc(&out_status);
455 check_error(err, "snd_pcm_status_malloc");
456
457 // set up the buffer
458 if (alsa_snd_buf)
459 free(alsa_snd_buf);
460 alsa_snd_buf = (void *)malloc(
461 sizeof(char) * alsa_samplewidth * DEFDACBLKSIZE *
462 (outchans > inchans ? outchans : inchans));
463 memset(alsa_snd_buf, 0, sizeof(char) * alsa_samplewidth * DEFDACBLKSIZE *
464 (outchans > inchans ? outchans : inchans));
465 /* make an array of pointers too in case we need them */
466 if (alsa_buf_ptrs)
467 free(alsa_buf_ptrs);
468 alsa_buf_ptrs = (void **)malloc(
469 sizeof(void *) * (outchans > inchans ? outchans : inchans));
470 for (i = 0; i < (outchans > inchans ? outchans : inchans); i++)
471 alsa_buf_ptrs[i] = (t_alsa_sample32 *)alsa_snd_buf + i * DEFDACBLKSIZE;
472
473 // fill the buffer with silence
474 if (outchans)
475 {
476 i = (frag_size * nfrags)/DEFDACBLKSIZE + 1;
477 while (i--)
478 {
479 if (alsa_device.outnoninterleave)
480 snd_pcm_writen(alsa_device.outhandle, alsa_buf_ptrs,
481 DEFDACBLKSIZE);
482 else snd_pcm_writei(alsa_device.outhandle, alsa_snd_buf,
483 DEFDACBLKSIZE);
484 }
485 /* confused about this: */
486 /* if ((err = snd_pcm_start(alsa_device.outhandle) < 0))
487 check_error(err, "output start failed\n"); */
488 }
489 else if (inchans)
490 {
491 if (snd_pcm_start(alsa_device.inhandle) < 0)
492 check_error(err, "input start failed\n");
493 }
494 alsa_outchannels = outchans;
495 alsa_inchannels = inchans;
496
497 return (!(inchans || outchans));
498}
499
500void alsa_close_audio(void)
501{
502 int err;
503 if (alsa_inchannels)
504 {
505 err = snd_pcm_close(alsa_device.inhandle);
506 check_error(err, "snd_pcm_close (input)");
507 }
508 if (alsa_outchannels)
509 {
510 err = snd_pcm_close(alsa_device.outhandle);
511 check_error(err, "snd_pcm_close (output)");
512 }
513}
514
515// #define DEBUG_ALSA_XFER
516
517int alsa_send_dacs(void)
518{
519 static int16_t *sp;
520 static int xferno = 0;
521 static int callno = 0;
522 static double timenow;
523 double timelast;
524 t_sample *fp, *fp1, *fp2;
525 int i, j, k, err, devno = 0;
526 int inputcount = 0, outputcount = 0, inputlate = 0, outputlate = 0;
527 int result;
528 int inchannels = (sys_inchannels > alsa_inchannels ?
529 alsa_inchannels : sys_inchannels);
530 int outchannels = (sys_outchannels > alsa_outchannels ?
531 alsa_outchannels : sys_outchannels);
532 unsigned int intransfersize = DEFDACBLKSIZE;
533 unsigned int outtransfersize = DEFDACBLKSIZE;
534
535 // get the status
536 if (!inchannels && !outchannels)
537 {
538 return SENDDACS_NO;
539 }
540
541 timelast = timenow;
542 timenow = sys_getrealtime();
543
544#ifdef DEBUG_ALSA_XFER
545 if (timenow - timelast > 0.050)
546 fprintf(stderr, "(%d)",
547 (int)(1000 * (timenow - timelast))), fflush(stderr);
548#endif
549
550 callno++;
551
552 alsa_checkiosync(); /* check I/O are in sync and data not late */
553
554 if (alsa_inchannels)
555 {
556 snd_pcm_status(alsa_device.inhandle, in_status);
557 if (snd_pcm_status_get_avail(in_status) < intransfersize)
558 return SENDDACS_NO;
559 }
560 if (alsa_outchannels)
561 {
562 snd_pcm_status(alsa_device.outhandle, out_status);
563 if (snd_pcm_status_get_avail(out_status) < outtransfersize)
564 return SENDDACS_NO;
565 }
566
567 /* do output */
568 if (alsa_outchannels)
569 {
570 fp = sys_soundout;
571 if (alsa_samplewidth == 4)
572 {
573 if (alsa_device.outnoninterleave)
574 {
575 int n = outchannels * DEFDACBLKSIZE;
576 for (i = 0, fp1 = fp; i < n; i++)
577 {
578 float s1 = *fp1 * INT32_MAX;
579 ((t_alsa_sample32 *)alsa_snd_buf)[i] = CLIP32(s1);
580 }
581 n = alsa_outchannels * DEFDACBLKSIZE;
582 for (; i < n; i++)
583 ((t_alsa_sample32 *)alsa_snd_buf)[i] = 0;
584 }
585 else
586 {
587 for (i = 0, fp1 = fp; i < outchannels; i++,
588 fp1 += DEFDACBLKSIZE)
589 {
590 for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--;
591 j += alsa_outchannels, fp2++)
592 {
593 float s1 = *fp2 * INT32_MAX;
594 ((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(s1);
595 }
596 }
597 }
598 }
599 else
600 {
601 for (i = 0, fp1 = fp; i < outchannels; i++, fp1 += DEFDACBLKSIZE)
602 {
603 for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--;
604 j += alsa_outchannels, fp2++)
605 {
606 int s = *fp2 * 32767.;
607 if (s > 32767)
608 s = 32767;
609 else if (s < -32767)
610 s = -32767;
611 ((t_alsa_sample16 *)alsa_snd_buf)[j] = s;
612 }
613 }
614 }
615
616 if (alsa_device.outnoninterleave)
617 result = snd_pcm_writen(alsa_device.outhandle, alsa_buf_ptrs,
618 outtransfersize);
619 else result = snd_pcm_writei(alsa_device.outhandle, alsa_snd_buf,
620 outtransfersize);
621
622 if (result != (int)outtransfersize)
623 {
624 #ifdef DEBUG_ALSA_XFER
625 if (result >= 0 || errno == EAGAIN)
626 fprintf(stderr, "ALSA: write returned %d of %d\n",
627 result, outtransfersize);
628 else fprintf(stderr, "ALSA: write: %s\n",
629 snd_strerror(errno));
630 fprintf(stderr,
631 "inputcount %d, outputcount %d, outbufsize %d\n",
632 inputcount, outputcount,
633 (ALSA_EXTRABUFFER + sys_advance_samples)
634 * alsa_samplewidth * outchannels);
635 #endif
636 sys_log_error(ERR_DACSLEPT);
637 return (SENDDACS_NO);
638 }
639
640 /* zero out the output buffer */
641 memset(sys_soundout, 0, DEFDACBLKSIZE * sizeof(*sys_soundout) *
642 sys_outchannels);
643 if (sys_getrealtime() - timenow > 0.002)
644 {
645 #ifdef DEBUG_ALSA_XFER
646 fprintf(stderr, "output %d took %d msec\n",
647 callno, (int)(1000 * (timenow - timelast))), fflush(stderr);
648 #endif
649 timenow = sys_getrealtime();
650 sys_log_error(ERR_DACSLEPT);
651 }
652 }
653 /* do input */
654 if (alsa_inchannels)
655 {
656 if (alsa_device.innoninterleave)
657 result = snd_pcm_readn(alsa_device.inhandle, alsa_buf_ptrs,
658 intransfersize);
659 else result = snd_pcm_readi(alsa_device.inhandle, alsa_snd_buf,
660 intransfersize);
661 if (result < (int)intransfersize)
662 {
663#ifdef DEBUG_ALSA_XFER
664 if (result < 0)
665 fprintf(stderr,
666 "snd_pcm_read %d %d: %s\n",
667 callno, xferno, snd_strerror(errno));
668 else fprintf(stderr,
669 "snd_pcm_read %d %d returned only %d\n",
670 callno, xferno, result);
671 fprintf(stderr,
672 "inputcount %d, outputcount %d, inbufsize %d\n",
673 inputcount, outputcount,
674 (ALSA_EXTRABUFFER + sys_advance_samples)
675 * alsa_samplewidth * inchannels);
676#endif
677 sys_log_error(ERR_ADCSLEPT);
678 return (SENDDACS_NO);
679 }
680 fp = sys_soundin;
681 if (alsa_samplewidth == 4)
682 {
683 if (alsa_device.innoninterleave)
684 {
685 int n = inchannels * DEFDACBLKSIZE;
686 for (i = 0, fp1 = fp; i < n; i++)
687 *fp1 = (float) ((t_alsa_sample32 *)alsa_snd_buf)[i]
688 * (1./ INT32_MAX);
689 }
690 else
691 {
692 for (i = 0, fp1 = fp; i < inchannels;
693 i++, fp1 += DEFDACBLKSIZE)
694 {
695 for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--;
696 j += alsa_inchannels, fp2++)
697 *fp2 = (float) ((t_alsa_sample32 *)alsa_snd_buf)[j]
698 * (1./ INT32_MAX);
699 }
700 }
701 }
702 else
703 {
704 for (i = 0, fp1 = fp; i < inchannels; i++, fp1 += DEFDACBLKSIZE)
705 {
706 for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--;
707 j += alsa_inchannels, fp2++)
708 *fp2 = (float) ((t_alsa_sample16 *)alsa_snd_buf)[j]
709 * 3.051850e-05;
710 }
711 }
712 }
713 xferno++;
714 if (sys_getrealtime() - timenow > 0.002)
715 {
716#ifdef DEBUG_ALSA_XFER
717 fprintf(stderr, "routine took %d msec\n",
718 (int)(1000 * (sys_getrealtime() - timenow)));
719#endif
720 sys_log_error(ERR_ADCSLEPT);
721 }
722 return SENDDACS_YES;
723}
724
725void alsa_printstate( void)
726{
727 int i, result;
728 snd_pcm_sframes_t indelay, outdelay;
729 if (sys_audioapi != API_ALSA)
730 {
731 error("restart-audio: implemented for ALSA only.");
732 return;
733 }
734 if (sys_inchannels)
735 {
736 result = snd_pcm_delay(alsa_device.inhandle, &indelay);
737 if (result < 0)
738 post("snd_pcm_delay 1 failed");
739 else post("in delay %d", indelay);
740 }
741 if (sys_outchannels)
742 {
743 result = snd_pcm_delay(alsa_device.outhandle, &outdelay);
744 if (result < 0)
745 post("snd_pcm_delay 2 failed");
746 else post("out delay %d", outdelay);
747 }
748 post("sum %d (%d mod 64)\n", indelay + outdelay, (indelay+outdelay)%64);
749
750 post("buf samples %d", alsa_buf_samps);
751}
752
753
754void alsa_resync( void)
755{
756 int i, result;
757 if (sys_audioapi != API_ALSA)
758 {
759 error("restart-audio: implemented for ALSA only.");
760 return;
761 }
762 memset(alsa_snd_buf, 0,
763 sizeof(char) * alsa_samplewidth * DEFDACBLKSIZE * sys_outchannels);
764 for (i = 0; i < 1000000; i++)
765 {
766 if (alsa_device.outnoninterleave)
767 result = snd_pcm_writen(alsa_device.outhandle, alsa_buf_ptrs,
768 DEFDACBLKSIZE);
769 else result = snd_pcm_writei(alsa_device.outhandle, alsa_snd_buf,
770 DEFDACBLKSIZE);
771 if (result != (int)DEFDACBLKSIZE)
772 break;
773 }
774 post("%d written", i);
775}
776
777void alsa_putzeros(int n)
778{
779 int i, result;
780 memset(alsa_snd_buf, 0,
781 sizeof(char) * alsa_samplewidth * DEFDACBLKSIZE * alsa_outchannels);
782 for (i = 0; i < n; i++)
783 {
784 if (alsa_device.outnoninterleave)
785 result = snd_pcm_writen(alsa_device.outhandle, alsa_buf_ptrs,
786 DEFDACBLKSIZE);
787 else result = snd_pcm_writei(alsa_device.outhandle, alsa_snd_buf,
788 DEFDACBLKSIZE);
789#if 0
790 if (result != DEFDACBLKSIZE)
791 post("result %d", result);
792#endif
793 }
794 /* post ("putzeros %d", n); */
795}
796
797void alsa_getzeros(int n)
798{
799 int i, result;
800 for (i = 0; i < n; i++)
801 {
802 result = snd_pcm_readi(alsa_device.inhandle, alsa_snd_buf,
803 DEFDACBLKSIZE);
804#if 0
805 if (result != DEFDACBLKSIZE)
806 post("result %d", result);
807#endif
808 }
809 /* post ("getzeros %d", n); */
810}
811
812 /* call this only if both input and output are open */
813static void alsa_checkiosync( void)
814{
815 int i, result, checkit = 1, giveup = 1000, alreadylogged = 0;
816 snd_pcm_sframes_t indelay, outdelay, defect;
817
818 if (!(alsa_outchannels && alsa_inchannels))
819 return;
820 while (checkit)
821 {
822 checkit = 0;
823 if (giveup-- <= 0)
824 return;
825 result = snd_pcm_delay(alsa_device.outhandle, &outdelay);
826 if (result < 0)
827 {
828 post("output snd_pcm_delay failed: %s", snd_strerror(result));
829 if (snd_pcm_status(alsa_device.outhandle, out_status) < 0)
830 post("output snd_pcm_status failed");
831 else post("astate %d",
832 snd_pcm_status_get_state(out_status));
833 return;
834 }
835 if (outdelay < 0)
836 sys_log_error(ERR_DATALATE), alreadylogged = 1;
837
838 if (sys_inchannels)
839 {
840 result = snd_pcm_delay(alsa_device.inhandle, &indelay);
841 if (result < 0)
842 {
843 post("input snd_pcm_delay failed");
844 return;
845 }
846 defect = indelay + outdelay - alsa_buf_samps;
847 if (defect < -(3 * DEFDACBLKSIZE / 2) )
848 {
849 checkit = 1;
850 alsa_putzeros(1);
851 if (!alreadylogged)
852 sys_log_error(ERR_RESYNC), alreadylogged = 1;
853 }
854 else if (defect > 0)
855 {
856 checkit = 1;
857 alsa_getzeros(1);
858 if (!alreadylogged)
859 sys_log_error(ERR_RESYNC), alreadylogged = 1;
860 }
861 /* if (alreadylogged)
862 post("in %d out %d defect %d", indelay, outdelay, defect); */
863 }
864 }
865}
866
867static int alsa_nnames = 0;
868static char **alsa_names = 0;
869
870void alsa_adddev(char *name)
871{
872 if (alsa_nnames)
873 alsa_names = (char **)t_resizebytes(alsa_names,
874 alsa_nnames * sizeof(char *),
875 (alsa_nnames+1) * sizeof(char *));
876 else alsa_names = (char **)t_getbytes(sizeof(char *));
877 alsa_names[alsa_nnames] = gensym(name)->s_name;
878 alsa_nnames++;
879}
880
881static void alsa_numbertoname(int devno, char *devname, int nchar)
882{
883 int ndev = 0, cardno = -1;
884 while (!snd_card_next(&cardno) && cardno >= 0)
885 ndev++;
886 if (devno < 2*ndev)
887 {
888 if (devno & 1)
889 snprintf(devname, nchar, "plughw:%d", devno/2);
890 else snprintf(devname, nchar, "hw:%d", devno/2);
891 }
892 else if (devno <2*ndev + alsa_nnames)
893 snprintf(devname, nchar, "%s", alsa_names[devno - 2*ndev]);
894 else snprintf(devname, nchar, "???");
895}
896
897 /* For each hardware card found, we list two devices, the "hard" and
898 "plug" one. The card scan is derived from portaudio code. */
899void alsa_getdevs(char *indevlist, int *nindevs,
900 char *outdevlist, int *noutdevs, int *canmulti,
901 int maxndev, int devdescsize)
902{
903 int ndev = 0, cardno = -1, i, j;
904 *canmulti = 0; /* only one device; must be the same for input&output */
905 while (!snd_card_next(&cardno) && cardno >= 0)
906 {
907 snd_ctl_t *ctl;
908 snd_ctl_card_info_t *info;
909 char devname[80];
910 const char *desc;
911 if (2 * ndev + 2 > maxndev)
912 break;
913 /* apparently, "cardno" is just a counter; but check that here */
914 if (ndev != cardno)
915 fprintf(stderr, "oops: ALSA cards not reported in order?\n");
916 sprintf(devname, "hw:%d", cardno );
917 /* fprintf(stderr, "\ntry %s...\n", devname); */
918 if (snd_ctl_open(&ctl, devname, 0) >= 0)
919 {
920 snd_ctl_card_info_malloc(&info);
921 snd_ctl_card_info(ctl, info);
922 desc = snd_ctl_card_info_get_name(info);
923 snd_ctl_card_info_free(info);
924 }
925 else
926 {
927 fprintf(stderr, "ALSA card scan error\n");
928 desc = "???";
929 }
930 /* fprintf(stderr, "name: %s\n", snd_ctl_card_info_get_name(info)); */
931 sprintf(indevlist + 2*ndev * devdescsize, "%s (hardware)", desc);
932 sprintf(indevlist + (2*ndev + 1) * devdescsize, "%s (plug-in)", desc);
933 sprintf(outdevlist + 2*ndev * devdescsize, "%s (hardware)", desc);
934 sprintf(outdevlist + (2*ndev + 1) * devdescsize, "%s (plug-in)", desc);
935 ndev++;
936 }
937 for (i = 0, j = 2*ndev; i < alsa_nnames; i++, j++)
938 {
939 if (j >= maxndev)
940 break;
941 snprintf(indevlist + j * devdescsize, devdescsize, "%s",
942 alsa_names[i]);
943 }
944 *nindevs = *noutdevs = j;
945}
946
diff --git a/apps/plugins/pdbox/PDa/src/s_audio_mmio.c b/apps/plugins/pdbox/PDa/src/s_audio_mmio.c
deleted file mode 100644
index 4a4a8f7354..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_audio_mmio.c
+++ /dev/null
@@ -1,795 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* modified 2/98 by Winfried Ritsch to deal with up to 4 synchronized
6"wave" devices, which is how ADAT boards appear to the WAVE API. */
7
8#include "m_pd.h"
9#include "s_stuff.h"
10#include <stdio.h>
11
12#include <windows.h>
13
14#include <MMSYSTEM.H>
15
16/* ------------------------- audio -------------------------- */
17
18static void nt_close_midiin(void);
19static void nt_noresync( void);
20
21static void postflags(void);
22
23#define NAPORTS 16 /* wini hack for multiple ADDA devices */
24#define CHANNELS_PER_DEVICE 2
25#define DEFAULTCHANS 2
26#define DEFAULTSRATE 44100
27#define SAMPSIZE 2
28
29int nt_realdacblksize;
30#define DEFREALDACBLKSIZE (4 * DEFDACBLKSIZE) /* larger underlying bufsize */
31
32#define MAXBUFFER 100 /* number of buffers in use at maximum advance */
33#define DEFBUFFER 30 /* default is about 30x6 = 180 msec! */
34static int nt_naudiobuffer = DEFBUFFER;
35float sys_dacsr = DEFAULTSRATE;
36
37static int nt_whichapi = API_MMIO;
38static int nt_meters; /* true if we're metering */
39static float nt_inmax; /* max input amplitude */
40static float nt_outmax; /* max output amplitude */
41static int nt_nwavein, nt_nwaveout; /* number of WAVE devices in and out */
42
43typedef struct _sbuf
44{
45 HANDLE hData;
46 HPSTR lpData; // pointer to waveform data memory
47 HANDLE hWaveHdr;
48 WAVEHDR *lpWaveHdr; // pointer to header structure
49} t_sbuf;
50
51t_sbuf ntsnd_outvec[NAPORTS][MAXBUFFER]; /* circular buffer array */
52HWAVEOUT ntsnd_outdev[NAPORTS]; /* output device */
53static int ntsnd_outphase[NAPORTS]; /* index of next buffer to send */
54
55t_sbuf ntsnd_invec[NAPORTS][MAXBUFFER]; /* circular buffer array */
56HWAVEIN ntsnd_indev[NAPORTS]; /* input device */
57static int ntsnd_inphase[NAPORTS]; /* index of next buffer to read */
58
59static void nt_waveinerror(char *s, int err)
60{
61 char t[256];
62 waveInGetErrorText(err, t, 256);
63 fprintf(stderr, s, t);
64}
65
66static void nt_waveouterror(char *s, int err)
67{
68 char t[256];
69 waveOutGetErrorText(err, t, 256);
70 fprintf(stderr, s, t);
71}
72
73static void wave_prep(t_sbuf *bp, int setdone)
74{
75 WAVEHDR *wh;
76 short *sp;
77 int i;
78 /*
79 * Allocate and lock memory for the waveform data. The memory
80 * for waveform data must be globally allocated with
81 * GMEM_MOVEABLE and GMEM_SHARE flags.
82 */
83
84 if (!(bp->hData =
85 GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
86 (DWORD) (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize))))
87 printf("alloc 1 failed\n");
88
89 if (!(bp->lpData =
90 (HPSTR) GlobalLock(bp->hData)))
91 printf("lock 1 failed\n");
92
93 /* Allocate and lock memory for the header. */
94
95 if (!(bp->hWaveHdr =
96 GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof(WAVEHDR))))
97 printf("alloc 2 failed\n");
98
99 if (!(wh = bp->lpWaveHdr =
100 (WAVEHDR *) GlobalLock(bp->hWaveHdr)))
101 printf("lock 2 failed\n");
102
103 for (i = CHANNELS_PER_DEVICE * nt_realdacblksize,
104 sp = (short *)bp->lpData; i--; )
105 *sp++ = 0;
106
107 wh->lpData = bp->lpData;
108 wh->dwBufferLength = (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize);
109 wh->dwFlags = 0;
110 wh->dwLoops = 0L;
111 wh->lpNext = 0;
112 wh->reserved = 0;
113 /* optionally (for writing) set DONE flag as if we had queued them */
114 if (setdone)
115 wh->dwFlags = WHDR_DONE;
116}
117
118static UINT nt_whichdac = WAVE_MAPPER, nt_whichadc = WAVE_MAPPER;
119
120int mmio_do_open_audio(void)
121{
122 PCMWAVEFORMAT form;
123 int i, j;
124 UINT mmresult;
125 int nad, nda;
126 static int naudioprepped = 0, nindevsprepped = 0, noutdevsprepped = 0;
127 if (sys_verbose)
128 post("%d devices in, %d devices out",
129 nt_nwavein, nt_nwaveout);
130
131 form.wf.wFormatTag = WAVE_FORMAT_PCM;
132 form.wf.nChannels = CHANNELS_PER_DEVICE;
133 form.wf.nSamplesPerSec = sys_dacsr;
134 form.wf.nAvgBytesPerSec = sys_dacsr * (CHANNELS_PER_DEVICE * SAMPSIZE);
135 form.wf.nBlockAlign = CHANNELS_PER_DEVICE * SAMPSIZE;
136 form.wBitsPerSample = 8 * SAMPSIZE;
137
138 if (nt_nwavein <= 1 && nt_nwaveout <= 1)
139 nt_noresync();
140
141 if (nindevsprepped < nt_nwavein)
142 {
143 for (i = nindevsprepped; i < nt_nwavein; i++)
144 for (j = 0; j < naudioprepped; j++)
145 wave_prep(&ntsnd_invec[i][j], 0);
146 nindevsprepped = nt_nwavein;
147 }
148 if (noutdevsprepped < nt_nwaveout)
149 {
150 for (i = noutdevsprepped; i < nt_nwaveout; i++)
151 for (j = 0; j < naudioprepped; j++)
152 wave_prep(&ntsnd_outvec[i][j], 1);
153 noutdevsprepped = nt_nwaveout;
154 }
155 if (naudioprepped < nt_naudiobuffer)
156 {
157 for (j = naudioprepped; j < nt_naudiobuffer; j++)
158 {
159 for (i = 0; i < nt_nwavein; i++)
160 wave_prep(&ntsnd_invec[i][j], 0);
161 for (i = 0; i < nt_nwaveout; i++)
162 wave_prep(&ntsnd_outvec[i][j], 1);
163 }
164 naudioprepped = nt_naudiobuffer;
165 }
166 for (nad=0; nad < nt_nwavein; nad++)
167 {
168 /* Open waveform device(s), sucessively numbered, for input */
169
170 mmresult = waveInOpen(&ntsnd_indev[nad], nt_whichadc+nad,
171 (WAVEFORMATEX *)(&form), 0L, 0L, CALLBACK_NULL);
172
173 if (sys_verbose)
174 printf("opened adc device %d with return %d\n",
175 nt_whichadc+nad,mmresult);
176
177 if (mmresult != MMSYSERR_NOERROR)
178 {
179 nt_waveinerror("waveInOpen: %s\n", mmresult);
180 nt_nwavein = nad; /* nt_nwavein = 0 wini */
181 }
182 else
183 {
184 for (i = 0; i < nt_naudiobuffer; i++)
185 {
186 mmresult = waveInPrepareHeader(ntsnd_indev[nad],
187 ntsnd_invec[nad][i].lpWaveHdr, sizeof(WAVEHDR));
188 if (mmresult != MMSYSERR_NOERROR)
189 nt_waveinerror("waveinprepareheader: %s\n", mmresult);
190 mmresult = waveInAddBuffer(ntsnd_indev[nad],
191 ntsnd_invec[nad][i].lpWaveHdr, sizeof(WAVEHDR));
192 if (mmresult != MMSYSERR_NOERROR)
193 nt_waveinerror("waveInAddBuffer: %s\n", mmresult);
194 }
195 }
196 }
197 /* quickly start them all together */
198 for (nad = 0; nad < nt_nwavein; nad++)
199 waveInStart(ntsnd_indev[nad]);
200
201 for (nda = 0; nda < nt_nwaveout; nda++)
202 {
203 /* Open a waveform device for output in sucessiv device numbering*/
204 mmresult = waveOutOpen(&ntsnd_outdev[nda], nt_whichdac + nda,
205 (WAVEFORMATEX *)(&form), 0L, 0L, CALLBACK_NULL);
206
207 if (sys_verbose)
208 fprintf(stderr,"opened dac device %d, with return %d\n",
209 nt_whichdac +nda, mmresult);
210
211 if (mmresult != MMSYSERR_NOERROR)
212 {
213 fprintf(stderr,"Wave out open device %d + %d\n",nt_whichdac,nda);
214 nt_waveouterror("waveOutOpen device: %s\n", mmresult);
215 nt_nwaveout = nda;
216 }
217 }
218
219 return (0);
220}
221
222void mmio_close_audio( void)
223{
224 int errcode;
225 int nda, nad;
226 if (sys_verbose)
227 post("closing audio...");
228
229 for (nda=0; nda < nt_nwaveout; nda++) /*if (nt_nwaveout) wini */
230 {
231 errcode = waveOutReset(ntsnd_outdev[nda]);
232 if (errcode != MMSYSERR_NOERROR)
233 printf("error resetting output %d: %d\n", nda, errcode);
234 errcode = waveOutClose(ntsnd_outdev[nda]);
235 if (errcode != MMSYSERR_NOERROR)
236 printf("error closing output %d: %d\n",nda , errcode);
237 }
238 nt_nwaveout = 0;
239
240 for(nad=0; nad < nt_nwavein;nad++) /* if (nt_nwavein) wini */
241 {
242 errcode = waveInReset(ntsnd_indev[nad]);
243 if (errcode != MMSYSERR_NOERROR)
244 printf("error resetting input: %d\n", errcode);
245 errcode = waveInClose(ntsnd_indev[nad]);
246 if (errcode != MMSYSERR_NOERROR)
247 printf("error closing input: %d\n", errcode);
248 }
249 nt_nwavein = 0;
250}
251
252
253#define ADCJITTER 10 /* We tolerate X buffers of jitter by default */
254#define DACJITTER 10
255
256static int nt_adcjitterbufsallowed = ADCJITTER;
257static int nt_dacjitterbufsallowed = DACJITTER;
258
259 /* ------------- MIDI time stamping from audio clock ------------ */
260
261#ifdef MIDI_TIMESTAMP
262
263static double nt_hibuftime;
264static double initsystime = -1;
265
266 /* call this whenever we reset audio */
267static void nt_resetmidisync(void)
268{
269 initsystime = clock_getsystime();
270 nt_hibuftime = sys_getrealtime();
271}
272
273 /* call this whenever we're idled waiting for audio to be ready.
274 The routine maintains a high and low water point for the difference
275 between real and DAC time. */
276
277static void nt_midisync(void)
278{
279 double jittersec, diff;
280
281 if (initsystime == -1) nt_resetmidisync();
282 jittersec = (nt_dacjitterbufsallowed > nt_adcjitterbufsallowed ?
283 nt_dacjitterbufsallowed : nt_adcjitterbufsallowed)
284 * nt_realdacblksize / sys_getsr();
285 diff = sys_getrealtime() - 0.001 * clock_gettimesince(initsystime);
286 if (diff > nt_hibuftime) nt_hibuftime = diff;
287 if (diff < nt_hibuftime - jittersec)
288 {
289 post("jitter excess %d %f", dac, diff);
290 nt_resetmidisync();
291 }
292}
293
294static double nt_midigettimefor(LARGE_INTEGER timestamp)
295{
296 /* this is broken now... used to work when "timestamp" was derived from
297 QueryPerformanceCounter() instead of the gates approved
298 timeGetSystemTime() call in the MIDI callback routine below. */
299 return (nt_tixtotime(timestamp) - nt_hibuftime);
300}
301#endif /* MIDI_TIMESTAMP */
302
303
304static int nt_fill = 0;
305#define WRAPFWD(x) ((x) >= nt_naudiobuffer ? (x) - nt_naudiobuffer: (x))
306#define WRAPBACK(x) ((x) < 0 ? (x) + nt_naudiobuffer: (x))
307#define MAXRESYNC 500
308
309#if 0 /* this is used for debugging */
310static void nt_printaudiostatus(void)
311{
312 int nad, nda;
313 for (nad = 0; nad < nt_nwavein; nad++)
314 {
315 int phase = ntsnd_inphase[nad];
316 int phase2 = phase, phase3 = WRAPFWD(phase2), count, ntrans = 0;
317 int firstphasedone = -1, firstphasebusy = -1;
318 for (count = 0; count < nt_naudiobuffer; count++)
319 {
320 int donethis =
321 (ntsnd_invec[nad][phase2].lpWaveHdr->dwFlags & WHDR_DONE);
322 int donenext =
323 (ntsnd_invec[nad][phase3].lpWaveHdr->dwFlags & WHDR_DONE);
324 if (donethis && !donenext)
325 {
326 if (firstphasebusy >= 0) goto multipleadc;
327 firstphasebusy = count;
328 }
329 if (!donethis && donenext)
330 {
331 if (firstphasedone >= 0) goto multipleadc;
332 firstphasedone = count;
333 }
334 phase2 = phase3;
335 phase3 = WRAPFWD(phase2 + 1);
336 }
337 post("nad %d phase %d busy %d done %d", nad, phase, firstphasebusy,
338 firstphasedone);
339 continue;
340 multipleadc:
341 startpost("nad %d phase %d: oops:", nad, phase);
342 for (count = 0; count < nt_naudiobuffer; count++)
343 {
344 char buf[80];
345 sprintf(buf, " %d",
346 (ntsnd_invec[nad][count].lpWaveHdr->dwFlags & WHDR_DONE));
347 poststring(buf);
348 }
349 endpost();
350 }
351 for (nda = 0; nda < nt_nwaveout; nda++)
352 {
353 int phase = ntsnd_outphase[nad];
354 int phase2 = phase, phase3 = WRAPFWD(phase2), count, ntrans = 0;
355 int firstphasedone = -1, firstphasebusy = -1;
356 for (count = 0; count < nt_naudiobuffer; count++)
357 {
358 int donethis =
359 (ntsnd_outvec[nda][phase2].lpWaveHdr->dwFlags & WHDR_DONE);
360 int donenext =
361 (ntsnd_outvec[nda][phase3].lpWaveHdr->dwFlags & WHDR_DONE);
362 if (donethis && !donenext)
363 {
364 if (firstphasebusy >= 0) goto multipledac;
365 firstphasebusy = count;
366 }
367 if (!donethis && donenext)
368 {
369 if (firstphasedone >= 0) goto multipledac;
370 firstphasedone = count;
371 }
372 phase2 = phase3;
373 phase3 = WRAPFWD(phase2 + 1);
374 }
375 if (firstphasebusy < 0) post("nda %d phase %d all %d",
376 nda, phase, (ntsnd_outvec[nad][0].lpWaveHdr->dwFlags & WHDR_DONE));
377 else post("nda %d phase %d busy %d done %d", nda, phase, firstphasebusy,
378 firstphasedone);
379 continue;
380 multipledac:
381 startpost("nda %d phase %d: oops:", nda, phase);
382 for (count = 0; count < nt_naudiobuffer; count++)
383 {
384 char buf[80];
385 sprintf(buf, " %d",
386 (ntsnd_outvec[nad][count].lpWaveHdr->dwFlags & WHDR_DONE));
387 poststring(buf);
388 }
389 endpost();
390 }
391}
392#endif /* 0 */
393
394/* this is a hack to avoid ever resyncing audio pointers in case for whatever
395reason the sync testing below gives false positives. */
396
397static int nt_resync_cancelled;
398
399static void nt_noresync( void)
400{
401 nt_resync_cancelled = 1;
402}
403
404static void nt_resyncaudio(void)
405{
406 UINT mmresult;
407 int nad, nda, count;
408 if (nt_resync_cancelled)
409 return;
410 /* for each open input device, eat all buffers which are marked
411 ready. The next one will thus be "busy". */
412 post("resyncing audio");
413 for (nad = 0; nad < nt_nwavein; nad++)
414 {
415 int phase = ntsnd_inphase[nad];
416 for (count = 0; count < MAXRESYNC; count++)
417 {
418 WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr;
419 if (!(inwavehdr->dwFlags & WHDR_DONE)) break;
420 if (inwavehdr->dwFlags & WHDR_PREPARED)
421 waveInUnprepareHeader(ntsnd_indev[nad],
422 inwavehdr, sizeof(WAVEHDR));
423 inwavehdr->dwFlags = 0L;
424 waveInPrepareHeader(ntsnd_indev[nad], inwavehdr, sizeof(WAVEHDR));
425 mmresult = waveInAddBuffer(ntsnd_indev[nad], inwavehdr,
426 sizeof(WAVEHDR));
427 if (mmresult != MMSYSERR_NOERROR)
428 nt_waveinerror("waveInAddBuffer: %s\n", mmresult);
429 ntsnd_inphase[nad] = phase = WRAPFWD(phase + 1);
430 }
431 if (count == MAXRESYNC) post("resync error 1");
432 }
433 /* Each output buffer which is "ready" is filled with zeros and
434 queued. */
435 for (nda = 0; nda < nt_nwaveout; nda++)
436 {
437 int phase = ntsnd_outphase[nda];
438 for (count = 0; count < MAXRESYNC; count++)
439 {
440 WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr;
441 if (!(outwavehdr->dwFlags & WHDR_DONE)) break;
442 if (outwavehdr->dwFlags & WHDR_PREPARED)
443 waveOutUnprepareHeader(ntsnd_outdev[nda],
444 outwavehdr, sizeof(WAVEHDR));
445 outwavehdr->dwFlags = 0L;
446 memset((char *)(ntsnd_outvec[nda][phase].lpData),
447 0, (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize));
448 waveOutPrepareHeader(ntsnd_outdev[nda], outwavehdr,
449 sizeof(WAVEHDR));
450 mmresult = waveOutWrite(ntsnd_outdev[nda], outwavehdr,
451 sizeof(WAVEHDR));
452 if (mmresult != MMSYSERR_NOERROR)
453 nt_waveouterror("waveOutAddBuffer: %s\n", mmresult);
454 ntsnd_outphase[nda] = phase = WRAPFWD(phase + 1);
455 }
456 if (count == MAXRESYNC) post("resync error 2");
457 }
458
459#ifdef MIDI_TIMESTAMP
460 nt_resetmidisync();
461#endif
462
463}
464
465#define LATE 0
466#define RESYNC 1
467#define NOTHING 2
468static int nt_errorcount;
469static int nt_resynccount;
470static double nt_nextreporttime = -1;
471
472void nt_logerror(int which)
473{
474#if 0
475 post("error %d %d", count, which);
476 if (which < NOTHING) nt_errorcount++;
477 if (which == RESYNC) nt_resynccount++;
478 if (sys_getrealtime() > nt_nextreporttime)
479 {
480 post("%d audio I/O error%s", nt_errorcount,
481 (nt_errorcount > 1 ? "s" : ""));
482 if (nt_resynccount) post("DAC/ADC sync error");
483 nt_errorcount = nt_resynccount = 0;
484 nt_nextreporttime = sys_getrealtime() - 5;
485 }
486#endif
487}
488
489/* system buffer with t_sample types for one tick */
490t_sample *sys_soundout;
491t_sample *sys_soundin;
492float sys_dacsr;
493
494int mmio_send_dacs(void)
495{
496 HMMIO hmmio;
497 UINT mmresult;
498 HANDLE hFormat;
499 int i, j;
500 short *sp1, *sp2;
501 float *fp1, *fp2;
502 int nextfill, doxfer = 0;
503 int nda, nad;
504 if (!nt_nwavein && !nt_nwaveout) return (0);
505
506
507 if (nt_meters)
508 {
509 int i, n;
510 float maxsamp;
511 for (i = 0, n = 2 * nt_nwavein * DEFDACBLKSIZE, maxsamp = nt_inmax;
512 i < n; i++)
513 {
514 float f = sys_soundin[i];
515 if (f > maxsamp) maxsamp = f;
516 else if (-f > maxsamp) maxsamp = -f;
517 }
518 nt_inmax = maxsamp;
519 for (i = 0, n = 2 * nt_nwaveout * DEFDACBLKSIZE, maxsamp = nt_outmax;
520 i < n; i++)
521 {
522 float f = sys_soundout[i];
523 if (f > maxsamp) maxsamp = f;
524 else if (-f > maxsamp) maxsamp = -f;
525 }
526 nt_outmax = maxsamp;
527 }
528
529 /* the "fill pointer" nt_fill controls where in the next
530 I/O buffers we will write and/or read. If it's zero, we
531 first check whether the buffers are marked "done". */
532
533 if (!nt_fill)
534 {
535 for (nad = 0; nad < nt_nwavein; nad++)
536 {
537 int phase = ntsnd_inphase[nad];
538 WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr;
539 if (!(inwavehdr->dwFlags & WHDR_DONE)) goto idle;
540 }
541 for (nda = 0; nda < nt_nwaveout; nda++)
542 {
543 int phase = ntsnd_outphase[nda];
544 WAVEHDR *outwavehdr =
545 ntsnd_outvec[nda][phase].lpWaveHdr;
546 if (!(outwavehdr->dwFlags & WHDR_DONE)) goto idle;
547 }
548 for (nad = 0; nad < nt_nwavein; nad++)
549 {
550 int phase = ntsnd_inphase[nad];
551 WAVEHDR *inwavehdr =
552 ntsnd_invec[nad][phase].lpWaveHdr;
553 if (inwavehdr->dwFlags & WHDR_PREPARED)
554 waveInUnprepareHeader(ntsnd_indev[nad],
555 inwavehdr, sizeof(WAVEHDR));
556 }
557 for (nda = 0; nda < nt_nwaveout; nda++)
558 {
559 int phase = ntsnd_outphase[nda];
560 WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr;
561 if (outwavehdr->dwFlags & WHDR_PREPARED)
562 waveOutUnprepareHeader(ntsnd_outdev[nda],
563 outwavehdr, sizeof(WAVEHDR));
564 }
565 }
566
567 /* Convert audio output to fixed-point and put it in the output
568 buffer. */
569 for (nda = 0, fp1 = sys_soundout; nda < nt_nwaveout; nda++)
570 {
571 int phase = ntsnd_outphase[nda];
572
573 for (i = 0, sp1 = (short *)(ntsnd_outvec[nda][phase].lpData) +
574 CHANNELS_PER_DEVICE * nt_fill;
575 i < 2; i++, fp1 += DEFDACBLKSIZE, sp1++)
576 {
577 for (j = 0, fp2 = fp1, sp2 = sp1; j < DEFDACBLKSIZE;
578 j++, fp2++, sp2 += CHANNELS_PER_DEVICE)
579 {
580 int x1 = 32767.f * *fp2;
581 if (x1 > 32767) x1 = 32767;
582 else if (x1 < -32767) x1 = -32767;
583 *sp2 = x1;
584 }
585 }
586 }
587 memset(sys_soundout, 0,
588 (DEFDACBLKSIZE *sizeof(t_sample)*CHANNELS_PER_DEVICE)*nt_nwaveout);
589
590 /* vice versa for the input buffer */
591
592 for (nad = 0, fp1 = sys_soundin; nad < nt_nwavein; nad++)
593 {
594 int phase = ntsnd_inphase[nad];
595
596 for (i = 0, sp1 = (short *)(ntsnd_invec[nad][phase].lpData) +
597 CHANNELS_PER_DEVICE * nt_fill;
598 i < 2; i++, fp1 += DEFDACBLKSIZE, sp1++)
599 {
600 for (j = 0, fp2 = fp1, sp2 = sp1; j < DEFDACBLKSIZE;
601 j++, fp2++, sp2 += CHANNELS_PER_DEVICE)
602 {
603 *fp2 = ((float)(1./32767.)) * (float)(*sp2);
604 }
605 }
606 }
607
608 nt_fill = nt_fill + DEFDACBLKSIZE;
609 if (nt_fill == nt_realdacblksize)
610 {
611 nt_fill = 0;
612
613 for (nad = 0; nad < nt_nwavein; nad++)
614 {
615 int phase = ntsnd_inphase[nad];
616 HWAVEIN device = ntsnd_indev[nad];
617 WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr;
618 waveInPrepareHeader(device, inwavehdr, sizeof(WAVEHDR));
619 mmresult = waveInAddBuffer(device, inwavehdr, sizeof(WAVEHDR));
620 if (mmresult != MMSYSERR_NOERROR)
621 nt_waveinerror("waveInAddBuffer: %s\n", mmresult);
622 ntsnd_inphase[nad] = WRAPFWD(phase + 1);
623 }
624 for (nda = 0; nda < nt_nwaveout; nda++)
625 {
626 int phase = ntsnd_outphase[nda];
627 HWAVEOUT device = ntsnd_outdev[nda];
628 WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr;
629 waveOutPrepareHeader(device, outwavehdr, sizeof(WAVEHDR));
630 mmresult = waveOutWrite(device, outwavehdr, sizeof(WAVEHDR));
631 if (mmresult != MMSYSERR_NOERROR)
632 nt_waveouterror("waveOutWrite: %s\n", mmresult);
633 ntsnd_outphase[nda] = WRAPFWD(phase + 1);
634 }
635
636 /* check for DAC underflow or ADC overflow. */
637 for (nad = 0; nad < nt_nwavein; nad++)
638 {
639 int phase = WRAPBACK(ntsnd_inphase[nad] - 2);
640 WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr;
641 if (inwavehdr->dwFlags & WHDR_DONE) goto late;
642 }
643 for (nda = 0; nda < nt_nwaveout; nda++)
644 {
645 int phase = WRAPBACK(ntsnd_outphase[nda] - 2);
646 WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr;
647 if (outwavehdr->dwFlags & WHDR_DONE) goto late;
648 }
649 }
650 return (1);
651
652late:
653
654 nt_logerror(LATE);
655 nt_resyncaudio();
656 return (1);
657
658idle:
659
660 /* If more than nt_adcjitterbufsallowed ADC buffers are ready
661 on any input device, resynchronize */
662
663 for (nad = 0; nad < nt_nwavein; nad++)
664 {
665 int phase = ntsnd_inphase[nad];
666 WAVEHDR *inwavehdr =
667 ntsnd_invec[nad]
668 [WRAPFWD(phase + nt_adcjitterbufsallowed)].lpWaveHdr;
669 if (inwavehdr->dwFlags & WHDR_DONE)
670 {
671 nt_resyncaudio();
672 return (0);
673 }
674 }
675
676 /* test dac sync the same way */
677 for (nda = 0; nda < nt_nwaveout; nda++)
678 {
679 int phase = ntsnd_outphase[nda];
680 WAVEHDR *outwavehdr =
681 ntsnd_outvec[nda]
682 [WRAPFWD(phase + nt_dacjitterbufsallowed)].lpWaveHdr;
683 if (outwavehdr->dwFlags & WHDR_DONE)
684 {
685 nt_resyncaudio();
686 return (0);
687 }
688 }
689#ifdef MIDI_TIMESTAMP
690 nt_midisync();
691#endif
692 return (0);
693}
694
695/* ------------------- public routines -------------------------- */
696
697void mmio_open_audio(int naudioindev, int *audioindev,
698 int nchindev, int *chindev, int naudiooutdev, int *audiooutdev,
699 int nchoutdev, int *choutdev, int rate) /* IOhannes */
700{
701 int nbuf;
702
703 nt_realdacblksize = (sys_blocksize ? sys_blocksize : DEFREALDACBLKSIZE);
704 nbuf = sys_advance_samples/nt_realdacblksize;
705 if (nbuf >= MAXBUFFER)
706 {
707 fprintf(stderr, "pd: audio buffering maxed out to %d\n",
708 (int)(MAXBUFFER * ((nt_realdacblksize * 1000.)/44100.)));
709 nbuf = MAXBUFFER;
710 }
711 else if (nbuf < 4) nbuf = 4;
712 fprintf(stderr, "%d audio buffers\n", nbuf);
713 nt_naudiobuffer = nbuf;
714 if (nt_adcjitterbufsallowed > nbuf - 2)
715 nt_adcjitterbufsallowed = nbuf - 2;
716 if (nt_dacjitterbufsallowed > nbuf - 2)
717 nt_dacjitterbufsallowed = nbuf - 2;
718
719 nt_nwavein = sys_inchannels / 2;
720 nt_nwaveout = sys_outchannels / 2;
721 nt_whichadc = (naudioindev < 1 ?
722 (nt_nwavein > 1 ? WAVE_MAPPER : -1) : audioindev[0]);
723 nt_whichdac = (naudiooutdev < 1 ?
724 (nt_nwaveout > 1 ? WAVE_MAPPER : -1) : audiooutdev[0]);
725 if (naudiooutdev > 1 || naudioindev > 1)
726 post("separate audio device choice not supported; using sequential devices.");
727 mmio_do_open_audio();
728}
729
730
731void mmio_reportidle(void)
732{
733}
734
735#if 0
736/* list the audio and MIDI device names */
737void mmio_listdevs(void)
738{
739 UINT wRtn, ndevices;
740 unsigned int i;
741
742 ndevices = waveInGetNumDevs();
743 for (i = 0; i < ndevices; i++)
744 {
745 WAVEINCAPS wicap;
746 wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &wicap,
747 sizeof(wicap));
748 if (wRtn) nt_waveinerror("waveInGetDevCaps: %s\n", wRtn);
749 else fprintf(stderr,
750 "audio input device #%d: %s\n", i+1, wicap.szPname);
751 }
752
753 ndevices = waveOutGetNumDevs();
754 for (i = 0; i < ndevices; i++)
755 {
756 WAVEOUTCAPS wocap;
757 wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS) &wocap,
758 sizeof(wocap));
759 if (wRtn) nt_waveouterror("waveOutGetDevCaps: %s\n", wRtn);
760 else fprintf(stderr,
761 "audio output device #%d: %s\n", i+1, wocap.szPname);
762 }
763}
764#endif
765
766void mmio_getdevs(char *indevlist, int *nindevs,
767 char *outdevlist, int *noutdevs, int *canmulti,
768 int maxndev, int devdescsize)
769{
770 int wRtn, ndev, i;
771
772 *canmulti = 2; /* supports multiple devices */
773 ndev = waveInGetNumDevs();
774 if (ndev > maxndev)
775 ndev = maxndev;
776 *nindevs = ndev;
777 for (i = 0; i < ndev; i++)
778 {
779 WAVEINCAPS wicap;
780 wRtn = waveInGetDevCaps(i, (LPWAVEINCAPS) &wicap, sizeof(wicap));
781 sprintf(indevlist + i * devdescsize, (wRtn ? "???" : wicap.szPname));
782 }
783
784 ndev = waveOutGetNumDevs();
785 if (ndev > maxndev)
786 ndev = maxndev;
787 *noutdevs = ndev;
788 for (i = 0; i < ndev; i++)
789 {
790 WAVEOUTCAPS wocap;
791 wRtn = waveOutGetDevCaps(i, (LPWAVEOUTCAPS) &wocap, sizeof(wocap));
792 sprintf(outdevlist + i * devdescsize, (wRtn ? "???" : wocap.szPname));
793 }
794}
795
diff --git a/apps/plugins/pdbox/PDa/src/s_audio_oss.c b/apps/plugins/pdbox/PDa/src/s_audio_oss.c
deleted file mode 100644
index de11f66243..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_audio_oss.c
+++ /dev/null
@@ -1,845 +0,0 @@
1/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler,
2* Winfried Ritsch, Karl MacMillan, and others.
3* For information on usage and redistribution, and for a DISCLAIMER OF ALL
4* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5
6/* this file inputs and outputs audio using the OSS API available on linux. */
7
8#ifdef USEAPI_OSS
9
10#include <linux/soundcard.h>
11
12#include "m_pd.h"
13#include "s_stuff.h"
14#include <errno.h>
15#include <stdio.h>
16#include <unistd.h>
17#include <stdlib.h>
18#include <string.h>
19#include <sys/types.h>
20#include <sys/time.h>
21#include <sys/stat.h>
22#include <sys/ioctl.h>
23#include <fcntl.h>
24#include <sched.h>
25#include <sys/mman.h>
26
27
28/* Defines */
29#define DEBUG(x) x
30#define DEBUG2(x) {x;}
31
32#define OSS_MAXCHPERDEV 32 /* max channels per OSS device */
33#define OSS_MAXDEV 4 /* maximum number of input or output devices */
34#define OSS_DEFFRAGSIZE 256 /* default log fragment size (frames) */
35#define OSS_DEFAUDIOBUF 40000 /* default audiobuffer, microseconds */
36#define OSS_DEFAULTCH 2
37#define RME_DEFAULTCH 8 /* need this even if RME undefined */
38typedef int16_t t_oss_int16;
39typedef int32_t t_oss_int32;
40#define OSS_MAXSAMPLEWIDTH sizeof(t_oss_int32)
41#define OSS_BYTESPERCHAN(width) (DEFDACBLKSIZE * (width))
42#define OSS_XFERSAMPS(chans) (DEFDACBLKSIZE* (chans))
43#define OSS_XFERSIZE(chans, width) (DEFDACBLKSIZE * (chans) * (width))
44
45/* GLOBALS */
46static int linux_meters; /* true if we're metering */
47static float linux_inmax; /* max input amplitude */
48static float linux_outmax; /* max output amplitude */
49static int linux_fragsize = 0; /* for block mode; block size (sample frames) */
50
51/* our device handles */
52
53typedef struct _oss_dev
54{
55 int d_fd;
56 unsigned int d_space; /* bytes available for writing/reading */
57 int d_bufsize; /* total buffer size in blocks for this device */
58 int d_dropcount; /* # of buffers to drop for resync (output only) */
59 unsigned int d_nchannels; /* number of channels for this device */
60 unsigned int d_bytespersamp; /* bytes per sample (2 for 16 bit, 4 for 32) */
61} t_oss_dev;
62
63static t_oss_dev linux_dacs[OSS_MAXDEV];
64static t_oss_dev linux_adcs[OSS_MAXDEV];
65static int linux_noutdevs = 0;
66static int linux_nindevs = 0;
67
68 /* exported variables */
69float sys_dacsr;
70t_sample *sys_soundout;
71t_sample *sys_soundin;
72
73 /* OSS-specific private variables */
74static int oss_blockmode = 1; /* flag to use "blockmode" */
75static int oss_32bit = 0; /* allow 23 bit transfers in OSS */
76static char ossdsp[] = "/dev/dsp%d";
77
78 /* don't assume we can turn all 31 bits when doing float-to-fix;
79 otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */
80#define FMAX 0x7ffff000
81#define CLIP32(x) (((x)>FMAX)?FMAX:((x) < -FMAX)?-FMAX:(x))
82
83
84/* ------------- private routines for all APIS ------------------- */
85
86static void linux_flush_all_underflows_to_zero(void)
87{
88/*
89 TODO: Implement similar thing for linux (GGeiger)
90
91 One day we will figure this out, I hope, because it
92 costs CPU time dearly on Intel - LT
93 */
94 /* union fpc_csr f;
95 f.fc_word = get_fpc_csr();
96 f.fc_struct.flush = 1;
97 set_fpc_csr(f.fc_word);
98 */
99}
100
101static int oss_ndev = 0;
102
103 /* find out how many OSS devices we have. Since this has to
104 open the devices to find out if they're there, we have
105 to be called before audio is actually started up. So we
106 cache the results, which in effect are the number of available
107 devices. */
108void oss_init(void)
109{
110 int fd, i;
111 static int countedthem = 0;
112 if (countedthem)
113 return;
114 for (i = 0; i < 10; i++)
115 {
116 char devname[100];
117 if (i == 0)
118 strcpy(devname, "/dev/dsp");
119 else sprintf(devname, "/dev/dsp%d", i);
120 if ( (fd = open(devname, O_WRONLY|O_NONBLOCK)) != -1)
121 {
122 oss_ndev++;
123 close(fd);
124 }
125 else break;
126 }
127 countedthem = 1;
128}
129
130
131void oss_set32bit( void)
132{
133 oss_32bit = 1;
134}
135
136
137typedef struct _multidev {
138 int fd;
139 int channels;
140 int format;
141} t_multidev;
142
143int oss_reset(int fd) {
144 int err;
145 if ((err = ioctl(fd,SNDCTL_DSP_RESET)) < 0)
146 error("OSS: Could not reset");
147 return err;
148}
149
150 /* The AFMT_S32_BLOCKED format is not defined in standard linux kernels
151 but is proposed by Guenter Geiger to support extending OSS to handle
152 32 bit sample. This is user in Geiger's OSS driver for RME Hammerfall.
153 I'm not clear why this isn't called AFMT_S32_[SLN]E... */
154
155#ifndef AFMT_S32_BLOCKED
156#define AFMT_S32_BLOCKED 0x0000400
157#endif
158
159void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize)
160{ /* IOhannes */
161 int orig, param, nblk, fd = dev->d_fd, wantformat;
162 int nchannels = dev->d_nchannels;
163 int advwas = sys_schedadvance;
164
165 audio_buf_info ainfo;
166
167 /* IOhannes :
168 * pd is very likely to crash if different formats are used on
169 multiple soundcards
170 */
171
172 /* set resolution - first try 4 byte samples */
173 if (oss_32bit && (ioctl(fd,SNDCTL_DSP_GETFMTS,&param) >= 0) &&
174 (param & AFMT_S32_BLOCKED))
175 {
176 wantformat = AFMT_S32_BLOCKED;
177 dev->d_bytespersamp = 4;
178 }
179 else
180 {
181 wantformat = AFMT_S16_NE;
182 dev->d_bytespersamp = 2;
183 }
184 param = wantformat;
185
186 if (sys_verbose)
187 post("bytes per sample = %d", dev->d_bytespersamp);
188 if (ioctl(fd, SNDCTL_DSP_SETFMT, &param) == -1)
189 fprintf(stderr,"OSS: Could not set DSP format\n");
190 else if (wantformat != param)
191 fprintf(stderr,"OSS: DSP format: wanted %d, got %d\n",
192 wantformat, param);
193
194 /* sample rate */
195 orig = param = srate;
196 if (ioctl(fd, SNDCTL_DSP_SPEED, &param) == -1)
197 fprintf(stderr,"OSS: Could not set sampling rate for device\n");
198 else if( orig != param )
199 fprintf(stderr,"OSS: sampling rate: wanted %d, got %d\n",
200 orig, param );
201
202 if (oss_blockmode && !skipblocksize)
203 {
204 int fragbytes, logfragsize, nfragment;
205 /* setting fragment count and size. */
206 if (!linux_fragsize)
207 {
208 linux_fragsize = OSS_DEFFRAGSIZE;
209 while (linux_fragsize > DEFDACBLKSIZE
210 && linux_fragsize * 4 > sys_advance_samples)
211 linux_fragsize = linux_fragsize/2;
212 }
213
214 /* post("adv_samples %d", sys_advance_samples); */
215 nfragment = (sys_schedadvance * (44100. * 1.e-6)) / linux_fragsize;
216
217 fragbytes = linux_fragsize * (dev->d_bytespersamp * nchannels);
218 logfragsize = ilog2(fragbytes);
219
220 if (fragbytes != (1 << logfragsize))
221 post("warning: OSS takes only power of 2 blocksize; using %d",
222 (1 << logfragsize)/(dev->d_bytespersamp * nchannels));
223 if (sys_verbose)
224 post("setting nfrags = %d, fragsize %d\n", nfragment, fragbytes);
225
226 param = orig = (nfragment<<16) + logfragsize;
227 if (ioctl(fd,SNDCTL_DSP_SETFRAGMENT, &param) == -1)
228 error("OSS: Could not set or read fragment size\n");
229 if (param != orig)
230 {
231 nfragment = ((param >> 16) & 0xffff);
232 logfragsize = (param & 0xffff);
233 post("warning: actual fragments %d, blocksize %d",
234 nfragment, (1 << logfragsize));
235 }
236 if (sys_verbose)
237 post("audiobuffer set to %d msec", (int)(0.001 * sys_schedadvance));
238 }
239 if (dac)
240 {
241 /* use "free space" to learn the buffer size. Normally you
242 should set this to your own desired value; but this seems not
243 to be implemented uniformly across different sound cards. LATER
244 we should figure out what to do if the requested scheduler advance
245 is greater than this buffer size; for now, we just print something
246 out. */
247
248 int defect;
249 if (ioctl(fd, SOUND_PCM_GETOSPACE,&ainfo) < 0)
250 fprintf(stderr,"OSS: ioctl on output device failed");
251 dev->d_bufsize = ainfo.bytes;
252
253 defect = sys_advance_samples * (dev->d_bytespersamp * nchannels)
254 - dev->d_bufsize - OSS_XFERSIZE(nchannels, dev->d_bytespersamp);
255 if (defect > 0)
256 {
257 if (sys_verbose || defect > (dev->d_bufsize >> 2))
258 fprintf(stderr,
259 "OSS: requested audio buffer size %d limited to %d\n",
260 sys_advance_samples * (dev->d_bytespersamp * nchannels),
261 dev->d_bufsize);
262 sys_advance_samples =
263 (dev->d_bufsize - OSS_XFERSAMPS(nchannels)) /
264 (dev->d_bytespersamp *nchannels);
265 }
266 }
267}
268
269static int oss_setchannels(int fd, int wantchannels, char *devname)
270{ /* IOhannes */
271 int param = wantchannels;
272
273 while (param>1) {
274 int save = param;
275 if (ioctl(fd, SNDCTL_DSP_CHANNELS, &param) == -1) {
276 error("OSS: SNDCTL_DSP_CHANNELS failed %s",devname);
277 } else {
278 if (param == save) return (param);
279 }
280 param=save-1;
281 }
282
283 return (0);
284}
285
286#define O_AUDIOFLAG 0 /* O_NDELAY */
287
288int oss_open_audio(int nindev, int *indev, int nchin, int *chin,
289 int noutdev, int *outdev, int nchout, int *chout, int rate)
290{ /* IOhannes */
291 int capabilities = 0;
292 int inchannels = 0, outchannels = 0;
293 char devname[20];
294 int n, i, fd;
295 char buf[OSS_MAXSAMPLEWIDTH * DEFDACBLKSIZE * OSS_MAXCHPERDEV];
296 int num_devs = 0;
297 int wantmore=0;
298 int spread = 0;
299 audio_buf_info ainfo;
300
301 linux_nindevs = linux_noutdevs = 0;
302
303
304 /* mark input devices unopened */
305 for (i = 0; i < OSS_MAXDEV; i++)
306 linux_adcs[i].d_fd = -1;
307
308 /* open output devices */
309 wantmore=0;
310 if (noutdev < 0 || nindev < 0)
311 bug("linux_open_audio");
312
313 for (n = 0; n < noutdev; n++)
314 {
315 int gotchans, j, inindex = -1;
316 int thisdevice = (outdev[n] >= 0 ? outdev[n] : n-1);
317 int wantchannels = (nchout>n) ? chout[n] : wantmore;
318 fd = -1;
319 if (!wantchannels)
320 goto end_out_loop;
321
322 if (thisdevice > 1)
323 sprintf(devname, "/dev/dsp%d", thisdevice-1);
324 else sprintf(devname, "/dev/dsp");
325
326 /* search for input request for same device. Succeed only
327 if the number of channels matches. */
328 for (j = 0; j < nindev; j++)
329 if (indev[j] == thisdevice && chin[j] == wantchannels)
330 inindex = j;
331
332 /* if the same device is requested for input and output,
333 try to open it read/write */
334 if (inindex >= 0)
335 {
336 sys_setalarm(1000000);
337 if ((fd = open(devname, O_RDWR | O_AUDIOFLAG)) == -1)
338 {
339 post("%s (read/write): %s", devname, strerror(errno));
340 post("(now will try write-only...)");
341 }
342 else
343 {
344 if (sys_verbose)
345 post("opened %s for reading and writing\n", devname);
346 linux_adcs[inindex].d_fd = fd;
347 }
348 }
349 /* if that didn't happen or if it failed, try write-only */
350 if (fd == -1)
351 {
352 sys_setalarm(1000000);
353 if ((fd = open(devname, O_WRONLY | O_AUDIOFLAG)) == -1)
354 {
355 post("%s (writeonly): %s",
356 devname, strerror(errno));
357 break;
358 }
359 if (sys_verbose)
360 post("opened %s for writing only\n", devname);
361 }
362 if (ioctl(fd, SNDCTL_DSP_GETCAPS, &capabilities) == -1)
363 error("OSS: SNDCTL_DSP_GETCAPS failed %s", devname);
364
365 gotchans = oss_setchannels(fd,
366 (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels,
367 devname);
368
369 if (sys_verbose)
370 post("opened audio output on %s; got %d channels",
371 devname, gotchans);
372
373 if (gotchans < 2)
374 {
375 /* can't even do stereo? just give up. */
376 close(fd);
377 }
378 else
379 {
380 linux_dacs[linux_noutdevs].d_nchannels = gotchans;
381 linux_dacs[linux_noutdevs].d_fd = fd;
382 oss_configure(linux_dacs+linux_noutdevs, rate, 1, 0);
383
384 linux_noutdevs++;
385 outchannels += gotchans;
386 if (inindex >= 0)
387 {
388 linux_adcs[inindex].d_nchannels = gotchans;
389 chin[inindex] = gotchans;
390 }
391 }
392 /* LATER think about spreading large numbers of channels over
393 various dsp's and vice-versa */
394 wantmore = wantchannels - gotchans;
395 end_out_loop: ;
396 }
397
398 /* open input devices */
399 wantmore = 0;
400 for (n = 0; n < nindev; n++)
401 {
402 int gotchans=0;
403 int thisdevice = (indev[n] >= 0 ? indev[n] : n-1);
404 int wantchannels = (nchin>n)?chin[n]:wantmore;
405 int alreadyopened = 0;
406 if (!wantchannels)
407 goto end_in_loop;
408
409 if (thisdevice > 1)
410 sprintf(devname, "/dev/dsp%d", thisdevice - 1);
411 else sprintf(devname, "/dev/dsp");
412
413 sys_setalarm(1000000);
414
415 /* perhaps it's already open from the above? */
416 if (linux_dacs[n].d_fd >= 0)
417 {
418 fd = linux_dacs[n].d_fd;
419 alreadyopened = 1;
420 }
421 else
422 {
423 /* otherwise try to open it here. */
424 if ((fd = open(devname, O_RDONLY | O_AUDIOFLAG)) == -1)
425 {
426 post("%s (readonly): %s", devname, strerror(errno));
427 goto end_in_loop;
428 }
429 if (sys_verbose)
430 post("opened %s for reading only\n", devname);
431 }
432 linux_adcs[linux_nindevs].d_fd = fd;
433 gotchans = oss_setchannels(fd,
434 (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels,
435 devname);
436 if (sys_verbose)
437 post("opened audio input device %s; got %d channels",
438 devname, gotchans);
439
440 if (gotchans < 1)
441 {
442 close(fd);
443 goto end_in_loop;
444 }
445
446 linux_adcs[linux_nindevs].d_nchannels = gotchans;
447
448 oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened);
449
450 inchannels += gotchans;
451 linux_nindevs++;
452
453 wantmore = wantchannels-gotchans;
454 /* LATER think about spreading large numbers of channels over
455 various dsp's and vice-versa */
456 end_in_loop: ;
457 }
458
459 /* We have to do a read to start the engine. This is
460 necessary because sys_send_dacs waits until the input
461 buffer is filled and only reads on a filled buffer.
462 This is good, because it's a way to make sure that we
463 will not block. But I wonder why we only have to read
464 from one of the devices and not all of them??? */
465
466 if (linux_nindevs)
467 {
468 if (sys_verbose)
469 fprintf(stderr,("OSS: issuing first ADC 'read' ... "));
470 read(linux_adcs[0].d_fd, buf,
471 linux_adcs[0].d_bytespersamp *
472 linux_adcs[0].d_nchannels * DEFDACBLKSIZE);
473 if (sys_verbose)
474 fprintf(stderr, "...done.\n");
475 }
476 sys_setalarm(0);
477 return (0);
478}
479
480void oss_close_audio( void)
481{
482 int i;
483 for (i=0;i<linux_nindevs;i++)
484 close(linux_adcs[i].d_fd);
485
486 for (i=0;i<linux_noutdevs;i++)
487 close(linux_dacs[i].d_fd);
488
489 linux_nindevs = linux_noutdevs = 0;
490}
491
492static int linux_dacs_write(int fd,void* buf,long bytes)
493{
494 return write(fd, buf, bytes);
495}
496
497static int linux_adcs_read(int fd,void* buf,long bytes)
498{
499 return read(fd, buf, bytes);
500}
501
502 /* query audio devices for "available" data size. */
503static void oss_calcspace(void)
504{
505 int dev;
506 audio_buf_info ainfo;
507 for (dev=0; dev < linux_noutdevs; dev++)
508 {
509 if (ioctl(linux_dacs[dev].d_fd, SOUND_PCM_GETOSPACE, &ainfo) < 0)
510 fprintf(stderr,"OSS: ioctl on output device %d failed",dev);
511 linux_dacs[dev].d_space = ainfo.bytes;
512 }
513
514 for (dev = 0; dev < linux_nindevs; dev++)
515 {
516 if (ioctl(linux_adcs[dev].d_fd, SOUND_PCM_GETISPACE,&ainfo) < 0)
517 fprintf(stderr, "OSS: ioctl on input device %d, fd %d failed",
518 dev, linux_adcs[dev].d_fd);
519 linux_adcs[dev].d_space = ainfo.bytes;
520 }
521}
522
523void linux_audiostatus(void)
524{
525 int dev;
526 if (!oss_blockmode)
527 {
528 oss_calcspace();
529 for (dev=0; dev < linux_noutdevs; dev++)
530 fprintf(stderr, "dac %d space %d\n", dev, linux_dacs[dev].d_space);
531
532 for (dev = 0; dev < linux_nindevs; dev++)
533 fprintf(stderr, "adc %d space %d\n", dev, linux_adcs[dev].d_space);
534
535 }
536}
537
538/* this call resyncs audio output and input which will cause discontinuities
539in audio output and/or input. */
540
541static void oss_doresync( void)
542{
543 int dev, zeroed = 0, wantsize;
544 char buf[OSS_MAXSAMPLEWIDTH * DEFDACBLKSIZE * OSS_MAXCHPERDEV];
545 audio_buf_info ainfo;
546
547 /* 1. if any input devices are ahead (have more than 1 buffer stored),
548 drop one or more buffers worth */
549 for (dev = 0; dev < linux_nindevs; dev++)
550 {
551 if (linux_adcs[dev].d_space == 0)
552 {
553 linux_adcs_read(linux_adcs[dev].d_fd, buf,
554 OSS_XFERSIZE(linux_adcs[dev].d_nchannels,
555 linux_adcs[dev].d_bytespersamp));
556 }
557 else while (linux_adcs[dev].d_space >
558 OSS_XFERSIZE(linux_adcs[dev].d_nchannels,
559 linux_adcs[dev].d_bytespersamp))
560 {
561 linux_adcs_read(linux_adcs[dev].d_fd, buf,
562 OSS_XFERSIZE(linux_adcs[dev].d_nchannels,
563 linux_adcs[dev].d_bytespersamp));
564 if (ioctl(linux_adcs[dev].d_fd, SOUND_PCM_GETISPACE, &ainfo) < 0)
565 {
566 fprintf(stderr, "OSS: ioctl on input device %d, fd %d failed",
567 dev, linux_adcs[dev].d_fd);
568 break;
569 }
570 linux_adcs[dev].d_space = ainfo.bytes;
571 }
572 }
573
574 /* 2. if any output devices are behind, feed them zeros to catch them
575 up */
576 for (dev = 0; dev < linux_noutdevs; dev++)
577 {
578 while (linux_dacs[dev].d_space > linux_dacs[dev].d_bufsize -
579 sys_advance_samples * (linux_dacs[dev].d_nchannels *
580 linux_dacs[dev].d_bytespersamp))
581 {
582 if (!zeroed)
583 {
584 unsigned int i;
585 for (i = 0; i < OSS_XFERSAMPS(linux_dacs[dev].d_nchannels);
586 i++)
587 buf[i] = 0;
588 zeroed = 1;
589 }
590 linux_dacs_write(linux_dacs[dev].d_fd, buf,
591 OSS_XFERSIZE(linux_dacs[dev].d_nchannels,
592 linux_dacs[dev].d_bytespersamp));
593 if (ioctl(linux_dacs[dev].d_fd, SOUND_PCM_GETOSPACE, &ainfo) < 0)
594 {
595 fprintf(stderr, "OSS: ioctl on output device %d, fd %d failed",
596 dev, linux_dacs[dev].d_fd);
597 break;
598 }
599 linux_dacs[dev].d_space = ainfo.bytes;
600 }
601 }
602 /* 3. if any DAC devices are too far ahead, plan to drop the
603 number of frames which will let the others catch up. */
604 for (dev = 0; dev < linux_noutdevs; dev++)
605 {
606 if (linux_dacs[dev].d_space > linux_dacs[dev].d_bufsize -
607 (sys_advance_samples - 1) * linux_dacs[dev].d_nchannels *
608 linux_dacs[dev].d_bytespersamp)
609 {
610 linux_dacs[dev].d_dropcount = sys_advance_samples - 1 -
611 (linux_dacs[dev].d_space - linux_dacs[dev].d_bufsize) /
612 (linux_dacs[dev].d_nchannels *
613 linux_dacs[dev].d_bytespersamp) ;
614 }
615 else linux_dacs[dev].d_dropcount = 0;
616 }
617}
618
619int oss_send_dacs(void)
620{
621 t_sample *fp1, *fp2;
622 long fill;
623 int i, j, dev, rtnval = SENDDACS_YES;
624 char buf[OSS_MAXSAMPLEWIDTH * DEFDACBLKSIZE * OSS_MAXCHPERDEV];
625 t_oss_int16 *sp;
626 t_oss_int32 *lp;
627 /* the maximum number of samples we should have in the ADC buffer */
628 int idle = 0;
629 int thischan;
630 t_time timeref, timenow;
631
632 if (!linux_nindevs && !linux_noutdevs)
633 return (SENDDACS_NO);
634
635 if (!oss_blockmode)
636 {
637 /* determine whether we're idle. This is true if either (1)
638 some input device has less than one buffer to read or (2) some
639 output device has fewer than (sys_advance_samples) blocks buffered
640 already. */
641 oss_calcspace();
642
643 for (dev=0; dev < linux_noutdevs; dev++)
644 if (linux_dacs[dev].d_dropcount ||
645 (linux_dacs[dev].d_bufsize - linux_dacs[dev].d_space >
646 sys_advance_samples * linux_dacs[dev].d_bytespersamp *
647 linux_dacs[dev].d_nchannels))
648 idle = 1;
649 for (dev=0; dev < linux_nindevs; dev++)
650 if (linux_adcs[dev].d_space <
651 OSS_XFERSIZE(linux_adcs[dev].d_nchannels,
652 linux_adcs[dev].d_bytespersamp))
653 idle = 1;
654 }
655
656 if (idle && !oss_blockmode)
657 {
658 /* sometimes---rarely---when the ADC available-byte-count is
659 zero, it's genuine, but usually it's because we're so
660 late that the ADC has overrun its entire kernel buffer. We
661 distinguish between the two by waiting 2 msec and asking again.
662 There should be an error flag we could check instead; look for this
663 someday... */
664 for (dev = 0;dev < linux_nindevs; dev++)
665 if (linux_adcs[dev].d_space == 0)
666 {
667 audio_buf_info ainfo;
668 sys_microsleep(2000);
669 oss_calcspace();
670 if (linux_adcs[dev].d_space != 0) continue;
671
672 /* here's the bad case. Give up and resync. */
673 sys_log_error(ERR_DATALATE);
674 oss_doresync();
675 return (SENDDACS_NO);
676 }
677 /* check for slippage between devices, either because
678 data got lost in the driver from a previous late condition, or
679 because the devices aren't synced. When we're idle, no
680 input device should have more than one buffer readable and
681 no output device should have less than sys_advance_samples-1
682 */
683
684 for (dev=0; dev < linux_noutdevs; dev++)
685 if (!linux_dacs[dev].d_dropcount &&
686 (linux_dacs[dev].d_bufsize - linux_dacs[dev].d_space <
687 (sys_advance_samples - 2) *
688 (linux_dacs[dev].d_bytespersamp *
689 linux_dacs[dev].d_nchannels)))
690 goto badsync;
691 for (dev=0; dev < linux_nindevs; dev++)
692 if (linux_adcs[dev].d_space > 3 *
693 OSS_XFERSIZE(linux_adcs[dev].d_nchannels,
694 linux_adcs[dev].d_bytespersamp))
695 goto badsync;
696
697 /* return zero to tell the scheduler we're idle. */
698 return (SENDDACS_NO);
699 badsync:
700 sys_log_error(ERR_RESYNC);
701 oss_doresync();
702 return (SENDDACS_NO);
703
704 }
705
706
707 /* do output */
708
709 timeref = sys_getrealtime();
710 for (dev=0, thischan = 0; dev < linux_noutdevs; dev++)
711 {
712 int nchannels = linux_dacs[dev].d_nchannels;
713 if (linux_dacs[dev].d_dropcount)
714 linux_dacs[dev].d_dropcount--;
715 else
716 {
717 if (linux_dacs[dev].d_bytespersamp == 4)
718 {
719 for (i = DEFDACBLKSIZE * nchannels, fp1 = sys_soundout +
720 DEFDACBLKSIZE*thischan,
721 lp = (t_oss_int32 *)buf; i--; fp1++, lp++)
722 {
723 t_sample f = SCALE32(*fp1);
724 *lp = (f >= 2147483647 ? 2147483647 :
725 (f < -2147483647 ? -2147483647 : f));
726 }
727 }
728 else
729 {
730 for (i = DEFDACBLKSIZE, fp1 = sys_soundout +
731 DEFDACBLKSIZE*thischan,
732 sp = (t_oss_int16 *)buf; i--; fp1++, sp += nchannels)
733 {
734 for (j=0, fp2 = fp1; j<nchannels; j++, fp2 += DEFDACBLKSIZE)
735 {
736 int s = SCALE16(*fp2);
737 if (s > 32767) s = 32767;
738 else if (s < -32767) s = -32767;
739 sp[j] = s;
740 }
741 }
742 }
743
744
745#if 0
746#define PR_S "%8d"
747 {
748 int nm = 64;
749 int* sp1 = buf;
750 post("dac:");
751 while (nm > 0)
752 {
753 post(PR_S PR_S PR_S PR_S PR_S PR_S PR_S PR_S,
754 sp1[0], sp1[1], sp1[2], sp1[3], sp1[4], sp1[5], sp1[6], sp1[7]);
755 nm -= 8;
756 sp1 += 8;
757 }
758 }
759#endif
760 linux_dacs_write(linux_dacs[dev].d_fd, buf,
761 OSS_XFERSIZE(nchannels, linux_dacs[dev].d_bytespersamp));
762
763#if 0
764 if ((timenow = sys_getrealtime()) - timeref > 200)
765 {
766 post("dacslept %d",sys_getrealtime() - timeref);
767 if (!oss_blockmode)
768 sys_log_error(ERR_DACSLEPT);
769 else rtnval = SENDDACS_SLEPT;
770 }
771#endif
772 timeref = timenow;
773 }
774 thischan += nchannels;
775 }
776 memset(sys_soundout, 0,
777 sys_outchannels * (sizeof(float) * DEFDACBLKSIZE));
778
779 /* do input */
780
781 for (dev = 0, thischan = 0; dev < linux_nindevs; dev++)
782 {
783 int nchannels = linux_adcs[dev].d_nchannels;
784 linux_adcs_read(linux_adcs[dev].d_fd, buf,
785 OSS_XFERSIZE(nchannels, linux_adcs[dev].d_bytespersamp));
786
787#if 0
788 if ((timenow = sys_getrealtime()) - timeref > 200)
789 {
790 if (!oss_blockmode)
791 sys_log_error(ERR_ADCSLEPT);
792 else
793 rtnval = SENDDACS_SLEPT;
794 }
795#endif
796 timeref = timenow;
797
798 if (linux_adcs[dev].d_bytespersamp == 4)
799 {
800 for (i = DEFDACBLKSIZE*nchannels,
801 fp1 = sys_soundin + thischan*DEFDACBLKSIZE,
802 lp = (t_oss_int32 *)buf; i--; fp1++, lp++)
803 {
804 *fp1 = ((t_sample)(*lp))*(t_sample)(1./2147483648.);
805 }
806 }
807 else
808 {
809 for (i = DEFDACBLKSIZE,fp1 = sys_soundin + thischan*DEFDACBLKSIZE,
810 sp = (t_oss_int16 *)buf; i--; fp1++, sp += nchannels)
811 {
812 for (j=0;j<sys_inchannels;j++)
813 fp1[j*DEFDACBLKSIZE] = INVSCALE16(sp[j]);
814 }
815 }
816 thischan += nchannels;
817 }
818 if (thischan != sys_inchannels)
819 bug("inchannels");
820 return (rtnval);
821}
822
823void oss_listdevs( void)
824{
825 post("device listing not implemented in OSS yet\n");
826}
827
828void oss_getdevs(char *indevlist, int *nindevs,
829 char *outdevlist, int *noutdevs, int *canmulti,
830 int maxndev, int devdescsize)
831{
832 int i, ndev;
833 *canmulti = 2; /* supports multiple devices */
834 if ((ndev = oss_ndev) > maxndev)
835 ndev = maxndev;
836 for (i = 0; i < ndev; i++)
837 {
838 sprintf(indevlist + i * devdescsize, "OSS device #%d", i+1);
839 sprintf(outdevlist + i * devdescsize, "OSS device #%d", i+1);
840 }
841 *nindevs = *noutdevs = ndev;
842}
843
844#endif
845
diff --git a/apps/plugins/pdbox/PDa/src/s_audio_pa.c b/apps/plugins/pdbox/PDa/src/s_audio_pa.c
deleted file mode 100644
index 943b57e212..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_audio_pa.c
+++ /dev/null
@@ -1,293 +0,0 @@
1/* Copyright (c) 2001 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* this file calls Ross Bencina's and Phil Burk's Portaudio package. It's
6 the main way in for Mac OS and, with Michael Casey's help, also into
7 ASIO in Windows. */
8
9
10#include "m_pd.h"
11#include "s_stuff.h"
12#include <stdio.h>
13#include <stdlib.h>
14#include "portaudio.h"
15#include "pablio_pd.h"
16
17 /* LATER try to figure out how to handle default devices in portaudio;
18 the way s_audio.c handles them isn't going to work here. */
19
20#if defined(MACOSX) || defined(MSW)
21#define Pa_GetDefaultInputDevice Pa_GetDefaultInputDeviceID
22#define Pa_GetDefaultOutputDevice Pa_GetDefaultOutputDeviceID
23#endif
24
25 /* public interface declared in m_imp.h */
26
27 /* implementation */
28static PABLIO_Stream *pa_stream;
29static int pa_inchans, pa_outchans;
30static float *pa_soundin, *pa_soundout;
31
32#define MAX_PA_CHANS 32
33#define MAX_SAMPLES_PER_FRAME MAX_PA_CHANS * DEFDACBLKSIZE
34
35int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
36 t_sample *soundout, int framesperbuf, int nbuffers,
37 int indeviceno, int outdeviceno)
38{
39 PaError err;
40 static int initialized;
41 int j, devno, pa_indev = 0, pa_outdev = 0;
42
43 if (!initialized)
44 {
45 /* Initialize PortAudio */
46 int err = Pa_Initialize();
47 if ( err != paNoError )
48 {
49 fprintf( stderr,
50 "Error number %d occured initializing portaudio\n",
51 err);
52 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
53 return (1);
54 }
55 initialized = 1;
56 }
57 /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */
58 if (inchans != 0 && outchans != 0 && inchans != outchans)
59 error("portaudio: number of input and output channels must match");
60 if (inchans > MAX_PA_CHANS)
61 {
62 post("input channels reduced to maximum %d", MAX_PA_CHANS);
63 inchans = MAX_PA_CHANS;
64 }
65 if (outchans > MAX_PA_CHANS)
66 {
67 post("output channels reduced to maximum %d", MAX_PA_CHANS);
68 outchans = MAX_PA_CHANS;
69 }
70
71 if (inchans > 0)
72 {
73 for (j = 0, devno = 0; j < Pa_CountDevices(); j++)
74 {
75 const PaDeviceInfo *info = Pa_GetDeviceInfo(j);
76 if (info->maxInputChannels > 0)
77 {
78 if (devno == indeviceno)
79 {
80 pa_indev = j;
81 break;
82 }
83 devno++;
84 }
85 }
86 }
87
88 if (outchans > 0)
89 {
90 for (j = 0, devno = 0; j < Pa_CountDevices(); j++)
91 {
92 const PaDeviceInfo *info = Pa_GetDeviceInfo(j);
93 if (info->maxOutputChannels > 0)
94 {
95 if (devno == outdeviceno)
96 {
97 pa_outdev = j;
98 break;
99 }
100 devno++;
101 }
102 }
103 }
104
105 if (sys_verbose)
106 {
107 post("input device %d, channels %d", pa_indev, inchans);
108 post("output device %d, channels %d", pa_outdev, outchans);
109 post("framesperbuf %d, nbufs %d", framesperbuf, nbuffers);
110 }
111 if (inchans && outchans)
112 err = OpenAudioStream( &pa_stream, rate, paFloat32,
113 PABLIO_READ_WRITE, inchans, framesperbuf, nbuffers,
114 pa_indev, pa_outdev);
115 else if (inchans)
116 err = OpenAudioStream( &pa_stream, rate, paFloat32,
117 PABLIO_READ, inchans, framesperbuf, nbuffers,
118 pa_indev, pa_outdev);
119 else if (outchans)
120 err = OpenAudioStream( &pa_stream, rate, paFloat32,
121 PABLIO_WRITE, outchans, framesperbuf, nbuffers,
122 pa_indev, pa_outdev);
123 else err = 0;
124 if ( err != paNoError )
125 {
126 fprintf( stderr, "Error number %d occured opening portaudio stream\n",
127 err);
128 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
129 Pa_Terminate();
130 sys_inchannels = sys_outchannels = 0;
131 return (1);
132 }
133 else if (sys_verbose)
134 post("... opened OK.");
135 pa_inchans = inchans;
136 pa_outchans = outchans;
137 pa_soundin = soundin;
138 pa_soundout = soundout;
139 return (0);
140}
141
142void pa_close_audio( void)
143{
144 if (pa_inchans || pa_outchans)
145 CloseAudioStream( pa_stream );
146 pa_inchans = pa_outchans = 0;
147}
148
149int pa_send_dacs(void)
150{
151 float samples[MAX_SAMPLES_PER_FRAME], *fp1, *fp2;
152 int i, j;
153 double timebefore;
154
155 timebefore = sys_getrealtime();
156 if ((pa_inchans && GetAudioStreamReadable(pa_stream) < DEFDACBLKSIZE) ||
157 (pa_outchans && GetAudioStreamWriteable(pa_stream) < DEFDACBLKSIZE))
158 {
159 if (pa_inchans && pa_outchans)
160 {
161 int synced = 0;
162 while (GetAudioStreamWriteable(pa_stream) > 2*DEFDACBLKSIZE)
163 {
164 for (j = 0; j < pa_outchans; j++)
165 for (i = 0, fp2 = samples + j; i < DEFDACBLKSIZE; i++,
166 fp2 += pa_outchans)
167 {
168 *fp2 = 0;
169 }
170 synced = 1;
171 WriteAudioStream(pa_stream, samples, DEFDACBLKSIZE);
172 }
173 while (GetAudioStreamReadable(pa_stream) > 2*DEFDACBLKSIZE)
174 {
175 synced = 1;
176 ReadAudioStream(pa_stream, samples, DEFDACBLKSIZE);
177 }
178 /* if (synced)
179 post("sync"); */
180 }
181 return (SENDDACS_NO);
182 }
183 if (pa_inchans)
184 {
185 ReadAudioStream(pa_stream, samples, DEFDACBLKSIZE);
186 for (j = 0, fp1 = pa_soundin; j < pa_inchans; j++, fp1 += DEFDACBLKSIZE)
187 for (i = 0, fp2 = samples + j; i < DEFDACBLKSIZE; i++,
188 fp2 += pa_inchans)
189 {
190 fp1[i] = *fp2;
191 }
192 }
193#if 0
194 {
195 static int nread;
196 if (nread == 0)
197 {
198 post("it's %f %f %f %f",
199 pa_soundin[0], pa_soundin[1], pa_soundin[2], pa_soundin[3]);
200 nread = 1000;
201 }
202 nread--;
203 }
204#endif
205 if (pa_outchans)
206 {
207 for (j = 0, fp1 = pa_soundout; j < pa_outchans; j++,
208 fp1 += DEFDACBLKSIZE)
209 for (i = 0, fp2 = samples + j; i < DEFDACBLKSIZE; i++,
210 fp2 += pa_outchans)
211 {
212 *fp2 = fp1[i];
213 fp1[i] = 0;
214 }
215 WriteAudioStream(pa_stream, samples, DEFDACBLKSIZE);
216 }
217
218 if (sys_getrealtime() > timebefore + 0.002)
219 {
220 /* post("slept"); */
221 return (SENDDACS_SLEPT);
222 }
223 else return (SENDDACS_YES);
224}
225
226
227void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */
228{
229 int i,j;
230 int numDevices;
231 const PaDeviceInfo *pdi;
232 PaError err;
233 Pa_Initialize();
234 numDevices = Pa_CountDevices();
235 if( numDevices < 0 )
236 {
237 fprintf(stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
238 err = numDevices;
239 goto error;
240 }
241 fprintf(stderr, "Audio Devices:\n");
242 for( i=0; i<numDevices; i++ )
243 {
244 pdi = Pa_GetDeviceInfo( i );
245 fprintf(stderr, "device %d:", i+1 );
246 fprintf(stderr, " %s;", pdi->name );
247 fprintf(stderr, "%d inputs, ", pdi->maxInputChannels );
248 fprintf(stderr, "%d outputs", pdi->maxOutputChannels );
249 if ( i == Pa_GetDefaultInputDevice() )
250 fprintf(stderr, " (Default Input)");
251 if ( i == Pa_GetDefaultOutputDevice() )
252 fprintf(stderr, " (Default Output)");
253 fprintf(stderr, "\n");
254 }
255
256 fprintf(stderr, "\n");
257 return;
258
259error:
260 fprintf( stderr, "An error occured while using the portaudio stream\n" );
261 fprintf( stderr, "Error number: %d\n", err );
262 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
263
264}
265
266 /* scanning for devices */
267void pa_getdevs(char *indevlist, int *nindevs,
268 char *outdevlist, int *noutdevs, int *canmulti,
269 int maxndev, int devdescsize)
270{
271 int i, nin = 0, nout = 0, ndev;
272 *canmulti = 1; /* one dev each for input and output */
273
274 Pa_Initialize();
275 ndev = Pa_CountDevices();
276 for (i = 0; i < ndev; i++)
277 {
278 const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i);
279 if (pdi->maxInputChannels > 0 && nin < maxndev)
280 {
281 strcpy(indevlist + nin * devdescsize, pdi->name);
282 nin++;
283 }
284 if (pdi->maxOutputChannels > 0 && nout < maxndev)
285 {
286 strcpy(outdevlist + nout * devdescsize, pdi->name);
287 nout++;
288 }
289 }
290 *nindevs = nin;
291 *noutdevs = nout;
292}
293
diff --git a/apps/plugins/pdbox/PDa/src/s_entry.c b/apps/plugins/pdbox/PDa/src/s_entry.c
deleted file mode 100644
index fd7b4c52fa..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_entry.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/* In MSW, this is all there is to pd; the rest sits in a "pdlib" dll so
2that externs can link back to functions defined in pd. */
3
4#include <stdio.h>
5
6int sys_main(int argc, char **argv);
7
8 /* WINBASEAPI PVOID WINAPI AddVectoredExceptionHandler(
9 ULONG FirstHandler,
10 PVECTORED_EXCEPTION_HANDLER VectoredHandler ); */
11
12#ifdef MSW
13#if 0
14#incldue "winbase.h"
15
16LONG NTAPI VectoredExceptionHandler(void *PEXCEPTION_POINTERS)
17{
18 fprintf(stderr, "caught exception\n");
19 return(EXCEPTION_CONTINUE_SEARCH);
20}
21
22
23int main(int argc, char **argv)
24{
25 printf("Pd entry point\n");
26 AddVectoredExceptionHandler(
27 ULONG FirstHandler,
28 PVECTORED_EXCEPTION_HANDLER VectoredHandler );
29
30
31#endif
32
33#if 1
34int main(int argc, char **argv)
35{
36 __try
37 {
38 sys_main(argc, argv);
39 }
40 __finally
41 {
42 printf("caught an exception; stopping\n");
43 }
44}
45#endif
46#else /* not MSW */
47int main(int argc, char **argv)
48{
49 return (sys_main(argc, argv));
50}
51#endif
52
diff --git a/apps/plugins/pdbox/PDa/src/s_inter.c b/apps/plugins/pdbox/PDa/src/s_inter.c
deleted file mode 100644
index 9df9c82b40..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_inter.c
+++ /dev/null
@@ -1,1000 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* Pd side of the Pd/Pd-gui interface. Also, some system interface routines
6that didn't really belong anywhere. */
7
8#include "m_pd.h"
9#include "s_stuff.h"
10#include "m_imp.h"
11#ifdef UNIX
12#include <unistd.h>
13#include <sys/socket.h>
14#include <netinet/in.h>
15#include <netinet/tcp.h>
16#include <netdb.h>
17#include <stdlib.h>
18#include <sys/time.h>
19#include <sys/mman.h>
20#endif
21#ifdef HAVE_BSTRING_H
22#include <bstring.h>
23#endif
24#ifdef MSW
25#include <io.h>
26#include <fcntl.h>
27#include <process.h>
28#include <winsock.h>
29typedef int pid_t;
30#define EADDRINUSE WSAEADDRINUSE
31#endif
32#include <stdarg.h>
33#include <signal.h>
34#include <fcntl.h>
35#include <errno.h>
36#include <string.h>
37#include <stdio.h>
38
39#ifdef MACOSX
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <pthread.h>
43#else
44#include <stdlib.h>
45#endif
46
47#define DEBUG_MESSUP 1 /* messages up from pd to pd-gui */
48#define DEBUG_MESSDOWN 2 /* messages down from pd-gui to pd */
49
50/* T.Grill - make it a _little_ more adaptable... */
51#ifndef PDBINDIR
52#define PDBINDIR "bin/"
53#endif
54
55#ifndef WISHAPP
56#define WISHAPP "wish83.exe"
57#endif
58
59extern char pd_version[];
60
61typedef struct _fdpoll
62{
63 int fdp_fd;
64 t_fdpollfn fdp_fn;
65 void *fdp_ptr;
66} t_fdpoll;
67
68#define INBUFSIZE 4096
69
70struct _socketreceiver
71{
72 char *sr_inbuf;
73 int sr_inhead;
74 int sr_intail;
75 void *sr_owner;
76 int sr_udp;
77 t_socketnotifier sr_notifier;
78 t_socketreceivefn sr_socketreceivefn;
79};
80
81static int sys_nfdpoll;
82static t_fdpoll *sys_fdpoll;
83static int sys_maxfd;
84static int sys_guisock;
85
86static t_binbuf *inbinbuf;
87static t_socketreceiver *sys_socketreceiver;
88extern int sys_addhist(int phase);
89
90#ifdef MSW
91static LARGE_INTEGER nt_inittime;
92static double nt_freq = 0;
93
94static void sys_initntclock(void)
95{
96 LARGE_INTEGER f1;
97 LARGE_INTEGER now;
98 QueryPerformanceCounter(&now);
99 if (!QueryPerformanceFrequency(&f1))
100 {
101 fprintf(stderr, "pd: QueryPerformanceFrequency failed\n");
102 f1.QuadPart = 1;
103 }
104 nt_freq = f1.QuadPart;
105 nt_inittime = now;
106}
107
108#if 0
109 /* this is a version you can call if you did the QueryPerformanceCounter
110 call yourself. Necessary for time tagging incoming MIDI at interrupt
111 level, for instance; but we're not doing that just now. */
112
113double nt_tixtotime(LARGE_INTEGER *dumbass)
114{
115 if (nt_freq == 0) sys_initntclock();
116 return (((double)(dumbass->QuadPart - nt_inittime.QuadPart)) / nt_freq);
117}
118#endif
119#endif /* MSW */
120
121 /* get "real time" in seconds; take the
122 first time we get called as a reference time of zero. */
123t_time sys_getrealtime(void)
124{
125#ifdef UNIX
126 static struct timeval then;
127 struct timeval now;
128 gettimeofday(&now, 0);
129 if (then.tv_sec == 0 && then.tv_usec == 0) then = now;
130 return (now.tv_sec - then.tv_sec)*1000000 +
131 (now.tv_usec - then.tv_usec);
132#endif
133#ifdef MSW
134 LARGE_INTEGER now;
135 QueryPerformanceCounter(&now);
136 if (nt_freq == 0) sys_initntclock();
137 return (((double)(now.QuadPart - nt_inittime.QuadPart)) / nt_freq);
138#endif
139}
140
141void sys_sockerror(char *s)
142{
143#ifdef MSW
144 int err = WSAGetLastError();
145 if (err == 10054) return;
146 else if (err == 10044)
147 {
148 fprintf(stderr,
149 "Warning: you might not have TCP/IP \"networking\" turned on\n");
150 fprintf(stderr, "which is needed for Pd to talk to its GUI layer.\n");
151 }
152#endif
153#ifdef UNIX
154 int err = errno;
155#endif
156 fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err);
157}
158
159void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr)
160{
161 int nfd = sys_nfdpoll;
162 int size = nfd * sizeof(t_fdpoll);
163 t_fdpoll *fp;
164 sys_fdpoll = (t_fdpoll *)t_resizebytes(sys_fdpoll, size,
165 size + sizeof(t_fdpoll));
166 fp = sys_fdpoll + nfd;
167 fp->fdp_fd = fd;
168 fp->fdp_fn = fn;
169 fp->fdp_ptr = ptr;
170 sys_nfdpoll = nfd + 1;
171 if (fd >= sys_maxfd) sys_maxfd = fd + 1;
172}
173
174void sys_rmpollfn(int fd)
175{
176 int nfd = sys_nfdpoll;
177 int i, size = nfd * sizeof(t_fdpoll);
178 t_fdpoll *fp;
179 for (i = nfd, fp = sys_fdpoll; i--; fp++)
180 {
181 if (fp->fdp_fd == fd)
182 {
183 while (i--)
184 {
185 fp[0] = fp[1];
186 fp++;
187 }
188 sys_fdpoll = (t_fdpoll *)t_resizebytes(sys_fdpoll, size,
189 size - sizeof(t_fdpoll));
190 sys_nfdpoll = nfd - 1;
191 return;
192 }
193 }
194 post("warning: %d removed from poll list but not found", fd);
195}
196
197static int sys_domicrosleep(int microsec, int pollem)
198{
199 struct timeval timout;
200 int i, didsomething = 0;
201 t_fdpoll *fp;
202 timout.tv_sec = 0;
203 timout.tv_usec = microsec;
204 if (pollem)
205 {
206 fd_set readset, writeset, exceptset;
207 FD_ZERO(&writeset);
208 FD_ZERO(&readset);
209 FD_ZERO(&exceptset);
210 for (fp = sys_fdpoll, i = sys_nfdpoll; i--; fp++)
211 FD_SET(fp->fdp_fd, &readset);
212 select(sys_maxfd+1, &readset, &writeset, &exceptset, &timout);
213 for (i = 0; i < sys_nfdpoll; i++)
214 if (FD_ISSET(sys_fdpoll[i].fdp_fd, &readset))
215 {
216 (*sys_fdpoll[i].fdp_fn)(sys_fdpoll[i].fdp_ptr, sys_fdpoll[i].fdp_fd);
217 didsomething = 1;
218 }
219 return (didsomething);
220 }
221 else
222 {
223 select(0, 0, 0, 0, &timout);
224 return (0);
225 }
226}
227
228void sys_microsleep(int microsec)
229{
230 sys_domicrosleep(microsec, 1);
231}
232
233t_socketreceiver *socketreceiver_new(void *owner, t_socketnotifier notifier,
234 t_socketreceivefn socketreceivefn, int udp)
235{
236 t_socketreceiver *x = (t_socketreceiver *)getbytes(sizeof(*x));
237 x->sr_inhead = x->sr_intail = 0;
238 x->sr_owner = owner;
239 x->sr_notifier = notifier;
240 x->sr_socketreceivefn = socketreceivefn;
241 x->sr_udp = udp;
242 if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_socketreceiver");;
243 return (x);
244}
245
246void socketreceiver_free(t_socketreceiver *x)
247{
248 free(x->sr_inbuf);
249 freebytes(x, sizeof(*x));
250}
251
252 /* this is in a separately called subroutine so that the buffer isn't
253 sitting on the stack while the messages are getting passed. */
254static int socketreceiver_doread(t_socketreceiver *x)
255{
256 char messbuf[INBUFSIZE], *bp = messbuf;
257 int indx;
258 int inhead = x->sr_inhead;
259 int intail = x->sr_intail;
260 char *inbuf = x->sr_inbuf;
261 if (intail == inhead) return (0);
262 for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1))
263 {
264 /* if we hit a semi that isn't preceeded by a \, it's a message
265 boundary. LATER we should deal with the possibility that the
266 preceeding \ might itself be escaped! */
267 char c = *bp++ = inbuf[indx];
268 if (c == ';' && (!indx || inbuf[indx-1] != '\\'))
269 {
270 intail = (indx+1)&(INBUFSIZE-1);
271 binbuf_text(inbinbuf, messbuf, bp - messbuf);
272 if (sys_debuglevel & DEBUG_MESSDOWN)
273 {
274 write(2, messbuf, bp - messbuf);
275 write(2, "\n", 1);
276 }
277 x->sr_inhead = inhead;
278 x->sr_intail = intail;
279 return (1);
280 }
281 }
282 return (0);
283}
284
285static void socketreceiver_getudp(t_socketreceiver *x, int fd)
286{
287 char buf[INBUFSIZE+1];
288 int ret = recv(fd, buf, INBUFSIZE, 0);
289 if (ret < 0)
290 {
291 sys_sockerror("recv");
292 sys_rmpollfn(fd);
293 sys_closesocket(fd);
294 }
295 else if (ret > 0)
296 {
297 buf[ret] = 0;
298#if 0
299 post("%s", buf);
300#endif
301 if (buf[ret-1] != '\n')
302 {
303#if 0
304 buf[ret] = 0;
305 error("dropped bad buffer %s\n", buf);
306#endif
307 }
308 else
309 {
310 char *semi = strchr(buf, ';');
311 if (semi)
312 *semi = 0;
313 binbuf_text(inbinbuf, buf, strlen(buf));
314 outlet_setstacklim();
315 if (x->sr_socketreceivefn)
316 (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
317 else bug("socketreceiver_getudp");
318 }
319 }
320}
321
322
323
324#include <termios.h>
325#include <string.h>
326
327static struct termios stored_settings;
328EXTERN int sys_stdin;
329
330void set_keypress(void)
331{
332 struct termios new_settings;
333
334 tcgetattr(0,&stored_settings);
335
336 new_settings = stored_settings;
337
338 /* Disable canonical mode, and set buffer size to 1 byte */
339 new_settings.c_lflag &= (~ICANON);
340 new_settings.c_cc[VTIME] = 0;
341 new_settings.c_cc[VMIN] = 1;
342
343/* echo off */
344 new_settings.c_lflag &= (~ECHO);
345
346 tcsetattr(0,TCSANOW,&new_settings);
347 return;
348}
349
350void reset_keypress(void)
351{
352 if (sys_stdin)
353 tcsetattr(0,TCSANOW,&stored_settings);
354 return;
355}
356
357static t_symbol* _ss;
358
359
360void stdin_read(t_socketreceiver *x, int fd) {
361 static char input[256];
362
363 char* in;
364 int got;
365
366 got = read(fd,input,256);
367 in = input;
368 while (got-- && _ss->s_thing)
369 pd_float(_ss->s_thing,(float)*in++);
370}
371
372void socketreceiver_read(t_socketreceiver *x, int fd)
373{
374 if (x->sr_udp) /* UDP ("datagram") socket protocol */
375 socketreceiver_getudp(x, fd);
376 else /* TCP ("streaming") socket protocol */
377 {
378 char *semi;
379 int readto =
380 (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
381 int ret;
382
383 /* the input buffer might be full. If so, drop the whole thing */
384 if (readto == x->sr_inhead)
385 {
386 fprintf(stderr, "pd: dropped message from gui\n");
387 x->sr_inhead = x->sr_intail = 0;
388 readto = INBUFSIZE;
389 }
390 else
391 {
392 ret = recv(fd, x->sr_inbuf + x->sr_inhead,
393 readto - x->sr_inhead, 0);
394 if (ret < 0)
395 {
396 sys_sockerror("recv");
397 if (x == sys_socketreceiver) sys_bail(1);
398 else
399 {
400 if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
401 sys_rmpollfn(fd);
402 sys_closesocket(fd);
403 }
404 }
405 else if (ret == 0)
406 {
407 if (x == sys_socketreceiver)
408 {
409 fprintf(stderr, "pd: exiting\n");
410 sys_bail(0);
411 }
412 else
413 {
414 post("EOF on socket %d\n", fd);
415 if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner);
416 sys_rmpollfn(fd);
417 sys_closesocket(fd);
418 }
419 }
420 else
421 {
422 x->sr_inhead += ret;
423 if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0;
424 while (socketreceiver_doread(x))
425 {
426 outlet_setstacklim();
427 if (x->sr_socketreceivefn)
428 (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf);
429 else binbuf_eval(inbinbuf, 0, 0, 0);
430 }
431 }
432 }
433 }
434}
435
436void sys_closesocket(int fd)
437{
438#ifdef UNIX
439 close(fd);
440#endif
441#ifdef MSW
442 closesocket(fd);
443#endif
444}
445
446
447void sys_gui(char *s)
448{
449 int length = strlen(s), written = 0, res, histwas = sys_addhist(4);
450 if (sys_debuglevel & DEBUG_MESSUP)
451 fprintf(stderr, "%s", s);
452 if (sys_nogui)
453 return;
454 while (1)
455 {
456 res = send(sys_guisock, s + written, length, 0);
457 if (res < 0)
458 {
459 perror("pd output pipe");
460 sys_bail(1);
461 }
462 else
463 {
464 written += res;
465 if (written >= length)
466 break;
467 }
468 }
469 sys_addhist(histwas);
470}
471
472/* LATER should do a bounds check -- but how do you get printf to do that?
473 See also rtext_senditup() in this regard */
474
475void sys_vgui(char *fmt, ...)
476{
477 int result, i;
478 char buf[2048];
479 va_list ap;
480
481 va_start(ap, fmt);
482 vsprintf(buf, fmt, ap);
483 sys_gui(buf);
484 va_end(ap);
485}
486
487
488#define FIRSTPORTNUM 5400
489
490/* -------------- signal handling for UNIX -------------- */
491
492#ifdef UNIX
493typedef void (*sighandler_t)(int);
494
495static void sys_signal(int signo, sighandler_t sigfun)
496{
497 struct sigaction action;
498 action.sa_flags = 0;
499 action.sa_handler = sigfun;
500 memset(&action.sa_mask, 0, sizeof(action.sa_mask));
501#if 0 /* GG says: don't use that */
502 action.sa_restorer = 0;
503#endif
504 if (sigaction(signo, &action, 0) < 0)
505 perror("sigaction");
506}
507
508static void sys_exithandler(int n)
509{
510 static int trouble = 0;
511 if (!trouble)
512 {
513 trouble = 1;
514 fprintf(stderr, "Pd: signal %d\n", n);
515 sys_bail(1);
516
517 }
518 else _exit(1);
519}
520
521static void sys_alarmhandler(int n)
522{
523 fprintf(stderr, "Pd: system call timed out\n");
524}
525
526static void sys_huphandler(int n)
527{
528 struct timeval timout;
529 timout.tv_sec = 0;
530 timout.tv_usec = 30000;
531 select(1, 0, 0, 0, &timout);
532}
533
534void sys_setalarm(int microsec)
535{
536 struct itimerval gonzo;
537#if 0
538 fprintf(stderr, "timer %d\n", microsec);
539#endif
540 gonzo.it_interval.tv_sec = 0;
541 gonzo.it_interval.tv_usec = 0;
542 gonzo.it_value.tv_sec = 0;
543 gonzo.it_value.tv_usec = microsec;
544 if (microsec)
545 sys_signal(SIGALRM, sys_alarmhandler);
546 else sys_signal(SIGALRM, SIG_IGN);
547 setitimer(ITIMER_REAL, &gonzo, 0);
548}
549
550#endif
551
552#ifdef __linux__
553
554#if defined(_POSIX_PRIORITY_SCHEDULING) || defined(_POSIX_MEMLOCK)
555#include <sched.h>
556#endif
557
558void sys_set_priority(int higher)
559{
560#ifdef _POSIX_PRIORITY_SCHEDULING
561 struct sched_param par;
562 int p1 ,p2, p3;
563 p1 = sched_get_priority_min(SCHED_FIFO);
564 p2 = sched_get_priority_max(SCHED_FIFO);
565#ifdef USEAPI_JACK
566 p3 = (higher ? p1 + 7 : p1 + 5);
567#else
568 p3 = (higher ? p2 - 1 : p2 - 3);
569#endif
570 par.sched_priority = p3;
571 if (sched_setscheduler(0,SCHED_FIFO,&par) != -1)
572 fprintf(stderr, "priority %d scheduling enabled.\n", p3);
573#endif
574
575#ifdef _POSIX_MEMLOCK
576 if (mlockall(MCL_FUTURE) != -1)
577 fprintf(stderr, "memory locking enabled.\n");
578#endif
579
580}
581
582#endif /* __linux__ */
583
584static int sys_watchfd;
585
586#ifdef __linux__
587void glob_ping(t_pd *dummy)
588{
589 if (write(sys_watchfd, "\n", 1) < 1)
590 {
591 fprintf(stderr, "pd: watchdog process died\n");
592 sys_bail(1);
593 }
594}
595#endif
596
597static int defaultfontshit[] = {
598 8, 5, 9, 10, 6, 10, 12, 7, 13, 14, 9, 17, 16, 10, 19, 24, 15, 28,
599 24, 15, 28};
600
601int sys_startgui(const char *guidir)
602{
603 pid_t childpid;
604 char cmdbuf[4*MAXPDSTRING];
605 struct sockaddr_in server;
606 int msgsock;
607 char buf[15];
608 int len = sizeof(server);
609 int ntry = 0, portno = FIRSTPORTNUM;
610 int xsock = -1;
611#ifdef MSW
612 short version = MAKEWORD(2, 0);
613 WSADATA nobby;
614#endif
615#ifdef UNIX
616 int stdinpipe[2];
617#endif
618 /* create an empty FD poll list */
619 sys_fdpoll = (t_fdpoll *)t_getbytes(0);
620 sys_nfdpoll = 0;
621 inbinbuf = binbuf_new();
622
623#ifdef UNIX
624 signal(SIGHUP, sys_huphandler);
625 signal(SIGINT, sys_exithandler);
626 signal(SIGQUIT, sys_exithandler);
627 signal(SIGILL, sys_exithandler);
628 signal(SIGIOT, sys_exithandler);
629 signal(SIGFPE, SIG_IGN);
630 /* signal(SIGILL, sys_exithandler);
631 signal(SIGBUS, sys_exithandler);
632 signal(SIGSEGV, sys_exithandler); */
633 signal(SIGPIPE, SIG_IGN);
634 signal(SIGALRM, SIG_IGN);
635 signal(SIGTERM, SIG_IGN);
636#if 0 /* GG says: don't use that */
637 signal(SIGSTKFLT, sys_exithandler);
638#endif
639#endif
640#ifdef MSW
641 if (WSAStartup(version, &nobby)) sys_sockerror("WSAstartup");
642#endif
643
644 if (sys_nogui)
645 {
646 /* fake the GUI's message giving cwd and font sizes; then
647 skip starting the GUI up. */
648 t_atom zz[19];
649 int i;
650#ifdef MSW
651 if (GetCurrentDirectory(MAXPDSTRING, cmdbuf) == 0)
652 strcpy(cmdbuf, ".");
653#endif
654#ifdef UNIX
655 if (!getcwd(cmdbuf, MAXPDSTRING))
656 strcpy(cmdbuf, ".");
657
658#endif
659 SETSYMBOL(zz, gensym(cmdbuf));
660 for (i = 1; i < 22; i++)
661 SETFLOAT(zz + i, defaultfontshit[i-1]);
662 SETFLOAT(zz+22,0);
663 glob_initfromgui(0, 0, 23, zz);
664 }
665 else
666 {
667#ifdef MSW
668 char scriptbuf[MAXPDSTRING+30], wishbuf[MAXPDSTRING+30], portbuf[80];
669 int spawnret;
670
671#endif
672#ifdef MSW
673 char intarg;
674#else
675 int intarg;
676#endif
677
678 /* create a socket */
679 xsock = socket(AF_INET, SOCK_STREAM, 0);
680 if (xsock < 0) sys_sockerror("socket");
681#if 0
682 intarg = 0;
683 if (setsockopt(xsock, SOL_SOCKET, SO_SNDBUF,
684 &intarg, sizeof(intarg)) < 0)
685 post("setsockopt (SO_RCVBUF) failed\n");
686 intarg = 0;
687 if (setsockopt(xsock, SOL_SOCKET, SO_RCVBUF,
688 &intarg, sizeof(intarg)) < 0)
689 post("setsockopt (SO_RCVBUF) failed\n");
690#endif
691 intarg = 1;
692 if (setsockopt(xsock, IPPROTO_TCP, TCP_NODELAY,
693 &intarg, sizeof(intarg)) < 0)
694#ifndef MSW
695 post("setsockopt (TCP_NODELAY) failed\n")
696#endif
697 ;
698
699
700 server.sin_family = AF_INET;
701 server.sin_addr.s_addr = INADDR_ANY;
702
703 /* assign server port number */
704 server.sin_port = htons((unsigned short)portno);
705
706 /* name the socket */
707 while (bind(xsock, (struct sockaddr *)&server, sizeof(server)) < 0)
708 {
709#ifdef MSW
710 int err = WSAGetLastError();
711#endif
712#ifdef UNIX
713 int err = errno;
714#endif
715 if ((ntry++ > 20) || (err != EADDRINUSE))
716 {
717 perror("bind");
718 fprintf(stderr,
719 "Pd needs your machine to be configured with\n");
720 fprintf(stderr,
721 "'networking' turned on (see Pd's html doc for details.)\n");
722 exit(1);
723 }
724 portno++;
725 server.sin_port = htons((unsigned short)(portno));
726 }
727
728 if (sys_verbose) fprintf(stderr, "port %d\n", portno);
729
730 sys_socketreceiver = socketreceiver_new(0, 0, 0, 0);
731
732#ifdef UNIX
733 childpid = fork();
734 if (childpid < 0)
735 {
736 if (errno) perror("sys_startgui");
737 else fprintf(stderr, "sys_startgui failed\n");
738 return (1);
739 }
740 else if (!childpid) /* we're the child */
741 {
742 seteuid(getuid()); /* lose setuid priveliges */
743#ifndef MACOSX
744 /* the wish process in Unix will make a wish shell and
745 read/write standard in and out unless we close the
746 file descriptors. Somehow this doesn't make the MAC OSX
747 version of Wish happy...*/
748 if (pipe(stdinpipe) < 0)
749 sys_sockerror("pipe");
750 else
751 {
752 if (stdinpipe[0] != 0)
753 {
754 close (0);
755 dup2(stdinpipe[0], 0);
756 close(stdinpipe[0]);
757 }
758 }
759#endif
760 if (!sys_guicmd)
761 {
762#ifdef MACOSX
763 char *homedir = getenv("HOME"), filename[250];
764 struct stat statbuf;
765 if (!homedir || strlen(homedir) > 150)
766 goto nohomedir;
767 sprintf(filename,
768 "%s/Applications/Utilities/Wish shell.app/Contents/MacOS/Wish Shell",
769 homedir);
770 if (stat(filename, &statbuf) >= 0)
771 goto foundit;
772 sprintf(filename,
773 "%s/Applications/Wish shell.app/Contents/MacOS/Wish Shell",
774 homedir);
775 if (stat(filename, &statbuf) >= 0)
776 goto foundit;
777 nohomedir:
778 strcpy(filename,
779 "/Applications/Utilities/Wish Shell.app/Contents/MacOS/Wish Shell");
780 if (stat(filename, &statbuf) >= 0)
781 goto foundit;
782 strcpy(filename,
783 "/Applications/Wish Shell.app/Contents/MacOS/Wish Shell");
784 foundit:
785 sprintf(cmdbuf, "\"%s\" %s/pd.tk %d\n", filename, guidir, portno);
786#else
787 sprintf(cmdbuf,
788"TCL_LIBRARY=\"%s/tcl/library\" TK_LIBRARY=\"%s/tk/library\" \
789 \"%s/pd-gui\" %d\n",
790 sys_libdir->s_name, sys_libdir->s_name, guidir, portno);
791#endif
792 sys_guicmd = cmdbuf;
793 }
794 if (sys_verbose) fprintf(stderr, "%s", sys_guicmd);
795 execl("/bin/sh", "sh", "-c", sys_guicmd, 0);
796 perror("pd: exec");
797 _exit(1);
798 }
799#endif /* UNIX */
800
801#ifdef MSW
802 /* in MSW land "guipath" is unused; we just do everything from
803 the libdir. */
804 /* fprintf(stderr, "%s\n", sys_libdir->s_name); */
805
806 strcpy(scriptbuf, "\"");
807 strcat(scriptbuf, sys_libdir->s_name);
808 strcat(scriptbuf, "/" PDBINDIR "pd.tk\"");
809 sys_bashfilename(scriptbuf, scriptbuf);
810
811 sprintf(portbuf, "%d", portno);
812
813 strcpy(wishbuf, sys_libdir->s_name);
814 strcat(wishbuf, "/" PDBINDIR WISHAPP);
815 sys_bashfilename(wishbuf, wishbuf);
816
817 spawnret = _spawnl(P_NOWAIT, wishbuf, WISHAPP, scriptbuf, portbuf, 0);
818 if (spawnret < 0)
819 {
820 perror("spawnl");
821 fprintf(stderr, "%s: couldn't load TCL\n", wishbuf);
822 exit(1);
823 }
824
825#endif /* MSW */
826 }
827
828#ifdef __linux__
829 /* now that we've spun off the child process we can promote
830 our process's priority, if we happen to be root. */
831 if (sys_hipriority)
832 {
833 if (!getuid() || !geteuid())
834 {
835 /* To prevent lockup, we fork off a watchdog process with
836 higher real-time priority than ours. The GUI has to send
837 a stream of ping messages to the watchdog THROUGH the Pd
838 process which has to pick them up from the GUI and forward
839 them. If any of these things aren't happening the watchdog
840 starts sending "stop" and "cont" signals to the Pd process
841 to make it timeshare with the rest of the system. (Version
842 0.33P2 : if there's no GUI, the watchdog pinging is done
843 from the scheduler idle routine in this process instead.) */
844
845 int pipe9[2], watchpid;
846 if (pipe(pipe9) < 0)
847 {
848 seteuid(getuid()); /* lose setuid priveliges */
849 sys_sockerror("pipe");
850 return (1);
851 }
852 watchpid = fork();
853 if (watchpid < 0)
854 {
855 seteuid(getuid()); /* lose setuid priveliges */
856 if (errno)
857 perror("sys_startgui");
858 else fprintf(stderr, "sys_startgui failed\n");
859 return (1);
860 }
861 else if (!watchpid) /* we're the child */
862 {
863 sys_set_priority(1);
864 seteuid(getuid()); /* lose setuid priveliges */
865 if (pipe9[1] != 0)
866 {
867 dup2(pipe9[0], 0);
868 close(pipe9[0]);
869 }
870 close(pipe9[1]);
871
872 sprintf(cmdbuf, "%s/pd-watchdog\n", guidir);
873 if (sys_verbose) fprintf(stderr, "%s", cmdbuf);
874 execl("/bin/sh", "sh", "-c", cmdbuf, 0);
875 perror("pd: exec");
876 _exit(1);
877 }
878 else /* we're the parent */
879 {
880 sys_set_priority(0);
881 seteuid(getuid()); /* lose setuid priveliges */
882 close(pipe9[0]);
883 sys_watchfd = pipe9[1];
884 /* We also have to start the ping loop in the GUI;
885 this is done later when the socket is open. */
886 }
887 }
888 else
889 {
890 post("realtime setting failed because not root\n");
891 sys_hipriority = 0;
892 }
893 }
894
895 seteuid(getuid()); /* lose setuid priveliges */
896#endif /* __linux__ */
897
898#ifdef MSW
899 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS))
900 fprintf(stderr, "pd: couldn't set high priority class\n");
901#endif
902#ifdef MACOSX
903 if (sys_hipriority)
904 {
905 struct sched_param param;
906 int policy = SCHED_RR;
907 int err;
908 param.sched_priority = 80; // adjust 0 : 100
909
910 err = pthread_setschedparam(pthread_self(), policy, &param);
911 if (err)
912 post("warning: high priority scheduling failed\n");
913 }
914#endif /* MACOSX */
915
916 if (!sys_nogui)
917 {
918 char buf[256];
919 if (sys_verbose)
920 fprintf(stderr, "Waiting for connection request... \n");
921 if (listen(xsock, 5) < 0) sys_sockerror("listen");
922
923 sys_guisock = accept(xsock, (struct sockaddr *) &server, &len);
924#ifdef OOPS
925 close(xsock);
926#endif
927 if (sys_guisock < 0) sys_sockerror("accept");
928 sys_addpollfn(sys_guisock, (t_fdpollfn)socketreceiver_read,
929 sys_socketreceiver);
930
931 if (sys_verbose)
932 fprintf(stderr, "... connected\n");
933
934 /* here is where we start the pinging. */
935#ifdef __linux__
936 if (sys_hipriority)
937 sys_gui("pdtk_watchdog\n");
938#endif
939 sys_get_audio_apis(buf);
940 sys_vgui("pdtk_pd_startup {%s} %s\n", pd_version, buf);
941 }
942 if (sys_stdin) {
943 set_keypress();
944 _ss = gensym("stdin");
945 sys_addpollfn(1, (t_fdpollfn) stdin_read,NULL);
946 }
947 return (0);
948
949}
950
951
952static int sys_poll_togui(void)
953{
954 /* LATER use this to flush output buffer to gui */
955 return (0);
956}
957
958int sys_pollgui(void)
959{
960 return (sys_domicrosleep(0, 1) || sys_poll_togui());
961}
962
963
964/* T.Grill - import clean quit function */
965extern void sys_exit(void);
966
967/* This is called when something bad has happened, like a segfault.
968Call glob_quit() below to exit cleanly.
969LATER try to save dirty documents even in the bad case. */
970void sys_bail(int n)
971{
972 static int reentered = 0;
973 reset_keypress();
974 if (!reentered)
975 {
976 reentered = 1;
977#ifndef __linux /* sys_close_audio() hangs if you're in a signal? */
978 fprintf(stderr, "closing audio...\n");
979 sys_close_audio();
980 fprintf(stderr, "closing MIDI...\n");
981 sys_close_midi();
982 fprintf(stderr, "... done.\n");
983#endif
984 exit(1);
985 }
986 else _exit(n);
987}
988
989void glob_quit(void *dummy)
990{
991 sys_vgui("exit\n");
992 if (!sys_nogui)
993 {
994 close(sys_guisock);
995 sys_rmpollfn(sys_guisock);
996 }
997 reset_keypress();
998 sys_bail(0);
999}
1000
diff --git a/apps/plugins/pdbox/PDa/src/s_main.c b/apps/plugins/pdbox/PDa/src/s_main.c
deleted file mode 100644
index b77f804e9f..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_main.c
+++ /dev/null
@@ -1,839 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* IOhannes :
6 * hacked the code to add advanced multidevice-support
7 * 1311:forum::für::umläute:2001
8 */
9
10char pd_version[] = "Pd version 0.37.4\n";
11char pd_compiletime[] = __TIME__;
12char pd_compiledate[] = __DATE__;
13
14#include "m_pd.h"
15#include "m_imp.h"
16#include "s_stuff.h"
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <limits.h>
20#include <string.h>
21#include <stdio.h>
22#include <fcntl.h>
23#include <stdlib.h>
24
25#ifdef UNIX
26#include <unistd.h>
27#endif
28#ifdef MSW
29#include <io.h>
30#include <windows.h>
31#include <winbase.h>
32#endif
33
34void pd_init(void);
35int sys_argparse(int argc, char **argv);
36void sys_findprogdir(char *progname);
37int sys_startgui(const char *guipath);
38int sys_rcfile(void);
39int m_scheduler(void);
40void sys_addhelppath(char *p);
41void alsa_adddev(char *name);
42
43int sys_debuglevel;
44int sys_verbose;
45int sys_noloadbang;
46int sys_nogui;
47int sys_stdin = 0;
48char *sys_guicmd;
49t_symbol *sys_libdir;
50static t_symbol *sys_guidir;
51static t_namelist *sys_externlist;
52static t_namelist *sys_openlist;
53static t_namelist *sys_messagelist;
54static int sys_version;
55int sys_oldtclversion; /* hack to warn g_rtext.c about old text sel */
56
57int sys_nmidiout = 1;
58#ifdef MSW
59int sys_nmidiin = 0;
60#else
61int sys_nmidiin = 1;
62#endif
63int sys_midiindevlist[MAXMIDIINDEV] = {1};
64int sys_midioutdevlist[MAXMIDIOUTDEV] = {1};
65
66static int sys_main_srate = DEFAULTSRATE;
67static int sys_main_advance = DEFAULTADVANCE;
68
69/* IOhannes { */
70
71 /* here the "-1" counts signify that the corresponding vector hasn't been
72 specified in command line arguments; sys_open_audio will detect this
73 and fill things in. */
74int sys_nsoundin = -1;
75int sys_nsoundout = -1;
76int sys_soundindevlist[MAXAUDIOINDEV];
77int sys_soundoutdevlist[MAXAUDIOOUTDEV];
78
79int sys_nchin = -1;
80int sys_nchout = -1;
81int sys_chinlist[MAXAUDIOINDEV];
82int sys_choutlist[MAXAUDIOOUTDEV];
83/* } IOhannes */
84
85
86typedef struct _fontinfo
87{
88 int fi_fontsize;
89 int fi_maxwidth;
90 int fi_maxheight;
91 int fi_hostfontsize;
92 int fi_width;
93 int fi_height;
94} t_fontinfo;
95
96 /* these give the nominal point size and maximum height of the characters
97 in the six fonts. */
98
99static t_fontinfo sys_fontlist[] = {
100 {8, 5, 9, 0, 0, 0}, {10, 7, 13, 0, 0, 0}, {12, 9, 16, 0, 0, 0},
101 {16, 10, 20, 0, 0, 0}, {24, 15, 25, 0, 0, 0}, {36, 25, 45, 0, 0, 0}};
102#define NFONT (sizeof(sys_fontlist)/sizeof(*sys_fontlist))
103
104/* here are the actual font size structs on msp's systems:
105MSW:
106font 8 5 9 8 5 11
107font 10 7 13 10 6 13
108font 12 9 16 14 8 16
109font 16 10 20 16 10 18
110font 24 15 25 16 10 18
111font 36 25 42 36 22 41
112
113linux:
114font 8 5 9 8 5 9
115font 10 7 13 12 7 13
116font 12 9 16 14 9 15
117font 16 10 20 16 10 19
118font 24 15 25 24 15 24
119font 36 25 42 36 22 41
120*/
121
122static t_fontinfo *sys_findfont(int fontsize)
123{
124 unsigned int i;
125 t_fontinfo *fi;
126 for (i = 0, fi = sys_fontlist; i < (NFONT-1); i++, fi++)
127 if (fontsize < fi[1].fi_fontsize) return (fi);
128 return (sys_fontlist + (NFONT-1));
129}
130
131int sys_nearestfontsize(int fontsize)
132{
133 return (sys_findfont(fontsize)->fi_fontsize);
134}
135
136int sys_hostfontsize(int fontsize)
137{
138 return (sys_findfont(fontsize)->fi_hostfontsize);
139}
140
141int sys_fontwidth(int fontsize)
142{
143 return (sys_findfont(fontsize)->fi_width);
144}
145
146int sys_fontheight(int fontsize)
147{
148 return (sys_findfont(fontsize)->fi_height);
149}
150
151int sys_defaultfont;
152#ifdef MSW
153#define DEFAULTFONT 12
154#else
155#define DEFAULTFONT 10
156#endif
157
158static void openit(const char *dirname, const char *filename)
159{
160 char dirbuf[MAXPDSTRING], *nameptr;
161 int fd = open_via_path(dirname, filename, "", dirbuf, &nameptr,
162 MAXPDSTRING, 0);
163 if (fd)
164 {
165 close (fd);
166 glob_evalfile(0, gensym(nameptr), gensym(dirbuf));
167 }
168 else
169 error("%s: can't open", filename);
170}
171
172#define NHOSTFONT 7
173
174/* this is called from the gui process. The first argument is the cwd, and
175succeeding args give the widths and heights of known fonts. We wait until
176these are known to open files and send messages specified on the command line.
177We ask the GUI to specify the "cwd" in case we don't have a local OS to get it
178from; for instance we could be some kind of RT embedded system. However, to
179really make this make sense we would have to implement
180open(), read(), etc, calls to be served somehow from the GUI too. */
181
182void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv)
183{
184 char *cwd = atom_getsymbolarg(0, argc, argv)->s_name;
185 t_namelist *nl;
186 unsigned int i, j;
187 if (argc != 2 + 3 * NHOSTFONT) bug("glob_initfromgui");
188 for (i = 0; i < NFONT; i++)
189 {
190 int wantheight = sys_fontlist[i].fi_maxheight;
191 for (j = 0; j < NHOSTFONT-1; j++)
192 {
193 if (atom_getintarg(3 * (j + 1) + 3, argc, argv) > wantheight)
194 break;
195 }
196 /* j is now the "real" font index for the desired font index i. */
197 sys_fontlist[i].fi_hostfontsize = atom_getintarg(3 * j + 1, argc, argv);
198 sys_fontlist[i].fi_width = atom_getintarg(3 * j + 2, argc, argv);
199 sys_fontlist[i].fi_height = atom_getintarg(3 * j + 3, argc, argv);
200 }
201#if 0
202 for (i = 0; i < 6; i++)
203 fprintf(stderr, "font %d %d %d %d %d\n",
204 sys_fontlist[i].fi_fontsize,
205 sys_fontlist[i].fi_maxheight,
206 sys_fontlist[i].fi_hostfontsize,
207 sys_fontlist[i].fi_width,
208 sys_fontlist[i].fi_height);
209#endif
210 /* load dynamic libraries specified with "-lib" args */
211 for (nl = sys_externlist; nl; nl = nl->nl_next)
212 if (!sys_load_lib(cwd, nl->nl_string))
213 post("%s: can't load library", nl->nl_string);
214 namelist_free(sys_externlist);
215 sys_externlist = 0;
216 /* open patches specifies with "-open" args */
217 for (nl = sys_openlist; nl; nl = nl->nl_next)
218 openit(cwd, nl->nl_string);
219 namelist_free(sys_openlist);
220 sys_openlist = 0;
221 /* send messages specified with "-send" args */
222 for (nl = sys_messagelist; nl; nl = nl->nl_next)
223 {
224 t_binbuf *b = binbuf_new();
225 binbuf_text(b, nl->nl_string, strlen(nl->nl_string));
226 binbuf_eval(b, 0, 0, 0);
227 binbuf_free(b);
228 }
229 namelist_free(sys_messagelist);
230 sys_messagelist = 0;
231 sys_oldtclversion = atom_getfloatarg(1 + 3 * NHOSTFONT, argc, argv);
232}
233
234static void sys_afterargparse(void);
235
236/* this is called from main() in s_entry.c */
237int sys_main(int argc, char **argv)
238{
239#ifdef PD_DEBUG
240 fprintf(stderr, "Pd: COMPILED FOR DEBUGGING\n");
241#endif
242 pd_init();
243 sys_findprogdir(argv[0]); /* set sys_progname, guipath */
244#ifdef UNIX
245 sys_rcfile(); /* parse the startup file */
246#endif
247 if (sys_argparse(argc, argv)) /* parse cmd line */
248 return (1);
249 sys_afterargparse(); /* post-argparse settings */
250 if (sys_verbose || sys_version) fprintf(stderr, "%scompiled %s %s\n",
251 pd_version, pd_compiletime, pd_compiledate);
252 if (sys_version) /* if we were just asked our version, exit here. */
253 return (0);
254 if (sys_startgui(sys_guidir->s_name)) /* start the gui */
255 return(1);
256 /* open audio and MIDI */
257 sys_open_midi(sys_nmidiin, sys_midiindevlist,
258 sys_nmidiout, sys_midioutdevlist);
259 sys_open_audio(sys_nsoundin, sys_soundindevlist, sys_nchin, sys_chinlist,
260 sys_nsoundout, sys_soundoutdevlist, sys_nchout, sys_choutlist,
261 sys_main_srate, sys_main_advance, 1);
262 /* run scheduler until it quits */
263
264 return (m_scheduler_pda());
265 return (m_scheduler());
266}
267
268static char *(usagemessage[]) = {
269"usage: pd [-flags] [file]...\n",
270"\naudio configuration flags:\n",
271"-r <n> -- specify sample rate\n",
272"-audioindev ... -- audio in devices; e.g., \"1,3\" for first and third\n",
273"-audiooutdev ... -- audio out devices (same)\n",
274"-audiodev ... -- specify input and output together\n",
275"-inchannels ... -- audio input channels (by device, like \"2\" or \"16,8\")\n",
276"-outchannels ... -- number of audio out channels (same)\n",
277"-channels ... -- specify both input and output channels\n",
278"-audiobuf <n> -- specify size of audio buffer in msec\n",
279"-blocksize <n> -- specify audio I/O block size in sample frames\n",
280"-sleepgrain <n> -- specify number of milliseconds to sleep when idle\n",
281"-nodac -- suppress audio output\n",
282"-noadc -- suppress audio input\n",
283"-noaudio -- suppress audio input and output (-nosound is synonym) \n",
284"-listdev -- list audio and MIDI devices\n",
285
286#ifdef USEAPI_OSS
287"-oss -- use OSS audio API\n",
288"-32bit ----- allow 32 bit OSS audio (for RME Hammerfall)\n",
289#endif
290
291#ifdef USEAPI_ALSA
292"-alsa -- use ALSA audio API\n",
293"-alsaadd <name> -- add an ALSA device name to list\n",
294"-alsadev <n> ----- obsolete: use -audiodev\n",
295#endif
296
297#ifdef USEAPI_JACK
298"-jack -- use JACK audio API\n",
299#endif
300
301#ifdef USEAPI_PORTAUDIO
302#ifdef MSW
303"-asio -- use ASIO audio driver (via Portaudio)\n",
304"-pa -- synonym for -asio\n",
305#else
306"-pa -- use Portaudio API\n",
307#endif
308#endif
309
310#ifdef USEAPI_MMIO
311"-mmio -- use MMIO audio API (default for Windows)\n",
312#endif
313" (default audio API for this platform: ", API_DEFSTRING, ")\n\n",
314
315"\nMIDI configuration flags:\n",
316"-midiindev ... -- midi in device list; e.g., \"1,3\" for first and third\n",
317"-midioutdev ... -- midi out device list, same format\n",
318"-mididev ... -- specify -midioutdev and -midiindev together\n",
319"-nomidiin -- suppress MIDI input\n",
320"-nomidiout -- suppress MIDI output\n",
321"-nomidi -- suppress MIDI input and output\n",
322
323"\nother flags:\n",
324"-path <path> -- add to file search path\n",
325"-helppath <path> -- add to help file search path\n",
326"-open <file> -- open file(s) on startup\n",
327"-lib <file> -- load object library(s)\n",
328"-font <n> -- specify default font size in points\n",
329"-verbose -- extra printout on startup and when searching for files\n",
330"-version -- don't run Pd; just print out which version it is \n",
331"-d <n> -- specify debug level\n",
332"-noloadbang -- suppress all loadbangs\n",
333"-nogui -- suppress starting the GUI\n",
334"-stdin -- scan stdin for keypresses\n",
335"-guicmd \"cmd...\" -- substitute another GUI program (e.g., rsh)\n",
336"-send \"msg...\" -- send a message at startup (after patches are loaded)\n",
337#ifdef UNIX
338"-rt or -realtime -- use real-time priority\n",
339"-nrt -- don't use real-time priority\n",
340#endif
341};
342
343static void sys_parsedevlist(int *np, int *vecp, int max, char *str)
344{
345 int n = 0;
346 while (n < max)
347 {
348 if (!*str) break;
349 else
350 {
351 char *endp;
352 vecp[n] = strtol(str, &endp, 10);
353 if (endp == str)
354 break;
355 n++;
356 if (!endp)
357 break;
358 str = endp + 1;
359 }
360 }
361 *np = n;
362}
363
364static int sys_getmultidevchannels(int n, int *devlist)
365{
366 int sum = 0;
367 if (n<0)return(-1);
368 if (n==0)return 0;
369 while(n--)sum+=*devlist++;
370 return sum;
371}
372
373
374 /* this routine tries to figure out where to find the auxilliary files
375 Pd will need to run. This is either done by looking at the command line
376 invokation for Pd, or if that fails, by consulting the variable
377 INSTALL_PREFIX. In MSW, we don't try to use INSTALL_PREFIX. */
378void sys_findprogdir(char *progname)
379{
380 char sbuf[MAXPDSTRING], sbuf2[MAXPDSTRING], *sp;
381 char *lastslash;
382#ifdef UNIX
383 struct stat statbuf;
384#endif
385
386 /* find out by what string Pd was invoked; put answer in "sbuf". */
387#ifdef MSW
388 GetModuleFileName(NULL, sbuf2, sizeof(sbuf2));
389 sbuf2[MAXPDSTRING-1] = 0;
390 sys_unbashfilename(sbuf2, sbuf);
391#endif /* MSW */
392#ifdef UNIX
393 strncpy(sbuf, progname, MAXPDSTRING);
394 sbuf[MAXPDSTRING-1] = 0;
395#endif
396 lastslash = strrchr(sbuf, '/');
397 if (lastslash)
398 {
399 /* bash last slash to zero so that sbuf is directory pd was in,
400 e.g., ~/pd/bin */
401 *lastslash = 0;
402 /* go back to the parent from there, e.g., ~/pd */
403 lastslash = strrchr(sbuf, '/');
404 if (lastslash)
405 {
406 strncpy(sbuf2, sbuf, lastslash-sbuf);
407 sbuf2[lastslash-sbuf] = 0;
408 }
409 else strcpy(sbuf2, "..");
410 }
411 else
412 {
413 /* no slashes found. Try INSTALL_PREFIX. */
414#ifdef INSTALL_PREFIX
415 strcpy(sbuf2, INSTALL_PREFIX);
416#else
417 strcpy(sbuf2, ".");
418#endif
419 }
420 /* now we believe sbuf2 holds the parent directory of the directory
421 pd was found in. We now want to infer the "lib" directory and the
422 "gui" directory. In "simple" UNIX installations, the layout is
423 .../bin/pd
424 .../bin/pd-gui
425 .../doc
426 and in "complicated" UNIX installations, it's:
427 .../bin/pd
428 .../lib/pd/bin/pd-gui
429 .../lib/pd/doc
430 To decide which, we stat .../lib/pd; if that exists, we assume it's
431 the complicated layout. In MSW, it's the "simple" layout, but
432 the gui program is straight wish80:
433 .../bin/pd
434 .../bin/wish80.exe
435 .../doc
436 */
437#ifdef UNIX
438 strncpy(sbuf, sbuf2, MAXPDSTRING-30);
439 sbuf[MAXPDSTRING-30] = 0;
440 strcat(sbuf, "/lib/pd");
441 if (stat(sbuf, &statbuf) >= 0)
442 {
443 /* complicated layout: lib dir is the one we just stat-ed above */
444 sys_libdir = gensym(sbuf);
445 /* gui lives in .../lib/pd/bin */
446 strncpy(sbuf, sbuf2, MAXPDSTRING-30);
447 sbuf[MAXPDSTRING-30] = 0;
448 strcat(sbuf, "/lib/pd/bin");
449 sys_guidir = gensym(sbuf);
450 }
451 else
452 {
453 /* simple layout: lib dir is the parent */
454 sys_libdir = gensym(sbuf2);
455 /* gui lives in .../bin */
456 strncpy(sbuf, sbuf2, MAXPDSTRING-30);
457 sbuf[MAXPDSTRING-30] = 0;
458 strcat(sbuf, "/bin");
459 sys_guidir = gensym(sbuf);
460 }
461#endif
462#ifdef MSW
463 sys_libdir = gensym(sbuf2);
464 sys_guidir = &s_; /* in MSW the guipath just depends on the libdir */
465#endif
466}
467
468#ifdef MSW
469static int sys_mmio = 1;
470#else
471static int sys_mmio = 0;
472#endif
473
474int sys_argparse(int argc, char **argv)
475{
476 char sbuf[MAXPDSTRING];
477 int i;
478 argc--; argv++;
479 while ((argc > 0) && **argv == '-')
480 {
481 if (!strcmp(*argv, "-r") && argc > 1 &&
482 sscanf(argv[1], "%d", &sys_main_srate) >= 1)
483 {
484 argc -= 2;
485 argv += 2;
486 }
487 else if (!strcmp(*argv, "-inchannels"))
488 { /* IOhannes */
489 sys_parsedevlist(&sys_nchin,
490 sys_chinlist, MAXAUDIOINDEV, argv[1]);
491
492 if (!sys_nchin)
493 goto usage;
494
495 argc -= 2; argv += 2;
496 }
497 else if (!strcmp(*argv, "-outchannels"))
498 { /* IOhannes */
499 sys_parsedevlist(&sys_nchout, sys_choutlist,
500 MAXAUDIOOUTDEV, argv[1]);
501
502 if (!sys_nchout)
503 goto usage;
504
505 argc -= 2; argv += 2;
506 }
507 else if (!strcmp(*argv, "-channels"))
508 {
509 sys_parsedevlist(&sys_nchin, sys_chinlist,MAXAUDIOINDEV,
510 argv[1]);
511 sys_parsedevlist(&sys_nchout, sys_choutlist,MAXAUDIOOUTDEV,
512 argv[1]);
513
514 if (!sys_nchout)
515 goto usage;
516
517 argc -= 2; argv += 2;
518 }
519 else if (!strcmp(*argv, "-soundbuf") || !strcmp(*argv, "-audiobuf"))
520 {
521 sys_main_advance = atoi(argv[1]);
522 argc -= 2; argv += 2;
523 }
524 else if (!strcmp(*argv, "-blocksize"))
525 {
526 sys_setblocksize(atoi(argv[1]));
527 argc -= 2; argv += 2;
528 }
529 else if (!strcmp(*argv, "-sleepgrain"))
530 {
531 sys_sleepgrain = 1000 * atoi(argv[1]);
532 argc -= 2; argv += 2;
533 }
534 else if (!strcmp(*argv, "-nodac"))
535 { /* IOhannes */
536 sys_nsoundout=0;
537 sys_nchout = 0;
538 argc--; argv++;
539 }
540 else if (!strcmp(*argv, "-noadc"))
541 { /* IOhannes */
542 sys_nsoundin=0;
543 sys_nchin = 0;
544 argc--; argv++;
545 }
546 else if (!strcmp(*argv, "-nosound") || !strcmp(*argv, "-noaudio"))
547 { /* IOhannes */
548 sys_nsoundin=sys_nsoundout = 0;
549 sys_nchin = sys_nchout = 0;
550 argc--; argv++;
551 }
552#ifdef USEAPI_OSS
553 else if (!strcmp(*argv, "-oss"))
554 {
555 sys_set_audio_api(API_OSS);
556 argc--; argv++;
557 }
558 else if (!strcmp(*argv, "-32bit"))
559 {
560 sys_set_audio_api(API_OSS);
561 oss_set32bit();
562 argc--; argv++;
563 }
564#endif
565#ifdef USEAPI_ALSA
566 else if (!strcmp(*argv, "-alsa"))
567 {
568 sys_set_audio_api(API_ALSA);
569 argc--; argv++;
570 }
571 else if (!strcmp(*argv, "-alsaadd"))
572 {
573 if (argc > 1)
574 alsa_adddev(argv[1]);
575 else goto usage;
576 argc -= 2; argv +=2;
577 }
578 /* obsolete flag for setting ALSA device number or name */
579 else if (!strcmp(*argv, "-alsadev"))
580 {
581 int devno = 0;
582 if (argv[1][0] >= '1' && argv[1][0] <= '9')
583 devno = 1 + 2 * (atoi(argv[1]) - 1);
584 else if (!strncmp(argv[1], "hw:", 3))
585 devno = 1 + 2 * atoi(argv[1]+3);
586 else if (!strncmp(argv[1], "plughw:", 7))
587 devno = 2 + 2 * atoi(argv[1]+7);
588 else goto usage;
589 sys_nsoundin = sys_nsoundout = 1;
590 sys_soundindevlist[0] = sys_soundoutdevlist[0] = devno;
591 sys_set_audio_api(API_ALSA);
592 argc -= 2; argv +=2;
593 }
594#endif
595#ifdef USEAPI_JACK
596 else if (!strcmp(*argv, "-jack"))
597 {
598 sys_set_audio_api(API_JACK);
599 argc--; argv++;
600 }
601#endif
602#ifdef USEAPI_PORTAUDIO
603 else if (!strcmp(*argv, "-pa") || !strcmp(*argv, "-portaudio")
604#ifdef MSW
605 || !strcmp(*argv, "-asio")
606#endif
607 )
608 {
609 sys_set_audio_api(API_PORTAUDIO);
610 sys_mmio = 0;
611 argc--; argv++;
612 }
613#endif
614#ifdef USEAPI_MMIO
615 else if (!strcmp(*argv, "-mmio"))
616 {
617 sys_set_audio_api(API_MMIO);
618 sys_mmio = 1;
619 argc--; argv++;
620 }
621#endif
622 else if (!strcmp(*argv, "-nomidiin"))
623 {
624 sys_nmidiin = 0;
625 argc--; argv++;
626 }
627 else if (!strcmp(*argv, "-nomidiout"))
628 {
629 sys_nmidiout = 0;
630 argc--; argv++;
631 }
632 else if (!strcmp(*argv, "-nomidi"))
633 {
634 sys_nmidiin = sys_nmidiout = 0;
635 argc--; argv++;
636 }
637 else if (!strcmp(*argv, "-midiindev"))
638 {
639 sys_parsedevlist(&sys_nmidiin, sys_midiindevlist, MAXMIDIINDEV,
640 argv[1]);
641 if (!sys_nmidiin)
642 goto usage;
643 argc -= 2; argv += 2;
644 }
645 else if (!strcmp(*argv, "-midioutdev"))
646 {
647 sys_parsedevlist(&sys_nmidiout, sys_midioutdevlist, MAXMIDIOUTDEV,
648 argv[1]);
649 if (!sys_nmidiout)
650 goto usage;
651 argc -= 2; argv += 2;
652 }
653 else if (!strcmp(*argv, "-mididev"))
654 {
655 sys_parsedevlist(&sys_nmidiin, sys_midiindevlist, MAXMIDIINDEV,
656 argv[1]);
657 sys_parsedevlist(&sys_nmidiout, sys_midioutdevlist, MAXMIDIOUTDEV,
658 argv[1]);
659 if (!sys_nmidiout)
660 goto usage;
661 argc -= 2; argv += 2;
662 }
663 else if (!strcmp(*argv, "-path"))
664 {
665 sys_addpath(argv[1]);
666 argc -= 2; argv += 2;
667 }
668 else if (!strcmp(*argv, "-helppath"))
669 {
670 sys_addhelppath(argv[1]);
671 argc -= 2; argv += 2;
672 }
673 else if (!strcmp(*argv, "-open") && argc > 1)
674 {
675 sys_openlist = namelist_append(sys_openlist, argv[1]);
676 argc -= 2; argv += 2;
677 }
678 else if (!strcmp(*argv, "-lib") && argc > 1)
679 {
680 sys_externlist = namelist_append(sys_externlist, argv[1]);
681 argc -= 2; argv += 2;
682 }
683 else if (!strcmp(*argv, "-font") && argc > 1)
684 {
685 sys_defaultfont = sys_nearestfontsize(atoi(argv[1]));
686 argc -= 2;
687 argv += 2;
688 }
689 else if (!strcmp(*argv, "-verbose"))
690 {
691 sys_verbose = 1;
692 argc--; argv++;
693 }
694 else if (!strcmp(*argv, "-version"))
695 {
696 sys_version = 1;
697 argc--; argv++;
698 }
699 else if (!strcmp(*argv, "-d") && argc > 1 &&
700 sscanf(argv[1], "%d", &sys_debuglevel) >= 1)
701 {
702 argc -= 2;
703 argv += 2;
704 }
705 else if (!strcmp(*argv, "-noloadbang"))
706 {
707 sys_noloadbang = 1;
708 argc--; argv++;
709 }
710 else if (!strcmp(*argv, "-nogui"))
711 {
712 sys_nogui = 1;
713 argc--; argv++;
714 }
715 else if (!strcmp(*argv, "-stdin"))
716 {
717 sys_stdin = 1;
718 argc--; argv++;
719 }
720 else if (!strcmp(*argv, "-guicmd") && argc > 1)
721 {
722 sys_guicmd = argv[1];
723 argc -= 2; argv += 2;
724 }
725 else if (!strcmp(*argv, "-send") && argc > 1)
726 {
727 sys_messagelist = namelist_append(sys_messagelist, argv[1]);
728 argc -= 2; argv += 2;
729 }
730 else if (!strcmp(*argv, "-listdev"))
731 {
732 sys_listdevs();
733 argc--; argv++;
734 }
735#ifdef UNIX
736 else if (!strcmp(*argv, "-rt") || !strcmp(*argv, "-realtime"))
737 {
738 sys_hipriority = 1;
739 argc--; argv++;
740 }
741 else if (!strcmp(*argv, "-nrt"))
742 {
743 sys_hipriority = 0;
744 argc--; argv++;
745 }
746#endif
747 else if (!strcmp(*argv, "-soundindev") ||
748 !strcmp(*argv, "-audioindev"))
749 { /* IOhannes */
750 sys_parsedevlist(&sys_nsoundin, sys_soundindevlist,
751 MAXAUDIOINDEV, argv[1]);
752 if (!sys_nsoundin)
753 goto usage;
754 argc -= 2; argv += 2;
755 }
756 else if (!strcmp(*argv, "-soundoutdev") ||
757 !strcmp(*argv, "-audiooutdev"))
758 { /* IOhannes */
759 sys_parsedevlist(&sys_nsoundout, sys_soundoutdevlist,
760 MAXAUDIOOUTDEV, argv[1]);
761 if (!sys_nsoundout)
762 goto usage;
763 argc -= 2; argv += 2;
764 }
765 else if (!strcmp(*argv, "-sounddev") || !strcmp(*argv, "-audiodev"))
766 {
767 sys_parsedevlist(&sys_nsoundin, sys_soundindevlist,
768 MAXAUDIOINDEV, argv[1]);
769 sys_parsedevlist(&sys_nsoundout, sys_soundoutdevlist,
770 MAXAUDIOOUTDEV, argv[1]);
771 if (!sys_nsoundout)
772 goto usage;
773 argc -= 2; argv += 2;
774 }
775 else
776 {
777 unsigned int i;
778 usage:
779 for (i = 0; i < sizeof(usagemessage)/sizeof(*usagemessage); i++)
780 fprintf(stderr, "%s", usagemessage[i]);
781 return (1);
782 }
783 }
784 if (!sys_defaultfont)
785 sys_defaultfont = DEFAULTFONT;
786 for (; argc > 0; argc--, argv++)
787 sys_openlist = namelist_append(sys_openlist, *argv);
788
789
790 return (0);
791}
792
793int sys_getblksize(void)
794{
795 return (DEFDACBLKSIZE);
796}
797
798 /* stuff to do, once, after calling sys_argparse() -- which may itself
799 be called twice because of the .pdrc hack. */
800static void sys_afterargparse(void)
801{
802 char sbuf[MAXPDSTRING];
803 int i;
804 /* add "extra" library to path */
805 strncpy(sbuf, sys_libdir->s_name, MAXPDSTRING-30);
806 sbuf[MAXPDSTRING-30] = 0;
807 strcat(sbuf, "/extra");
808 sys_addpath(sbuf);
809 strncpy(sbuf, sys_libdir->s_name, MAXPDSTRING-30);
810 sbuf[MAXPDSTRING-30] = 0;
811 strcat(sbuf, "/intern");
812 sys_addpath(sbuf);
813 /* add "doc/5.reference" library to helppath */
814 strncpy(sbuf, sys_libdir->s_name, MAXPDSTRING-30);
815 sbuf[MAXPDSTRING-30] = 0;
816 strcat(sbuf, "/doc/5.reference");
817 sys_addhelppath(sbuf);
818 /* correct to make audio and MIDI device lists zero based. On
819 MMIO, however, "1" really means the second device (the first one
820 is "mapper" which is was not included when the command args were
821 set up, so we leave it that way for compatibility. */
822 if (!sys_mmio)
823 {
824 for (i = 0; i < sys_nsoundin; i++)
825 sys_soundindevlist[i]--;
826 for (i = 0; i < sys_nsoundout; i++)
827 sys_soundoutdevlist[i]--;
828 }
829 for (i = 0; i < sys_nmidiin; i++)
830 sys_midiindevlist[i]--;
831 for (i = 0; i < sys_nmidiout; i++)
832 sys_midioutdevlist[i]--;
833}
834
835static void sys_addreferencepath(void)
836{
837 char sbuf[MAXPDSTRING];
838}
839
diff --git a/apps/plugins/pdbox/PDa/src/s_midi.c b/apps/plugins/pdbox/PDa/src/s_midi.c
deleted file mode 100644
index 72a8792b25..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_midi.c
+++ /dev/null
@@ -1,642 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* Clock functions (which should move, but where?) and MIDI queueing */
6
7#include "m_pd.h"
8#include "s_stuff.h"
9#include "m_imp.h"
10#ifdef UNIX
11#include <unistd.h>
12#include <sys/time.h>
13#ifdef HAVE_BSTRING_H
14#include <bstring.h>
15#endif
16#endif
17#ifdef MSW
18#include <winsock.h>
19#include <sys/types.h>
20#include <sys/timeb.h>
21#include <wtypes.h>
22#endif
23#include <string.h>
24#include <stdio.h>
25#include <signal.h>
26
27typedef struct _midiqelem
28{
29 double q_time;
30 int q_portno;
31 unsigned char q_onebyte;
32 unsigned char q_byte1;
33 unsigned char q_byte2;
34 unsigned char q_byte3;
35} t_midiqelem;
36
37#define MIDIQSIZE 1024
38
39t_midiqelem midi_outqueue[MIDIQSIZE];
40int midi_outhead, midi_outtail;
41t_midiqelem midi_inqueue[MIDIQSIZE];
42int midi_inhead, midi_intail;
43static double sys_midiinittime;
44
45 /* this is our current estimate for at what "system" real time the
46 current logical time's output should occur. */
47static double sys_dactimeminusrealtime;
48 /* same for input, should be schduler advance earlier. */
49static double sys_adctimeminusrealtime;
50
51static double sys_newdactimeminusrealtime = -1e20;
52static double sys_newadctimeminusrealtime = -1e20;
53static double sys_whenupdate;
54
55void sys_initmidiqueue( void)
56{
57 sys_midiinittime = clock_getlogicaltime();
58 sys_dactimeminusrealtime = sys_adctimeminusrealtime = 0;
59}
60
61 /* this is called from the OS dependent code from time to time when we
62 think we know the delay (outbuftime) in seconds, at which the last-output
63 audio sample will go out the door. */
64void sys_setmiditimediff(double inbuftime, double outbuftime)
65{
66 double dactimeminusrealtime =
67 .001 * clock_gettimesince(sys_midiinittime)
68 - outbuftime - sys_getrealtime();
69 double adctimeminusrealtime =
70 .001 * clock_gettimesince(sys_midiinittime)
71 + inbuftime - sys_getrealtime();
72 if (dactimeminusrealtime > sys_newdactimeminusrealtime)
73 sys_newdactimeminusrealtime = dactimeminusrealtime;
74 if (adctimeminusrealtime > sys_newadctimeminusrealtime)
75 sys_newadctimeminusrealtime = adctimeminusrealtime;
76 if (sys_getrealtime() > sys_whenupdate)
77 {
78 sys_dactimeminusrealtime = sys_newdactimeminusrealtime;
79 sys_adctimeminusrealtime = sys_newadctimeminusrealtime;
80 sys_newdactimeminusrealtime = -1e20;
81 sys_newadctimeminusrealtime = -1e20;
82 sys_whenupdate = sys_getrealtime() + 1;
83 }
84}
85
86 /* return the logical time of the DAC sample we believe is currently
87 going out, based on how much "system time" has elapsed since the
88 last time sys_setmiditimediff got called. */
89static double sys_getmidioutrealtime( void)
90{
91 return (sys_getrealtime() + sys_dactimeminusrealtime);
92}
93
94static double sys_getmidiinrealtime( void)
95{
96 return (sys_getrealtime() + sys_adctimeminusrealtime);
97}
98
99static void sys_putnext( void)
100{
101 int portno = midi_outqueue[midi_outtail].q_portno;
102 if (midi_outqueue[midi_outtail].q_onebyte)
103 sys_putmidibyte(portno, midi_outqueue[midi_outtail].q_byte1);
104 else sys_putmidimess(portno, midi_outqueue[midi_outtail].q_byte1,
105 midi_outqueue[midi_outtail].q_byte2,
106 midi_outqueue[midi_outtail].q_byte3);
107 midi_outtail = (midi_outtail + 1 == MIDIQSIZE ? 0 : midi_outtail + 1);
108}
109
110/* #define TEST_DEJITTER */
111
112void sys_pollmidioutqueue( void)
113{
114#ifdef TEST_DEJITTER
115 static int db = 0;
116#endif
117 double midirealtime = sys_getmidioutrealtime();
118#ifdef TEST_DEJITTER
119 if (midi_outhead == midi_outtail)
120 db = 0;
121#endif
122 while (midi_outhead != midi_outtail)
123 {
124#ifdef TEST_DEJITTER
125 if (!db)
126 {
127 post("out: del %f, midiRT %f logicaltime %f, RT %f dacminusRT %f",
128 (midi_outqueue[midi_outtail].q_time - midirealtime),
129 midirealtime, .001 * clock_gettimesince(sys_midiinittime),
130 sys_getrealtime(), sys_dactimeminusrealtime);
131 db = 1;
132 }
133#endif
134 if (midi_outqueue[midi_outtail].q_time <= midirealtime)
135 sys_putnext();
136 else break;
137 }
138}
139
140static void sys_queuemidimess(int portno, int onebyte, int a, int b, int c)
141{
142 t_midiqelem *midiqelem;
143 int newhead = midi_outhead +1;
144 if (newhead == MIDIQSIZE)
145 newhead = 0;
146 /* if FIFO is full flush an element to make room */
147 if (newhead == midi_outtail)
148 sys_putnext();
149 midi_outqueue[midi_outhead].q_portno = portno;
150 midi_outqueue[midi_outhead].q_onebyte = onebyte;
151 midi_outqueue[midi_outhead].q_byte1 = a;
152 midi_outqueue[midi_outhead].q_byte2 = b;
153 midi_outqueue[midi_outhead].q_byte3 = c;
154 midi_outqueue[midi_outhead].q_time =
155 .001 * clock_gettimesince(sys_midiinittime);
156 midi_outhead = newhead;
157 sys_pollmidioutqueue();
158}
159
160#define MIDI_NOTEON 144
161#define MIDI_POLYAFTERTOUCH 160
162#define MIDI_CONTROLCHANGE 176
163#define MIDI_PROGRAMCHANGE 192
164#define MIDI_AFTERTOUCH 208
165#define MIDI_PITCHBEND 224
166
167void outmidi_noteon(int portno, int channel, int pitch, int velo)
168{
169 if (pitch < 0) pitch = 0;
170 else if (pitch > 127) pitch = 127;
171 if (velo < 0) velo = 0;
172 else if (velo > 127) velo = 127;
173 sys_queuemidimess(portno, 0, MIDI_NOTEON + (channel & 0xf), pitch, velo);
174}
175
176void outmidi_controlchange(int portno, int channel, int ctl, int value)
177{
178 if (ctl < 0) ctl = 0;
179 else if (ctl > 127) ctl = 127;
180 if (value < 0) value = 0;
181 else if (value > 127) value = 127;
182 sys_queuemidimess(portno, 0, MIDI_CONTROLCHANGE + (channel & 0xf),
183 ctl, value);
184}
185
186void outmidi_programchange(int portno, int channel, int value)
187{
188 if (value < 0) value = 0;
189 else if (value > 127) value = 127;
190 sys_queuemidimess(portno, 0,
191 MIDI_PROGRAMCHANGE + (channel & 0xf), value, 0);
192}
193
194void outmidi_pitchbend(int portno, int channel, int value)
195{
196 if (value < 0) value = 0;
197 else if (value > 16383) value = 16383;
198 sys_queuemidimess(portno, 0, MIDI_PITCHBEND + (channel & 0xf),
199 (value & 127), ((value>>7) & 127));
200}
201
202void outmidi_aftertouch(int portno, int channel, int value)
203{
204 if (value < 0) value = 0;
205 else if (value > 127) value = 127;
206 sys_queuemidimess(portno, 0, MIDI_AFTERTOUCH + (channel & 0xf), value, 0);
207}
208
209void outmidi_polyaftertouch(int portno, int channel, int pitch, int value)
210{
211 if (pitch < 0) pitch = 0;
212 else if (pitch > 127) pitch = 127;
213 if (value < 0) value = 0;
214 else if (value > 127) value = 127;
215 sys_queuemidimess(portno, 0, MIDI_POLYAFTERTOUCH + (channel & 0xf),
216 pitch, value);
217}
218
219void outmidi_mclk(int portno)
220{
221 sys_queuemidimess(portno, 1, 0xf8, 0,0);
222}
223
224/* ------------------------- MIDI input queue handling ------------------ */
225typedef struct midiparser
226{
227 int mp_status;
228 int mp_gotbyte1;
229 int mp_byte1;
230} t_midiparser;
231
232#define MIDINOTEOFF 0x80 /* 2 following 'data bytes' */
233#define MIDINOTEON 0x90 /* 2 */
234#define MIDIPOLYTOUCH 0xa0 /* 2 */
235#define MIDICONTROLCHANGE 0xb0 /* 2 */
236#define MIDIPROGRAMCHANGE 0xc0 /* 1 */
237#define MIDICHANNELTOUCH 0xd0 /* 1 */
238#define MIDIPITCHBEND 0xe0 /* 2 */
239#define MIDISTARTSYSEX 0xf0 /* (until F7) */
240#define MIDITIMECODE 0xf1 /* 1 */
241#define MIDISONGPOS 0xf2 /* 2 */
242#define MIDISONGSELECT 0xf3 /* 1 */
243#define MIDIRESERVED1 0xf4 /* ? */
244#define MIDIRESERVED2 0xf5 /* ? */
245#define MIDITUNEREQUEST 0xf6 /* 0 */
246#define MIDIENDSYSEX 0xf7 /* 0 */
247#define MIDICLOCK 0xf8 /* 0 */
248#define MIDITICK 0xf9 /* 0 */
249#define MIDISTART 0xfa /* 0 */
250#define MIDICONT 0xfb /* 0 */
251#define MIDISTOP 0xfc /* 0 */
252#define MIDIACTIVESENSE 0xfe /* 0 */
253#define MIDIRESET 0xff /* 0 */
254
255 /* functions in x_midi.c */
256void inmidi_realtimein(int portno, int cmd);
257void inmidi_byte(int portno, int byte);
258void inmidi_sysex(int portno, int byte);
259void inmidi_noteon(int portno, int channel, int pitch, int velo);
260void inmidi_controlchange(int portno, int channel, int ctlnumber, int value);
261void inmidi_programchange(int portno, int channel, int value);
262void inmidi_pitchbend(int portno, int channel, int value);
263void inmidi_aftertouch(int portno, int channel, int value);
264void inmidi_polyaftertouch(int portno, int channel, int pitch, int value);
265
266static void sys_dispatchnextmidiin( void)
267{
268 static t_midiparser parser[MAXMIDIINDEV], *parserp;
269 int portno = midi_inqueue[midi_intail].q_portno,
270 byte = midi_inqueue[midi_intail].q_byte1;
271 if (!midi_inqueue[midi_intail].q_onebyte)
272 bug("sys_dispatchnextmidiin");
273 if (portno < 0 || portno >= MAXMIDIINDEV)
274 bug("sys_dispatchnextmidiin 2");
275 parserp = parser + portno;
276 outlet_setstacklim();
277
278 if (byte >= 0xf8)
279 inmidi_realtimein(portno, byte);
280 else
281 {
282 inmidi_byte(portno, byte);
283 if (byte & 0x80)
284 {
285 if (byte == MIDITUNEREQUEST || byte == MIDIRESERVED1 ||
286 byte == MIDIRESERVED2)
287 parserp->mp_status = 0;
288 else if (byte == MIDISTARTSYSEX)
289 {
290 inmidi_sysex(portno, byte);
291 parserp->mp_status = byte;
292 }
293 else if (byte == MIDIENDSYSEX)
294 {
295 inmidi_sysex(portno, byte);
296 parserp->mp_status = 0;
297 }
298 else
299 {
300 parserp->mp_status = byte;
301 }
302 parserp->mp_gotbyte1 = 0;
303 }
304 else
305 {
306 int cmd = (parserp->mp_status >= 0xf0 ? parserp->mp_status :
307 (parserp->mp_status & 0xf0));
308 int chan = (parserp->mp_status & 0xf);
309 int byte1 = parserp->mp_byte1, gotbyte1 = parserp->mp_gotbyte1;
310 switch (cmd)
311 {
312 case MIDINOTEOFF:
313 if (gotbyte1)
314 inmidi_noteon(portno, chan, byte1, 0),
315 parserp->mp_gotbyte1 = 0;
316 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
317 break;
318 case MIDINOTEON:
319 if (gotbyte1)
320 inmidi_noteon(portno, chan, byte1, byte),
321 parserp->mp_gotbyte1 = 0;
322 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
323 break;
324 case MIDIPOLYTOUCH:
325 if (gotbyte1)
326 inmidi_polyaftertouch(portno, chan, byte1, byte),
327 parserp->mp_gotbyte1 = 0;
328 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
329 break;
330 case MIDICONTROLCHANGE:
331 if (gotbyte1)
332 inmidi_controlchange(portno, chan, byte1, byte),
333 parserp->mp_gotbyte1 = 0;
334 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
335 break;
336 case MIDIPROGRAMCHANGE:
337 inmidi_programchange(portno, chan, byte);
338 break;
339 case MIDICHANNELTOUCH:
340 inmidi_aftertouch(portno, chan, byte);
341 break;
342 case MIDIPITCHBEND:
343 if (gotbyte1)
344 inmidi_pitchbend(portno, chan, ((byte << 7) + byte1)),
345 parserp->mp_gotbyte1 = 0;
346 else parserp->mp_byte1 = byte, parserp->mp_gotbyte1 = 1;
347 break;
348 case MIDISTARTSYSEX:
349 inmidi_sysex(portno, byte);
350 break;
351
352 /* other kinds of messages are just dropped here. We'll
353 need another status byte before we start letting MIDI in
354 again (no running status across "system" messages). */
355 case MIDITIMECODE: /* 1 data byte*/
356 break;
357 case MIDISONGPOS: /* 2 */
358 break;
359 case MIDISONGSELECT: /* 1 */
360 break;
361 }
362 }
363 }
364 midi_intail = (midi_intail + 1 == MIDIQSIZE ? 0 : midi_intail + 1);
365}
366
367void sys_pollmidiinqueue( void)
368{
369#ifdef TEST_DEJITTER
370 static int db = 0;
371#endif
372 double logicaltime = .001 * clock_gettimesince(sys_midiinittime);
373#ifdef TEST_DEJITTER
374 if (midi_inhead == midi_intail)
375 db = 0;
376#endif
377 while (midi_inhead != midi_intail)
378 {
379#ifdef TEST_DEJITTER
380 if (!db)
381 {
382 post("in del %f, logicaltime %f, RT %f adcminusRT %f",
383 (midi_inqueue[midi_intail].q_time - logicaltime),
384 logicaltime, sys_getrealtime(), sys_adctimeminusrealtime);
385 db = 1;
386 }
387#endif
388#if 0
389 if (midi_inqueue[midi_intail].q_time <= logicaltime - 0.007)
390 post("late %f",
391 1000 * (logicaltime - midi_inqueue[midi_intail].q_time));
392#endif
393 if (midi_inqueue[midi_intail].q_time <= logicaltime)
394 {
395#if 0
396 post("diff %f",
397 1000* (logicaltime - midi_inqueue[midi_intail].q_time));
398#endif
399 sys_dispatchnextmidiin();
400 }
401 else break;
402 }
403}
404
405 /* this should be called from the system dependent MIDI code when a byte
406 comes in, as a result of our calling sys_poll_midi. We stick it on a
407 timetag queue and dispatch it at the appropriate logical time. */
408
409
410void sys_midibytein(int portno, int byte)
411{
412 static int warned = 0;
413 t_midiqelem *midiqelem;
414 int newhead = midi_inhead +1;
415 if (newhead == MIDIQSIZE)
416 newhead = 0;
417 /* if FIFO is full flush an element to make room */
418 if (newhead == midi_intail)
419 {
420 if (!warned)
421 {
422 post("warning: MIDI timing FIFO overflowed");
423 warned = 1;
424 }
425 sys_dispatchnextmidiin();
426 }
427 midi_inqueue[midi_inhead].q_portno = portno;
428 midi_inqueue[midi_inhead].q_onebyte = 1;
429 midi_inqueue[midi_inhead].q_byte1 = byte;
430 midi_inqueue[midi_inhead].q_time = sys_getmidiinrealtime();
431 midi_inhead = newhead;
432 sys_pollmidiinqueue();
433}
434
435void sys_pollmidiqueue( void)
436{
437#if 0
438 static double lasttime;
439 double newtime = sys_getrealtime();
440 if (newtime - lasttime > 0.007)
441 post("delay %d", (int)(1000 * (newtime - lasttime)));
442 lasttime = newtime;
443#endif
444 sys_poll_midi(); /* OS dependent poll for MIDI input */
445 sys_pollmidioutqueue();
446 sys_pollmidiinqueue();
447}
448
449/******************** dialog window and device listing ********************/
450
451#ifdef USEAPI_OSS
452void midi_oss_init( void);
453#endif
454
455 /* last requested parameters */
456static int midi_nmidiindev;
457static int midi_midiindev[MAXMIDIINDEV];
458static int midi_nmidioutdev;
459static int midi_midioutdev[MAXMIDIOUTDEV];
460
461static void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,
462 int *pnmidioutdev, int *pmidioutdev)
463{
464 int i;
465 *pnmidiindev = midi_nmidiindev;
466 for (i = 0; i < MAXMIDIINDEV; i++)
467 pmidiindev[i] = midi_midiindev[i];
468 *pnmidioutdev = midi_nmidioutdev;
469 for (i = 0; i < MAXMIDIOUTDEV; i++)
470 pmidioutdev[i] = midi_midioutdev[i];
471}
472
473static void sys_save_midi_params(
474 int nmidiindev, int *midiindev,
475 int nmidioutdev, int *midioutdev)
476{
477 int i;
478 midi_nmidiindev = nmidiindev;
479 for (i = 0; i < MAXMIDIINDEV; i++)
480 midi_midiindev[i] = midiindev[i];
481 midi_nmidioutdev = nmidioutdev;
482 for (i = 0; i < MAXMIDIOUTDEV; i++)
483 midi_midioutdev[i] = midioutdev[i];
484}
485
486void sys_open_midi(int nmidiindev, int *midiindev,
487 int nmidioutdev, int *midioutdev)
488{
489#ifdef USEAPI_OSS
490 midi_oss_init();
491#endif
492 sys_do_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev);
493 sys_save_midi_params(nmidiindev, midiindev,
494 nmidioutdev, midioutdev);
495}
496
497 /* open midi using whatever parameters were last used */
498void sys_reopen_midi( void)
499{
500 int nmidiindev, midiindev[MAXMIDIINDEV];
501 int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
502 sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev);
503 sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev);
504}
505
506#define MAXNDEV 20
507#define DEVDESCSIZE 80
508
509#ifdef MSW
510#define DEVONSET 0 /* microsoft device list starts at 0 (the "mapper"). */
511#else /* (see also MSW ifdef in sys_parsedevlist(), s_main.c) */
512#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */
513#endif
514
515void sys_listmididevs(void )
516{
517 char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
518 int nindevs = 0, noutdevs = 0, i;
519
520 midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs,
521 MAXNDEV, DEVDESCSIZE);
522
523 if (!nindevs)
524 post("no midi input devices found");
525 else
526 {
527 post("input devices:");
528 for (i = 0; i < nindevs; i++)
529 post("%d. %s", i+1, indevlist + i * DEVDESCSIZE);
530 }
531 if (!noutdevs)
532 post("no midi output devices found");
533 else
534 {
535 post("output devices:");
536 for (i = 0; i < noutdevs; i++)
537 post("%d. %s", i+DEVONSET, outdevlist + i * DEVDESCSIZE);
538 }
539}
540
541extern t_class *glob_pdobject;
542
543 /* start an midi settings dialog window */
544void glob_midi_properties(t_pd *dummy, t_floatarg flongform)
545{
546 char buf[1024 + 2 * MAXNDEV*(DEVDESCSIZE+4)];
547 /* these are the devices you're using: */
548 int nindev, midiindev[MAXMIDIINDEV];
549 int noutdev, midioutdev[MAXMIDIOUTDEV];
550 int midiindev1, midiindev2, midiindev3, midiindev4,
551 midioutdev1, midioutdev2, midioutdev3, midioutdev4;
552
553 /* these are all the devices on your system: */
554 char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE];
555 int nindevs = 0, noutdevs = 0, i;
556
557 char indevliststring[MAXNDEV*(DEVDESCSIZE+4)+80],
558 outdevliststring[MAXNDEV*(DEVDESCSIZE+4)+80];
559
560 midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs,
561 MAXNDEV, DEVDESCSIZE);
562
563 strcpy(indevliststring, "{ {none} ");
564 for (i = 0; i < nindevs; i++)
565 {
566 strcat(indevliststring, "\"");
567 strcat(indevliststring, indevlist + i * DEVDESCSIZE);
568 strcat(indevliststring, "\" ");
569 }
570 strcat(indevliststring, "}");
571
572 strcpy(outdevliststring, "{ {none} ");
573 for (i = 0; i < noutdevs; i++)
574 {
575 strcat(outdevliststring, "\"");
576 strcat(outdevliststring, outdevlist + i * DEVDESCSIZE);
577 strcat(outdevliststring, "\" ");
578 }
579 strcat(outdevliststring, "}");
580
581 sys_get_midi_params(&nindev, midiindev, &noutdev, midioutdev);
582
583 if (nindev > 1 || noutdev > 1)
584 flongform = 1;
585
586 midiindev1 = (nindev > 0 && midiindev[0]>= 0 ? midiindev[0]+1 : 0);
587 midiindev2 = (nindev > 1 && midiindev[1]>= 0 ? midiindev[1]+1 : 0);
588 midiindev3 = (nindev > 2 && midiindev[2]>= 0 ? midiindev[2]+1 : 0);
589 midiindev4 = (nindev > 3 && midiindev[3]>= 0 ? midiindev[3]+1 : 0);
590 midioutdev1 = (noutdev > 0 && midioutdev[0]>=0 ? midioutdev[0]+1 : 0);
591 midioutdev2 = (noutdev > 1 && midioutdev[1]>=0 ? midioutdev[1]+1 : 0);
592 midioutdev3 = (noutdev > 2 && midioutdev[2]>=0 ? midioutdev[2]+1 : 0);
593 midioutdev4 = (noutdev > 3 && midioutdev[3]>=0 ? midioutdev[3]+1 : 0);
594
595 sprintf(buf,
596"pdtk_midi_dialog %%s \
597%s %d %d %d %d %s %d %d %d %d \
598%d\n",
599 indevliststring,
600 midiindev1, midiindev2, midiindev3, midiindev4,
601 outdevliststring,
602 midioutdev1, midioutdev2, midioutdev3, midioutdev4,
603 (flongform != 0));
604 gfxstub_deleteforkey(0);
605 gfxstub_new(&glob_pdobject, glob_midi_properties, buf);
606}
607
608 /* new values from dialog window */
609void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
610{
611 int nmidiindev, midiindev[MAXMIDIINDEV];
612 int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
613 int i, nindev, noutdev;
614 int newmidiindev[4], newmidioutdev[4];
615
616 for (i = 0; i < 4; i++)
617 {
618 newmidiindev[i] = atom_getintarg(i, argc, argv);
619 newmidioutdev[i] = atom_getintarg(i+4, argc, argv);
620 }
621
622 for (i = 0, nindev = 0; i < 4; i++)
623 {
624 if (newmidiindev[i] > 0)
625 {
626 newmidiindev[nindev] = newmidiindev[i]-1;
627 nindev++;
628 }
629 }
630 for (i = 0, noutdev = 0; i < 4; i++)
631 {
632 if (newmidioutdev[i] > 0)
633 {
634 newmidioutdev[noutdev] = newmidioutdev[i]-1;
635 noutdev++;
636 }
637 }
638
639 sys_close_midi();
640 sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev);
641}
642
diff --git a/apps/plugins/pdbox/PDa/src/s_midi_oss.c b/apps/plugins/pdbox/PDa/src/s_midi_oss.c
deleted file mode 100644
index fab1d84b6f..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_midi_oss.c
+++ /dev/null
@@ -1,360 +0,0 @@
1/* Copyright (c) 1997-1999 Guenter Geiger, Miller Puckette, Larry Troxler,
2* Winfried Ritsch, Karl MacMillan, and others.
3* For information on usage and redistribution, and for a DISCLAIMER OF ALL
4* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5
6/* MIDI I/O for Linux using OSS */
7
8#include <stdio.h>
9#ifdef UNIX
10#include <unistd.h>
11#endif
12#include <stdlib.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#include <errno.h>
17#include "m_pd.h"
18#include "s_stuff.h"
19
20static int oss_nmidiin;
21static int oss_midiinfd[MAXMIDIINDEV];
22static int oss_nmidiout;
23static int oss_midioutfd[MAXMIDIOUTDEV];
24
25static void oss_midiout(int fd, int n)
26{
27 char b = n;
28 if ((write(fd, (char *) &b, 1)) != 1)
29 perror("midi write");
30}
31
32#define O_MIDIFLAG O_NDELAY
33
34void sys_do_open_midi(int nmidiin, int *midiinvec,
35 int nmidiout, int *midioutvec)
36{
37 int i;
38 for (i = 0; i < nmidiout; i++)
39 oss_midioutfd[i] = -1;
40 for (i = 0, oss_nmidiin = 0; i < nmidiin; i++)
41 {
42 int fd = -1, j, outdevindex = -1;
43 char namebuf[80];
44 int devno = midiinvec[i];
45
46 for (j = 0; j < nmidiout; j++)
47 if (midioutvec[j] == midiinvec[i])
48 outdevindex = j;
49
50 /* try to open the device for read/write. */
51 if (devno == 0 && fd < 0 && outdevindex >= 0)
52 {
53 sys_setalarm(1000000);
54 fd = open("/dev/midi", O_RDWR | O_MIDIFLAG);
55 if (sys_verbose)
56 fprintf(stderr,
57 "device 1: tried /dev/midi READ/WRITE; returned %d\n", fd);
58 if (outdevindex >= 0 && fd >= 0)
59 oss_midioutfd[outdevindex] = fd;
60 }
61 if (fd < 0 && outdevindex >= 0)
62 {
63 sys_setalarm(1000000);
64 sprintf(namebuf, "/dev/midi%2.2d", devno);
65 fd = open(namebuf, O_RDWR | O_MIDIFLAG);
66 if (sys_verbose)
67 fprintf(stderr,
68 "device %d: tried %s READ/WRITE; returned %d\n",
69 devno, namebuf, fd);
70 if (outdevindex >= 0 && fd >= 0)
71 oss_midioutfd[outdevindex] = fd;
72 }
73 if (fd < 0 && outdevindex >= 0)
74 {
75 sys_setalarm(1000000);
76 sprintf(namebuf, "/dev/midi%d", devno);
77 fd = open(namebuf, O_RDWR | O_MIDIFLAG);
78 if (sys_verbose)
79 fprintf(stderr, "device %d: tried %s READ/WRITE; returned %d\n",
80 devno, namebuf, fd);
81 if (outdevindex >= 0 && fd >= 0)
82 oss_midioutfd[outdevindex] = fd;
83 }
84 if (devno == 1 && fd < 0)
85 {
86 sys_setalarm(1000000);
87 fd = open("/dev/midi", O_RDONLY | O_MIDIFLAG);
88 if (sys_verbose)
89 fprintf(stderr,
90 "device 1: tried /dev/midi READONLY; returned %d\n", fd);
91 }
92 if (fd < 0)
93 {
94 sys_setalarm(1000000);
95 sprintf(namebuf, "/dev/midi%2.2d", devno);
96 fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
97 if (sys_verbose)
98 fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
99 devno, namebuf, fd);
100 }
101 if (fd < 0)
102 {
103 sys_setalarm(1000000);
104 sprintf(namebuf, "/dev/midi%d", devno);
105 fd = open(namebuf, O_RDONLY | O_MIDIFLAG);
106 if (sys_verbose)
107 fprintf(stderr, "device %d: tried %s READONLY; returned %d\n",
108 devno, namebuf, fd);
109 }
110 if (fd >= 0)
111 oss_midiinfd[oss_nmidiin++] = fd;
112 else post("couldn't open MIDI input device %d", devno);
113 }
114 for (i = 0, oss_nmidiout = 0; i < nmidiout; i++)
115 {
116 int fd = oss_midioutfd[i];
117 char namebuf[80];
118 int devno = midioutvec[i];
119 if (devno == 1 && fd < 0)
120 {
121 sys_setalarm(1000000);
122 fd = open("/dev/midi", O_WRONLY | O_MIDIFLAG);
123 if (sys_verbose)
124 fprintf(stderr,
125 "device 1: tried /dev/midi WRITEONLY; returned %d\n", fd);
126 }
127 if (fd < 0)
128 {
129 sys_setalarm(1000000);
130 sprintf(namebuf, "/dev/midi%2.2d", devno);
131 fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
132 if (sys_verbose)
133 fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
134 devno, namebuf, fd);
135 }
136 if (fd < 0)
137 {
138 sys_setalarm(1000000);
139 sprintf(namebuf, "/dev/midi%d", devno);
140 fd = open(namebuf, O_WRONLY | O_MIDIFLAG);
141 if (sys_verbose)
142 fprintf(stderr, "device %d: tried %s WRITEONLY; returned %d\n",
143 devno, namebuf, fd);
144 }
145 if (fd >= 0)
146 oss_midioutfd[oss_nmidiout++] = fd;
147 else post("couldn't open MIDI output device %d", devno);
148 }
149
150 if (oss_nmidiin < nmidiin || oss_nmidiout < nmidiout || sys_verbose)
151 post("opened %d MIDI input device(s) and %d MIDI output device(s).",
152 oss_nmidiin, oss_nmidiout);
153
154 sys_setalarm(0);
155}
156
157#define md_msglen(x) (((x)<0xC0)?2:((x)<0xE0)?1:((x)<0xF0)?2:\
158 ((x)==0xF2)?2:((x)<0xF4)?1:0)
159
160void sys_putmidimess(int portno, int a, int b, int c)
161{
162 if (portno >= 0 && portno < oss_nmidiout)
163 {
164 switch (md_msglen(a))
165 {
166 case 2:
167 oss_midiout(oss_midioutfd[portno],a);
168 oss_midiout(oss_midioutfd[portno],b);
169 oss_midiout(oss_midioutfd[portno],c);
170 return;
171 case 1:
172 oss_midiout(oss_midioutfd[portno],a);
173 oss_midiout(oss_midioutfd[portno],b);
174 return;
175 case 0:
176 oss_midiout(oss_midioutfd[portno],a);
177 return;
178 };
179 }
180}
181
182void sys_putmidibyte(int portno, int byte)
183{
184 if (portno >= 0 && portno < oss_nmidiout)
185 oss_midiout(oss_midioutfd[portno], byte);
186}
187
188#if 0 /* this is the "select" version which doesn't work with OSS
189 driver for emu10k1 (it doesn't implement select.) */
190void sys_poll_midi(void)
191{
192 int i, throttle = 100;
193 struct timeval timout;
194 int did = 1, maxfd = 0;
195 while (did)
196 {
197 fd_set readset, writeset, exceptset;
198 did = 0;
199 if (throttle-- < 0)
200 break;
201 timout.tv_sec = 0;
202 timout.tv_usec = 0;
203
204 FD_ZERO(&writeset);
205 FD_ZERO(&readset);
206 FD_ZERO(&exceptset);
207 for (i = 0; i < oss_nmidiin; i++)
208 {
209 if (oss_midiinfd[i] > maxfd)
210 maxfd = oss_midiinfd[i];
211 FD_SET(oss_midiinfd[i], &readset);
212 }
213 select(maxfd+1, &readset, &writeset, &exceptset, &timout);
214 for (i = 0; i < oss_nmidiin; i++)
215 if (FD_ISSET(oss_midiinfd[i], &readset))
216 {
217 char c;
218 int ret = read(oss_midiinfd[i], &c, 1);
219 if (ret <= 0)
220 fprintf(stderr, "Midi read error\n");
221 else sys_midibytein(i, (c & 0xff));
222 did = 1;
223 }
224 }
225}
226#else
227
228 /* this version uses the asynchronous "read()" ... */
229void sys_poll_midi(void)
230{
231 int i, throttle = 100;
232 struct timeval timout;
233 int did = 1, maxfd = 0;
234 while (did)
235 {
236 fd_set readset, writeset, exceptset;
237 did = 0;
238 if (throttle-- < 0)
239 break;
240 for (i = 0; i < oss_nmidiin; i++)
241 {
242 char c;
243 int ret = read(oss_midiinfd[i], &c, 1);
244 if (ret < 0)
245 {
246 if (errno != EAGAIN)
247 perror("MIDI");
248 }
249 else if (ret != 0)
250 {
251 sys_midibytein(i, (c & 0xff));
252 did = 1;
253 }
254 }
255 }
256}
257#endif
258
259void sys_close_midi()
260{
261 int i;
262 for (i = 0; i < oss_nmidiin; i++)
263 close(oss_midiinfd[i]);
264 for (i = 0; i < oss_nmidiout; i++)
265 close(oss_midioutfd[i]);
266 oss_nmidiin = oss_nmidiout = 0;
267}
268
269#define NSEARCH 10
270static int oss_nmidiindevs, oss_nmidioutdevs, oss_initted;
271
272void midi_oss_init(void)
273{
274 int i;
275 if (oss_initted)
276 return;
277 oss_initted = 1;
278 for (i = 0; i < NSEARCH; i++)
279 {
280 int fd;
281 char namebuf[80];
282
283 oss_nmidiindevs = i;
284 /* try to open the device for reading */
285 if (i == 0)
286 {
287 fd = open("/dev/midi", O_RDONLY | O_NDELAY);
288 if (fd >= 0)
289 {
290 close(fd);
291 continue;
292 }
293 }
294 sprintf(namebuf, "/dev/midi%2.2d", i);
295 fd = open(namebuf, O_RDONLY | O_NDELAY);
296 if (fd >= 0)
297 {
298 close(fd);
299 continue;
300 }
301 sprintf(namebuf, "/dev/midi%d", i);
302 fd = open(namebuf, O_RDONLY | O_NDELAY);
303 if (fd >= 0)
304 {
305 close(fd);
306 continue;
307 }
308 break;
309 }
310 for (i = 0; i < NSEARCH; i++)
311 {
312 int fd;
313 char namebuf[80];
314
315 oss_nmidioutdevs = i;
316 /* try to open the device for writing */
317 if (i == 0)
318 {
319 fd = open("/dev/midi", O_WRONLY | O_NDELAY);
320 if (fd >= 0)
321 {
322 close(fd);
323 continue;
324 }
325 }
326 sprintf(namebuf, "/dev/midi%2.2d", i);
327 fd = open(namebuf, O_WRONLY | O_NDELAY);
328 if (fd >= 0)
329 {
330 close(fd);
331 continue;
332 }
333 sprintf(namebuf, "/dev/midi%d", i);
334 fd = open(namebuf, O_WRONLY | O_NDELAY);
335 if (fd >= 0)
336 {
337 close(fd);
338 continue;
339 }
340 break;
341 }
342}
343
344void midi_getdevs(char *indevlist, int *nindevs,
345 char *outdevlist, int *noutdevs, int maxndev, int devdescsize)
346{
347 int i, ndev;
348 if ((ndev = oss_nmidiindevs) > maxndev)
349 ndev = maxndev;
350 for (i = 0; i < ndev; i++)
351 sprintf(indevlist + i * devdescsize, "OSS MIDI device #%d", i+1);
352 *nindevs = ndev;
353
354 if ((ndev = oss_nmidioutdevs) > maxndev)
355 ndev = maxndev;
356 for (i = 0; i < ndev; i++)
357 sprintf(outdevlist + i * devdescsize, "OSS MIDI device #%d", i+1);
358 *noutdevs = ndev;
359}
360
diff --git a/apps/plugins/pdbox/PDa/src/s_midi_pm.c b/apps/plugins/pdbox/PDa/src/s_midi_pm.c
deleted file mode 100644
index a4f376e0ca..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_midi_pm.c
+++ /dev/null
@@ -1,167 +0,0 @@
1/* Copyright (c) 1997-2003 Guenter Geiger, Miller Puckette, Larry Troxler,
2* Winfried Ritsch, Karl MacMillan, and others.
3* For information on usage and redistribution, and for a DISCLAIMER OF ALL
4* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
5
6 this file calls portmidi to do MIDI I/O for MSW and Mac OSX.
7
8*/
9
10#include "m_pd.h"
11#include "s_stuff.h"
12#include <stdio.h>
13#ifdef UNIX
14#include <unistd.h>
15#include <sys/time.h>
16#include <sys/resource.h>
17#endif
18#include <stdlib.h>
19#include <string.h>
20#include <errno.h>
21#include "portaudio.h"
22#include "portmidi.h"
23#include "porttime.h"
24#include "pminternal.h"
25
26static PmStream *mac_midiindevlist[MAXMIDIINDEV];
27static PmStream *mac_midioutdevlist[MAXMIDIOUTDEV];
28static int mac_nmidiindev;
29static int mac_nmidioutdev;
30
31void sys_open_midi(int nmidiin, int *midiinvec,
32 int nmidiout, int *midioutvec)
33{
34 int i = 0;
35 int n = 0;
36 PmError err;
37
38 Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */
39 mac_nmidiindev = 0;
40
41 /* protect the unwary from having MIDI inputs open; they're
42 bad news if you close Pd's terminal window. see sys_nmidiin
43 in s_main.c too. */
44#ifdef MSW
45 if (nmidiin)
46 {
47 post(
48 "midi input enabled; warning, don't close the DOS window directly!");
49 }
50 else post("not using MIDI input (use 'pd -midiindev 1' to override)");
51#endif
52
53 for (i = 0; i < nmidiin; i++)
54 {
55 if (midiinvec[i] == DEFMIDIDEV)
56 midiinvec[i] = Pm_GetDefaultInputDeviceID();
57 err = Pm_OpenInput(&mac_midiindevlist[mac_nmidiindev], midiinvec[i],
58 NULL, 100, NULL, NULL, NULL);
59 if (err)
60 post("could not open midi input device number %d: %s",
61 midiinvec[i], Pm_GetErrorText(err));
62 else
63 {
64 if (sys_verbose)
65 post("Midi Input opened.\n");
66 mac_nmidiindev++;
67 }
68 }
69
70 mac_nmidioutdev = 0;
71 for (i = 0; i < nmidiout; i++)
72 {
73 if (midioutvec[i] == DEFMIDIDEV)
74 midioutvec[i] = Pm_GetDefaultOutputDeviceID();
75 err = Pm_OpenOutput(&mac_midioutdevlist[mac_nmidioutdev], midioutvec[i],
76 NULL, 0, NULL, NULL, 0);
77 if (err)
78 post("could not open midi output device number %d: %s",
79 midioutvec[i], Pm_GetErrorText(err));
80 else
81 {
82 if (sys_verbose)
83 post("Midi Output opened.\n");
84 mac_nmidioutdev++;
85 }
86 }
87}
88
89void sys_close_midi( void)
90{
91 int i;
92 for (i = 0; i < mac_nmidiindev; i++)
93 Pm_Close(mac_midiindevlist[mac_nmidiindev]);
94 mac_nmidiindev = 0;
95 for (i = 0; i < mac_nmidioutdev; i++)
96 Pm_Close(mac_midioutdevlist[mac_nmidioutdev]);
97 mac_nmidioutdev = 0;
98}
99
100void sys_putmidimess(int portno, int a, int b, int c)
101{
102 PmEvent buffer;
103 fprintf(stderr, "put 1 msg %d %d\n", portno, mac_nmidioutdev);
104 if (portno >= 0 && portno < mac_nmidioutdev)
105 {
106 buffer.message = Pm_Message(a, b, c);
107 buffer.timestamp = 0;
108 fprintf(stderr, "put msg\n");
109 Pm_Write(mac_midioutdevlist[portno], &buffer, 1);
110 }
111}
112
113void sys_putmidibyte(int portno, int byte)
114{
115 post("sorry, no byte-by-byte MIDI output implemented in MAC OSX");
116}
117
118void sys_poll_midi(void)
119{
120 int i, nmess;
121 PmEvent buffer;
122 for (i = 0; i < mac_nmidiindev; i++)
123 {
124 int nmess = Pm_Read(mac_midiindevlist[i], &buffer, 1);
125 if (nmess > 0)
126 {
127 int status = Pm_MessageStatus(buffer.message);
128 int data1 = Pm_MessageData1(buffer.message);
129 int data2 = Pm_MessageData2(buffer.message);
130 int msgtype = (status >> 4) - 8;
131 switch (msgtype)
132 {
133 case 0:
134 case 1:
135 case 2:
136 case 3:
137 case 6:
138 sys_midibytein(i, status);
139 sys_midibytein(i, data1);
140 sys_midibytein(i, data2);
141 break;
142 case 4:
143 case 5:
144 sys_midibytein(i, status);
145 sys_midibytein(i, data1);
146 break;
147 case 7:
148 sys_midibytein(i, status);
149 break;
150 }
151 }
152 }
153}
154
155void sys_listmididevs(void) /* lifted from pa_devs.c in portaudio */
156{
157 int i,j;
158 for (i = 0; i < Pm_CountDevices(); i++)
159 {
160 const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
161 printf("%d: %s, %s", i, info->interf, info->name);
162 if (info->input) printf(" (input)");
163 if (info->output) printf(" (output)");
164 printf("\n");
165 }
166}
167
diff --git a/apps/plugins/pdbox/PDa/src/s_midi_sgi.c b/apps/plugins/pdbox/PDa/src/s_midi_sgi.c
deleted file mode 100644
index 105a812b49..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_midi_sgi.c
+++ /dev/null
@@ -1,189 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5#include "s_stuff.h"
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <string.h>
10#ifdef HAVE_BSTRING_H
11#include <bstring.h>
12#endif
13#include <sys/types.h>
14#include <sys/time.h>
15
16#include <dmedia/audio.h>
17#include <sys/fpu.h>
18#include <dmedia/midi.h>
19int mdInit(void); /* prototype was messed up in midi.h */
20/* #include "sys/select.h" */
21
22
23 /*
24 set the special "flush zero" but (FS, bit 24) in the
25 Control Status Register of the FPU of R4k and beyond
26 so that the result of any underflowing operation will
27 be clamped to zero, and no exception of any kind will
28 be generated on the CPU.
29
30 thanks to cpirazzi@cp.esd.sgi.com (Chris Pirazzi).
31 */
32
33static void sgi_flush_all_underflows_to_zero(void)
34{
35 union fpc_csr f;
36 f.fc_word = get_fpc_csr();
37 f.fc_struct.flush = 1;
38 set_fpc_csr(f.fc_word);
39}
40
41#define NPORT 2
42
43static MDport sgi_inport[NPORT];
44static MDport sgi_outport[NPORT];
45
46void sgi_open_midi(int midiin, int midiout)
47{
48 int i;
49 int sgi_nports = mdInit();
50 if (sgi_nports < 0) sgi_nports = 0;
51 else if (sgi_nports > NPORT) sgi_nports = NPORT;
52 if (sys_verbose)
53 {
54 if (!sgi_nports)
55 {
56 post("no serial ports are configured for MIDI;");
57 post("if you want to use MIDI, try exiting Pd, typing");
58 post("'startmidi -d /dev/ttyd2' to a shell, and restarting Pd.");
59 }
60 else if (sgi_nports == 1)
61 post("Found one MIDI port on %s", mdGetName(0));
62 else if (sgi_nports == 2)
63 post("Found MIDI ports on %s and %s",
64 mdGetName(0), mdGetName(1));
65 }
66 if (midiin)
67 {
68 for (i = 0; i < sgi_nports; i++)
69 {
70 if (!(sgi_inport[i] = mdOpenInPort(mdGetName(i))))
71 error("MIDI input port %d: open failed", i+1);;
72 }
73 }
74 if (midiout)
75 {
76 for (i = 0; i < sgi_nports; i++)
77 {
78 if (!(sgi_outport[i] = mdOpenOutPort(mdGetName(i))))
79 error("MIDI output port %d: open failed", i+1);;
80 }
81 }
82 return;
83}
84
85void sys_putmidimess(int portno, int a, int b, int c)
86{
87 MDevent mdv;
88 if (portno >= NPORT || portno < 0 || !sgi_outport[portno]) return;
89 mdv.msg[0] = a;
90 mdv.msg[1] = b;
91 mdv.msg[2] = c;
92 mdv.msg[3] = 0;
93 mdv.sysexmsg = 0;
94 mdv.stamp = 0;
95 mdv.msglen = 0;
96 if (mdSend(sgi_outport[portno], &mdv, 1) < 0)
97 error("MIDI output error\n");
98 post("msg out %d %d %d", a, b, c);
99}
100
101void sys_putmidibyte(int portno, int foo)
102{
103 error("MIDI raw byte output not available on SGI");
104}
105
106void inmidi_noteon(int portno, int channel, int pitch, int velo);
107void inmidi_controlchange(int portno, int channel, int ctlnumber, int value);
108void inmidi_programchange(int portno, int channel, int value);
109void inmidi_pitchbend(int portno, int channel, int value);
110void inmidi_aftertouch(int portno, int channel, int value);
111void inmidi_polyaftertouch(int portno, int channel, int pitch, int value);
112
113void sys_poll_midi(void)
114{
115 int i;
116 MDport *mp;
117 for (i = 0, mp = sgi_inport; i < NPORT; i++, mp++)
118 {
119 int ret, status, b1, b2, nfds;
120 MDevent mdv;
121 fd_set inports;
122 struct timeval timeout;
123 timeout.tv_sec = 0;
124 timeout.tv_usec = 0;
125 if (!*mp) continue;
126 FD_ZERO(&inports);
127 FD_SET(mdGetFd(*mp), &inports);
128
129 if (select(mdGetFd(*mp)+1 , &inports, 0, 0, &timeout) < 0)
130 perror("midi select");
131 if (FD_ISSET(mdGetFd(*mp),&inports))
132 {
133 if (mdReceive(*mp, &mdv, 1) < 0)
134 error("failure receiving message\n");
135 else if (mdv.msg[0] == MD_SYSEX) mdFree(mdv.sysexmsg);
136
137 else
138 {
139 int status = mdv.msg[0];
140 int channel = (status & 0xf) + 1;
141 int b1 = mdv.msg[1];
142 int b2 = mdv.msg[2];
143 switch(status & 0xf0)
144 {
145 case MD_NOTEOFF:
146 inmidi_noteon(i, channel, b1, 0);
147 break;
148 case MD_NOTEON:
149 inmidi_noteon(i, channel, b1, b2);
150 break;
151 case MD_POLYKEYPRESSURE:
152 inmidi_polyaftertouch(i, channel, b1, b2);
153 break;
154 case MD_CONTROLCHANGE:
155 inmidi_controlchange(i, channel, b1, b2);
156 break;
157 case MD_PITCHBENDCHANGE:
158 inmidi_pitchbend(i, channel, ((b2 << 7) + b1));
159 break;
160 case MD_PROGRAMCHANGE:
161 inmidi_programchange(i, channel, b1);
162 break;
163 case MD_CHANNELPRESSURE:
164 inmidi_aftertouch(i, channel, b1);
165 break;
166 }
167 }
168 }
169 }
170}
171
172void sys_open_midi(int nmidiin, int *midiinvec,
173 int nmidiout, int *midioutvec)
174{
175 sgi_open_midi(nmidiin!=0, nmidiout!=0);
176}
177
178
179void sys_close_midi( void)
180{
181 /* ??? */
182}
183
184void sys_set_priority(int foo)
185{
186 fprintf(stderr,
187 "warning: priority boosting in IRIX not implemented yet\n");
188}
189
diff --git a/apps/plugins/pdbox/PDa/src/s_watchdog.c b/apps/plugins/pdbox/PDa/src/s_watchdog.c
deleted file mode 100644
index e8653e9e39..0000000000
--- a/apps/plugins/pdbox/PDa/src/s_watchdog.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/* Copyright (c) 1997-2000 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* This file is compiled into the separate program, "pd-watchdog," which
6tries to prevent Pd from locking up the processor if it's at realtime
7priority. Linux only. Invoked from s_inter.c. */
8
9#include <sys/time.h>
10#include <sys/types.h>
11#include <unistd.h>
12#include <signal.h>
13#include <stdio.h>
14
15int main(int argc, char **argv)
16{
17 int happy = 1;
18 while (1)
19 {
20 struct timeval timout;
21 fd_set readset;
22 if (happy)
23 {
24 timout.tv_sec = 5;
25 timout.tv_usec = 0;
26 }
27 else
28 {
29 timout.tv_sec = 2;
30 timout.tv_usec = 0;
31 }
32 FD_ZERO(&readset);
33 FD_SET(0, &readset);
34 select(1, &readset, 0, 0, &timout);
35 if (FD_ISSET(0, &readset))
36 {
37 char buf[100];
38 happy = 1;
39 if (read(0, &buf, 100) <= 0)
40 return (0);
41 else continue;
42 }
43 happy = 0;
44 kill(getppid(), SIGHUP);
45 fprintf(stderr, "watchdog: signaling pd...\n");
46 }
47}
48
diff --git a/apps/plugins/pdbox/PDa/src/t_main.c b/apps/plugins/pdbox/PDa/src/t_main.c
deleted file mode 100644
index d68579e745..0000000000
--- a/apps/plugins/pdbox/PDa/src/t_main.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* This file should be compared with the corresponding thing in the TK
6* distribution whenever updating to newer versions of TCL/TK. */
7
8/*
9 * Copyright (c) 1993 The Regents of the University of California.
10 * Copyright (c) 1994 Sun Microsystems, Inc.
11 *
12 * See the file "license.terms" for information on usage and redistribution
13 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 */
15
16
17#ifndef MACOSX /* linux and IRIX only; in MACOSX we don't link this in */
18#include "tk.h"
19#include <stdlib.h>
20
21/*
22 * The following variable is a special hack that is needed in order for
23 * Sun shared libraries to be used for Tcl.
24 */
25
26extern int matherr(void);
27int *tclDummyMathPtr = (int *) matherr;
28
29/*
30 *----------------------------------------------------------------------
31 *
32 * main --
33 *
34 * This is the main program for the application.
35 *
36 * Results:
37 * None: Tk_Main never returns here, so this procedure never
38 * returns either.
39 *
40 * Side effects:
41 * Whatever the application does.
42 *
43 *----------------------------------------------------------------------
44 */
45
46void pdgui_startup(Tcl_Interp *interp);
47void pdgui_setname(char *name);
48void pdgui_setsock(int port);
49void pdgui_sethost(char *name);
50
51int
52main(int argc, char **argv)
53{
54 pdgui_setname(argv[0]);
55 if (argc >= 2)
56 {
57 pdgui_setsock(atoi(argv[1]));
58 argc--; argv++;
59 argv[0] = "Pd";
60 }
61 if (argc >= 2)
62 {
63 pdgui_sethost(argv[1]);
64 argc--; argv++;
65 argv[0] = "Pd";
66 }
67 Tk_Main(argc, argv, Tcl_AppInit);
68 return 0; /* Needed only to prevent compiler warning. */
69}
70
71
72/*
73 *----------------------------------------------------------------------
74 *
75 * Tcl_AppInit --
76 *
77 * This procedure performs application-specific initialization.
78 * Most applications, especially those that incorporate additional
79 * packages, will have their own version of this procedure.
80 * Results:
81 * Returns a standard Tcl completion code, and leaves an error
82 * message in interp->result if an error occurs.
83 *
84 * Side effects:
85 * Depends on the startup script.
86 *
87 *----------------------------------------------------------------------
88 */
89
90int
91Tcl_AppInit(interp)
92 Tcl_Interp *interp; /* Interpreter for application. */
93{
94
95 if (Tcl_Init(interp) == TCL_ERROR) {
96 return TCL_ERROR;
97 }
98 if (Tk_Init(interp) == TCL_ERROR) {
99 return TCL_ERROR;
100 }
101
102 /* setup specific to pd-gui: */
103
104 pdgui_startup(interp);
105
106 /*
107 * Specify a user-specific startup file to invoke if the application
108 * is run interactively. Typically the startup file is "~/.apprc"
109 * where "app" is the name of the application. If this line is deleted
110 * then no user-specific startup file will be run under any conditions.
111 */
112
113#if 0
114 tcl_RcFileName = "~/.pdrc";
115#endif
116
117 return TCL_OK;
118}
119
120#endif /* MACOSX */
121
diff --git a/apps/plugins/pdbox/PDa/src/t_tkcmd.c b/apps/plugins/pdbox/PDa/src/t_tkcmd.c
deleted file mode 100644
index ff12a28494..0000000000
--- a/apps/plugins/pdbox/PDa/src/t_tkcmd.c
+++ /dev/null
@@ -1,398 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5#ifdef UNIX /* in unix this only works first; in NT it only works last. */
6#include "tk.h"
7#endif
8
9#include "t_tk.h"
10#include <stdlib.h>
11#include <string.h>
12#include <stdio.h>
13#include <stdarg.h>
14#include <sys/types.h>
15#ifdef UNIX
16#include <unistd.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <netdb.h>
20#ifdef HAVE_BSTRING_H
21#include <bstring.h>
22#endif
23#include <sys/time.h>
24#include <errno.h>
25#endif
26#ifdef MSW
27#include <winsock.h>
28#include <io.h>
29#endif
30#ifdef MSW
31#pragma warning( disable : 4305 ) /* uncast const double to float */
32#pragma warning( disable : 4244 ) /* uncast double to float */
33#pragma warning( disable : 4101 ) /* unused local variables */
34#endif
35
36#ifdef MSW
37#include "tk.h"
38#endif
39
40void tcl_mess(char *s);
41
42/***************** the socket setup code ********************/
43
44static int portno = 5400;
45
46 /* some installations of linux don't know about "localhost" so give
47 the loopback address; NT, on the other hand, can't understand the
48 hostname "127.0.0.1". */
49char hostname[100] =
50#ifdef __linux__
51 "127.0.0.1";
52#else
53 "localhost";
54#endif
55
56void pdgui_setsock(int port)
57{
58 portno = port;
59}
60
61void pdgui_sethost(char *name)
62{
63 strncpy(hostname, name, 100);
64 hostname[99] = 0;
65}
66
67static void pdgui_sockerror(char *s)
68{
69#ifdef MSW
70 int err = WSAGetLastError();
71#endif
72#ifdef UNIX
73 int err = errno;
74#endif
75
76 fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err);
77 tcl_mess("exit\n");
78 exit(1);
79}
80
81static int sockfd;
82
83/* The "pd_suck" command, which polls the socket.
84 FIXME: if Pd sends something bigger than SOCKSIZE we're in trouble!
85 This has to be set bigger than any array update message for instance.
86*/
87#define SOCKSIZE 20000
88
89static char pd_tkbuf[SOCKSIZE+1];
90int pd_spillbytes = 0;
91
92static void pd_readsocket(ClientData cd, int mask)
93{
94 int ngot;
95 fd_set readset, writeset, exceptset;
96 struct timeval timout;
97
98 timout.tv_sec = 0;
99 timout.tv_usec = 0;
100 FD_ZERO(&writeset);
101 FD_ZERO(&readset);
102 FD_ZERO(&exceptset);
103 FD_SET(sockfd, &readset);
104 FD_SET(sockfd, &exceptset);
105
106 if (select(sockfd+1, &readset, &writeset, &exceptset, &timout) < 0)
107 perror("select");
108 if (FD_ISSET(sockfd, &exceptset) || FD_ISSET(sockfd, &readset))
109 {
110 int ret;
111 ret = recv(sockfd, pd_tkbuf + pd_spillbytes,
112 SOCKSIZE - pd_spillbytes, 0);
113 if (ret < 0) pdgui_sockerror("socket receive error");
114 else if (ret == 0)
115 {
116 /* fprintf(stderr, "read %d\n", SOCKSIZE - pd_spillbytes); */
117 fprintf(stderr, "pd_gui: pd process exited\n");
118 tcl_mess("exit\n");
119 }
120 else
121 {
122 char *lastcr = 0, *bp = pd_tkbuf, *ep = bp + (pd_spillbytes + ret);
123 int brace = 0;
124 char lastc = 0;
125 while (bp < ep)
126 {
127 char c = *bp;
128 if (c == '}' && brace) brace--;
129 else if (c == '{') brace++;
130 else if (!brace && c == '\n' && lastc != '\\') lastcr = bp;
131 lastc = c;
132 bp++;
133 }
134 if (lastcr)
135 {
136 int xtra = pd_tkbuf + pd_spillbytes + ret - (lastcr+1);
137 char bashwas = lastcr[1];
138 lastcr[1] = 0;
139 tcl_mess(pd_tkbuf);
140 lastcr[1] = bashwas;
141 if (xtra)
142 {
143 /* fprintf(stderr, "x %d\n", xtra); */
144 memmove(pd_tkbuf, lastcr+1, xtra);
145 }
146 pd_spillbytes = xtra;
147 }
148 else
149 {
150 pd_spillbytes += ret;
151 }
152 }
153 }
154}
155
156#ifndef UNIX
157 /* if we aren't UNIX, we add a tcl command to poll the
158 socket for data. */
159static int pd_pollsocketCmd(ClientData cd, Tcl_Interp *interp,
160 int argc, char **argv)
161{
162 pd_readsocket(cd, 0);
163 return (TCL_OK);
164}
165#endif
166
167void pdgui_setupsocket(void)
168{
169 struct sockaddr_in server;
170 struct hostent *hp;
171#ifdef UNIX
172 int retry = 10;
173#else
174 int retry = 1;
175#endif
176#ifdef MSW
177 short version = MAKEWORD(2, 0);
178 WSADATA nobby;
179
180 if (WSAStartup(version, &nobby)) pdgui_sockerror("setup");
181#endif
182
183 /* create a socket */
184 sockfd = socket(AF_INET, SOCK_STREAM, 0);
185 if (sockfd < 0) pdgui_sockerror("socket");
186
187 /* connect socket using hostname provided in command line */
188 server.sin_family = AF_INET;
189
190 hp = gethostbyname(hostname);
191
192 if (hp == 0)
193 {
194 fprintf(stderr,
195 "localhost not found (inet protocol not installed?)\n");
196 exit(1);
197 }
198 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
199
200 /* assign client port number */
201 server.sin_port = htons((unsigned short)portno);
202
203 /* try to connect */
204 while (1)
205 {
206 if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) >= 0)
207 goto gotit;
208 retry--;
209 if (retry <= 0)
210 break;
211 /* In UNIX there's a race condition; the child won't be
212 able to connect before the parent (pd) has shed its
213 setuid-ness. In case this is the problem, sleep and
214 retry. */
215 else
216 {
217#ifdef UNIX
218 fd_set readset, writeset, exceptset;
219 struct timeval timout;
220
221 timout.tv_sec = 0;
222 timout.tv_usec = 100000;
223 FD_ZERO(&writeset);
224 FD_ZERO(&readset);
225 FD_ZERO(&exceptset);
226 fprintf(stderr, "retrying connect...\n");
227 if (select(1, &readset, &writeset, &exceptset, &timout) < 0)
228 perror("select");
229#endif /* UNIX */
230 }
231 }
232 pdgui_sockerror("connecting stream socket");
233gotit: ;
234#ifdef UNIX
235 /* in unix we ask TK to call us back. In NT we have to poll. */
236 Tk_CreateFileHandler(sockfd, TK_READABLE | TK_EXCEPTION,
237 pd_readsocket, 0);
238#endif /* UNIX */
239}
240
241/**************************** commands ************************/
242static char *pdgui_path;
243
244/* The "pd" command, which cats its args together and throws the result
245* at the Pd interpreter.
246*/
247#define MAXWRITE 1024
248
249static int pdCmd(ClientData cd, Tcl_Interp *interp, int argc, char **argv)
250{
251 if (argc == 2)
252 {
253 int n = strlen(argv[1]);
254 if (send(sockfd, argv[1], n, 0) < n)
255 {
256 perror("stdout");
257 tcl_mess("exit\n");
258 }
259 }
260 else
261 {
262 int i;
263 char buf[MAXWRITE];
264 buf[0] = 0;
265 for (i = 1; i < argc; i++)
266 {
267 if (strlen(argv[i]) + strlen(buf) + 2 > MAXWRITE)
268 {
269 interp->result = "pd: arg list too long";
270 return (TCL_ERROR);
271 }
272 if (i > 1) strcat(buf, " ");
273 strcat(buf, argv[i]);
274 }
275 if (send(sockfd, buf, strlen(buf), 0) < 0)
276 {
277 perror("stdout");
278 tcl_mess("exit\n");
279 }
280 }
281 return (TCL_OK);
282}
283
284/*********** "c" level access to tk functions. ******************/
285
286static Tcl_Interp *tk_myinterp;
287
288void tcl_mess(char *s)
289{
290 int result;
291 result = Tcl_Eval(tk_myinterp, s);
292 if (result != TCL_OK)
293 {
294 if (*tk_myinterp->result) printf("%s\n", tk_myinterp->result);
295 }
296}
297
298/* LATER should do a bounds check -- but how do you get printf to do that? */
299void tcl_vmess(char *fmt, ...)
300{
301 int result, i;
302 char buf[MAXWRITE];
303 va_list ap;
304
305 va_start(ap, fmt);
306
307 vsprintf(buf, fmt, ap);
308 result = Tcl_Eval(tk_myinterp, buf);
309 if (result != TCL_OK)
310 {
311 if (*tk_myinterp->result) printf("%s\n", tk_myinterp->result);
312 }
313 va_end(ap);
314}
315
316#ifdef UNIX
317void pdgui_doevalfile(Tcl_Interp *interp, char *s)
318{
319 char buf[GUISTRING];
320 sprintf(buf, "set pd_guidir \"%s\"\n", pdgui_path);
321 tcl_mess(buf);
322 strcpy(buf, pdgui_path);
323 strcat(buf, "/bin/");
324 strcat(buf, s);
325 if (Tcl_EvalFile(interp, buf) != TCL_OK)
326 {
327 char buf2[1000];
328 sprintf(buf2, "puts [concat tcl: %s: can't open script]\n",
329 buf);
330 tcl_mess(buf2);
331 }
332}
333
334void pdgui_evalfile(char *s)
335{
336 pdgui_doevalfile(tk_myinterp, s);
337}
338#endif
339
340void pdgui_startup(Tcl_Interp *interp)
341{
342
343 /* save pointer to the main interpreter */
344 tk_myinterp = interp;
345
346
347 /* add our own TK commands */
348 Tcl_CreateCommand(interp, "pd", (Tcl_CmdProc*)pdCmd, (ClientData)NULL,
349 (Tcl_CmdDeleteProc *)NULL);
350#ifndef UNIX
351 Tcl_CreateCommand(interp, "pd_pollsocket",(Tcl_CmdProc*) pd_pollsocketCmd,
352 (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
353#endif
354 pdgui_setupsocket();
355
356 /* read in the startup file */
357#if !defined(MSW) && !defined(MACOSX)
358 pdgui_evalfile("pd.tk");
359#endif
360}
361
362#ifdef UNIX
363void pdgui_setname(char *s)
364{
365 char *t;
366 char *str;
367 int n;
368 if (t = strrchr(s, '/')) str = s, n = (t-s) + 1;
369 else str = "./", n = 2;
370 if (n > GUISTRING-100) n = GUISTRING-100;
371 pdgui_path = malloc(n+9);
372
373 strncpy(pdgui_path, str, n);
374 while (strlen(pdgui_path) > 0 && pdgui_path[strlen(pdgui_path)-1] == '/')
375 pdgui_path[strlen(pdgui_path)-1] = 0;
376 if (t = strrchr(pdgui_path, '/'))
377 *t = 0;
378}
379#endif
380
381int Pdtcl_Init(Tcl_Interp *interp)
382{
383 const char *myvalue = Tcl_GetVar(interp, "argv", 0);
384 int myportno;
385 if (myvalue && (myportno = atoi(myvalue)) > 1)
386 pdgui_setsock(myportno);
387 tk_myinterp = interp;
388 pdgui_startup(interp);
389 interp->result = "loaded pdtcl_init";
390
391 return (TCL_OK);
392}
393
394int Pdtcl_SafeInit(Tcl_Interp *interp) {
395 fprintf(stderr, "Pdtcl_Safeinit 51\n");
396 return (TCL_OK);
397}
398
diff --git a/apps/plugins/pdbox/PDa/src/u_main.tk b/apps/plugins/pdbox/PDa/src/u_main.tk
deleted file mode 100644
index e8d5702f32..0000000000
--- a/apps/plugins/pdbox/PDa/src/u_main.tk
+++ /dev/null
@@ -1,3368 +0,0 @@
1set pd_nt 1
2# (The above is 0 for unix, 1 for microsoft, and 2 for Mac OSX. The first
3# line is automatically munged by the relevant makefiles.)
4
5# Copyright (c) 1997-1999 Miller Puckette.
6# For information on usage and redistribution, and for a DISCLAIMER OF ALL
7# WARRANTIES, see the file, "LICENSE.txt," in this distribution.
8
9# changed by Thomas Musil 09.2001
10# between "pdtk_graph_dialog -- dialog window for graphs"
11# and "pdtk_array_dialog -- dialog window for arrays"
12# a new dialogbox was inserted, named:
13# "pdtk_iemgui_dialog -- dialog window for iem guis"
14#
15# all this changes are labeled with #######iemlib##########
16
17# Tearoff is set to true by default:
18set pd_tearoff 0
19set menubar 1
20
21set File "F"
22set Windows "W"
23set Edit "E"
24set Find "F"
25set Put "P"
26set Media "M"
27set Help "H"
28
29set color grey16
30set lightcolor grey24
31
32option add *font -*-helvetica-*--bold--9-*
33
34# los colores de la muerte
35
36option add *background $color
37option add *activeBackground $lightcolor
38
39option add *foreground white
40option add *activeForeground white
41
42option add *troughColor $lightcolor
43
44option add *highlightThickness 0
45option add *relief solid startupFile
46
47if {$pd_nt == 1} {
48 global pd_guidir
49 global pd_tearoff
50 set pd_gui2 [string range $argv0 0 [expr [string last \\ $argv0 ] - 1]]
51 regsub -all \\\\ $pd_gui2 / pd_gui3
52 set pd_guidir $pd_gui3/..
53 load $pd_guidir/bin/pdtcl
54 set pd_tearoff 1
55}
56
57if {$pd_nt == 2} {
58 global pd_guidir
59 global pd_tearoff
60 set pd_gui2 [string range $argv0 0 [expr [string last / $argv0 ] - 1]]
61 set pd_guidir $pd_gui2/..
62 load $pd_guidir/bin/pdtcl
63 set pd_tearoff 0
64}
65
66# hack so you can easily test-run this script in linux... define pd_guidir
67# (which is normally defined at startup in pd under linux...)
68
69if {$pd_nt == 0} {
70 if {! [info exists pd_guidir]} {
71 global pd_guidir
72 puts stderr {setting pd_guidir to '.'}
73 set pd_guidir .
74 }
75}
76
77# it's unfortunate but we seem to have to turn off global bindings
78# for Text objects to get control-s and control-t to do what we want for
79# "text" dialogs below. Also we have to get rid of tab's changing the focus.
80
81bind all <Key-Tab> ""
82bind all <<PrevWindow>> ""
83bind Text <Control-t> {}
84bind Text <Control-s> {}
85# puts stderr [bind all]
86
87################## set up main window #########################
88menu .mbar
89canvas .dummy -height 2p -width 6c
90
91frame .controls
92pack .controls .dummy -side top -fill x
93menu .mbar.file -tearoff $pd_tearoff
94.mbar add cascade -label "$File" -menu .mbar.file
95menu .mbar.find -tearoff $pd_tearoff
96.mbar add cascade -label "$Find" -menu .mbar.find
97menu .mbar.windows -postcommand [concat pdtk_fixwindowmenu] -tearoff $pd_tearoff
98menu .mbar.audio -tearoff $pd_tearoff
99if {$pd_nt != 2} {
100 .mbar add cascade -label "$Windows" -menu .mbar.windows
101 .mbar add cascade -label "$Media" -menu .mbar.audio
102} else {
103# Perhaps this is silly, but Mac HIG want "Window Help" as the last menus
104 .mbar add cascade -label "$Media" -menu .mbar.audio
105 .mbar add cascade -label "$Windows" -menu .mbar.windows
106}
107menu .mbar.help -tearoff $pd_tearoff
108.mbar add cascade -label "$Help" -menu .mbar.help
109
110set ctrls_audio_on 0
111set ctrls_meter_on 0
112set ctrls_inlevel 0
113set ctrls_outlevel 0
114
115frame .controls.switches
116checkbutton .controls.switches.audiobutton -text {compute audio} \
117 -variable ctrls_audio_on \
118 -anchor w \
119 -command {pd [concat pd dsp $ctrls_audio_on \;]}
120
121checkbutton .controls.switches.meterbutton -text {peak meters} \
122 -variable ctrls_meter_on \
123 -anchor w \
124 -command {pd [concat pd meters $ctrls_meter_on \;]}
125
126pack .controls.switches.meterbutton .controls.switches.audiobutton -side left
127
128frame .controls.inout
129frame .controls.inout.in
130label .controls.inout.in.label -text IN
131entry .controls.inout.in.level -textvariable ctrls_inlevel -width 3
132button .controls.inout.in.clip -text {CLIP} -state disabled
133pack .controls.inout.in.label .controls.inout.in.level \
134 .controls.inout.in.clip -side top -pady 2
135
136frame .controls.inout.out
137label .controls.inout.out.label -text OUT
138entry .controls.inout.out.level -textvariable ctrls_outlevel -width 3
139button .controls.inout.out.clip -text {CLIP} -state disabled
140pack .controls.inout.out.label .controls.inout.out.level \
141 .controls.inout.out.clip -side top -pady 2
142
143button .controls.dio -text "DIO\nerrors" \
144 -command {pd [concat pd audiostatus \;]}
145
146pack .controls.switches -side bottom -pady 12
147pack .controls.inout.in .controls.inout.out -side left -padx 6
148pack .controls.inout -side left -padx 14
149pack .controls.dio -side right -padx 20
150
151bind . <Control-Key> {pdtk_pd_ctrlkey %W %K 0}
152bind . <Control-Shift-Key> {pdtk_pd_ctrlkey %W %K 1}
153if {$pd_nt == 2} {
154 bind . <Mod1-Key> {pdtk_canvas_ctrlkey %W %K 0}
155 bind . <Mod1-Shift-Key> {pdtk_canvas_ctrlkey %W %K 1}
156}
157
158
159wm title . "PDa"
160. configure -menu .mbar -width 200 -height 150
161
162############### set up global variables ################################
163
164set untitled_number 1
165set untitled_directory [pwd]
166set saveas_client doggy
167set pd_opendir $untitled_directory
168set pd_undoaction no
169set pd_redoaction no
170set pd_undocanvas no
171
172################ utility functions #########################
173
174proc pdtk_enquote {x} {
175 set foo [string map {"," "" ";" "" \" ""} $x]
176 set foo2 [string map {" " "\\ "} $foo]
177 concat $foo2
178}
179
180proc pdtk_debug {x} {
181 tk_messageBox -message $x -type ok
182}
183
184proc pdtk_watchdog {} {
185 pd [concat pd ping \;]
186 after 2000 {pdtk_watchdog}
187}
188
189proc pdtk_check {x message} {
190 set answer [tk_messageBox \-message $x \-type yesno \-icon question]
191 switch $answer {
192 yes {pd $message} }
193# no {tk_messageBox \-message "cancelled" \-type ok}
194}
195
196set menu_windowlist {}
197
198proc pdtk_fixwindowmenu {} {
199 global menu_windowlist
200 .mbar.windows delete 0 end
201 foreach i $menu_windowlist {
202 .mbar.windows add command -label [lindex $i 0] \
203 -command [concat menu_domenuwindow [lindex $i 1]]
204 menu_fixwindowmenu [lindex $i 1]
205 }
206}
207
208####### Odd little function to make better Mac accelerators #####
209
210proc accel_munge {acc} {
211 global pd_nt
212
213 if {$pd_nt == 2} {
214 if [string is upper [string index $acc end]] {
215 return [format "%s%s" "Shift+" \
216 [string toupper [string map {Ctrl Meta} $acc] end]]
217 } else {
218 return [string toupper [string map {Ctrl Meta} $acc] end]
219 }
220 } else {
221 return $acc
222 }
223}
224
225
226
227############### the "New" menu command ########################
228proc menu_new {} {
229 global untitled_number
230 global untitled_directory
231 pd [concat pd filename Untitled-$untitled_number $untitled_directory \;]
232 pd {
233 #N canvas;
234 #X pop 1;
235 }
236 set untitled_number [expr $untitled_number + 1]
237}
238
239################## the "Open" menu command #########################
240
241proc menu_open {} {
242 global pd_opendir
243
244 set filename [tk_getOpenFile -defaultextension .pd \
245 -filetypes { {{pd files} {.pd}} {{max files} {.pat}}} \
246 -initialdir $pd_opendir]
247
248 if {$filename != ""} {
249 set directory [string range $filename 0 \
250 [expr [string last / $filename ] - 1]]
251 set pd_opendir $directory
252 set basename [string range $filename \
253 [expr [string last / $filename ] + 1] end]
254
255# pd_debug [concat file $filename base $basename dir $directory]
256
257 pd [concat pd open [pdtk_enquote $basename] \
258 [pdtk_enquote $directory]\;]
259 }
260}
261
262################## the "Message" menu command #########################
263proc menu_send {} {
264 toplevel .sendpanel
265 entry .sendpanel.entry -textvariable send_textvariable
266 pack .sendpanel.entry -side bottom -fill both -ipadx 100
267 .sendpanel.entry select from 0
268 .sendpanel.entry select adjust end
269 bind .sendpanel.entry <KeyPress-Return> {
270 pd [concat $send_textvariable \;]
271 after 50 {destroy .sendpanel}
272 }
273 focus .sendpanel.entry
274}
275
276################## the "Quit" menu command #########################
277proc menu_really_quit {} {pd {pd quit;}}
278
279proc menu_quit {} {pd {pd quit;}}
280
281######### the "Pd" menu command, which puts the Pd window on top ########
282proc menu_pop_pd {} {raise .}
283
284######### the "audio" menu command ###############
285proc menu_audio {flag} {pd [concat pd dsp $flag \;]}
286
287######### the "documentation" menu command ###############
288
289set doc_number 1
290
291proc menu_opentext {filename} {
292 global doc_number
293 global pd_guidir
294 global pd_myversion
295 set name [format ".help%d" $doc_number]
296 toplevel $name
297 text $name.text -fg black -relief raised -bd 2 -font -*-courier-bold--normal--12-* \
298 -yscrollcommand "$name.scroll set" -background white
299 scrollbar $name.scroll -command "$name.text yview"
300 pack $name.scroll -side right -fill y
301 pack $name.text -side left -fill both -expand 1
302
303 set f [open $filename]
304 while {![eof $f]} {
305 set bigstring [read $f 1000]
306 regsub -all PD_BASEDIR $bigstring $pd_guidir bigstring2
307 regsub -all PD_VERSION $bigstring2 $pd_myversion bigstring3
308 $name.text insert end $bigstring3
309 }
310 close $f
311 set doc_number [expr $doc_number + 1]
312}
313
314set help_directory $pd_guidir/doc
315
316proc menu_documentation {} {
317 global help_directory
318 global pd_nt
319
320 set filename [tk_getOpenFile -defaultextension .pd \
321 -filetypes { {{documentation} {.pd .txt .htm}} } \
322 -initialdir $help_directory]
323
324 if {$filename != ""} {
325 if {[string first .txt $filename] >= 0} {
326 menu_opentext $filename
327 } elseif {[string first .htm $filename] >= 0} {
328 if {$pd_nt == 0} {
329 exec sh -c \
330 [format "mozilla file:%s || netscape file:%s &\n" \
331 $filename $filename]
332 } elseif {$pd_nt == 2} {
333 puts stderr [format "open %s" $filename]
334 exec sh -c \
335 [format "open %s" $filename]
336 } else {
337 exec rundll32 url.dll,FileProtocolHandler \
338 [format "file:%s" $filename] &
339 }
340 } else {
341 set help_directory [string range $filename 0 \
342 [expr [string last / $filename ] - 1]]
343 set basename [string range $filename \
344 [expr [string last / $filename ] + 1] end]
345 pd [concat pd open [pdtk_enquote $basename] \
346 [pdtk_enquote $help_directory] \;]
347 }
348 }
349}
350
351proc menu_doc_open {subdir basename} {
352 global pd_guidir
353
354 set dirname $pd_guidir/$subdir
355
356 if {[string first .txt $basename] >= 0} {
357 menu_opentext $dirname/$basename
358 } else {
359 pd [concat pd open [pdtk_enquote $basename] \
360 [pdtk_enquote $dirname] \;]
361 }
362}
363
364############# routine to add audio and help menus ###############
365
366proc menu_addstd {mbar} {
367 global pd_apilist
368# the "Audio" menu
369 $mbar.audio add command -label {audio ON} -accelerator [accel_munge "Ctrl+/"] \
370 -command {menu_audio 1}
371 $mbar.audio add command -label {audio OFF} -accelerator [accel_munge "Ctrl+."] \
372 -command {menu_audio 0}
373 for {set x 0} {$x<[llength $pd_apilist]} {incr x} {
374 $mbar.audio add radiobutton -label [lindex [lindex $pd_apilist $x] 0] \
375 -command {menu_audio 0} -variable pd_whichapi \
376 -value [lindex [lindex $pd_apilist $x] 1]\
377 -command {pd [concat pd audio-setapi $pd_whichapi \;]}
378 }
379 $mbar.audio add command -label {Audio settings...} \
380 -command {pd pd audio-properties \;}
381
382 $mbar.audio add command -label {MIDI settings...} \
383 -command {pd pd midi-properties \;}
384 $mbar.audio add command -label {Test Audio and MIDI} \
385 -command {menu_doc_open doc/7.stuff/tools testtone.pd}
386 $mbar.audio add command -label {Load Meter} \
387 -command {menu_doc_open doc/7.stuff/tools load-meter.pd}
388
389
390 $mbar.audio add checkbutton -label "Show Menubar" \
391 -indicatoron true -selectcolor grey85 \
392 -variable menubar
393
394# the "Help" menu
395 $mbar.help add command -label {About Pd} \
396 -command {menu_doc_open doc/1.manual 1.introduction.txt}
397 $mbar.help add command -label {Pure Documentation...} \
398 -command {menu_documentation}
399}
400
401#################### the "File" menu for the Pd window ##############
402
403.mbar.file add command -label New -command {menu_new} \
404 -accelerator [accel_munge "Ctrl+n"]
405.mbar.file add command -label Open -command {menu_open} \
406 -accelerator [accel_munge "Ctrl+o"]
407.mbar.file add separator
408.mbar.file add command -label Message -command {menu_send} \
409 -accelerator [accel_munge "Ctrl+m"]
410.mbar.file add command -label Path... \
411 -command {pd pd start-path-dialog \;}
412.mbar.file add separator
413.mbar.file add command -label Quit -command {menu_quit} \
414 -accelerator [accel_munge "Ctrl+q"]
415
416#################### the "Find" menu for the Pd window ##############
417.mbar.find add command -label {last error?} -command {menu_finderror}
418
419########### functions for menu functions on document windows ########
420
421proc menu_save {name} {
422 pdtk_canvas_checkgeometry $name
423 pd [concat $name menusave \;]
424}
425
426proc menu_saveas {name} {
427 pdtk_canvas_checkgeometry $name
428 pd [concat $name menusaveas \;]
429}
430
431proc menu_print {name} {
432 set filename [tk_getSaveFile -initialfile pd.ps \
433 -defaultextension .ps \
434 -filetypes { {{postscript} {.ps}} }]
435
436 if {$filename != ""} {
437 $name.c postscript -file $filename
438 }
439}
440
441proc menu_close {name} {
442 pd [concat $name menuclose \;]
443}
444
445proc menu_undo {name} {
446 global pd_undoaction
447 global pd_redoaction
448 global pd_undocanvas
449 if {$name == $pd_undocanvas && $pd_undoaction != "no"} {
450 pd [concat $name undo \;]
451 }
452}
453
454proc menu_redo {name} {
455 global pd_undoaction
456 global pd_redoaction
457 global pd_undocanvas
458 if {$name == $pd_undocanvas && $pd_redoaction != "no"} {
459 pd [concat $name redo \;]
460 }
461}
462
463proc menu_cut {name} {
464 pd [concat $name cut \;]
465}
466
467proc menu_copy {name} {
468 pd [concat $name copy \;]
469}
470
471proc menu_paste {name} {
472 pd [concat $name paste \;]
473}
474
475proc menu_duplicate {name} {
476 pd [concat $name duplicate \;]
477}
478
479proc menu_selectall {name} {
480 pd [concat $name selectall \;]
481}
482
483proc menu_texteditor {name} {
484 pd [concat $name texteditor \;]
485}
486
487proc menu_font {name} {
488 pd [concat $name menufont \;]
489}
490
491proc menu_tidyup {name} {
492 pd [concat $name tidy \;]
493}
494
495proc menu_editmode {name} {
496 pd [concat $name editmode 0 \;]
497}
498
499proc menu_object {name accel} {
500 pd [concat $name obj $accel \;]
501}
502
503proc menu_message {name accel} {
504 pd [concat $name msg $accel \;]
505}
506
507proc menu_floatatom {name accel} {
508 pd [concat $name floatatom $accel \;]
509}
510
511proc menu_symbolatom {name accel} {
512 pd [concat $name symbolatom $accel \;]
513}
514
515proc menu_comment {name accel} {
516 pd [concat $name text $accel \;]
517}
518
519proc menu_graph {name} {
520 pd [concat $name graph \;]
521}
522
523proc menu_array {name} {
524 pd [concat $name menuarray \;]
525}
526
527############iemlib##################
528proc menu_bng {name accel} {
529 pd [concat $name bng $accel \;]
530}
531
532proc menu_toggle {name accel} {
533 pd [concat $name toggle $accel \;]
534}
535
536proc menu_numbox {name accel} {
537 pd [concat $name numbox $accel \;]
538}
539
540proc menu_vslider {name accel} {
541 pd [concat $name vslider $accel \;]
542}
543
544proc menu_hslider {name accel} {
545 pd [concat $name hslider $accel \;]
546}
547
548proc menu_hradio {name accel} {
549 pd [concat $name hradio $accel \;]
550}
551
552proc menu_vradio {name accel} {
553 pd [concat $name vradio $accel \;]
554}
555
556proc menu_vumeter {name accel} {
557 pd [concat $name vumeter $accel \;]
558}
559
560proc menu_mycnv {name accel} {
561 pd [concat $name mycnv $accel \;]
562}
563
564############iemlib##################
565
566# correct edit menu, enabling or disabling undo/redo
567# LATER also cut/copy/paste
568proc menu_fixeditmenu {name} {
569 global pd_undoaction
570 global pd_redoaction
571 global pd_undocanvas
572# puts stderr [concat menu_fixeditmenu $name $pd_undocanvas $pd_undoaction]
573 if {$name == $pd_undocanvas && $pd_undoaction != "no"} {
574 $name.m.edit entryconfigure "Undo*" -state normal \
575 -label [concat "Undo " $pd_undoaction]
576 } else {
577 $name.m.edit entryconfigure "Undo*" -state disabled -label "Undo"
578 }
579 if {$name == $pd_undocanvas && $pd_redoaction != "no"} {
580 $name.m.edit entryconfigure "Redo*" -state normal\
581 -label [concat "Redo " $pd_redoaction]
582 } else {
583 $name.m.edit entryconfigure "Redo*" -state disabled
584 }
585}
586
587# message from Pd to update the currently available undo/redo action
588proc pdtk_undomenu {name undoaction redoaction} {
589 global pd_undoaction
590 global pd_redoaction
591 global pd_undocanvas
592# puts stderr [concat pdtk_undomenu $name $undoaction $redoaction]
593 set pd_undocanvas $name
594 set pd_undoaction $undoaction
595 set pd_redoaction $redoaction
596 if {$name != "nobody"} {
597# unpleasant way of avoiding a more unpleasant bug situation --atl 2002.11.25
598 menu_fixeditmenu $name
599 }
600}
601
602proc menu_windowparent {name} {
603 pd [concat $name findparent \;]
604}
605
606proc menu_findagain {name} {
607 pd [concat $name findagain \;]
608}
609
610proc menu_finderror {} {
611 pd [concat pd finderror \;]
612}
613
614proc menu_domenuwindow {i} {
615 raise $i
616}
617
618proc menu_fixwindowmenu {name} {
619 global menu_windowlist
620 global pd_tearoff
621 global menubar
622
623 if { $menubar == 1 } {
624 $name.m.windows add command
625 if $pd_tearoff {
626 $name.m.windows delete 4 end
627 } else {
628 $name.m.windows delete 3 end
629 }
630 foreach i $menu_windowlist {
631 $name.m.windows add command -label [lindex $i 0] \
632 -command [concat menu_domenuwindow [lindex $i 1]]
633 }
634 }
635}
636
637################## the "find" menu item ###################
638
639set find_canvas nobody
640set find_string ""
641set find_count 1
642
643proc find_apply {name} {
644 global find_string
645 global find_canvas
646 regsub -all \; $find_string " _semi_ " find_string2
647 regsub -all \, $find_string2 " _comma_ " find_string3
648# puts stderr [concat $find_canvas find $find_string3 \
649# \;]
650 pd [concat $find_canvas find $find_string3 \
651 \;]
652 after 50 destroy $name
653}
654
655proc find_cancel {name} {
656 after 50 destroy $name
657}
658
659proc menu_findobject {canvas} {
660 global find_string
661 global find_canvas
662 global find_count
663
664 set name [format ".find%d" $find_count]
665 set find_count [expr $find_count + 1]
666
667 set find_canvas $canvas
668
669 toplevel $name
670
671 label $name.label -text {find...}
672 pack $name.label -side top
673
674 entry $name.entry -textvariable find_string
675 pack $name.entry -side top
676
677 frame $name.buttonframe
678 pack $name.buttonframe -side bottom -fill x -pady 2m
679 button $name.buttonframe.cancel -text {Cancel}\
680 -command "find_cancel $name"
681 button $name.buttonframe.ok -text {OK}\
682 -command "find_apply $name"
683 pack $name.buttonframe.cancel -side left -expand 1
684 pack $name.buttonframe.ok -side left -expand 1
685
686 $name.entry select from 0
687 $name.entry select adjust end
688 bind $name.entry <KeyPress-Return> [ concat find_apply $name]
689 focus $name.entry
690}
691
692
693
694proc pdtk_canvas_menubar {name width height geometry editable} {
695 global pd_opendir
696 global pd_tearoff
697 global pd_nt
698
699 global File Edit Find Put Windows Media Help
700
701
702 menu $name.m.file -tearoff $pd_tearoff
703 $name.m add cascade -label "$File" -menu $name.m.file
704
705 $name.m.file add command -label New -command {menu_new} \
706 -accelerator [accel_munge "Ctrl+n"]
707
708 $name.m.file add command -label Open -command {menu_open} \
709 -accelerator [accel_munge "Ctrl+o"]
710
711 $name.m.file add separator
712 $name.m.file add command -label Message -command {menu_send} \
713 -accelerator [accel_munge "Ctrl+m"]
714
715 $name.m.file add command -label Path... \
716 -command {pd pd start-path-dialog \;}
717
718 $name.m.file add separator
719 $name.m.file add command -label Close \
720 -command [concat menu_close $name] \
721 -accelerator [accel_munge "Ctrl+w"]
722
723 $name.m.file add command -label Save -command [concat menu_save $name] \
724 -accelerator [accel_munge "Ctrl+s"]
725
726 $name.m.file add command -label "Save as..." \
727 -command [concat menu_saveas $name] \
728 -accelerator [accel_munge "Ctrl+S"]
729
730 $name.m.file add command -label Print -command [concat menu_print $name] \
731 -accelerator [accel_munge "Ctrl+p"]
732
733 $name.m.file add separator
734
735 $name.m.file add command -label Quit -command {menu_quit} \
736 -accelerator [accel_munge "Ctrl+q"]
737
738# the edit menu
739 menu $name.m.edit -postcommand [concat menu_fixeditmenu $name] -tearoff $pd_tearoff
740 $name.m add cascade -label $Edit -menu $name.m.edit
741
742 $name.m.edit add command -label Undo -command [concat menu_undo $name] \
743 -accelerator [accel_munge "Ctrl+z"]
744
745 $name.m.edit add command -label Redo -command [concat menu_redo $name] \
746 -accelerator [accel_munge "Ctrl+Z"]
747
748 $name.m.edit add separator
749
750 $name.m.edit add command -label Cut -command [concat menu_cut $name] \
751 -accelerator [accel_munge "Ctrl+x"]
752
753 $name.m.edit add command -label Copy -command [concat menu_copy $name] \
754 -accelerator [accel_munge "Ctrl+c"]
755
756 $name.m.edit add command -label Paste \
757 -command [concat menu_paste $name] \
758 -accelerator [accel_munge "Ctrl+v"]
759
760 $name.m.edit add command -label Duplicate \
761 -command [concat menu_duplicate $name] \
762 -accelerator [accel_munge "Ctrl+d"]
763
764 $name.m.edit add command -label {Select all} \
765 -command [concat menu_selectall $name] \
766 -accelerator [accel_munge "Ctrl+a"]
767
768 $name.m.edit add separator
769
770 $name.m.edit add command -label {Text Editor} \
771 -command [concat menu_texteditor $name] \
772 -accelerator [accel_munge "Ctrl+t"]
773
774 $name.m.edit add command -label Font \
775 -command [concat menu_font $name]
776
777 $name.m.edit add command -label {Tidy Up} \
778 -command [concat menu_tidyup $name]
779
780 $name.m.edit add separator
781
782############iemlib##################
783# instead of "red = #BC3C60" we take "grey85", so there is no difference,
784# if widget is selected or not.
785
786 $name.m.edit add checkbutton -label "Edit mode" \
787 -indicatoron true -selectcolor grey85 \
788 -command [concat menu_editmode $name] \
789 -accelerator [accel_munge "Ctrl+e"]
790
791 if { $editable == 0 } {
792 $name.m.edit entryconfigure "Edit mode" -indicatoron false }
793
794############iemlib##################
795
796# the put menu
797 menu $name.m.put -tearoff $pd_tearoff
798 $name.m add cascade -label $Put -menu $name.m.put
799
800 $name.m.put add command -label Object \
801 -command [concat menu_object $name 0] \
802 -accelerator [accel_munge "Ctrl+1"]
803
804 $name.m.put add command -label Message \
805 -command [concat menu_message $name 0] \
806 -accelerator [accel_munge "Ctrl+2"]
807
808 $name.m.put add command -label Number \
809 -command [concat menu_floatatom $name 0] \
810 -accelerator [accel_munge "Ctrl+3"]
811
812 $name.m.put add command -label Symbol \
813 -command [concat menu_symbolatom $name 0] \
814 -accelerator [accel_munge "Ctrl+4"]
815
816 $name.m.put add command -label Comment \
817 -command [concat menu_comment $name 0] \
818 -accelerator [accel_munge "Ctrl+5"]
819
820 $name.m.put add separator
821
822############iemlib##################
823
824 $name.m.put add command -label Bang \
825 -command [concat menu_bng $name 0] \
826 -accelerator [accel_munge "Alt+b"]
827
828 $name.m.put add command -label Toggle \
829 -command [concat menu_toggle $name 0] \
830 -accelerator [accel_munge "Alt+t"]
831
832 $name.m.put add command -label Number2 \
833 -command [concat menu_numbox $name 0] \
834 -accelerator [accel_munge "Alt+n"]
835
836 $name.m.put add command -label Vslider \
837 -command [concat menu_vslider $name 0] \
838 -accelerator [accel_munge "Alt+v"]
839
840 $name.m.put add command -label Hslider \
841 -command [concat menu_hslider $name 0] \
842 -accelerator [accel_munge "Alt+h"]
843
844 $name.m.put add command -label Vradio \
845 -command [concat menu_vradio $name 0] \
846 -accelerator [accel_munge "Alt+d"]
847
848 $name.m.put add command -label Hradio \
849 -command [concat menu_hradio $name 0] \
850 -accelerator [accel_munge "Alt+i"]
851
852 $name.m.put add command -label VU \
853 -command [concat menu_vumeter $name 0] \
854 -accelerator [accel_munge "Alt+u"]
855
856 $name.m.put add command -label Canvas \
857 -command [concat menu_mycnv $name 0] \
858 -accelerator [accel_munge "Alt+c"]
859
860############iemlib##################
861
862 $name.m.put add separator
863
864 $name.m.put add command -label Graph \
865 -command [concat menu_graph $name]
866
867 $name.m.put add command -label Array \
868 -command [concat menu_array $name]
869
870# the find menu
871 menu $name.m.find -tearoff $pd_tearoff
872 $name.m add cascade -label "$Find" -menu $name.m.find
873
874 $name.m.find add command -label {Find...} \
875 -accelerator [accel_munge "Ctrl+f"] \
876 -command [concat menu_findobject $name]
877 $name.m.find add command -label {Find Again} \
878 -accelerator [accel_munge "Ctrl+g"] \
879 -command [concat menu_findagain $name]
880 $name.m.find add command -label {Find last error} \
881 -command [concat menu_finderror]
882
883# the window menu
884 menu $name.m.windows -postcommand [concat menu_fixwindowmenu $name] \
885 -tearoff $pd_tearoff
886
887 $name.m.windows add command -label {parent window}\
888 -command [concat menu_windowparent $name]
889 $name.m.windows add command -label {Pd window} -command menu_pop_pd
890 $name.m.windows add separator
891
892# the audio menu
893 menu $name.m.audio -tearoff $pd_tearoff
894
895 if {$pd_nt != 2} {
896 $name.m add cascade -label $Windows -menu $name.m.windows
897 $name.m add cascade -label $Media -menu $name.m.audio
898 } else {
899 $name.m add cascade -label $Media -menu $name.m.audio
900 $name.m add cascade -label $Windows -menu $name.m.windows
901 }
902
903# the help menu
904 menu $name.m.help -tearoff $pd_tearoff
905 $name.m add cascade -label $Help -menu $name.m.help
906
907 menu_addstd $name.m
908}
909
910
911############# pdtk_canvas_new -- create a new canvas ###############
912proc pdtk_canvas_new {name width height geometry editable} {
913 global pd_opendir
914 global pd_tearoff
915 global pd_nt
916 global menubar
917
918 toplevel $name -menu $name.m
919# puts stderr [concat geometry: $geometry]
920 wm geometry $name $geometry
921 wm minsize $name 1 1
922
923 canvas $name.c -width $width -height $height -background white \
924 -yscrollcommand "$name.scrollvert set" \
925 -xscrollcommand "$name.scrollhort set" \
926 -scrollregion [concat 0 0 $width $height]
927
928
929 scrollbar $name.scrollvert -command "$name.c yview" -width 7
930 scrollbar $name.scrollhort -command "$name.c xview" \
931 -orient horizontal -width 7
932
933 pack $name.scrollhort -side bottom -fill x
934 pack $name.scrollvert -side right -fill y
935 pack $name.c -side left -expand 1 -fill both
936
937# the menubar
938
939 menu $name.m
940
941 if { $menubar == 1 } {
942 pdtk_canvas_menubar $name $width $height $geometry $editable
943 }
944
945# the popup menu
946 menu $name.popup -tearoff false
947 $name.popup add command -label {Properties} \
948 -command [concat popup_action $name 0]
949 $name.popup add command -label {Open} \
950 -command [concat popup_action $name 1]
951 $name.popup add command -label {Help} \
952 -command [concat popup_action $name 2]
953
954# WM protocol
955 wm protocol $name WM_DELETE_WINDOW [concat menu_close $name]
956
957# bindings.
958# this is idiotic -- how do you just sense what mod keys are down and
959# pass them on? I can't find it anywhere.
960# Here we encode shift as 1, control 2, alt 4, in agreement
961# with definitions in g_canvas.c. The third button gets "8" but we don't
962# bother with modifiers there.
963# We don't handle multiple clicks yet.
964
965 bind $name.c <Button> {pdtk_canvas_click %W %x %y %b 0}
966 bind $name.c <Shift-Button> {pdtk_canvas_click %W %x %y %b 1}
967 bind $name.c <Control-Shift-Button> {pdtk_canvas_click %W %x %y %b 3}
968 bind $name.c <Alt-Button> {pdtk_canvas_click %W %x %y %b 4}
969 bind $name.c <Alt-Shift-Button> {pdtk_canvas_click %W %x %y %b 5}
970 bind $name.c <Alt-Control-Button> {pdtk_canvas_click %W %x %y %b 6}
971 bind $name.c <Alt-Control-Shift-Button> {pdtk_canvas_click %W %x %y %b 7}
972 global pd_nt
973 if {$pd_nt == 2} {
974 bind $name.c <Button-2> {pdtk_canvas_click %W %x %y %b 8}
975 bind $name.c <Control-Button> {pdtk_canvas_click %W %x %y %b 8}
976 } else {
977 bind $name.c <Button-3> {pdtk_canvas_click %W %x %y %b 8}
978 bind $name.c <Control-Button> {pdtk_canvas_click %W %x %y %b 2}
979 }
980# change mac to right-click, not middle click -atl 2002.09.02
981
982 bind $name.c <ButtonRelease> {pdtk_canvas_mouseup %W %x %y %b}
983 bind $name.c <Control-Key> {pdtk_canvas_ctrlkey %W %K 0}
984 bind $name.c <Control-Shift-Key> {pdtk_canvas_ctrlkey %W %K 1}
985 bind $name.c <Alt-Key> {pdtk_canvas_altkey %W %K %A}
986# bind $name.c <Mod1-Key> {puts stderr [concat mod1 %W %K %A]}
987 if {$pd_nt == 2} {
988 bind $name.c <Mod1-Key> {pdtk_canvas_ctrlkey %W %K 0}
989 bind $name.c <Mod1-Shift-Key> {pdtk_canvas_ctrlkey %W %K 1}
990 }
991 bind $name.c <Key> {pdtk_canvas_key %W %K %A 0}
992 bind $name.c <Shift-Key> {pdtk_canvas_key %W %K %A 1}
993 bind $name.c <KeyRelease> {pdtk_canvas_keyup %W %K %A}
994 bind $name.c <Motion> {pdtk_canvas_motion %W %x %y 0}
995 bind $name.c <Alt-Motion> {pdtk_canvas_motion %W %x %y 4}
996 bind $name.c <Map> {pdtk_canvas_map %W}
997 bind $name.c <Unmap> {pdtk_canvas_unmap %W}
998 focus $name.c
999# puts stderr "all done"
1000# after 1 [concat raise $name]
1001}
1002
1003#################### event binding procedures ################
1004
1005#get the name of the toplevel window for a canvas; this is also
1006#the name of the canvas object in Pd.
1007
1008proc canvastosym {name} {
1009 string range $name 0 [expr [string length $name] - 3]
1010}
1011
1012set pdtk_lastcanvasconfigured ""
1013set pdtk_lastcanvasconfiguration ""
1014
1015proc pdtk_canvas_checkgeometry {topname} {
1016 set boo [winfo geometry $topname.c]
1017 set boo2 [wm geometry $topname]
1018 global pdtk_lastcanvasconfigured
1019 global pdtk_lastcanvasconfiguration
1020 if {$topname != $pdtk_lastcanvasconfigured || \
1021 $boo != $pdtk_lastcanvasconfiguration} {
1022 set pdtk_lastcanvasconfigured $topname
1023 set pdtk_lastcanvasconfiguration $boo
1024 pd $topname relocate $boo $boo2 \;
1025 }
1026}
1027
1028proc pdtk_canvas_click {name x y b f} {
1029# puts stderr [concat got $f]
1030 pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b $f \;
1031}
1032
1033proc pdtk_canvas_shiftclick {name x y b} {
1034 pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 1 \;
1035}
1036
1037proc pdtk_canvas_ctrlclick {name x y b} {
1038 pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 2 \;
1039}
1040
1041proc pdtk_canvas_altclick {name x y b} {
1042 pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 3 \;
1043}
1044
1045proc pdtk_canvas_dblclick {name x y b} {
1046 pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 4 \;
1047}
1048
1049set pdtk_canvas_mouseup_name 0
1050set pdtk_canvas_mouseup_xminval 0
1051set pdtk_canvas_mouseup_xmaxval 0
1052set pdtk_canvas_mouseup_yminval 0
1053set pdtk_canvas_mouseup_ymaxval 0
1054
1055proc pdtk_canvas_mouseup {name x y b} {
1056 pd [concat [canvastosym $name] mouseup [$name canvasx $x] \
1057 [$name canvasy $y] $b \;]
1058
1059# we use the mouseup event to update scrollbar ranges and recheck the
1060# geometry of the window since I haven't taken the time to figure out
1061# how to do it right.
1062
1063 global pdtk_canvas_mouseup_name
1064 global pdtk_canvas_mouseup_xminval
1065 global pdtk_canvas_mouseup_xmaxval
1066 global pdtk_canvas_mouseup_yminval
1067 global pdtk_canvas_mouseup_ymaxval
1068
1069 set size [$name bbox all]
1070 if {$size != ""} {
1071 set xminval 0
1072 set yminval 0
1073 set xmaxval 100
1074 set ymaxval 100
1075 set x1 [lindex $size 0]
1076 set x2 [lindex $size 2]
1077 set y1 [lindex $size 1]
1078 set y2 [lindex $size 3]
1079
1080 if {$x1 < 0} {set xminval $x1}
1081 if {$y1 < 0} {set yminval $y1}
1082
1083 if {$x2 > 100} {set xmaxval $x2}
1084 if {$y2 > 100} {set ymaxval $y2}
1085
1086 if {$pdtk_canvas_mouseup_name != $name || \
1087 $pdtk_canvas_mouseup_xminval != $xminval || \
1088 $pdtk_canvas_mouseup_xmaxval != $xmaxval || \
1089 $pdtk_canvas_mouseup_yminval != $yminval || \
1090 $pdtk_canvas_mouseup_ymaxval != $ymaxval } {
1091
1092 set newsize "$xminval $yminval $xmaxval $ymaxval"
1093 $name configure -scrollregion $newsize
1094 set pdtk_canvas_mouseup_name $name
1095 set pdtk_canvas_mouseup_xminval $xminval
1096 set pdtk_canvas_mouseup_xmaxval $xmaxval
1097 set pdtk_canvas_mouseup_yminval $yminval
1098 set pdtk_canvas_mouseup_ymaxval $ymaxval
1099 }
1100
1101 }
1102 pdtk_canvas_checkgeometry [canvastosym $name]
1103}
1104
1105proc pdtk_canvas_key {name key iso shift} {
1106# puts stderr [concat down key= $key iso= $iso]
1107# .controls.switches.meterbutton configure -text $key
1108# HACK for MAC OSX -- backspace seems different; I don't understand why.
1109# invesigate this LATER...
1110 global pd_nt
1111 if {$pd_nt == 2} {
1112 if {$key == "BackSpace"} {
1113 set key 8
1114 set keynum 8
1115 }
1116 if {$key == "Delete"} {
1117 set key 8
1118 set keynum 8
1119 }
1120 }
1121 if {$key == "KP_Delete"} {
1122 set key 127
1123 set keynum 127
1124 }
1125 if {$iso != ""} {
1126 scan $iso %c keynum
1127 pd [canvastosym $name] key 1 $keynum $shift\;
1128 } else {
1129 pd [canvastosym $name] key 1 $key $shift\;
1130 }
1131}
1132
1133proc pdtk_canvas_keyup {name key iso} {
1134# puts stderr [concat up key= $key iso= $iso]
1135 if {$iso != ""} {
1136 scan $iso %c keynum
1137 pd [canvastosym $name] key 0 $keynum 0 \;
1138 } else {
1139 pd [canvastosym $name] key 0 $key 0 \;
1140 }
1141}
1142
1143proc pdtk_canvas_altkey {name key iso} {
1144# puts stderr [concat alt-key $iso]
1145############iemlib##################
1146 set topname [string trimright $name .c]
1147 if {$key == "b" || $key == "B"} {menu_bng $topname 1}
1148 if {$key == "t" || $key == "T"} {menu_toggle $topname 1}
1149 if {$key == "n" || $key == "N"} {menu_numbox $topname 1}
1150 if {$key == "v" || $key == "V"} {menu_vslider $topname 1}
1151 if {$key == "h" || $key == "H"} {menu_hslider $topname 1}
1152 if {$key == "i" || $key == "I"} {menu_hradio $topname 1}
1153 if {$key == "d" || $key == "D"} {menu_vradio $topname 1}
1154 if {$key == "u" || $key == "U"} {menu_vumeter $topname 1}
1155 if {$key == "c" || $key == "C"} {menu_mycnv $topname 1}
1156############iemlib##################
1157}
1158
1159proc pdtk_canvas_ctrlkey {name key shift} {
1160# first get rid of ".c" suffix; we'll refer to the toplevel instead
1161 set topname [string trimright $name .c]
1162# puts stderr [concat ctrl-key $key $topname]
1163
1164 if {$key == "n" || $key == "N"} {menu_new}
1165 if {$key == "o" || $key == "O"} {menu_open}
1166 if {$key == "m" || $key == "M"} {menu_send}
1167 if {$key == "q" || $key == "Q"} {
1168 if {$shift == 1} {menu_really_quit} else {menu_quit}
1169 }
1170 if {$key == "s" || $key == "S"} {
1171 if {$shift == 1} {menu_saveas $topname} else {menu_save $topname}
1172 }
1173 if {$key == "z" || $key == "Z"} {
1174 if {$shift == 1} {menu_redo $topname} else {menu_undo $topname}
1175 }
1176 if {$key == "w" || $key == "W"} {menu_close $topname}
1177 if {$key == "p" || $key == "P"} {menu_print $topname}
1178 if {$key == "x" || $key == "X"} {menu_cut $topname}
1179 if {$key == "c" || $key == "C"} {menu_copy $topname}
1180 if {$key == "v" || $key == "V"} {menu_paste $topname}
1181 if {$key == "d" || $key == "D"} {menu_duplicate $topname}
1182 if {$key == "a" || $key == "A"} {menu_selectall $topname}
1183 if {$key == "t" || $key == "T"} {menu_texteditor $topname}
1184 if {$key == "f" || $key == "F"} {menu_findobject $topname}
1185 if {$key == "g" || $key == "G"} {menu_findagain $topname}
1186 if {$key == "1"} {menu_object $topname 1}
1187 if {$key == "2"} {menu_message $topname 1}
1188 if {$key == "3"} {menu_floatatom $topname 1}
1189 if {$key == "4"} {menu_symbolatom $topname 1}
1190 if {$key == "5"} {menu_comment $topname 1}
1191 if {$key == "slash"} {menu_audio 1}
1192 if {$key == "period"} {menu_audio 0}
1193 if {$key == "e" || $key == "E"} {menu_editmode $topname}
1194}
1195
1196proc pdtk_canvas_motion {name x y mods} {
1197# puts stderr [concat [canvastosym $name] $name $x $y]
1198 pd [canvastosym $name] motion [$name canvasx $x] [$name canvasy $y] $mods \;
1199}
1200
1201# "map" event tells us when the canvas becomes visible (arg is "0") or
1202# invisible (arg is ""). Invisibility means the Window Manager has minimized
1203# us. We don't get a final "unmap" event when we destroy the window.
1204proc pdtk_canvas_map {name} {
1205# puts stderr [concat map $name]
1206 pd [canvastosym $name] map 1 \;
1207}
1208
1209proc pdtk_canvas_unmap {name} {
1210# puts stderr [concat unmap $name]
1211 pd [canvastosym $name] map 0 \;
1212}
1213
1214set saveas_dir nowhere
1215
1216############ pdtk_canvas_saveas -- run a saveas dialog ##############
1217
1218proc pdtk_canvas_saveas {name initfile initdir} {
1219 set filename [tk_getSaveFile -initialfile $initfile \
1220 -initialdir $initdir -defaultextension .pd \
1221 -filetypes { {{pd files} {.pd}} {{max files} {.pat}} }]
1222
1223 if {$filename != ""} {
1224 set directory [string range $filename 0 \
1225 [expr [string last / $filename ] - 1]]
1226 set basename [string range $filename \
1227 [expr [string last / $filename ] + 1] end]
1228 pd [concat $name savetofile [pdtk_enquote $basename] \
1229 [pdtk_enquote $directory] \;]
1230# pd [concat $name savetofile $basename $directory \;]
1231 }
1232}
1233
1234############ pdtk_canvas_dofont -- run a font and resize dialog #########
1235
1236set fontsize 0
1237set stretchval 0
1238set whichstretch 0
1239
1240proc dofont_apply {name} {
1241 global fontsize
1242 global stretchval
1243 global whichstretch
1244 set cmd [concat $name font $fontsize $stretchval $whichstretch \;]
1245# puts stderr $cmd
1246 pd $cmd
1247}
1248
1249proc dofont_cancel {name} {
1250 set cmd [concat $name cancel \;]
1251# puts stderr $cmd
1252 pd $cmd
1253}
1254
1255proc pdtk_canvas_dofont {name initsize} {
1256
1257 global fontsize
1258 set fontsize $initsize
1259
1260 global stretchval
1261 set stretchval 100
1262
1263 global whichstretch
1264 set whichstretch 1
1265
1266 toplevel $name
1267 wm title $name {FONT BOMB}
1268 wm protocol $name WM_DELETE_WINDOW [concat dofont_cancel $name]
1269
1270 frame $name.buttonframe
1271 pack $name.buttonframe -side bottom -fill x -pady 2m
1272 button $name.buttonframe.cancel -text {Cancel}\
1273 -command "dofont_cancel $name"
1274 button $name.buttonframe.ok -text {Do it}\
1275 -command "dofont_apply $name"
1276 pack $name.buttonframe.cancel -side left -expand 1
1277 pack $name.buttonframe.ok -side left -expand 1
1278
1279 frame $name.radiof
1280 pack $name.radiof -side left
1281
1282 label $name.radiof.label -text {Font Size:}
1283 pack $name.radiof.label -side top
1284
1285 radiobutton $name.radiof.radio8 -value 8 -variable fontsize -text "8"
1286 radiobutton $name.radiof.radio10 -value 10 -variable fontsize -text "10"
1287 radiobutton $name.radiof.radio12 -value 12 -variable fontsize -text "12"
1288 radiobutton $name.radiof.radio16 -value 16 -variable fontsize -text "16"
1289 radiobutton $name.radiof.radio24 -value 24 -variable fontsize -text "24"
1290 radiobutton $name.radiof.radio36 -value 36 -variable fontsize -text "36"
1291 pack $name.radiof.radio8 -side top -anchor w
1292 pack $name.radiof.radio10 -side top -anchor w
1293 pack $name.radiof.radio12 -side top -anchor w
1294 pack $name.radiof.radio16 -side top -anchor w
1295 pack $name.radiof.radio24 -side top -anchor w
1296 pack $name.radiof.radio36 -side top -anchor w
1297
1298 frame $name.stretchf
1299 pack $name.stretchf -side left
1300
1301 label $name.stretchf.label -text {Stretch:}
1302 pack $name.stretchf.label -side top
1303
1304 entry $name.stretchf.entry -textvariable stretchval -width 5
1305 pack $name.stretchf.entry -side left
1306
1307 radiobutton $name.stretchf.radio1 \
1308 -value 1 -variable whichstretch -text "X and Y"
1309 radiobutton $name.stretchf.radio2 \
1310 -value 2 -variable whichstretch -text "X only"
1311 radiobutton $name.stretchf.radio3 \
1312 -value 3 -variable whichstretch -text "Y only"
1313
1314 pack $name.stretchf.radio1 -side top -anchor w
1315 pack $name.stretchf.radio2 -side top -anchor w
1316 pack $name.stretchf.radio3 -side top -anchor w
1317
1318}
1319
1320############ pdtk_gatom_dialog -- run a gatom dialog #########
1321
1322# see graph_apply, etc., for comments about handling variable names here...
1323
1324proc gatom_escape {sym} {
1325 if {[string length $sym] == 0} {
1326 set ret "-"
1327# puts stderr [concat escape1 $sym $ret]
1328 } else {
1329 if {[string equal -length 1 $sym "-"]} {
1330 set ret [string replace $sym 0 0 "--"]
1331# puts stderr [concat escape $sym $ret]
1332 } else {
1333 if {[string equal -length 1 $sym "$"]} {
1334 set ret [string replace $sym 0 0 "#"]
1335# puts stderr [concat unescape $sym $ret]
1336 } else {
1337 set ret $sym
1338# puts stderr [concat escape $sym "no change"]
1339 }
1340 }
1341 }
1342 concat $ret
1343}
1344
1345proc gatom_unescape {sym} {
1346 if {[string equal -length 1 $sym "-"]} {
1347 set ret [string replace $sym 0 0 ""]
1348# puts stderr [concat unescape $sym $ret]
1349 } else {
1350 if {[string equal -length 1 $sym "#"]} {
1351 set ret [string replace $sym 0 0 "$"]
1352# puts stderr [concat unescape $sym $ret]
1353 } else {
1354 set ret $sym
1355# puts stderr [concat unescape $sym "no change"]
1356 }
1357 }
1358 concat $ret
1359}
1360
1361proc dogatom_apply {id} {
1362 set vid [string trimleft $id .]
1363
1364 set var_gatomwidth [concat gatomwidth_$vid]
1365 global $var_gatomwidth
1366 set var_gatomlo [concat gatomlo_$vid]
1367 global $var_gatomlo
1368 set var_gatomhi [concat gatomhi_$vid]
1369 global $var_gatomhi
1370 set var_gatomwherelabel [concat gatomwherelabel_$vid]
1371 global $var_gatomwherelabel
1372 set var_gatomlabel [concat gatomlabel_$vid]
1373 global $var_gatomlabel
1374 set var_gatomsymfrom [concat gatomsymfrom_$vid]
1375 global $var_gatomsymfrom
1376 set var_gatomsymto [concat gatomsymto_$vid]
1377 global $var_gatomsymto
1378
1379# set cmd [concat $id param $gatomwidth $gatomlo $gatomhi \;]
1380
1381 set cmd [concat $id param \
1382 [eval concat $$var_gatomwidth] \
1383 [eval concat $$var_gatomlo] \
1384 [eval concat $$var_gatomhi] \
1385 [eval gatom_escape $$var_gatomlabel] \
1386 [eval concat $$var_gatomwherelabel] \
1387 [eval gatom_escape $$var_gatomsymfrom] \
1388 [eval gatom_escape $$var_gatomsymto] \
1389 \;]
1390
1391# puts stderr $cmd
1392 pd $cmd
1393}
1394
1395proc dogatom_cancel {name} {
1396 set cmd [concat $name cancel \;]
1397# puts stderr $cmd
1398 pd $cmd
1399}
1400
1401proc dogatom_ok {name} {
1402 dogatom_apply $name
1403 dogatom_cancel $name
1404}
1405
1406proc pdtk_gatom_dialog {id initwidth initlo inithi \
1407 wherelabel label symfrom symto} {
1408
1409 set vid [string trimleft $id .]
1410
1411 set var_gatomwidth [concat gatomwidth_$vid]
1412 global $var_gatomwidth
1413 set var_gatomlo [concat gatomlo_$vid]
1414 global $var_gatomlo
1415 set var_gatomhi [concat gatomhi_$vid]
1416 global $var_gatomhi
1417 set var_gatomwherelabel [concat gatomwherelabel_$vid]
1418 global $var_gatomwherelabel
1419 set var_gatomlabel [concat gatomlabel_$vid]
1420 global $var_gatomlabel
1421 set var_gatomsymfrom [concat gatomsymfrom_$vid]
1422 global $var_gatomsymfrom
1423 set var_gatomsymto [concat gatomsymto_$vid]
1424 global $var_gatomsymto
1425
1426 set $var_gatomwidth $initwidth
1427 set $var_gatomlo $initlo
1428 set $var_gatomhi $inithi
1429 set $var_gatomwherelabel $wherelabel
1430 set $var_gatomlabel [gatom_unescape $label]
1431 set $var_gatomsymfrom [gatom_unescape $symfrom]
1432 set $var_gatomsymto [gatom_unescape $symto]
1433
1434 toplevel $id
1435 wm title $id {Atom}
1436 wm protocol $id WM_DELETE_WINDOW [concat dogatom_cancel $id]
1437
1438 frame $id.buttonframe
1439 pack $id.buttonframe -side bottom -fill x -pady 2m
1440 button $id.buttonframe.cancel -text {Cancel}\
1441 -command "dogatom_cancel $id"
1442 button $id.buttonframe.apply -text {Apply}\
1443 -command "dogatom_apply $id"
1444 button $id.buttonframe.ok -text {OK}\
1445 -command "dogatom_ok $id"
1446 pack $id.buttonframe.cancel -side left -expand 1
1447 pack $id.buttonframe.apply -side left -expand 1
1448 pack $id.buttonframe.ok -side left -expand 1
1449
1450 frame $id.paramsymto
1451 pack $id.paramsymto -side bottom
1452 label $id.paramsymto.entryname -text {send symbol}
1453 entry $id.paramsymto.entry -textvariable $var_gatomsymto -width 20
1454 pack $id.paramsymto.entryname $id.paramsymto.entry -side left
1455
1456 frame $id.paramsymfrom
1457 pack $id.paramsymfrom -side bottom
1458 label $id.paramsymfrom.entryname -text {receive symbol}
1459 entry $id.paramsymfrom.entry -textvariable $var_gatomsymfrom -width 20
1460 pack $id.paramsymfrom.entryname $id.paramsymfrom.entry -side left
1461
1462 frame $id.radio
1463 pack $id.radio -side bottom
1464 label $id.radio.label -text {show label on:}
1465 frame $id.radio.l
1466 frame $id.radio.r
1467 pack $id.radio.label -side top
1468 pack $id.radio.l $id.radio.r -side left
1469 radiobutton $id.radio.l.radio0 -value 0 \
1470 -variable $var_gatomwherelabel \
1471 -text "left"
1472 radiobutton $id.radio.l.radio1 -value 1 \
1473 -variable $var_gatomwherelabel \
1474 -text "right"
1475 radiobutton $id.radio.r.radio2 -value 2 \
1476 -variable $var_gatomwherelabel \
1477 -text "top"
1478 radiobutton $id.radio.r.radio3 -value 3 \
1479 -variable $var_gatomwherelabel \
1480 -text "bottom"
1481 pack $id.radio.l.radio0 $id.radio.l.radio1 -side top -anchor w
1482 pack $id.radio.r.radio2 $id.radio.r.radio3 -side top -anchor w
1483
1484
1485 frame $id.paramlabel
1486 pack $id.paramlabel -side bottom
1487 label $id.paramlabel.entryname -text label
1488 entry $id.paramlabel.entry -textvariable $var_gatomlabel -width 20
1489 pack $id.paramlabel.entryname $id.paramlabel.entry -side left
1490
1491 frame $id.paramhi
1492 pack $id.paramhi -side bottom
1493 label $id.paramhi.entryname -text "upper limit"
1494 entry $id.paramhi.entry -textvariable $var_gatomhi -width 8
1495 pack $id.paramhi.entryname $id.paramhi.entry -side left
1496
1497 frame $id.paramlo
1498 pack $id.paramlo -side bottom
1499 label $id.paramlo.entryname -text "lower limit"
1500 entry $id.paramlo.entry -textvariable $var_gatomlo -width 8
1501 pack $id.paramlo.entryname $id.paramlo.entry -side left
1502
1503 frame $id.params
1504 pack $id.params -side bottom
1505 label $id.params.entryname -text width
1506 entry $id.params.entry -textvariable $var_gatomwidth -width 4
1507 pack $id.params.entryname $id.params.entry -side left
1508
1509
1510
1511 bind $id.paramhi.entry <KeyPress-Return> [concat dogatom_ok $id]
1512 bind $id.paramlo.entry <KeyPress-Return> [concat dogatom_ok $id]
1513 bind $id.params.entry <KeyPress-Return> [concat dogatom_ok $id]
1514 $id.params.entry select from 0
1515 $id.params.entry select adjust end
1516 focus $id.params.entry
1517}
1518
1519############ pdtk_canvas_popup -- popup menu for canvas #########
1520
1521set popup_xpix 0
1522set popup_ypix 0
1523
1524proc popup_action {name action} {
1525 global popup_xpix popup_ypix
1526 set cmd [concat $name done-popup $action $popup_xpix $popup_ypix \;]
1527# puts stderr $cmd
1528 pd $cmd
1529}
1530
1531proc pdtk_canvas_popup {name xpix ypix canprop canopen} {
1532 global popup_xpix popup_ypix
1533 set popup_xpix $xpix
1534 set popup_ypix $ypix
1535 if {$canprop == 0} {$name.popup entryconfigure 0 -state disabled}
1536 if {$canprop == 1} {$name.popup entryconfigure 0 -state active}
1537 if {$canopen == 0} {$name.popup entryconfigure 1 -state disabled}
1538 if {$canopen == 1} {$name.popup entryconfigure 1 -state active}
1539 tk_popup $name.popup [expr $xpix + [winfo rootx $name.c]] \
1540 [expr $ypix + [winfo rooty $name.c]] 0
1541}
1542
1543############ pdtk_graph_dialog -- dialog window for graphs #########
1544
1545# the graph and array dialogs can come up in many copies; but in TK the easiest
1546# way to get data from an "entry", etc., is to set an associated variable
1547# name. This is especially true for grouped "radio buttons". So we have
1548# to synthesize variable names for each instance of the dialog. The dialog
1549# gets a TK pathname $id, from which it strips the leading "." to make a
1550# variable suffix $vid. Then you can get the actual value out by asking for
1551# [eval concat $$variablename]. There should be an easier way but I don't see
1552# it yet.
1553
1554proc graph_apply {id} {
1555# strip "." from the TK id to make a variable name suffix
1556 set vid [string trimleft $id .]
1557# for each variable, make a local variable to hold its name...
1558 set var_graph_x1 [concat graph_x1_$vid]
1559 global $var_graph_x1
1560 set var_graph_x2 [concat graph_x2_$vid]
1561 global $var_graph_x2
1562 set var_graph_xpix [concat graph_xpix_$vid]
1563 global $var_graph_xpix
1564 set var_graph_y1 [concat graph_y1_$vid]
1565 global $var_graph_y1
1566 set var_graph_y2 [concat graph_y2_$vid]
1567 global $var_graph_y2
1568 set var_graph_ypix [concat graph_ypix_$vid]
1569 global $var_graph_ypix
1570
1571 pd [concat $id dialog \
1572 [eval concat $$var_graph_x1] \
1573 [eval concat $$var_graph_y1] \
1574 [eval concat $$var_graph_x2] \
1575 [eval concat $$var_graph_y2] \
1576 [eval concat $$var_graph_xpix] \
1577 [eval concat $$var_graph_ypix] \
1578 \;]
1579}
1580
1581proc graph_cancel {id} {
1582 set cmd [concat $id cancel \;]
1583# puts stderr $cmd
1584 pd $cmd
1585}
1586
1587proc graph_ok {id} {
1588 graph_apply $id
1589 graph_cancel $id
1590}
1591
1592proc pdtk_graph_dialog {id x1 y1 x2 y2 xpix ypix} {
1593 set vid [string trimleft $id .]
1594 set var_graph_x1 [concat graph_x1_$vid]
1595 global $var_graph_x1
1596 set var_graph_x2 [concat graph_x2_$vid]
1597 global $var_graph_x2
1598 set var_graph_xpix [concat graph_xpix_$vid]
1599 global $var_graph_xpix
1600 set var_graph_y1 [concat graph_y1_$vid]
1601 global $var_graph_y1
1602 set var_graph_y2 [concat graph_y2_$vid]
1603 global $var_graph_y2
1604 set var_graph_ypix [concat graph_ypix_$vid]
1605 global $var_graph_ypix
1606
1607 set $var_graph_x1 $x1
1608 set $var_graph_x2 $x2
1609 set $var_graph_xpix $xpix
1610 set $var_graph_y1 $y1
1611 set $var_graph_y2 $y2
1612 set $var_graph_ypix $ypix
1613
1614 toplevel $id
1615 wm title $id {graph}
1616 wm protocol $id WM_DELETE_WINDOW [concat graph_cancel $id]
1617
1618 label $id.label -text {GRAPH BOUNDS}
1619 pack $id.label -side top
1620
1621 frame $id.buttonframe
1622 pack $id.buttonframe -side bottom -fill x -pady 2m
1623 button $id.buttonframe.cancel -text {Cancel}\
1624 -command "graph_cancel $id"
1625 button $id.buttonframe.apply -text {Apply}\
1626 -command "graph_apply $id"
1627 button $id.buttonframe.ok -text {OK}\
1628 -command "graph_ok $id"
1629 pack $id.buttonframe.cancel -side left -expand 1
1630 pack $id.buttonframe.apply -side left -expand 1
1631 pack $id.buttonframe.ok -side left -expand 1
1632
1633 frame $id.xrangef
1634 pack $id.xrangef -side top
1635
1636 label $id.xrangef.l1 -text "X from:"
1637 entry $id.xrangef.x1 -textvariable $var_graph_x1 -width 7
1638 label $id.xrangef.l2 -text "to:"
1639 entry $id.xrangef.x2 -textvariable $var_graph_x2 -width 7
1640 label $id.xrangef.l3 -text "screen width:"
1641 entry $id.xrangef.xpix -textvariable $var_graph_xpix -width 7
1642 pack $id.xrangef.l1 $id.xrangef.x1 \
1643 $id.xrangef.l2 $id.xrangef.x2 \
1644 $id.xrangef.l3 $id.xrangef.xpix -side left
1645
1646 frame $id.yrangef
1647 pack $id.yrangef -side top
1648
1649# dig in the following that the upper bound is labeled y1 but the variable is
1650# y2, etc. This is to deal with the inconsistent use of "upper and lower"
1651# graph bounds... in the dialog the upper Y bound is the lower valued Y pixel.
1652 label $id.yrangef.l1 -text "Y from:"
1653 entry $id.yrangef.y1 -textvariable $var_graph_y2 -width 7
1654 label $id.yrangef.l2 -text "to:"
1655 entry $id.yrangef.y2 -textvariable $var_graph_y1 -width 7
1656 label $id.yrangef.l3 -text "screen height:"
1657 entry $id.yrangef.ypix -textvariable $var_graph_ypix -width 7
1658 pack $id.yrangef.l1 $id.yrangef.y1 \
1659 $id.yrangef.l2 $id.yrangef.y2 \
1660 $id.yrangef.l3 $id.yrangef.ypix -side left
1661
1662 bind $id.xrangef.x1 <KeyPress-Return> [concat graph_ok $id]
1663 bind $id.xrangef.x2 <KeyPress-Return> [concat graph_ok $id]
1664 bind $id.xrangef.xpix <KeyPress-Return> [concat graph_ok $id]
1665 bind $id.yrangef.y1 <KeyPress-Return> [concat graph_ok $id]
1666 bind $id.yrangef.y2 <KeyPress-Return> [concat graph_ok $id]
1667 bind $id.yrangef.ypix <KeyPress-Return> [concat graph_ok $id]
1668 $id.xrangef.x2 select from 0
1669 $id.xrangef.x2 select adjust end
1670 focus $id.xrangef.x2
1671}
1672
1673# begin of change "iemlib"
1674############ pdtk_iemgui_dialog -- dialog window for iem guis #########
1675
1676set iemgui_define_min_flashhold 50
1677set iemgui_define_min_flashbreak 10
1678set iemgui_define_min_fontsize 4
1679
1680proc iemgui_clip_dim {id} {
1681 set vid [string trimleft $id .]
1682
1683 set var_iemgui_wdt [concat iemgui_wdt_$vid]
1684 global $var_iemgui_wdt
1685 set var_iemgui_min_wdt [concat iemgui_min_wdt_$vid]
1686 global $var_iemgui_min_wdt
1687 set var_iemgui_hgt [concat iemgui_hgt_$vid]
1688 global $var_iemgui_hgt
1689 set var_iemgui_min_hgt [concat iemgui_min_hgt_$vid]
1690 global $var_iemgui_min_hgt
1691
1692 if {[eval concat $$var_iemgui_wdt] < [eval concat $$var_iemgui_min_wdt]} {
1693 set $var_iemgui_wdt [eval concat $$var_iemgui_min_wdt]
1694 $id.dim.w_ent configure -textvariable $var_iemgui_wdt
1695 }
1696 if {[eval concat $$var_iemgui_hgt] < [eval concat $$var_iemgui_min_hgt]} {
1697 set $var_iemgui_hgt [eval concat $$var_iemgui_min_hgt]
1698 $id.dim.h_ent configure -textvariable $var_iemgui_hgt
1699 }
1700}
1701
1702proc iemgui_clip_num {id} {
1703 set vid [string trimleft $id .]
1704
1705 set var_iemgui_num [concat iemgui_num_$vid]
1706 global $var_iemgui_num
1707
1708 if {[eval concat $$var_iemgui_num] > 2000} {
1709 set $var_iemgui_num 2000
1710 $id.para.num_ent configure -textvariable $var_iemgui_num
1711 }
1712 if {[eval concat $$var_iemgui_num] < 1} {
1713 set $var_iemgui_num 1
1714 $id.para.num_ent configure -textvariable $var_iemgui_num
1715 }
1716}
1717
1718proc iemgui_sched_rng {id} {
1719 set vid [string trimleft $id .]
1720
1721 set var_iemgui_min_rng [concat iemgui_min_rng_$vid]
1722 global $var_iemgui_min_rng
1723 set var_iemgui_max_rng [concat iemgui_max_rng_$vid]
1724 global $var_iemgui_max_rng
1725 set var_iemgui_rng_sch [concat iemgui_rng_sch_$vid]
1726 global $var_iemgui_rng_sch
1727
1728 global iemgui_define_min_flashhold
1729 global iemgui_define_min_flashbreak
1730
1731 if {[eval concat $$var_iemgui_rng_sch] == 2} {
1732 if {[eval concat $$var_iemgui_max_rng] < [eval concat $$var_iemgui_min_rng]} {
1733 set hhh [eval concat $$var_iemgui_min_rng]
1734 set $var_iemgui_min_rng [eval concat $$var_iemgui_max_rng]
1735 set $var_iemgui_max_rng $hhh
1736 $id.rng.max_ent configure -textvariable $var_iemgui_max_rng
1737 $id.rng.min_ent configure -textvariable $var_iemgui_min_rng }
1738 if {[eval concat $$var_iemgui_max_rng] < $iemgui_define_min_flashhold} {
1739 set $var_iemgui_max_rng $iemgui_define_min_flashhold
1740 $id.rng.max_ent configure -textvariable $var_iemgui_max_rng
1741 }
1742 if {[eval concat $$var_iemgui_min_rng] < $iemgui_define_min_flashbreak} {
1743 set $var_iemgui_min_rng $iemgui_define_min_flashbreak
1744 $id.rng.min_ent configure -textvariable $var_iemgui_min_rng
1745 }
1746 }
1747 if {[eval concat $$var_iemgui_rng_sch] == 1} {
1748 if {[eval concat $$var_iemgui_min_rng] == 0.0} {
1749 set $var_iemgui_min_rng 1.0
1750 $id.rng.min_ent configure -textvariable $var_iemgui_min_rng
1751 }
1752 }
1753}
1754
1755proc iemgui_verify_rng {id} {
1756 set vid [string trimleft $id .]
1757
1758 set var_iemgui_min_rng [concat iemgui_min_rng_$vid]
1759 global $var_iemgui_min_rng
1760 set var_iemgui_max_rng [concat iemgui_max_rng_$vid]
1761 global $var_iemgui_max_rng
1762 set var_iemgui_lin0_log1 [concat iemgui_lin0_log1_$vid]
1763 global $var_iemgui_lin0_log1
1764
1765 if {[eval concat $$var_iemgui_lin0_log1] == 1} {
1766 if {[eval concat $$var_iemgui_max_rng] == 0.0 && [eval concat $$var_iemgui_min_rng] == 0.0} {
1767 set $var_iemgui_max_rng 1.0
1768 $id.rng.max_ent configure -textvariable $var_iemgui_max_rng
1769 }
1770 if {[eval concat $$var_iemgui_max_rng] > 0} {
1771 if {[eval concat $$var_iemgui_min_rng] <= 0} {
1772 set $var_iemgui_min_rng [expr [eval concat $$var_iemgui_max_rng] * 0.01]
1773 $id.rng.min_ent configure -textvariable $var_iemgui_min_rng
1774 }
1775 } else {
1776 if {[eval concat $$var_iemgui_min_rng] > 0} {
1777 set $var_iemgui_max_rng [expr [eval concat $$var_iemgui_min_rng] * 0.01]
1778 $id.rng.max_ent configure -textvariable $var_iemgui_max_rng
1779 }
1780 }
1781 }
1782}
1783
1784proc iemgui_clip_fontsize {id} {
1785 set vid [string trimleft $id .]
1786
1787 set var_iemgui_gn_fs [concat iemgui_gn_fs_$vid]
1788 global $var_iemgui_gn_fs
1789
1790 global iemgui_define_min_fontsize
1791
1792 if {[eval concat $$var_iemgui_gn_fs] < $iemgui_define_min_fontsize} {
1793 set $var_iemgui_gn_fs $iemgui_define_min_fontsize
1794 $id.gnfs.fs_ent configure -textvariable $var_iemgui_gn_fs
1795 }
1796}
1797
1798proc iemgui_set_col_example {id} {
1799 set vid [string trimleft $id .]
1800
1801 set var_iemgui_bcol [concat iemgui_bcol_$vid]
1802 global $var_iemgui_bcol
1803 set var_iemgui_fcol [concat iemgui_fcol_$vid]
1804 global $var_iemgui_fcol
1805 set var_iemgui_lcol [concat iemgui_lcol_$vid]
1806 global $var_iemgui_lcol
1807
1808 $id.col_example_choose.lb_bk configure \
1809 -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1810 -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1811 -foreground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \
1812 -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_lcol]]
1813
1814 if { [eval concat $$var_iemgui_fcol] >= 0 } {
1815 $id.col_example_choose.fr_bk configure \
1816 -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1817 -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1818 -foreground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \
1819 -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_fcol]]
1820 } else {
1821 $id.col_example_choose.fr_bk configure \
1822 -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1823 -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1824 -foreground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
1825 -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_bcol]]}
1826}
1827
1828proc iemgui_preset_col {id presetcol} {
1829 set vid [string trimleft $id .]
1830
1831 set var_iemgui_l2_f1_b0 [concat iemgui_l2_f1_b0_$vid]
1832 global $var_iemgui_l2_f1_b0
1833 set var_iemgui_bcol [concat iemgui_bcol_$vid]
1834 global $var_iemgui_bcol
1835 set var_iemgui_fcol [concat iemgui_fcol_$vid]
1836 global $var_iemgui_fcol
1837 set var_iemgui_lcol [concat iemgui_lcol_$vid]
1838 global $var_iemgui_lcol
1839
1840 if { [eval concat $$var_iemgui_l2_f1_b0] == 0 } { set $var_iemgui_bcol $presetcol }
1841 if { [eval concat $$var_iemgui_l2_f1_b0] == 1 } { set $var_iemgui_fcol $presetcol }
1842 if { [eval concat $$var_iemgui_l2_f1_b0] == 2 } { set $var_iemgui_lcol $presetcol }
1843 iemgui_set_col_example $id
1844}
1845
1846proc iemgui_choose_col_bkfrlb {id} {
1847 set vid [string trimleft $id .]
1848
1849 set var_iemgui_l2_f1_b0 [concat iemgui_l2_f1_b0_$vid]
1850 global $var_iemgui_l2_f1_b0
1851 set var_iemgui_bcol [concat iemgui_bcol_$vid]
1852 global $var_iemgui_bcol
1853 set var_iemgui_fcol [concat iemgui_fcol_$vid]
1854 global $var_iemgui_fcol
1855 set var_iemgui_lcol [concat iemgui_lcol_$vid]
1856 global $var_iemgui_lcol
1857
1858 if {[eval concat $$var_iemgui_l2_f1_b0] == 0} {
1859 set $var_iemgui_bcol [expr [eval concat $$var_iemgui_bcol] & 0xFCFCFC]
1860 set helpstring [tk_chooseColor -title "Background-Color" -initialcolor [format "#%6.6x" [eval concat $$var_iemgui_bcol]]]
1861 if { $helpstring != "" } {
1862 set $var_iemgui_bcol [string replace $helpstring 0 0 "0x"]
1863 set $var_iemgui_bcol [expr [eval concat $$var_iemgui_bcol] & 0xFCFCFC] }
1864 }
1865 if {[eval concat $$var_iemgui_l2_f1_b0] == 1} {
1866 set $var_iemgui_fcol [expr [eval concat $$var_iemgui_fcol] & 0xFCFCFC]
1867 set helpstring [tk_chooseColor -title "Front-Color" -initialcolor [format "#%6.6x" [eval concat $$var_iemgui_fcol]]]
1868 if { $helpstring != "" } {
1869 set $var_iemgui_fcol [string replace $helpstring 0 0 "0x"]
1870 set $var_iemgui_fcol [expr [eval concat $$var_iemgui_fcol] & 0xFCFCFC] }
1871 }
1872 if {[eval concat $$var_iemgui_l2_f1_b0] == 2} {
1873 set $var_iemgui_lcol [expr [eval concat $$var_iemgui_lcol] & 0xFCFCFC]
1874 set helpstring [tk_chooseColor -title "Label-Color" -initialcolor [format "#%6.6x" [eval concat $$var_iemgui_lcol]]]
1875 if { $helpstring != "" } {
1876 set $var_iemgui_lcol [string replace $helpstring 0 0 "0x"]
1877 set $var_iemgui_lcol [expr [eval concat $$var_iemgui_lcol] & 0xFCFCFC] }
1878 }
1879 iemgui_set_col_example $id
1880}
1881
1882proc iemgui_lilo {id} {
1883 set vid [string trimleft $id .]
1884
1885 set var_iemgui_lin0_log1 [concat iemgui_lin0_log1_$vid]
1886 global $var_iemgui_lin0_log1
1887 set var_iemgui_lilo0 [concat iemgui_lilo0_$vid]
1888 global $var_iemgui_lilo0
1889 set var_iemgui_lilo1 [concat iemgui_lilo1_$vid]
1890 global $var_iemgui_lilo1
1891
1892 iemgui_sched_rng $id
1893
1894 if {[eval concat $$var_iemgui_lin0_log1] == 0} {
1895 set $var_iemgui_lin0_log1 1
1896 $id.para.lilo configure -text [eval concat $$var_iemgui_lilo1]
1897 iemgui_verify_rng $id
1898 iemgui_sched_rng $id
1899 } else {
1900 set $var_iemgui_lin0_log1 0
1901 $id.para.lilo configure -text [eval concat $$var_iemgui_lilo0]
1902 }
1903}
1904
1905proc iemgui_toggle_font {id} {
1906 set vid [string trimleft $id .]
1907
1908 set var_iemgui_gn_f [concat iemgui_gn_f_$vid]
1909 global $var_iemgui_gn_f
1910
1911 set $var_iemgui_gn_f [expr [eval concat $$var_iemgui_gn_f] + 1]
1912 if {[eval concat $$var_iemgui_gn_f] > 2} {set $var_iemgui_gn_f 0}
1913 if {[eval concat $$var_iemgui_gn_f] == 0} {$id.gnfs.fb configure -text "courier" -font {courier 10 bold}}
1914 if {[eval concat $$var_iemgui_gn_f] == 1} {$id.gnfs.fb configure -text "helvetica" -font {helvetica 10 bold}}
1915 if {[eval concat $$var_iemgui_gn_f] == 2} {$id.gnfs.fb configure -text "times" -font {times 10 bold}}
1916}
1917
1918proc iemgui_lb {id} {
1919 set vid [string trimleft $id .]
1920
1921 set var_iemgui_loadbang [concat iemgui_loadbang_$vid]
1922 global $var_iemgui_loadbang
1923
1924 if {[eval concat $$var_iemgui_loadbang] == 0} {
1925 set $var_iemgui_loadbang 1
1926 $id.para.lb configure -text "init"
1927 } else {
1928 set $var_iemgui_loadbang 0
1929 $id.para.lb configure -text "no init"
1930 }
1931}
1932
1933proc iemgui_stdy_jmp {id} {
1934 set vid [string trimleft $id .]
1935
1936 set var_iemgui_steady [concat iemgui_steady_$vid]
1937 global $var_iemgui_steady
1938
1939 if {[eval concat $$var_iemgui_steady]} {
1940 set $var_iemgui_steady 0
1941 $id.para.stdy_jmp configure -text "jump on click"
1942 } else {
1943 set $var_iemgui_steady 1
1944 $id.para.stdy_jmp configure -text "steady on click"
1945 }
1946}
1947
1948proc iemgui_apply {id} {
1949 set vid [string trimleft $id .]
1950
1951 set var_iemgui_wdt [concat iemgui_wdt_$vid]
1952 global $var_iemgui_wdt
1953 set var_iemgui_min_wdt [concat iemgui_min_wdt_$vid]
1954 global $var_iemgui_min_wdt
1955 set var_iemgui_hgt [concat iemgui_hgt_$vid]
1956 global $var_iemgui_hgt
1957 set var_iemgui_min_hgt [concat iemgui_min_hgt_$vid]
1958 global $var_iemgui_min_hgt
1959 set var_iemgui_min_rng [concat iemgui_min_rng_$vid]
1960 global $var_iemgui_min_rng
1961 set var_iemgui_max_rng [concat iemgui_max_rng_$vid]
1962 global $var_iemgui_max_rng
1963 set var_iemgui_lin0_log1 [concat iemgui_lin0_log1_$vid]
1964 global $var_iemgui_lin0_log1
1965 set var_iemgui_lilo0 [concat iemgui_lilo0_$vid]
1966 global $var_iemgui_lilo0
1967 set var_iemgui_lilo1 [concat iemgui_lilo1_$vid]
1968 global $var_iemgui_lilo1
1969 set var_iemgui_loadbang [concat iemgui_loadbang_$vid]
1970 global $var_iemgui_loadbang
1971 set var_iemgui_num [concat iemgui_num_$vid]
1972 global $var_iemgui_num
1973 set var_iemgui_steady [concat iemgui_steady_$vid]
1974 global $var_iemgui_steady
1975 set var_iemgui_snd [concat iemgui_snd_$vid]
1976 global $var_iemgui_snd
1977 set var_iemgui_rcv [concat iemgui_rcv_$vid]
1978 global $var_iemgui_rcv
1979 set var_iemgui_gui_nam [concat iemgui_gui_nam_$vid]
1980 global $var_iemgui_gui_nam
1981 set var_iemgui_gn_dx [concat iemgui_gn_dx_$vid]
1982 global $var_iemgui_gn_dx
1983 set var_iemgui_gn_dy [concat iemgui_gn_dy_$vid]
1984 global $var_iemgui_gn_dy
1985 set var_iemgui_gn_f [concat iemgui_gn_f_$vid]
1986 global $var_iemgui_gn_f
1987 set var_iemgui_gn_fs [concat iemgui_gn_fs_$vid]
1988 global $var_iemgui_gn_fs
1989 set var_iemgui_bcol [concat iemgui_bcol_$vid]
1990 global $var_iemgui_bcol
1991 set var_iemgui_fcol [concat iemgui_fcol_$vid]
1992 global $var_iemgui_fcol
1993 set var_iemgui_lcol [concat iemgui_lcol_$vid]
1994 global $var_iemgui_lcol
1995
1996 iemgui_clip_dim $id
1997 iemgui_clip_num $id
1998 iemgui_sched_rng $id
1999 iemgui_verify_rng $id
2000 iemgui_sched_rng $id
2001 iemgui_clip_fontsize $id
2002
2003 if {[eval concat $$var_iemgui_snd] == ""} {set hhhsnd "empty"} else {set hhhsnd [eval concat $$var_iemgui_snd]}
2004 if {[eval concat $$var_iemgui_rcv] == ""} {set hhhrcv "empty"} else {set hhhrcv [eval concat $$var_iemgui_rcv]}
2005 if {[eval concat $$var_iemgui_gui_nam] == ""} {set hhhgui_nam "empty"
2006 } else {
2007 set hhhgui_nam [eval concat $$var_iemgui_gui_nam]}
2008
2009 if {[string index $hhhsnd 0] == "$"} {
2010 set hhhsnd [string replace $hhhsnd 0 0 #] }
2011 if {[string index $hhhrcv 0] == "$"} {
2012 set hhhrcv [string replace $hhhrcv 0 0 #] }
2013 if {[string index $hhhgui_nam 0] == "$"} {
2014 set hhhgui_nam [string replace $hhhgui_nam 0 0 #] }
2015
2016 set hhhsnd [string map {" " _} $hhhsnd]
2017 set hhhrcv [string map {" " _} $hhhrcv]
2018 set hhhgui_nam [string map {" " _} $hhhgui_nam]
2019
2020 pd [concat $id dialog \
2021 [eval concat $$var_iemgui_wdt] \
2022 [eval concat $$var_iemgui_hgt] \
2023 [eval concat $$var_iemgui_min_rng] \
2024 [eval concat $$var_iemgui_max_rng] \
2025 [eval concat $$var_iemgui_lin0_log1] \
2026 [eval concat $$var_iemgui_loadbang] \
2027 [eval concat $$var_iemgui_num] \
2028 $hhhsnd \
2029 $hhhrcv \
2030 $hhhgui_nam \
2031 [eval concat $$var_iemgui_gn_dx] \
2032 [eval concat $$var_iemgui_gn_dy] \
2033 [eval concat $$var_iemgui_gn_f] \
2034 [eval concat $$var_iemgui_gn_fs] \
2035 [eval concat $$var_iemgui_bcol] \
2036 [eval concat $$var_iemgui_fcol] \
2037 [eval concat $$var_iemgui_lcol] \
2038 [eval concat $$var_iemgui_steady] \
2039 \;]
2040}
2041
2042proc iemgui_cancel {id} {pd [concat $id cancel \;]}
2043
2044proc iemgui_ok {id} {
2045 iemgui_apply $id
2046 iemgui_cancel $id
2047}
2048
2049proc pdtk_iemgui_dialog {id mainheader \
2050 dim_header wdt min_wdt wdt_label hgt min_hgt hgt_label \
2051 rng_header min_rng min_rng_label max_rng max_rng_label rng_sched \
2052 lin0_log1 lilo0_label lilo1_label loadbang steady num_label num \
2053 snd rcv \
2054 gui_name \
2055 gn_dx gn_dy \
2056 gn_f gn_fs \
2057 bcol fcol lcol} {
2058
2059 set vid [string trimleft $id .]
2060
2061 set var_iemgui_wdt [concat iemgui_wdt_$vid]
2062 global $var_iemgui_wdt
2063 set var_iemgui_min_wdt [concat iemgui_min_wdt_$vid]
2064 global $var_iemgui_min_wdt
2065 set var_iemgui_hgt [concat iemgui_hgt_$vid]
2066 global $var_iemgui_hgt
2067 set var_iemgui_min_hgt [concat iemgui_min_hgt_$vid]
2068 global $var_iemgui_min_hgt
2069 set var_iemgui_min_rng [concat iemgui_min_rng_$vid]
2070 global $var_iemgui_min_rng
2071 set var_iemgui_max_rng [concat iemgui_max_rng_$vid]
2072 global $var_iemgui_max_rng
2073 set var_iemgui_rng_sch [concat iemgui_rng_sch_$vid]
2074 global $var_iemgui_rng_sch
2075 set var_iemgui_lin0_log1 [concat iemgui_lin0_log1_$vid]
2076 global $var_iemgui_lin0_log1
2077 set var_iemgui_lilo0 [concat iemgui_lilo0_$vid]
2078 global $var_iemgui_lilo0
2079 set var_iemgui_lilo1 [concat iemgui_lilo1_$vid]
2080 global $var_iemgui_lilo1
2081 set var_iemgui_loadbang [concat iemgui_loadbang_$vid]
2082 global $var_iemgui_loadbang
2083 set var_iemgui_num [concat iemgui_num_$vid]
2084 global $var_iemgui_num
2085 set var_iemgui_steady [concat iemgui_steady_$vid]
2086 global $var_iemgui_steady
2087 set var_iemgui_snd [concat iemgui_snd_$vid]
2088 global $var_iemgui_snd
2089 set var_iemgui_rcv [concat iemgui_rcv_$vid]
2090 global $var_iemgui_rcv
2091 set var_iemgui_gui_nam [concat iemgui_gui_nam_$vid]
2092 global $var_iemgui_gui_nam
2093 set var_iemgui_gn_dx [concat iemgui_gn_dx_$vid]
2094 global $var_iemgui_gn_dx
2095 set var_iemgui_gn_dy [concat iemgui_gn_dy_$vid]
2096 global $var_iemgui_gn_dy
2097 set var_iemgui_gn_f [concat iemgui_gn_f_$vid]
2098 global $var_iemgui_gn_f
2099 set var_iemgui_gn_fs [concat iemgui_gn_fs_$vid]
2100 global $var_iemgui_gn_fs
2101 set var_iemgui_l2_f1_b0 [concat iemgui_l2_f1_b0_$vid]
2102 global $var_iemgui_l2_f1_b0
2103 set var_iemgui_bcol [concat iemgui_bcol_$vid]
2104 global $var_iemgui_bcol
2105 set var_iemgui_fcol [concat iemgui_fcol_$vid]
2106 global $var_iemgui_fcol
2107 set var_iemgui_lcol [concat iemgui_lcol_$vid]
2108 global $var_iemgui_lcol
2109
2110 set $var_iemgui_wdt $wdt
2111 set $var_iemgui_min_wdt $min_wdt
2112 set $var_iemgui_hgt $hgt
2113 set $var_iemgui_min_hgt $min_hgt
2114 set $var_iemgui_min_rng $min_rng
2115 set $var_iemgui_max_rng $max_rng
2116 set $var_iemgui_rng_sch $rng_sched
2117 set $var_iemgui_lin0_log1 $lin0_log1
2118 set $var_iemgui_lilo0 $lilo0_label
2119 set $var_iemgui_lilo1 $lilo1_label
2120 set $var_iemgui_loadbang $loadbang
2121 set $var_iemgui_num $num
2122 set $var_iemgui_steady $steady
2123 if {$snd == "empty"} {set $var_iemgui_snd [format ""]
2124 } else {set $var_iemgui_snd [format "%s" $snd]}
2125 if {$rcv == "empty"} {set $var_iemgui_rcv [format ""]
2126 } else {set $var_iemgui_rcv [format "%s" $rcv]}
2127 if {$gui_name == "empty"} {set $var_iemgui_gui_nam [format ""]
2128 } else {set $var_iemgui_gui_nam [format "%s" $gui_name]}
2129
2130 if {[string index [eval concat $$var_iemgui_snd] 0] == "#"} {
2131 set $var_iemgui_snd [string replace [eval concat $$var_iemgui_snd] 0 0 $] }
2132 if {[string index [eval concat $$var_iemgui_rcv] 0] == "#"} {
2133 set $var_iemgui_rcv [string replace [eval concat $$var_iemgui_rcv] 0 0 $] }
2134 if {[string index [eval concat $$var_iemgui_gui_nam] 0] == "#"} {
2135 set $var_iemgui_gui_nam [string replace [eval concat $$var_iemgui_gui_nam] 0 0 $] }
2136 set $var_iemgui_gn_dx $gn_dx
2137 set $var_iemgui_gn_dy $gn_dy
2138 set $var_iemgui_gn_f $gn_f
2139 set $var_iemgui_gn_fs $gn_fs
2140
2141 set $var_iemgui_bcol $bcol
2142 set $var_iemgui_fcol $fcol
2143 set $var_iemgui_lcol $lcol
2144
2145 set $var_iemgui_l2_f1_b0 0
2146
2147 toplevel $id
2148 wm title $id [format "%s-PROPERTIES" $mainheader]
2149 wm protocol $id WM_DELETE_WINDOW [concat iemgui_cancel $id]
2150
2151 frame $id.dim
2152 pack $id.dim -side top
2153 label $id.dim.head -text $dim_header
2154 label $id.dim.w_lab -text $wdt_label -width 6
2155 entry $id.dim.w_ent -textvariable $var_iemgui_wdt -width 5
2156 label $id.dim.dummy1 -text " " -width 10
2157 label $id.dim.h_lab -text $hgt_label -width 6
2158 entry $id.dim.h_ent -textvariable $var_iemgui_hgt -width 5
2159 pack $id.dim.head -side top
2160 pack $id.dim.w_lab $id.dim.w_ent $id.dim.dummy1 -side left
2161 if { $hgt_label != "empty" } {
2162 pack $id.dim.h_lab $id.dim.h_ent -side left}
2163
2164 frame $id.rng
2165 pack $id.rng -side top
2166 label $id.rng.head -text $rng_header
2167 label $id.rng.min_lab -text $min_rng_label -width 6
2168 entry $id.rng.min_ent -textvariable $var_iemgui_min_rng -width 9
2169 label $id.rng.dummy1 -text " " -width 1
2170 label $id.rng.max_lab -text $max_rng_label -width 8
2171 entry $id.rng.max_ent -textvariable $var_iemgui_max_rng -width 9
2172 if { $rng_header != "empty" } {
2173 pack $id.rng.head -side top
2174 if { $min_rng_label != "empty" } {
2175 pack $id.rng.min_lab $id.rng.min_ent -side left}
2176 if { $max_rng_label != "empty" } {
2177 pack $id.rng.dummy1 \
2178 $id.rng.max_lab $id.rng.max_ent -side left} }
2179
2180 if { [eval concat $$var_iemgui_lin0_log1] >= 0 || [eval concat $$var_iemgui_loadbang] >= 0 || [eval concat $$var_iemgui_num] > 0 || [eval concat $$var_iemgui_steady] >= 0 } {
2181 label $id.space1 -text "---------------------------------"
2182 pack $id.space1 -side top }
2183
2184 frame $id.para
2185 pack $id.para -side top
2186 label $id.para.dummy2 -text "" -width 1
2187 label $id.para.dummy3 -text "" -width 1
2188 if {[eval concat $$var_iemgui_lin0_log1] == 0} {
2189 button $id.para.lilo -text [eval concat $$var_iemgui_lilo0] -width 5 -command "iemgui_lilo $id" }
2190 if {[eval concat $$var_iemgui_lin0_log1] == 1} {
2191 button $id.para.lilo -text [eval concat $$var_iemgui_lilo1] -width 5 -command "iemgui_lilo $id" }
2192 if {[eval concat $$var_iemgui_loadbang] == 0} {
2193 button $id.para.lb -text "no init" -width 5 -command "iemgui_lb $id" }
2194 if {[eval concat $$var_iemgui_loadbang] == 1} {
2195 button $id.para.lb -text "init" -width 5 -command "iemgui_lb $id" }
2196 label $id.para.num_lab -text $num_label -width 9
2197 entry $id.para.num_ent -textvariable $var_iemgui_num -width 4
2198 if {[eval concat $$var_iemgui_steady] == 0} {
2199 button $id.para.stdy_jmp -text "jump on click" -width 11 -command "iemgui_stdy_jmp $id" }
2200 if {[eval concat $$var_iemgui_steady] == 1} {
2201 button $id.para.stdy_jmp -text "steady on click" -width 11 -command "iemgui_stdy_jmp $id" }
2202 if {[eval concat $$var_iemgui_lin0_log1] >= 0} {
2203 pack $id.para.lilo -side left -expand 1}
2204 if {[eval concat $$var_iemgui_loadbang] >= 0} {
2205 pack $id.para.dummy2 $id.para.lb -side left -expand 1}
2206 if {[eval concat $$var_iemgui_num] > 0} {
2207 pack $id.para.dummy3 $id.para.num_lab $id.para.num_ent -side left -expand 1}
2208 if {[eval concat $$var_iemgui_steady] >= 0} {
2209 pack $id.para.dummy3 $id.para.stdy_jmp -side left -expand 1}
2210 if { $snd != "nosndno" || $rcv != "norcvno" } {
2211 label $id.space2 -text "---------------------------------"
2212 pack $id.space2 -side top }
2213
2214 frame $id.snd
2215 pack $id.snd -side top
2216 label $id.snd.dummy1 -text "" -width 2
2217 label $id.snd.lab -text "send-symbol:" -width 12
2218 entry $id.snd.ent -textvariable $var_iemgui_snd -width 20
2219 if { $snd != "nosndno" } {
2220 pack $id.snd.dummy1 $id.snd.lab $id.snd.ent -side left}
2221
2222 frame $id.rcv
2223 pack $id.rcv -side top
2224 label $id.rcv.lab -text "receive-symbol:" -width 15
2225 entry $id.rcv.ent -textvariable $var_iemgui_rcv -width 20
2226 if { $rcv != "norcvno" } {
2227 pack $id.rcv.lab $id.rcv.ent -side left}
2228
2229 frame $id.gnam
2230 pack $id.gnam -side top
2231 label $id.gnam.head -text "--------------label:---------------"
2232 label $id.gnam.dummy1 -text "" -width 1
2233 label $id.gnam.lab -text "name:" -width 6
2234 entry $id.gnam.ent -textvariable $var_iemgui_gui_nam -width 29
2235 label $id.gnam.dummy2 -text "" -width 1
2236 pack $id.gnam.head -side top
2237 pack $id.gnam.dummy1 $id.gnam.lab $id.gnam.ent $id.gnam.dummy2 -side left
2238
2239 frame $id.gnxy
2240 pack $id.gnxy -side top
2241 label $id.gnxy.x_lab -text "x_off:" -width 6
2242 entry $id.gnxy.x_ent -textvariable $var_iemgui_gn_dx -width 5
2243 label $id.gnxy.dummy1 -text " " -width 10
2244 label $id.gnxy.y_lab -text "y_off:" -width 6
2245 entry $id.gnxy.y_ent -textvariable $var_iemgui_gn_dy -width 5
2246 pack $id.gnxy.x_lab $id.gnxy.x_ent $id.gnxy.dummy1 \
2247 $id.gnxy.y_lab $id.gnxy.y_ent -side left
2248
2249 frame $id.gnfs
2250 pack $id.gnfs -side top
2251 label $id.gnfs.f_lab -text "font:" -width 6
2252 if {[eval concat $$var_iemgui_gn_f] == 0} {
2253 button $id.gnfs.fb -text "courier" -font {courier 10 bold} -width 7 -command "iemgui_toggle_font $id" }
2254 if {[eval concat $$var_iemgui_gn_f] == 1} {
2255 button $id.gnfs.fb -text "helvetica" -font {helvetica 10 bold} -width 7 -command "iemgui_toggle_font $id" }
2256 if {[eval concat $$var_iemgui_gn_f] == 2} {
2257 button $id.gnfs.fb -text "times" -font {times 10 bold} -width 7 -command "iemgui_toggle_font $id" }
2258 label $id.gnfs.dummy1 -text "" -width 1
2259 label $id.gnfs.fs_lab -text "fontsize:" -width 8
2260 entry $id.gnfs.fs_ent -textvariable $var_iemgui_gn_fs -width 5
2261 pack $id.gnfs.f_lab $id.gnfs.fb $id.gnfs.dummy1 \
2262 $id.gnfs.fs_lab $id.gnfs.fs_ent -side left
2263
2264 label $id.col_head -text "--------------colors:--------------"
2265 pack $id.col_head -side top
2266
2267 frame $id.col_select
2268 pack $id.col_select -side top
2269 radiobutton $id.col_select.radio0 -value 0 -variable $var_iemgui_l2_f1_b0 \
2270 -text "backgd" -width 5
2271 radiobutton $id.col_select.radio1 -value 1 -variable $var_iemgui_l2_f1_b0 \
2272 -text "front" -width 5
2273 radiobutton $id.col_select.radio2 -value 2 -variable $var_iemgui_l2_f1_b0 \
2274 -text "label" -width 5
2275 if { [eval concat $$var_iemgui_fcol] >= 0 } {
2276 pack $id.col_select.radio0 $id.col_select.radio1 $id.col_select.radio2 -side left
2277 } else {pack $id.col_select.radio0 $id.col_select.radio2 -side left}
2278
2279 frame $id.col_example_choose
2280 pack $id.col_example_choose -side top
2281 button $id.col_example_choose.but -text "compose color" -width 10 \
2282 -command "iemgui_choose_col_bkfrlb $id"
2283 label $id.col_example_choose.dummy1 -text "" -width 1
2284 if { [eval concat $$var_iemgui_fcol] >= 0 } {
2285 button $id.col_example_choose.fr_bk -text "o=||=o" -width 5 \
2286 -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2287 -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2288 -foreground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] \
2289 -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_fcol]] -pady 2
2290 } else {
2291 button $id.col_example_choose.fr_bk -text "o=||=o" -width 5 \
2292 -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2293 -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2294 -foreground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2295 -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] -pady 2}
2296 button $id.col_example_choose.lb_bk -text "testlabel" -width 7 \
2297 -background [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2298 -activebackground [format "#%6.6x" [eval concat $$var_iemgui_bcol]] \
2299 -foreground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] \
2300 -activeforeground [format "#%6.6x" [eval concat $$var_iemgui_lcol]] -pady 2
2301
2302 pack $id.col_example_choose.but $id.col_example_choose.dummy1 \
2303 $id.col_example_choose.fr_bk $id.col_example_choose.lb_bk -side left
2304
2305 label $id.space3 -text "------or click color preset:-------"
2306 pack $id.space3 -side top
2307
2308 frame $id.bcol
2309 pack $id.bcol -side top
2310 foreach i { 0 1 2 3 4 5 6 7 8 9 } hexcol { 16579836 14737632 12369084 \
2311 16572640 16572608 16579784 14220504 14220540 14476540 16308476 } {
2312 button $id.bcol.c$i -background [format "#%6.6x" $hexcol] \
2313 -activebackground [format "#%6.6x" $hexcol] \
2314 -font {courier 2 normal} -padx 7 -pady 6 \
2315 -command [format "iemgui_preset_col %s %d" $id $hexcol] }
2316 pack $id.bcol.c0 $id.bcol.c1 $id.bcol.c2 $id.bcol.c3 $id.bcol.c4 \
2317 $id.bcol.c5 $id.bcol.c6 $id.bcol.c7 $id.bcol.c8 $id.bcol.c9 -side left
2318
2319 frame $id.fcol
2320 pack $id.fcol -side top
2321 foreach i { 0 1 2 3 4 5 6 7 8 9 } hexcol { 10526880 8158332 6316128 \
2322 16525352 16559172 15263784 1370132 2684148 3952892 16003312 } {
2323 button $id.fcol.c$i -background [format "#%6.6x" $hexcol] \
2324 -activebackground [format "#%6.6x" $hexcol] \
2325 -font {courier 2 normal} -padx 7 -pady 6 \
2326 -command [format "iemgui_preset_col %s %d" $id $hexcol] }
2327 pack $id.fcol.c0 $id.fcol.c1 $id.fcol.c2 $id.fcol.c3 $id.fcol.c4 \
2328 $id.fcol.c5 $id.fcol.c6 $id.fcol.c7 $id.fcol.c8 $id.fcol.c9 -side left
2329
2330 frame $id.lcol
2331 pack $id.lcol -side top
2332 foreach i { 0 1 2 3 4 5 6 7 8 9 } hexcol { 4210752 2105376 0 \
2333 9177096 5779456 7874580 2641940 17488 5256 5767248 } {
2334 button $id.lcol.c$i -background [format "#%6.6x" $hexcol] \
2335 -activebackground [format "#%6.6x" $hexcol] \
2336 -font {courier 2 normal} -padx 7 -pady 6 \
2337 -command [format "iemgui_preset_col %s %d" $id $hexcol] }
2338 pack $id.lcol.c0 $id.lcol.c1 $id.lcol.c2 $id.lcol.c3 $id.lcol.c4 \
2339 $id.lcol.c5 $id.lcol.c6 $id.lcol.c7 $id.lcol.c8 $id.lcol.c9 -side left
2340
2341
2342 label $id.space4 -text "---------------------------------"
2343 pack $id.space4 -side top
2344
2345 frame $id.cao
2346 pack $id.cao -side top
2347 button $id.cao.cancel -text {Cancel} -width 6 \
2348 -command "iemgui_cancel $id"
2349 label $id.cao.dummy1 -text "" -width 3
2350 button $id.cao.apply -text {Apply} -width 6 \
2351 -command "iemgui_apply $id"
2352 label $id.cao.dummy2 -text "" -width 3
2353 button $id.cao.ok -text {OK} -width 6 \
2354 -command "iemgui_ok $id"
2355 pack $id.cao.cancel $id.cao.dummy1 \
2356 $id.cao.apply $id.cao.dummy2 \
2357 $id.cao.ok -side left
2358
2359 label $id.space5 -text ""
2360 pack $id.space5 -side top
2361
2362 if {[info tclversion] < 8.4} {
2363 bind $id <Key-Tab> {tkTabToWindow [tk_focusNext %W]}
2364 bind $id <<PrevWindow>> {tkTabToWindow [tk_focusPrev %W]}
2365 } else {
2366 bind $id <Key-Tab> {tk::TabToWindow [tk_focusNext %W]}
2367 bind $id <<PrevWindow>> {tk::TabToWindow [tk_focusPrev %W]}
2368 }
2369
2370 bind $id.dim.w_ent <KeyPress-Return> [concat iemgui_ok $id]
2371 bind $id.dim.h_ent <KeyPress-Return> [concat iemgui_ok $id]
2372 bind $id.rng.min_ent <KeyPress-Return> [concat iemgui_ok $id]
2373 bind $id.rng.max_ent <KeyPress-Return> [concat iemgui_ok $id]
2374 bind $id.para.num_ent <KeyPress-Return> [concat iemgui_ok $id]
2375 bind $id.snd.ent <KeyPress-Return> [concat iemgui_ok $id]
2376 bind $id.rcv.ent <KeyPress-Return> [concat iemgui_ok $id]
2377 bind $id.gnam.ent <KeyPress-Return> [concat iemgui_ok $id]
2378 bind $id.gnxy.x_ent <KeyPress-Return> [concat iemgui_ok $id]
2379 bind $id.gnxy.y_ent <KeyPress-Return> [concat iemgui_ok $id]
2380 bind $id.gnfs.fs_ent <KeyPress-Return> [concat iemgui_ok $id]
2381 bind $id.cao.ok <KeyPress-Return> [concat iemgui_ok $id]
2382
2383 $id.dim.w_ent select from 0
2384 $id.dim.w_ent select adjust end
2385 focus $id.dim.w_ent
2386}
2387# end of change "iemlib"
2388
2389############ pdtk_array_dialog -- dialog window for arrays #########
2390proc array_apply {id} {
2391# strip "." from the TK id to make a variable name suffix
2392 set vid [string trimleft $id .]
2393# for each variable, make a local variable to hold its name...
2394 set var_array_name [concat array_name_$vid]
2395 global $var_array_name
2396 set var_array_n [concat array_n_$vid]
2397 global $var_array_n
2398 set var_array_saveit [concat array_saveit_$vid]
2399 global $var_array_saveit
2400 set var_array_otherflag [concat array_otherflag_$vid]
2401 global $var_array_otherflag
2402 set mofo [eval concat $$var_array_name]
2403 if {[string index $mofo 0] == "$"} {
2404 set mofo [string replace $mofo 0 0 #] }
2405
2406 pd [concat $id arraydialog $mofo \
2407 [eval concat $$var_array_n] \
2408 [eval concat $$var_array_saveit] \
2409 [eval concat $$var_array_otherflag] \
2410 \;]
2411}
2412
2413proc array_cancel {id} {
2414 set cmd [concat $id cancel \;]
2415 pd $cmd
2416}
2417
2418proc array_ok {id} {
2419 array_apply $id
2420 array_cancel $id
2421}
2422
2423proc pdtk_array_dialog {id name n saveit newone} {
2424 set vid [string trimleft $id .]
2425
2426 set var_array_name [concat array_name_$vid]
2427 global $var_array_name
2428 set var_array_n [concat array_n_$vid]
2429 global $var_array_n
2430 set var_array_saveit [concat array_saveit_$vid]
2431 global $var_array_saveit
2432 set var_array_otherflag [concat array_otherflag_$vid]
2433 global $var_array_otherflag
2434
2435 set $var_array_name $name
2436 set $var_array_n $n
2437 set $var_array_saveit $saveit
2438 set $var_array_otherflag 0
2439
2440 toplevel $id
2441 wm title $id {array}
2442 wm protocol $id WM_DELETE_WINDOW [concat array_cancel $id]
2443
2444 frame $id.name
2445 pack $id.name -side top
2446 label $id.name.label -text "name"
2447 entry $id.name.entry -textvariable $var_array_name
2448 pack $id.name.label $id.name.entry -side left
2449
2450 frame $id.n
2451 pack $id.n -side top
2452 label $id.n.label -text "size"
2453 entry $id.n.entry -textvariable $var_array_n
2454 pack $id.n.label $id.n.entry -side left
2455
2456 checkbutton $id.saveme -text {save contents} -variable $var_array_saveit \
2457 -anchor w
2458 pack $id.saveme -side top
2459
2460 if {$newone != 0} {
2461 frame $id.radio
2462 pack $id.radio -side top
2463 radiobutton $id.radio.radio0 -value 0 \
2464 -variable $var_array_otherflag \
2465 -text "in new graph"
2466 radiobutton $id.radio.radio1 -value 1 \
2467 -variable $var_array_otherflag \
2468 -text "in last graph"
2469 pack $id.radio.radio0 -side top -anchor w
2470 pack $id.radio.radio1 -side top -anchor w
2471 } else {
2472 checkbutton $id.deleteme -text {delete me} \
2473 -variable $var_array_otherflag -anchor w
2474 pack $id.deleteme -side top
2475 }
2476 frame $id.buttonframe
2477 pack $id.buttonframe -side bottom -fill x -pady 2m
2478 button $id.buttonframe.cancel -text {Cancel}\
2479 -command "array_cancel $id"
2480 if {$newone == 0} {button $id.buttonframe.apply -text {Apply}\
2481 -command "array_apply $id"}
2482 button $id.buttonframe.ok -text {OK}\
2483 -command "array_ok $id"
2484 pack $id.buttonframe.cancel -side left -expand 1
2485 if {$newone == 0} {pack $id.buttonframe.apply -side left -expand 1}
2486 pack $id.buttonframe.ok -side left -expand 1
2487
2488 bind $id.name.entry <KeyPress-Return> [concat array_ok $id]
2489 bind $id.n.entry <KeyPress-Return> [concat array_ok $id]
2490 $id.name.entry select from 0
2491 $id.name.entry select adjust end
2492 focus $id.name.entry
2493}
2494
2495############ pdtk_canvas_dialog -- dialog window for canvass #########
2496proc canvas_apply {id} {
2497# strip "." from the TK id to make a variable name suffix
2498 set vid [string trimleft $id .]
2499# for each variable, make a local variable to hold its name...
2500 set var_canvas_xscale [concat canvas_xscale_$vid]
2501 global $var_canvas_xscale
2502 set var_canvas_yscale [concat canvas_yscale_$vid]
2503 global $var_canvas_yscale
2504 set var_canvas_graphme [concat canvas_graphme_$vid]
2505 global $var_canvas_graphme
2506# set var_canvas_stretch [concat canvas_stretch_$vid]
2507# global $var_canvas_stretch
2508 pd [concat $id donecanvasdialog \
2509 [eval concat $$var_canvas_xscale] \
2510 [eval concat $$var_canvas_yscale] \
2511 [eval concat $$var_canvas_graphme] \
2512 \;]
2513}
2514
2515proc canvas_cancel {id} {
2516 set cmd [concat $id cancel \;]
2517 pd $cmd
2518}
2519
2520proc canvas_ok {id} {
2521 canvas_apply $id
2522 canvas_cancel $id
2523}
2524
2525proc pdtk_canvas_dialog {id xscale yscale graphme stretch} {
2526 set vid [string trimleft $id .]
2527
2528 set var_canvas_xscale [concat canvas_xscale_$vid]
2529 global $var_canvas_xscale
2530 set var_canvas_yscale [concat canvas_yscale_$vid]
2531 global $var_canvas_yscale
2532 set var_canvas_graphme [concat canvas_graphme_$vid]
2533 global $var_canvas_graphme
2534# set var_canvas_stretch [concat canvas_stretch_$vid]
2535# global $var_canvas_stretch
2536
2537 set $var_canvas_xscale $xscale
2538 set $var_canvas_yscale $yscale
2539 set $var_canvas_graphme $graphme
2540# set $var_canvas_stretch $stretch
2541
2542 toplevel $id
2543 wm title $id {canvas}
2544 wm protocol $id WM_DELETE_WINDOW [concat canvas_cancel $id]
2545
2546 frame $id.xscale
2547 pack $id.xscale -side top
2548 label $id.xscale.label -text "X units per pixel"
2549 entry $id.xscale.entry -textvariable $var_canvas_xscale -width 10
2550 pack $id.xscale.label $id.xscale.entry -side left
2551
2552 frame $id.yscale
2553 pack $id.yscale -side top
2554 label $id.yscale.label -text "Y units per pixel"
2555 entry $id.yscale.entry -textvariable $var_canvas_yscale -width 10
2556 pack $id.yscale.label $id.yscale.entry -side left
2557
2558 checkbutton $id.graphme -text {graph on parent} \
2559 -variable $var_canvas_graphme -anchor w
2560 pack $id.graphme -side top
2561
2562# checkbutton $id.stretch -text {stretch on resize} \
2563# -variable $var_canvas_stretch -anchor w
2564# pack $id.stretch -side top
2565
2566
2567 frame $id.buttonframe
2568 pack $id.buttonframe -side bottom -fill x -pady 2m
2569 button $id.buttonframe.cancel -text {Cancel}\
2570 -command "canvas_cancel $id"
2571 button $id.buttonframe.apply -text {Apply}\
2572 -command "canvas_apply $id"
2573 button $id.buttonframe.ok -text {OK}\
2574 -command "canvas_ok $id"
2575 pack $id.buttonframe.cancel -side left -expand 1
2576 pack $id.buttonframe.apply -side left -expand 1
2577 pack $id.buttonframe.ok -side left -expand 1
2578
2579 bind $id.xscale.entry <KeyPress-Return> [concat canvas_ok $id]
2580 bind $id.yscale.entry <KeyPress-Return> [concat canvas_ok $id]
2581 $id.xscale.entry select from 0
2582 $id.xscale.entry select adjust end
2583 focus $id.xscale.entry
2584}
2585
2586############ pdtk_data_dialog -- run a data dialog #########
2587proc dodata_send {name} {
2588# puts stderr [$name.text get 0.0 end]
2589
2590 for {set i 1} {[$name.text compare [concat $i.0 + 3 chars] < end]} \
2591 {incr i 1} {
2592# puts stderr [concat it's [$name.text get $i.0 [expr $i + 1].0]]
2593 set cmd [concat $name data [$name.text get $i.0 [expr $i + 1].0] \;]
2594# puts stderr $cmd
2595 pd $cmd
2596 }
2597 set cmd [concat $name end \;]
2598# puts stderr $cmd
2599 pd $cmd
2600}
2601
2602proc dodata_cancel {name} {
2603 set cmd [concat $name cancel \;]
2604# puts stderr $cmd
2605 pd $cmd
2606}
2607
2608proc dodata_ok {name} {
2609 dodata_send $name
2610 dodata_cancel $name
2611}
2612
2613proc pdtk_data_dialog {name stuff} {
2614
2615 toplevel $name
2616 wm title $name {Atom}
2617 wm protocol $name WM_DELETE_WINDOW [concat dodata_cancel $name]
2618
2619 frame $name.buttonframe
2620 pack $name.buttonframe -side bottom -fill x -pady 2m
2621 button $name.buttonframe.send -text {Send (Ctrl s)}\
2622 -command [concat dodata_send $name]
2623 button $name.buttonframe.ok -text {OK (Ctrl t)}\
2624 -command [concat dodata_ok $name]
2625 pack $name.buttonframe.send -side left -expand 1
2626 pack $name.buttonframe.ok -side left -expand 1
2627
2628 text $name.text -relief raised -bd 2 -height 40 -width 60 \
2629 -yscrollcommand "$name.scroll set" -font -*-courier-bold--normal--12-*
2630 scrollbar $name.scroll -command "$name.text yview"
2631 pack $name.scroll -side right -fill y
2632 pack $name.text -side left -fill both -expand 1
2633 $name.text insert end $stuff
2634 focus $name.text
2635 bind $name.text <Control-t> [concat dodata_ok $name]
2636 bind $name.text <Control-s> [concat dodata_send $name]
2637}
2638
2639############ check or uncheck the "edit" menu item ##############
2640#####################iemlib#######################
2641proc pdtk_canvas_editval {name value} {
2642 if { $value } {
2643 $name.m.edit entryconfigure "Edit mode" -indicatoron true
2644 } else {
2645 $name.m.edit entryconfigure "Edit mode" -indicatoron false
2646 }
2647}
2648#####################iemlib#######################
2649
2650############ pdtk_text_new -- create a new text object #2###########
2651proc pdtk_text_new {canvasname myname x y text font color} {
2652# if {$font < 13} {set fontname [format -*-courier-bold----%d-* $font]}
2653# if {$font >= 13} {set fontname [format -*-courier-----%d-* $font]}
2654 $canvasname create text $x $y \
2655 -font [format -*-courier-bold--normal--%d-* $font] \
2656 -tags $myname -text $text -fill $color -anchor nw
2657# pd [concat $myname size [$canvasname bbox $myname] \;]
2658}
2659
2660################ pdtk_text_set -- change the text ##################
2661proc pdtk_text_set {canvasname myname text} {
2662 $canvasname itemconfig $myname -text $text
2663# pd [concat $myname size [$canvasname bbox $myname] \;]
2664}
2665
2666############### event binding procedures for Pd window ################
2667
2668proc pdtk_pd_ctrlkey {name key shift} {
2669# puts stderr [concat key $key shift $shift]
2670# .dummy itemconfig goo -text [concat ---> control-key event $key];
2671 if {$key == "n" || $key == "N"} {menu_new}
2672 if {$key == "o" || $key == "O"} {menu_open}
2673 if {$key == "m" || $key == "M"} {menu_send}
2674 if {$key == "q" || $key == "Q"} {
2675 if {$shift == 1} {menu_really_quit} else {menu_quit}
2676 }
2677 if {$key == "slash"} {menu_audio 1}
2678 if {$key == "period"} {menu_audio 0}
2679}
2680
2681######### startup function. ##############
2682# Tell pd the current directory; this is used in case the command line
2683# asked pd to open something. Also, get character width and height for
2684# font sizes 8, 10, 12, 14, 16, and 24.
2685
2686proc pdtk_pd_startup {version apilist} {
2687 global pd_myversion pd_apilist
2688 set pd_myversion $version
2689 set pd_apilist $apilist
2690
2691 set width1 [font measure -*-courier-bold--normal--8-* x]
2692 set height1 [lindex [font metrics -*-courier-bold--normal--8-*] 5]
2693
2694 set width2 [font measure -*-courier-bold--normal--10-* x]
2695 set height2 [lindex [font metrics -*-courier-bold--normal--10-*] 5]
2696
2697 set width3 [font measure -*-courier-bold--normal--12-* x]
2698 set height3 [lindex [font metrics -*-courier-bold--normal--12-*] 5]
2699
2700 set width4 [font measure -*-courier-bold--normal--14-* x]
2701 set height4 [lindex [font metrics -*-courier-bold--normal--14-*] 5]
2702
2703 set width5 [font measure -*-courier-bold--normal--16-* x]
2704 set height5 [lindex [font metrics -*-courier-bold--normal--16-*] 5]
2705
2706 set width6 [font measure -*-courier-bold--normal--24-* x]
2707 set height6 [lindex [font metrics -*-courier-bold--normal--24-*] 5]
2708
2709 set width7 [font measure -*-courier-bold--normal--36-* x]
2710 set height7 [lindex [font metrics -*-courier-bold--normal--36-*] 5]
2711
2712 set tclpatch [info patchlevel]
2713 if {$tclpatch == "8.3.0" || \
2714 $tclpatch == "8.3.1" || \
2715 $tclpatch == "8.3.2" || \
2716 $tclpatch == "8.3.3" } {
2717 set oldtclversion 1
2718 } else {
2719 set oldtclversion 0
2720 }
2721 pd [concat pd init [pdtk_enquote [pwd]] \
2722 8 $width1 $height1 \
2723 10 $width2 $height2 \
2724 12 $width3 $height3 \
2725 14 $width4 $height4 \
2726 16 $width5 $height5 \
2727 24 $width6 $height6 \
2728 36 $width7 $height7 \
2729 $oldtclversion \;];
2730
2731 # add the audio and help menus to the Pd window. We delayed this
2732 # so that we'd know the value of "apilist".
2733 menu_addstd .mbar
2734
2735}
2736
2737##################### DSP ON/OFF, METERS, DIO ERROR ###################
2738proc pdtk_pd_dsp {value} {
2739 global ctrls_audio_on
2740 if {$value == "ON"} {set ctrls_audio_on 1} else {set ctrls_audio_on 0}
2741# puts stderr [concat its $ctrls_audio_on]
2742}
2743
2744proc pdtk_pd_meters {indb outdb inclip outclip} {
2745# puts stderr [concat meters $indb $outdb $inclip $outclip]
2746 global ctrls_inlevel ctrls_outlevel
2747 set ctrls_inlevel $indb
2748 if {$inclip == 1} {
2749 .controls.inout.in.clip configure -background red
2750 } else {
2751 .controls.inout.in.clip configure -background grey
2752 }
2753 set ctrls_outlevel $outdb
2754 if {$outclip == 1} {
2755 .controls.inout.out.clip configure -background red
2756 } else {
2757 .controls.inout.out.clip configure -background grey
2758 }
2759
2760}
2761
2762proc pdtk_pd_dio {red} {
2763# puts stderr [concat dio $red]
2764 if {$red == 1} {
2765 .controls.dio configure -background red -activebackground red
2766 } else {
2767 .controls.dio configure -background grey -activebackground lightgrey
2768 }
2769
2770}
2771
2772############# text editing from the "edit" menu ###################
2773set edit_number 1
2774
2775proc texteditor_send {name} {
2776 set topname [string trimright $name .text]
2777 for {set i 0} \
2778 {[$name compare [concat 0.0 + [expr $i + 1] chars] < end]} \
2779 {incr i 1} {
2780 set cha [$name get [concat 0.0 + $i chars]]
2781 scan $cha %c keynum
2782 pd [concat pd key 1 $keynum 0 \;]
2783 }
2784}
2785
2786proc texteditor_ok {name} {
2787 set topname [string trimright $name .text]
2788 texteditor_send $name
2789 destroy $topname
2790}
2791
2792
2793proc pdtk_pd_texteditor {stuff} {
2794 global edit_number
2795 set name [format ".text%d" $edit_number]
2796 set edit_number [expr $edit_number + 1]
2797
2798 toplevel $name
2799 wm title $name {TEXT}
2800
2801 frame $name.buttons
2802 pack $name.buttons -side bottom -fill x -pady 2m
2803 button $name.buttons.send -text {Send (Ctrl s)}\
2804 -command "texteditor_send $name.text"
2805 button $name.buttons.ok -text {OK (Ctrl t)}\
2806 -command "texteditor_ok $name.text"
2807 pack $name.buttons.send -side left -expand 1
2808 pack $name.buttons.ok -side left -expand 1
2809
2810 text $name.text -relief raised -bd 2 -height 12 -width 60 \
2811 -yscrollcommand "$name.scroll set" -font -*-courier-bold--normal--12-*
2812 scrollbar $name.scroll -command "$name.text yview"
2813 pack $name.scroll -side right -fill y
2814 pack $name.text -side left -fill both -expand 1
2815 $name.text insert end $stuff
2816 focus $name.text
2817 bind $name.text <Control-t> {texteditor_ok %W}
2818 bind $name.text <Control-s> {texteditor_send %W}
2819}
2820
2821############# open and save dialogs for objects in Pd ##########
2822
2823proc pdtk_openpanel {target} {
2824 global pd_opendir
2825 set filename [tk_getOpenFile \
2826 -initialdir $pd_opendir]
2827 if {$filename != ""} {
2828 set directory [string range $filename 0 \
2829 [expr [string last / $filename ] - 1]]
2830 set pd_opendir $directory
2831
2832 pd [concat $target symbol [pdtk_enquote $filename] \;]
2833 }
2834}
2835
2836proc pdtk_savepanel {target} {
2837 set filename [tk_getSaveFile]
2838 if {$filename != ""} {
2839 pd [concat $target symbol [pdtk_enquote $filename] \;]
2840 }
2841}
2842
2843########################### comport hack ########################
2844
2845set com1 0
2846set com2 0
2847set com3 0
2848set com4 0
2849
2850proc com1_open {} {
2851 global com1
2852 set com1 [open com1 w]
2853 .dummy itemconfig goo -text $com1
2854 fconfigure $com1 -buffering none
2855 fconfigure $com1 -mode 19200,e,8,2
2856}
2857
2858proc com1_send {str} {
2859 global com1
2860 puts -nonewline $com1 $str
2861}
2862
2863
2864############# start a polling process to watch the socket ##############
2865# this is needed for nt, and presumably for Mac as well.
2866# in UNIX this is handled by a tcl callback (set up in t_tkcmd.c)
2867
2868if {$pd_nt == 1} {
2869 proc polleofloop {} {
2870 pd_pollsocket
2871 after 20 polleofloop
2872 }
2873
2874 polleofloop
2875}
2876
2877####################### audio dialog ##################3
2878
2879proc audio_apply {id} {
2880 global audio_indev1 audio_indev2 audio_indev3 audio_indev4
2881 global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4
2882 global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4
2883 global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4
2884 global audio_sr audio_advance
2885
2886 pd [concat pd audio-dialog \
2887 $audio_indev1 \
2888 $audio_indev2 \
2889 $audio_indev3 \
2890 $audio_indev4 \
2891 $audio_inchan1 \
2892 $audio_inchan2 \
2893 $audio_inchan3 \
2894 $audio_inchan4 \
2895 $audio_outdev1 \
2896 $audio_outdev2 \
2897 $audio_outdev3 \
2898 $audio_outdev4 \
2899 $audio_outchan1 \
2900 $audio_outchan2 \
2901 $audio_outchan3 \
2902 $audio_outchan4 \
2903 $audio_sr \
2904 $audio_advance \
2905 \;]
2906}
2907
2908proc audio_cancel {id} {
2909 pd [concat $id cancel \;]
2910}
2911
2912proc audio_ok {id} {
2913 audio_apply $id
2914 audio_cancel $id
2915}
2916
2917# callback from popup menu
2918proc audio_popup_action {buttonname varname devlist index} {
2919 global audio_indevlist audio_outdevlist $varname
2920 $buttonname configure -text [lindex $devlist $index]
2921# puts stderr [concat popup_action $buttonname $varname $index]
2922 set $varname $index
2923}
2924
2925# create a popup menu
2926proc audio_popup {name buttonname varname devlist} {
2927 if [winfo exists $name.popup] {destroy $name.popup}
2928 menu $name.popup -tearoff false
2929# puts stderr [concat $devlist ]
2930 for {set x 0} {$x<[llength $devlist]} {incr x} {
2931 $name.popup add command -label [lindex $devlist $x] \
2932 -command [list audio_popup_action \
2933 $buttonname $varname $devlist $x]
2934 }
2935 tk_popup $name.popup [winfo pointerx $name] [winfo pointery $name] 0
2936}
2937
2938# start a dialog window to select audio devices and settings. "multi"
2939# is 0 if only one device is allowed; 1 if one apiece may be specified for
2940# input and output; and 2 if we can select multiple devices. "longform"
2941# (which only makes sense if "multi" is 2) asks us to make controls for
2942# opening several devices; if not, we get an extra button to turn longform
2943# on and restart the dialog.
2944
2945proc pdtk_audio_dialog {id indevlist indev1 indev2 indev3 indev4 \
2946 inchan1 inchan2 inchan3 inchan4 \
2947 outdevlist outdev1 outdev2 outdev3 outdev4 \
2948 outchan1 outchan2 outchan3 outchan4 sr advance multi longform} {
2949 global audio_indev1 audio_indev2 audio_indev3 audio_indev4
2950 global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4
2951 global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4
2952 global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4
2953 global audio_sr audio_advance
2954 global audio_indevlist audio_outdevlist
2955
2956 set audio_indev1 $indev1
2957 set audio_indev2 $indev2
2958 set audio_indev3 $indev3
2959 set audio_indev4 $indev4
2960 set audio_inchan1 $inchan1
2961 set audio_inchan2 $inchan2
2962 set audio_inchan3 $inchan3
2963 set audio_inchan4 $inchan4
2964 set audio_outdev1 $outdev1
2965 set audio_outdev2 $outdev2
2966 set audio_outdev3 $outdev3
2967 set audio_outdev4 $outdev4
2968 set audio_outchan1 $outchan1
2969 set audio_outchan2 $outchan2
2970 set audio_outchan3 $outchan3
2971 set audio_outchan4 $outchan4
2972 set audio_sr $sr
2973 set audio_advance $advance
2974 set audio_indevlist $indevlist
2975 set audio_outdevlist $outdevlist
2976
2977 toplevel $id
2978 wm title $id {audio}
2979 wm protocol $id WM_DELETE_WINDOW [concat audio_cancel $id]
2980
2981 frame $id.buttonframe
2982 pack $id.buttonframe -side bottom -fill x -pady 2m
2983 button $id.buttonframe.cancel -text {Cancel}\
2984 -command "audio_cancel $id"
2985 button $id.buttonframe.apply -text {Apply}\
2986 -command "audio_apply $id"
2987 button $id.buttonframe.ok -text {OK}\
2988 -command "audio_ok $id"
2989 pack $id.buttonframe.cancel -side left -expand 1
2990 pack $id.buttonframe.apply -side left -expand 1
2991 pack $id.buttonframe.ok -side left -expand 1
2992
2993 # sample rate and advance
2994 frame $id.srf
2995 pack $id.srf -side top
2996
2997 label $id.srf.l1 -text "sample rate:"
2998 entry $id.srf.x1 -textvariable audio_sr -width 7
2999 label $id.srf.l2 -text "delay (msec):"
3000 entry $id.srf.x2 -textvariable audio_advance -width 4
3001 pack $id.srf.l1 $id.srf.x1 $id.srf.l2 $id.srf.x2 -side left
3002
3003 # input device 1
3004 frame $id.in1f
3005 pack $id.in1f -side top
3006
3007 label $id.in1f.l1 -text "input device 1:"
3008 button $id.in1f.x1 -text [lindex $indevlist $audio_indev1] \
3009 -command [list audio_popup $id $id.in1f.x1 audio_indev1 $indevlist]
3010 label $id.in1f.l2 -text "channels:"
3011 entry $id.in1f.x2 -textvariable audio_inchan1 -width 3
3012 pack $id.in1f.l1 $id.in1f.x1 $id.in1f.l2 $id.in1f.x2 -side left
3013
3014 # input device 2
3015 if {$longform && $multi > 1 && [llength $indevlist] > 1} {
3016 frame $id.in2f
3017 pack $id.in2f -side top
3018
3019 label $id.in2f.l1 -text "input device 2:"
3020 button $id.in2f.x1 -text [lindex $indevlist $audio_indev2] \
3021 -command [list audio_popup $id $id.in2f.x1 audio_indev2 $indevlist]
3022 label $id.in2f.l2 -text "channels:"
3023 entry $id.in2f.x2 -textvariable audio_inchan2 -width 3
3024 pack $id.in2f.l1 $id.in2f.x1 $id.in2f.l2 $id.in2f.x2 -side left
3025 }
3026
3027 # input device 3
3028 if {$longform && $multi > 1 && [llength $indevlist] > 2} {
3029 frame $id.in3f
3030 pack $id.in3f -side top
3031
3032 label $id.in3f.l1 -text "input device 3:"
3033 button $id.in3f.x1 -text [lindex $indevlist $audio_indev3] \
3034 -command [list audio_popup $id $id.in3f.x1 audio_indev3 $indevlist]
3035 label $id.in3f.l2 -text "channels:"
3036 entry $id.in3f.x2 -textvariable audio_inchan3 -width 3
3037 pack $id.in3f.l1 $id.in3f.x1 $id.in3f.l2 $id.in3f.x2 -side left
3038 }
3039
3040 # input device 4
3041 if {$longform && $multi > 1 && [llength $indevlist] > 3} {
3042 frame $id.in4f
3043 pack $id.in4f -side top
3044
3045 label $id.in4f.l1 -text "input device 4:"
3046 button $id.in4f.x1 -text [lindex $indevlist $audio_indev4] \
3047 -command [list audio_popup $id $id.in4f.x1 audio_indev4 $indevlist]
3048 label $id.in4f.l2 -text "channels:"
3049 entry $id.in4f.x2 -textvariable audio_inchan4 -width 3
3050 pack $id.in4f.l1 $id.in4f.x1 $id.in4f.l2 $id.in4f.x2 -side left
3051 }
3052
3053 # output device 1
3054 frame $id.out1f
3055 pack $id.out1f -side top
3056
3057 if {$multi == 0} {
3058 label $id.out1f.l1 \
3059 -text "(output device same as input device) .............. "
3060 } else {
3061 label $id.out1f.l1 -text "output device 1:"
3062 button $id.out1f.x1 -text [lindex $outdevlist $audio_outdev1] \
3063 -command \
3064 [list audio_popup $id $id.out1f.x1 audio_outdev1 $outdevlist]
3065 }
3066 label $id.out1f.l2 -text "channels:"
3067 entry $id.out1f.x2 -textvariable audio_outchan1 -width 3
3068 if {$multi == 0} {
3069 pack $id.out1f.l1 $id.out1f.l2 $id.out1f.x2 -side left
3070 } else {
3071 pack $id.out1f.l1 $id.out1f.x1 $id.out1f.l2 $id.out1f.x2 -side left
3072 }
3073
3074 # output device 2
3075 if {$longform && $multi > 1 && [llength $indevlist] > 1} {
3076 frame $id.out2f
3077 pack $id.out2f -side top
3078 label $id.out2f.l1 -text "output device 2:"
3079 button $id.out2f.x1 -text [lindex $outdevlist $audio_outdev2] \
3080 -command \
3081 [list audio_popup $id $id.out2f.x1 audio_outdev2 $outdevlist]
3082 label $id.out2f.l2 -text "channels:"
3083 entry $id.out2f.x2 -textvariable audio_outchan2 -width 3
3084 pack $id.out2f.l1 $id.out2f.x1 $id.out2f.l2 $id.out2f.x2 -side left
3085 }
3086
3087 # output device 3
3088 if {$longform && $multi > 1 && [llength $indevlist] > 2} {
3089 frame $id.out3f
3090 pack $id.out3f -side top
3091 label $id.out3f.l1 -text "output device 3:"
3092 button $id.out3f.x1 -text [lindex $outdevlist $audio_outdev3] \
3093 -command \
3094 [list audio_popup $id $id.out3f.x1 audio_outdev3 $outdevlist]
3095 label $id.out3f.l2 -text "channels:"
3096 entry $id.out3f.x2 -textvariable audio_outchan3 -width 3
3097 pack $id.out3f.l1 $id.out3f.x1 $id.out3f.l2 $id.out3f.x2 -side left
3098 }
3099
3100 # output device 4
3101 if {$longform && $multi > 1 && [llength $indevlist] > 3} {
3102 frame $id.out4f
3103 pack $id.out4f -side top
3104 label $id.out4f.l1 -text "output device 4:"
3105 button $id.out4f.x1 -text [lindex $outdevlist $audio_outdev4] \
3106 -command \
3107 [list audio_popup $id $id.out4f.x1 audio_outdev4 $outdevlist]
3108 label $id.out4f.l2 -text "channels:"
3109 entry $id.out4f.x2 -textvariable audio_outchan4 -width 3
3110 pack $id.out4f.l1 $id.out4f.x1 $id.out4f.l2 $id.out4f.x2 -side left
3111 }
3112
3113 # if not the "long form" but if "multi" is 2, make a button to
3114 # restart with longform set.
3115
3116 if {$longform == 0 && $multi > 1} {
3117 frame $id.longbutton
3118 pack $id.longbutton -side top
3119 button $id.longbutton.b -text {use multiple devices} \
3120 -command {pd pd audio-properties 1 \;}
3121 pack $id.longbutton.b
3122 }
3123 bind $id.srf.x1 <KeyPress-Return> [concat audio_ok $id]
3124 bind $id.srf.x2 <KeyPress-Return> [concat audio_ok $id]
3125 bind $id.in1f.x2 <KeyPress-Return> [concat audio_ok $id]
3126 $id.srf.x1 select from 0
3127 $id.srf.x1 select adjust end
3128 focus $id.srf.x1
3129}
3130
3131####################### midi dialog ##################3
3132
3133proc midi_apply {id} {
3134 global midi_indev1 midi_indev2 midi_indev3 midi_indev4
3135 global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4
3136
3137 pd [concat pd midi-dialog \
3138 $midi_indev1 \
3139 $midi_indev2 \
3140 $midi_indev3 \
3141 $midi_indev4 \
3142 $midi_outdev1 \
3143 $midi_outdev2 \
3144 $midi_outdev3 \
3145 $midi_outdev4 \
3146 \;]
3147}
3148
3149proc midi_cancel {id} {
3150 pd [concat $id cancel \;]
3151}
3152
3153proc midi_ok {id} {
3154 midi_apply $id
3155 midi_cancel $id
3156}
3157
3158# callback from popup menu
3159proc midi_popup_action {buttonname varname devlist index} {
3160 global midi_indevlist midi_outdevlist $varname
3161 $buttonname configure -text [lindex $devlist $index]
3162# puts stderr [concat popup_action $buttonname $varname $index]
3163 set $varname $index
3164}
3165
3166# create a popup menu
3167proc midi_popup {name buttonname varname devlist} {
3168 if [winfo exists $name.popup] {destroy $name.popup}
3169 menu $name.popup -tearoff false
3170# puts stderr [concat $devlist ]
3171 for {set x 0} {$x<[llength $devlist]} {incr x} {
3172 $name.popup add command -label [lindex $devlist $x] \
3173 -command [list midi_popup_action \
3174 $buttonname $varname $devlist $x]
3175 }
3176 tk_popup $name.popup [winfo pointerx $name] [winfo pointery $name] 0
3177}
3178
3179# start a dialog window to select midi devices. "longform" asks us to make
3180# controls for opening several devices; if not, we get an extra button to
3181# turn longform on and restart the dialog.
3182
3183proc pdtk_midi_dialog {id indevlist indev1 indev2 indev3 indev4 \
3184 outdevlist outdev1 outdev2 outdev3 outdev4 longform} {
3185 global midi_indev1 midi_indev2 midi_indev3 midi_indev4
3186 global midi_outdev1 midi_outdev2 midi_outdev3 midi_outdev4
3187 global midi_indevlist midi_outdevlist
3188
3189 set midi_indev1 $indev1
3190 set midi_indev2 $indev2
3191 set midi_indev3 $indev3
3192 set midi_indev4 $indev4
3193 set midi_outdev1 $outdev1
3194 set midi_outdev2 $outdev2
3195 set midi_outdev3 $outdev3
3196 set midi_outdev4 $outdev4
3197 set midi_indevlist $indevlist
3198 set midi_outdevlist $outdevlist
3199
3200 toplevel $id
3201 wm title $id {midi}
3202 wm protocol $id WM_DELETE_WINDOW [concat midi_cancel $id]
3203
3204 frame $id.buttonframe
3205 pack $id.buttonframe -side bottom -fill x -pady 2m
3206 button $id.buttonframe.cancel -text {Cancel}\
3207 -command "midi_cancel $id"
3208 button $id.buttonframe.apply -text {Apply}\
3209 -command "midi_apply $id"
3210 button $id.buttonframe.ok -text {OK}\
3211 -command "midi_ok $id"
3212 pack $id.buttonframe.cancel -side left -expand 1
3213 pack $id.buttonframe.apply -side left -expand 1
3214 pack $id.buttonframe.ok -side left -expand 1
3215
3216 # input device 1
3217 frame $id.in1f
3218 pack $id.in1f -side top
3219
3220 label $id.in1f.l1 -text "input device 1:"
3221 button $id.in1f.x1 -text [lindex $indevlist $midi_indev1] \
3222 -command [list midi_popup $id $id.in1f.x1 midi_indev1 $indevlist]
3223 pack $id.in1f.l1 $id.in1f.x1 -side left
3224
3225 # input device 2
3226 if {$longform && [llength $indevlist] > 2} {
3227 frame $id.in2f
3228 pack $id.in2f -side top
3229
3230 label $id.in2f.l1 -text "input device 2:"
3231 button $id.in2f.x1 -text [lindex $indevlist $midi_indev2] \
3232 -command [list midi_popup $id $id.in2f.x1 midi_indev2 $indevlist]
3233 pack $id.in2f.l1 $id.in2f.x1 -side left
3234 }
3235
3236 # input device 3
3237 if {$longform && [llength $indevlist] > 3} {
3238 frame $id.in3f
3239 pack $id.in3f -side top
3240
3241 label $id.in3f.l1 -text "input device 3:"
3242 button $id.in3f.x1 -text [lindex $indevlist $midi_indev3] \
3243 -command [list midi_popup $id $id.in3f.x1 midi_indev3 $indevlist]
3244 pack $id.in3f.l1 $id.in3f.x1 -side left
3245 }
3246
3247 # input device 4
3248 if {$longform && [llength $indevlist] > 4} {
3249 frame $id.in4f
3250 pack $id.in4f -side top
3251
3252 label $id.in4f.l1 -text "input device 4:"
3253 button $id.in4f.x1 -text [lindex $indevlist $midi_indev4] \
3254 -command [list midi_popup $id $id.in4f.x1 midi_indev4 $indevlist]
3255 pack $id.in4f.l1 $id.in4f.x1 -side left
3256 }
3257
3258 # output device 1
3259
3260 frame $id.out1f
3261 pack $id.out1f -side top
3262 label $id.out1f.l1 -text "output device 1:"
3263 button $id.out1f.x1 -text [lindex $outdevlist $midi_outdev1] \
3264 -command [list midi_popup $id $id.out1f.x1 midi_outdev1 $outdevlist]
3265 pack $id.out1f.l1 $id.out1f.x1 -side left
3266
3267 # output device 2
3268 if {$longform && [llength $indevlist] > 2} {
3269 frame $id.out2f
3270 pack $id.out2f -side top
3271 label $id.out2f.l1 -text "output device 2:"
3272 button $id.out2f.x1 -text [lindex $outdevlist $midi_outdev2] \
3273 -command \
3274 [list midi_popup $id $id.out2f.x1 midi_outdev2 $outdevlist]
3275 pack $id.out2f.l1 $id.out2f.x1 -side left
3276 }
3277
3278 # output device 3
3279 if {$longform && [llength $indevlist] > 3} {
3280 frame $id.out3f
3281 pack $id.out3f -side top
3282 label $id.out3f.l1 -text "output device 3:"
3283 button $id.out3f.x1 -text [lindex $outdevlist $midi_outdev3] \
3284 -command \
3285 [list midi_popup $id $id.out3f.x1 midi_outdev3 $outdevlist]
3286 pack $id.out3f.l1 $id.out3f.x1 -side left
3287 }
3288
3289 # output device 4
3290 if {$longform && [llength $indevlist] > 4} {
3291 frame $id.out4f
3292 pack $id.out4f -side top
3293 label $id.out4f.l1 -text "output device 4:"
3294 button $id.out4f.x1 -text [lindex $outdevlist $midi_outdev4] \
3295 -command \
3296 [list midi_popup $id $id.out4f.x1 midi_outdev4 $outdevlist]
3297 pack $id.out4f.l1 $id.out4f.x1 -side left
3298 }
3299
3300 # if not the "long form" make a button to
3301 # restart with longform set.
3302
3303 if {$longform == 0} {
3304 frame $id.longbutton
3305 pack $id.longbutton -side top
3306 button $id.longbutton.b -text {use multiple devices} \
3307 -command {pd pd midi-properties 1 \;}
3308 pack $id.longbutton.b
3309 }
3310}
3311
3312############ pdtk_path_dialog -- dialog window for search path #########
3313
3314proc path_apply {id} {
3315 global pd_path0 pd_path1 pd_path2 pd_path3 pd_path4
3316 global pd_path5 pd_path6 pd_path7 pd_path8 pd_path9
3317
3318 pd [concat pd path-dialog \
3319 $pd_path0 $pd_path1 $pd_path2 $pd_path3 $pd_path4 \
3320 $pd_path5 $pd_path6 $pd_path7 $pd_path8 $pd_path9 \
3321 \;]
3322}
3323
3324proc path_cancel {id} {
3325 pd [concat $id cancel \;]
3326}
3327
3328proc path_ok {id} {
3329 path_apply $id
3330 path_cancel $id
3331}
3332set pd_path0 sdfgh
3333
3334proc pdtk_path_dialog {id} {
3335 global pd_path0 pd_path1 pd_path2 pd_path3 pd_path4
3336 global pd_path5 pd_path6 pd_path7 pd_path8 pd_path9
3337
3338 toplevel $id
3339 wm title $id {PD search path for patches and other files}
3340 wm protocol $id WM_DELETE_WINDOW [concat path_cancel $id]
3341
3342 frame $id.buttonframe
3343 pack $id.buttonframe -side bottom -fill x -pady 2m
3344 button $id.buttonframe.cancel -text {Cancel}\
3345 -command "path_cancel $id"
3346 button $id.buttonframe.apply -text {Apply}\
3347 -command "path_apply $id"
3348 button $id.buttonframe.ok -text {OK}\
3349 -command "path_ok $id"
3350 pack $id.buttonframe.cancel -side left -expand 1
3351 pack $id.buttonframe.apply -side left -expand 1
3352 pack $id.buttonframe.ok -side left -expand 1
3353
3354 for {set x 0} {$x < 10} {incr x} {
3355 # input device 1
3356 entry $id.f$x -textvariable pd_path$x -width 80
3357 bind $id.f$x <KeyPress-Return> [concat path_ok $id]
3358 pack $id.f$x -side top
3359 }
3360
3361 focus $id.f0
3362}
3363
3364proc pd_set {var value} {
3365 global $var
3366 set $var $value
3367}
3368
diff --git a/apps/plugins/pdbox/PDa/src/u_pdreceive.c b/apps/plugins/pdbox/PDa/src/u_pdreceive.c
deleted file mode 100644
index 51e60f7d5f..0000000000
--- a/apps/plugins/pdbox/PDa/src/u_pdreceive.c
+++ /dev/null
@@ -1,326 +0,0 @@
1/* Copyright (c) 2000 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */
4
5/* the "pdreceive" command. This is a standalone program that receives messages
6from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to
7standard output. */
8
9#include <sys/types.h>
10#include <string.h>
11#include <stdio.h>
12#include <errno.h>
13#include <stdlib.h>
14#ifdef UNIX
15#include <sys/time.h>
16#include <unistd.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <netdb.h>
20#define SOCKET_ERROR -1
21#else
22#include <winsock.h>
23#endif
24
25typedef struct _fdpoll
26{
27 int fdp_fd;
28 char *fdp_inbuf;
29 int fdp_inhead;
30 int fdp_intail;
31 int fdp_udp;
32} t_fdpoll;
33
34static int nfdpoll;
35static t_fdpoll *fdpoll;
36static int maxfd;
37static int sockfd;
38static int protocol;
39
40static void sockerror(char *s);
41static void x_closesocket(int fd);
42static void dopoll(void);
43#define BUFSIZE 4096
44
45int main(int argc, char **argv)
46{
47 int portno;
48 struct sockaddr_in server;
49 int nretry = 10;
50#ifdef MSW
51 short version = MAKEWORD(2, 0);
52 WSADATA nobby;
53#endif
54 if (argc < 2 || sscanf(argv[1], "%d", &portno) < 1 || portno <= 0)
55 goto usage;
56 if (argc >= 3)
57 {
58 if (!strcmp(argv[2], "tcp"))
59 protocol = SOCK_STREAM;
60 else if (!strcmp(argv[2], "udp"))
61 protocol = SOCK_DGRAM;
62 else goto usage;
63 }
64 else protocol = SOCK_STREAM;
65#ifdef MSW
66 if (WSAStartup(version, &nobby)) sockerror("WSAstartup");
67#endif
68 sockfd = socket(AF_INET, protocol, 0);
69 if (sockfd < 0)
70 {
71 sockerror("socket()");
72 exit(1);
73 }
74 maxfd = sockfd + 1;
75 server.sin_family = AF_INET;
76 server.sin_addr.s_addr = INADDR_ANY;
77
78#ifdef IRIX
79 /* this seems to work only in IRIX but is unnecessary in
80 Linux. Not sure what MSW needs in place of this. */
81 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
82 post("setsockopt failed\n");
83#endif
84
85 /* assign client port number */
86 server.sin_port = htons((unsigned short)portno);
87
88 /* name the socket */
89 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
90 {
91 sockerror("bind");
92 x_closesocket(sockfd);
93 return (0);
94 }
95 if (protocol == SOCK_STREAM)
96 {
97 if (listen(sockfd, 5) < 0)
98 {
99 sockerror("listen");
100 x_closesocket(sockfd);
101 exit(1);
102 }
103 }
104 /* now loop forever selecting on sockets */
105 while (1)
106 dopoll();
107
108usage:
109 fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n");
110 fprintf(stderr, "(default is tcp)\n");
111 exit(1);
112}
113
114static void addport(int fd)
115{
116 int nfd = nfdpoll;
117 t_fdpoll *fp;
118 fdpoll = (t_fdpoll *)realloc(fdpoll,
119 (nfdpoll+1) * sizeof(t_fdpoll));
120 fp = fdpoll + nfdpoll;
121 fp->fdp_fd = fd;
122 nfdpoll++;
123 if (fd >= maxfd) maxfd = fd + 1;
124 fp->fdp_inhead = fp->fdp_intail = 0;
125 if (!(fp->fdp_inbuf = malloc(BUFSIZE)))
126 {
127 fprintf(stderr, "out of memory");
128 exit(1);
129 }
130 printf("number_connected %d;\n", nfdpoll);
131}
132
133static void rmport(t_fdpoll *x)
134{
135 int nfd = nfdpoll;
136 int i, size = nfdpoll * sizeof(t_fdpoll);
137 t_fdpoll *fp;
138 for (i = nfdpoll, fp = fdpoll; i--; fp++)
139 {
140 if (fp == x)
141 {
142 x_closesocket(fp->fdp_fd);
143 free(fp->fdp_inbuf);
144 while (i--)
145 {
146 fp[0] = fp[1];
147 fp++;
148 }
149 fdpoll = (t_fdpoll *)realloc(fdpoll,
150 (nfdpoll-1) * sizeof(t_fdpoll));
151 nfdpoll--;
152 printf("number_connected %d;\n", nfdpoll);
153 return;
154 }
155 }
156 fprintf(stderr, "warning: item removed from poll list but not found");
157}
158
159static void doconnect(void)
160{
161 int fd = accept(sockfd, 0, 0);
162 if (fd < 0)
163 perror("accept");
164 else addport(fd);
165}
166
167static void udpread(void)
168{
169 char buf[BUFSIZE];
170 int ret = recv(sockfd, buf, BUFSIZE, 0);
171 if (ret < 0)
172 {
173 sockerror("recv (udp)");
174 x_closesocket(sockfd);
175 exit(1);
176 }
177 else if (ret > 0)
178 {
179#ifdef UNIX
180 if (write(1, buf, ret) < ret)
181 {
182 perror("write");
183 exit(1);
184 }
185#else
186 int j;
187 for (j = 0; j < ret; j++)
188 putchar(buf[j]);
189#endif
190 }
191}
192
193static int tcpmakeoutput(t_fdpoll *x)
194{
195 char messbuf[BUFSIZE+1], *bp = messbuf;
196 int indx;
197 int inhead = x->fdp_inhead;
198 int intail = x->fdp_intail;
199 char *inbuf = x->fdp_inbuf;
200 if (intail == inhead)
201 return (0);
202 for (indx = intail; indx != inhead; indx = (indx+1)&(BUFSIZE-1))
203 {
204 /* search for a semicolon. */
205 char c = *bp++ = inbuf[indx];
206 if (c == ';')
207 {
208 intail = (indx+1)&(BUFSIZE-1);
209 if (inbuf[intail] == '\n')
210 intail = (intail+1)&(BUFSIZE-1);
211 *bp++ = '\n';
212#ifdef UNIX
213 write(1, messbuf, bp - messbuf);
214#else
215 {
216 int j;
217 for (j = 0; j < bp - messbuf; j++)
218 putchar(messbuf[j]);
219 }
220#endif
221 x->fdp_inhead = inhead;
222 x->fdp_intail = intail;
223 return (1);
224 }
225 }
226 return (0);
227}
228
229static void tcpread(t_fdpoll *x)
230{
231 int readto =
232 (x->fdp_inhead >= x->fdp_intail ? BUFSIZE : x->fdp_intail-1);
233 int ret;
234
235 /* the input buffer might be full. If so, drop the whole thing */
236 if (readto == x->fdp_inhead)
237 {
238 fprintf(stderr, "pd: dropped message from gui\n");
239 x->fdp_inhead = x->fdp_intail = 0;
240 readto = BUFSIZE;
241 }
242 else
243 {
244 ret = recv(x->fdp_fd, x->fdp_inbuf + x->fdp_inhead,
245 readto - x->fdp_inhead, 0);
246 if (ret < 0)
247 {
248 sockerror("recv (tcp)");
249 rmport(x);
250 }
251 else if (ret == 0)
252 rmport(x);
253 else
254 {
255 x->fdp_inhead += ret;
256 if (x->fdp_inhead >= BUFSIZE)
257 x->fdp_inhead = 0;
258 while (tcpmakeoutput(x))
259 ;
260 }
261 }
262}
263
264static void dopoll(void)
265{
266 int i;
267 t_fdpoll *fp;
268 fd_set readset, writeset, exceptset;
269 FD_ZERO(&writeset);
270 FD_ZERO(&readset);
271 FD_ZERO(&exceptset);
272
273 FD_SET(sockfd, &readset);
274 if (protocol == SOCK_STREAM)
275 {
276 for (fp = fdpoll, i = nfdpoll; i--; fp++)
277 FD_SET(fp->fdp_fd, &readset);
278 }
279 if (select(maxfd+1, &readset, &writeset, &exceptset, 0) < 0)
280 {
281 perror("select");
282 exit(1);
283 }
284 if (protocol == SOCK_STREAM)
285 {
286 for (i = 0; i < nfdpoll; i++)
287 if (FD_ISSET(fdpoll[i].fdp_fd, &readset))
288 tcpread(&fdpoll[i]);
289 if (FD_ISSET(sockfd, &readset))
290 doconnect();
291 }
292 else
293 {
294 if (FD_ISSET(sockfd, &readset))
295 udpread();
296 }
297}
298
299
300static void sockerror(char *s)
301{
302#ifdef MSW
303 int err = WSAGetLastError();
304 if (err == 10054) return;
305 else if (err == 10044)
306 {
307 fprintf(stderr,
308 "Warning: you might not have TCP/IP \"networking\" turned on\n");
309 }
310#endif
311#ifdef UNIX
312 int err = errno;
313#endif
314 fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err);
315}
316
317static void x_closesocket(int fd)
318{
319#ifdef UNIX
320 close(fd);
321#endif
322#ifdef MSW
323 closesocket(fd);
324#endif
325}
326
diff --git a/apps/plugins/pdbox/PDa/src/u_pdsend.c b/apps/plugins/pdbox/PDa/src/u_pdsend.c
deleted file mode 100644
index 4fe714d70f..0000000000
--- a/apps/plugins/pdbox/PDa/src/u_pdsend.c
+++ /dev/null
@@ -1,158 +0,0 @@
1/* Copyright (c) 2000 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in the Pd distribution. */
4
5/* the "pdsend" command. This is a standalone program that forwards messages
6from its standard input to Pd via the netsend/netreceive ("FUDI") protocol. */
7
8#include <sys/types.h>
9#include <string.h>
10#include <stdio.h>
11#include <errno.h>
12#include <stdlib.h>
13#ifdef UNIX
14#include <unistd.h>
15#include <sys/socket.h>
16#include <netinet/in.h>
17#include <netdb.h>
18#define SOCKET_ERROR -1
19#else
20#include <winsock.h>
21#endif
22
23void sockerror(char *s);
24void x_closesocket(int fd);
25#define BUFSIZE 4096
26
27int main(int argc, char **argv)
28{
29 int sockfd, portno, protocol;
30 struct sockaddr_in server;
31 struct hostent *hp;
32 char *hostname;
33 int nretry = 10;
34#ifdef MSW
35 short version = MAKEWORD(2, 0);
36 WSADATA nobby;
37#endif
38 if (argc < 2 || sscanf(argv[1], "%d", &portno) < 1 || portno <= 0)
39 goto usage;
40 if (argc >= 3)
41 hostname = argv[2];
42 else hostname = "127.0.0.1";
43 if (argc >= 4)
44 {
45 if (!strcmp(argv[3], "tcp"))
46 protocol = SOCK_STREAM;
47 else if (!strcmp(argv[3], "udp"))
48 protocol = SOCK_DGRAM;
49 else goto usage;
50 }
51 else protocol = SOCK_STREAM;
52#ifdef MSW
53 if (WSAStartup(version, &nobby)) sockerror("WSAstartup");
54#endif
55
56 sockfd = socket(AF_INET, protocol, 0);
57 if (sockfd < 0)
58 {
59 sockerror("socket()");
60 exit(1);
61 }
62 /* connect socket using hostname provided in command line */
63 server.sin_family = AF_INET;
64 hp = gethostbyname(hostname);
65 if (hp == 0)
66 {
67 fprintf(stderr, "%s: unknown host\n", hostname);
68 x_closesocket(sockfd);
69 exit(1);
70 }
71 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
72
73 /* assign client port number */
74 server.sin_port = htons((unsigned short)portno);
75
76#if 0 /* try this again for 4.0; this crashed my RH 6.2 machine!) */
77
78 /* try to connect. */
79 for (nretry = 0; nretry < (protocol == SOCK_STREAM ? 10 : 1); nretry++)
80
81 {
82 if (nretry > 0)
83 {
84 sleep (nretry < 5 ? 1 : 5);
85 fprintf(stderr, "retrying...");
86 }
87 if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) >= 0)
88 goto connected;
89 sockerror("connect");
90 }
91 x_closesocket(sockfd);
92 exit(1);
93connected: ;
94#else
95 /* try to connect. */
96 if (connect(sockfd, (struct sockaddr *) &server, sizeof (server)) < 0)
97 {
98 sockerror("connect");
99 x_closesocket(sockfd);
100 exit(1);
101 }
102#endif
103 /* now loop reading stdin and sending it to socket */
104 while (1)
105 {
106 char buf[BUFSIZE], *bp, nsent, nsend;
107 if (!fgets(buf, BUFSIZE, stdin))
108 break;
109 nsend = strlen(buf);
110 for (bp = buf, nsent = 0; nsent < nsend;)
111 {
112 int res = send(sockfd, buf, nsend-nsent, 0);
113 if (res < 0)
114 {
115 sockerror("send");
116 goto done;
117 }
118 nsent += res;
119 bp += res;
120 }
121 }
122done:
123 if (ferror(stdin))
124 perror("stdin");
125 exit (0);
126usage:
127 fprintf(stderr, "usage: pdsend <portnumber> [host] [udp|tcp]\n");
128 fprintf(stderr, "(default is localhost and tcp)\n");
129 exit(1);
130}
131
132void sockerror(char *s)
133{
134#ifdef MSW
135 int err = WSAGetLastError();
136 if (err == 10054) return;
137 else if (err == 10044)
138 {
139 fprintf(stderr,
140 "Warning: you might not have TCP/IP \"networking\" turned on\n");
141 }
142#endif
143#ifdef UNIX
144 int err = errno;
145#endif
146 fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err);
147}
148
149void x_closesocket(int fd)
150{
151#ifdef UNIX
152 close(fd);
153#endif
154#ifdef MSW
155 closesocket(fd);
156#endif
157}
158
diff --git a/apps/plugins/pdbox/PDa/src/x_gui.c b/apps/plugins/pdbox/PDa/src/x_gui.c
deleted file mode 100644
index c54fef948d..0000000000
--- a/apps/plugins/pdbox/PDa/src/x_gui.c
+++ /dev/null
@@ -1,378 +0,0 @@
1/* Copyright (c) 1997-2000 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* dialogs. LATER, deal with the situation where the object goes
6away before the panel does... */
7
8#include "m_pd.h"
9#include <stdio.h>
10#include <string.h>
11#ifdef UNIX
12#include <unistd.h>
13#endif
14
15/* --------------------- graphics responder ---------------- */
16
17/* make one of these if you want to put up a dialog window but want to be
18protected from getting deleted and then having the dialog call you back. In
19this design the calling object doesn't have to keep the address of the dialog
20window around; instead we keep a list of all open dialogs. Any object that
21might have dialogs, when it is deleted, simply checks down the dialog window
22list and breaks off any dialogs that might later have sent messages to it.
23Only when the dialog window itself closes do we delete the gfxstub object. */
24
25static t_class *gfxstub_class;
26
27typedef struct _gfxstub
28{
29 t_pd x_pd;
30 t_pd *x_owner;
31 void *x_key;
32 t_symbol *x_sym;
33 struct _gfxstub *x_next;
34} t_gfxstub;
35
36static t_gfxstub *gfxstub_list;
37
38 /* create a new one. the "key" is an address by which the owner
39 will identify it later; if the owner only wants one dialog, this
40 could just be a pointer to the owner itself. The string "cmd"
41 is a TK command to create the dialog, with "%s" embedded in
42 it so we can provide a name by which the GUI can send us back
43 messages; e.g., "pdtk_canvas_dofont %s 10". */
44
45void gfxstub_new(t_pd *owner, void *key, const char *cmd)
46{
47 char buf[MAXPDSTRING];
48 char namebuf[80];
49 t_gfxstub *x;
50 t_symbol *s;
51 /* if any exists with matching key, no need to make a
52 new one; just tell tk to send it front. */
53 for (x = gfxstub_list; x; x = x->x_next)
54 {
55 if (x->x_key == key)
56 {
57 sys_vgui("raise .gfxstub%x\n", x);
58 sys_vgui("focus .gfxstub%x\n", x);
59 return;
60 }
61 }
62 if (strlen(cmd) + 84 > MAXPDSTRING)
63 return;
64 x = (t_gfxstub *)pd_new(gfxstub_class);
65 sprintf(namebuf, ".gfxstub%x", (t_int)x);
66
67 s = gensym(namebuf);
68 pd_bind(&x->x_pd, s);
69 x->x_owner = owner;
70 x->x_sym = s;
71 x->x_key = key;
72 x->x_next = gfxstub_list;
73 gfxstub_list = x;
74 sprintf(buf, cmd, s->s_name);
75 sys_gui(buf);
76}
77
78static void gfxstub_offlist(t_gfxstub *x)
79{
80 t_gfxstub *y1, *y2;
81 if (gfxstub_list == x)
82 gfxstub_list = x->x_next;
83 else for (y1 = gfxstub_list; y2 = y1->x_next; y1 = y2)
84 if (y2 == x)
85 {
86 y1->x_next = y2->x_next;
87 break;
88 }
89}
90
91 /* if the owner disappears, we still may have to stay around until our
92 dialog window signs off. Anyway we can now tell the GUI to destroy the
93 window. */
94void gfxstub_deleteforkey(void *key)
95{
96 t_gfxstub *y;
97 int didit = 1;
98 while (didit)
99 {
100 didit = 0;
101 for (y = gfxstub_list; y; y = y->x_next)
102 {
103 if (y->x_key == key)
104 {
105 sys_vgui("destroy .gfxstub%x\n", y);
106 y->x_owner = 0;
107 gfxstub_offlist(y);
108 didit = 1;
109 break;
110 }
111 }
112 }
113}
114
115/* --------- pd messages for gfxstub (these come from the GUI) ---------- */
116
117 /* "cancel" to request that we close the dialog window. */
118static void gfxstub_cancel(t_gfxstub *x)
119{
120 gfxstub_deleteforkey(x->x_key);
121}
122
123 /* "signoff" comes from the GUI to say the dialog window closed. */
124static void gfxstub_signoff(t_gfxstub *x)
125{
126 gfxstub_offlist(x);
127 pd_free(&x->x_pd);
128}
129
130static t_binbuf *gfxstub_binbuf;
131
132 /* a series of "data" messages rebuilds a scalar */
133static void gfxstub_data(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv)
134{
135 if (!gfxstub_binbuf)
136 gfxstub_binbuf = binbuf_new();
137 binbuf_add(gfxstub_binbuf, argc, argv);
138 binbuf_addsemi(gfxstub_binbuf);
139}
140 /* the "end" message terminates rebuilding the scalar */
141static void gfxstub_end(t_gfxstub *x)
142{
143 canvas_dataproperties((t_canvas *)x->x_owner,
144 (t_scalar *)x->x_key, gfxstub_binbuf);
145 binbuf_free(gfxstub_binbuf);
146 gfxstub_binbuf = 0;
147}
148
149 /* anything else is a message from the dialog window to the owner;
150 just forward it. */
151static void gfxstub_anything(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv)
152{
153 if (x->x_owner)
154 pd_typedmess(x->x_owner, s, argc, argv);
155}
156
157static void gfxstub_free(t_gfxstub *x)
158{
159 pd_unbind(&x->x_pd, x->x_sym);
160}
161
162static void gfxstub_setup(void)
163{
164 gfxstub_class = class_new(gensym("gfxstub"), (t_newmethod)gfxstub_new,
165 (t_method)gfxstub_free,
166 sizeof(t_gfxstub), CLASS_PD, 0);
167 class_addanything(gfxstub_class, gfxstub_anything);
168 class_addmethod(gfxstub_class, (t_method)gfxstub_signoff,
169 gensym("signoff"), 0);
170 class_addmethod(gfxstub_class, (t_method)gfxstub_data,
171 gensym("data"), A_GIMME, 0);
172 class_addmethod(gfxstub_class, (t_method)gfxstub_end,
173 gensym("end"), 0);
174 class_addmethod(gfxstub_class, (t_method)gfxstub_cancel,
175 gensym("cancel"), 0);
176}
177
178/* -------------------------- openpanel ------------------------------ */
179
180static t_class *openpanel_class;
181
182typedef struct _openpanel
183{
184 t_object x_obj;
185 t_symbol *x_s;
186} t_openpanel;
187
188static void *openpanel_new(void)
189{
190 char buf[50];
191 t_openpanel *x = (t_openpanel *)pd_new(openpanel_class);
192 sprintf(buf, "d%x", (t_int)x);
193 x->x_s = gensym(buf);
194 pd_bind(&x->x_obj.ob_pd, x->x_s);
195 outlet_new(&x->x_obj, &s_symbol);
196 return (x);
197}
198
199static void openpanel_bang(t_openpanel *x)
200{
201 sys_vgui("pdtk_openpanel %s\n", x->x_s->s_name);
202}
203
204static void openpanel_symbol(t_openpanel *x, t_symbol *s)
205{
206 outlet_symbol(x->x_obj.ob_outlet, s);
207}
208
209static void openpanel_free(t_openpanel *x)
210{
211 pd_unbind(&x->x_obj.ob_pd, x->x_s);
212}
213
214static void openpanel_setup(void)
215{
216 openpanel_class = class_new(gensym("openpanel"),
217 (t_newmethod)openpanel_new, (t_method)openpanel_free,
218 sizeof(t_openpanel), 0, A_DEFFLOAT, 0);
219 class_addbang(openpanel_class, openpanel_bang);
220 class_addsymbol(openpanel_class, openpanel_symbol);
221}
222
223/* -------------------------- savepanel ------------------------------ */
224
225static t_class *savepanel_class;
226
227typedef struct _savepanel
228{
229 t_object x_obj;
230 t_symbol *x_s;
231} t_savepanel;
232
233static void *savepanel_new(void)
234{
235 char buf[50];
236 t_savepanel *x = (t_savepanel *)pd_new(savepanel_class);
237 sprintf(buf, "d%x", (t_int)x);
238 x->x_s = gensym(buf);
239 pd_bind(&x->x_obj.ob_pd, x->x_s);
240 outlet_new(&x->x_obj, &s_symbol);
241 return (x);
242}
243
244static void savepanel_bang(t_savepanel *x)
245{
246 sys_vgui("pdtk_savepanel %s\n", x->x_s->s_name);
247}
248
249static void savepanel_symbol(t_savepanel *x, t_symbol *s)
250{
251 outlet_symbol(x->x_obj.ob_outlet, s);
252}
253
254static void savepanel_free(t_savepanel *x)
255{
256 pd_unbind(&x->x_obj.ob_pd, x->x_s);
257}
258
259static void savepanel_setup(void)
260{
261 savepanel_class = class_new(gensym("savepanel"),
262 (t_newmethod)savepanel_new, (t_method)savepanel_free,
263 sizeof(t_savepanel), 0, A_DEFFLOAT, 0);
264 class_addbang(savepanel_class, savepanel_bang);
265 class_addsymbol(savepanel_class, savepanel_symbol);
266}
267
268/* ---------------------- key and its relatives ------------------ */
269
270static t_symbol *key_sym, *keyup_sym, *keyname_sym;
271static t_class *key_class, *keyup_class, *keyname_class;
272
273typedef struct _key
274{
275 t_object x_obj;
276} t_key;
277
278static void *key_new( void)
279{
280 t_key *x = (t_key *)pd_new(key_class);
281 outlet_new(&x->x_obj, &s_float);
282 pd_bind(&x->x_obj.ob_pd, key_sym);
283 return (x);
284}
285
286static void key_float(t_key *x, t_floatarg f)
287{
288 outlet_float(x->x_obj.ob_outlet, f);
289}
290
291static void key_free(t_key *x)
292{
293 pd_unbind(&x->x_obj.ob_pd, key_sym);
294}
295
296typedef struct _keyup
297{
298 t_object x_obj;
299} t_keyup;
300
301static void *keyup_new( void)
302{
303 t_keyup *x = (t_keyup *)pd_new(keyup_class);
304 outlet_new(&x->x_obj, &s_float);
305 pd_bind(&x->x_obj.ob_pd, keyup_sym);
306 return (x);
307}
308
309static void keyup_float(t_keyup *x, t_floatarg f)
310{
311 outlet_float(x->x_obj.ob_outlet, f);
312}
313
314static void keyup_free(t_keyup *x)
315{
316 pd_unbind(&x->x_obj.ob_pd, keyup_sym);
317}
318
319typedef struct _keyname
320{
321 t_object x_obj;
322 t_outlet *x_outlet1;
323 t_outlet *x_outlet2;
324} t_keyname;
325
326static void *keyname_new( void)
327{
328 t_keyname *x = (t_keyname *)pd_new(keyname_class);
329 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
330 x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
331 pd_bind(&x->x_obj.ob_pd, keyname_sym);
332 return (x);
333}
334
335static void keyname_list(t_keyname *x, t_symbol *s, int ac, t_atom *av)
336{
337 outlet_symbol(x->x_outlet2, atom_getsymbolarg(1, ac, av));
338 outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
339}
340
341static void keyname_free(t_keyname *x)
342{
343 pd_unbind(&x->x_obj.ob_pd, keyname_sym);
344}
345
346static void key_setup(void)
347{
348 key_class = class_new(gensym("key"),
349 (t_newmethod)key_new, (t_method)key_free,
350 sizeof(t_key), CLASS_NOINLET, 0);
351 class_addfloat(key_class, key_float);
352 key_sym = gensym("#key");
353
354 keyup_class = class_new(gensym("keyup"),
355 (t_newmethod)keyup_new, (t_method)keyup_free,
356 sizeof(t_keyup), CLASS_NOINLET, 0);
357 class_addfloat(keyup_class, keyup_float);
358 keyup_sym = gensym("#keyup");
359 class_sethelpsymbol(keyup_class, gensym("key"));
360
361 keyname_class = class_new(gensym("keyname"),
362 (t_newmethod)keyname_new, (t_method)keyname_free,
363 sizeof(t_keyname), CLASS_NOINLET, 0);
364 class_addlist(keyname_class, keyname_list);
365 keyname_sym = gensym("#keyname");
366 class_sethelpsymbol(keyname_class, gensym("key"));
367}
368
369/* -------------------------- setup routine ------------------------------ */
370
371void x_gui_setup(void)
372{
373 gfxstub_setup();
374 openpanel_setup();
375 savepanel_setup();
376 key_setup();
377}
378
diff --git a/apps/plugins/pdbox/PDa/src/x_midi.c b/apps/plugins/pdbox/PDa/src/x_midi.c
deleted file mode 100644
index e9f3601057..0000000000
--- a/apps/plugins/pdbox/PDa/src/x_midi.c
+++ /dev/null
@@ -1,1314 +0,0 @@
1/* Copyright (c) 1997-2001 Miller Puckette and others.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* MIDI. */
6
7#include "m_pd.h"
8void outmidi_noteon(int portno, int channel, int pitch, int velo);
9void outmidi_controlchange(int portno, int channel, int ctlno, int value);
10void outmidi_programchange(int portno, int channel, int value);
11void outmidi_pitchbend(int portno, int channel, int value);
12void outmidi_aftertouch(int portno, int channel, int value);
13void outmidi_polyaftertouch(int portno, int channel, int pitch, int value);
14void outmidi_mclk(int portno);
15
16/* ----------------------- midiin and sysexin ------------------------- */
17
18static t_symbol *midiin_sym, *sysexin_sym;
19
20static t_class *midiin_class, *sysexin_class;
21
22typedef struct _midiin
23{
24 t_object x_obj;
25 t_outlet *x_outlet1;
26 t_outlet *x_outlet2;
27} t_midiin;
28
29static void *midiin_new( void)
30{
31 t_midiin *x = (t_midiin *)pd_new(midiin_class);
32 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
33 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
34 pd_bind(&x->x_obj.ob_pd, midiin_sym);
35#ifndef __linux__
36 pd_error(x, "midiin: works under Linux only");
37#endif
38 return (x);
39}
40
41static void midiin_list(t_midiin *x, t_symbol *s, int ac, t_atom *av)
42{
43 outlet_float(x->x_outlet2, atom_getfloatarg(1, ac, av) + 1);
44 outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
45}
46
47static void midiin_free(t_midiin *x)
48{
49 pd_unbind(&x->x_obj.ob_pd, midiin_sym);
50}
51
52static void *sysexin_new( void)
53{
54 t_midiin *x = (t_midiin *)pd_new(sysexin_class);
55 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
56 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
57 pd_bind(&x->x_obj.ob_pd, sysexin_sym);
58#ifndef __linux__
59 pd_error(x, "sysexin: works under Linux only");
60#endif
61 return (x);
62}
63
64static void sysexin_free(t_midiin *x)
65{
66 pd_unbind(&x->x_obj.ob_pd, sysexin_sym);
67}
68
69static void midiin_setup(void)
70{
71 midiin_class = class_new(gensym("midiin"), (t_newmethod)midiin_new,
72 (t_method)midiin_free, sizeof(t_midiin),
73 CLASS_NOINLET, A_DEFFLOAT, 0);
74 class_addlist(midiin_class, midiin_list);
75 class_sethelpsymbol(midiin_class, gensym("midi"));
76 midiin_sym = gensym("#midiin");
77
78 sysexin_class = class_new(gensym("sysexin"), (t_newmethod)sysexin_new,
79 (t_method)sysexin_free, sizeof(t_midiin),
80 CLASS_NOINLET, A_DEFFLOAT, 0);
81 class_addlist(sysexin_class, midiin_list);
82 class_sethelpsymbol(sysexin_class, gensym("midi"));
83 sysexin_sym = gensym("#sysexin");
84}
85
86void inmidi_byte(int portno, int byte)
87{
88 t_atom at[2];
89 if (midiin_sym->s_thing)
90 {
91 SETFLOAT(at, byte);
92 SETFLOAT(at+1, portno + 1);
93 pd_list(midiin_sym->s_thing, 0, 2, at);
94 }
95}
96
97void inmidi_sysex(int portno, int byte)
98{
99 t_atom at[2];
100 if (sysexin_sym->s_thing)
101 {
102 SETFLOAT(at, byte);
103 SETFLOAT(at+1, portno + 1);
104 pd_list(sysexin_sym->s_thing, 0, 2, at);
105 }
106}
107
108/* ----------------------- notein ------------------------- */
109
110static t_symbol *notein_sym;
111
112static t_class *notein_class;
113
114typedef struct _notein
115{
116 t_object x_obj;
117 t_float x_channel;
118 t_outlet *x_outlet1;
119 t_outlet *x_outlet2;
120 t_outlet *x_outlet3;
121} t_notein;
122
123static void *notein_new(t_floatarg f)
124{
125 t_notein *x = (t_notein *)pd_new(notein_class);
126 x->x_channel = f;
127 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
128 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
129 if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
130 pd_bind(&x->x_obj.ob_pd, notein_sym);
131 return (x);
132}
133
134static void notein_list(t_notein *x, t_symbol *s, int argc, t_atom *argv)
135{
136 float pitch = atom_getfloatarg(0, argc, argv);
137 float velo = atom_getfloatarg(1, argc, argv);
138 float channel = atom_getfloatarg(2, argc, argv);
139 if (x->x_channel != 0)
140 {
141 if (channel != x->x_channel) return;
142 outlet_float(x->x_outlet2, velo);
143 outlet_float(x->x_outlet1, pitch);
144 }
145 else
146 {
147 outlet_float(x->x_outlet3, channel);
148 outlet_float(x->x_outlet2, velo);
149 outlet_float(x->x_outlet1, pitch);
150 }
151}
152
153static void notein_free(t_notein *x)
154{
155 pd_unbind(&x->x_obj.ob_pd, notein_sym);
156}
157
158static void notein_setup(void)
159{
160 notein_class = class_new(gensym("notein"), (t_newmethod)notein_new,
161 (t_method)notein_free, sizeof(t_notein), CLASS_NOINLET, A_DEFFLOAT, 0);
162 class_addlist(notein_class, notein_list);
163 class_sethelpsymbol(notein_class, gensym("midi"));
164 notein_sym = gensym("#notein");
165}
166
167void inmidi_noteon(int portno, int channel, int pitch, int velo)
168{
169 if (notein_sym->s_thing)
170 {
171 t_atom at[3];
172 SETFLOAT(at, pitch);
173 SETFLOAT(at+1, velo);
174 SETFLOAT(at+2, (channel + (portno << 4) + 1));
175 pd_list(notein_sym->s_thing, &s_list, 3, at);
176 }
177}
178
179/* ----------------------- ctlin ------------------------- */
180
181static t_symbol *ctlin_sym;
182
183static t_class *ctlin_class;
184
185typedef struct _ctlin
186{
187 t_object x_obj;
188 t_float x_channel;
189 t_float x_ctlno;
190 t_outlet *x_outlet1;
191 t_outlet *x_outlet2;
192 t_outlet *x_outlet3;
193} t_ctlin;
194
195static void *ctlin_new(t_symbol *s, int argc, t_atom *argv)
196{
197 int ctlno, channel;
198 t_ctlin *x = (t_ctlin *)pd_new(ctlin_class);
199 if (!argc) ctlno = -1;
200 else ctlno = atom_getfloatarg(0, argc, argv);
201 channel = atom_getfloatarg(1, argc, argv);
202 x->x_channel = channel;
203 x->x_ctlno = ctlno;
204 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
205 if (!channel)
206 {
207 if (x->x_ctlno < 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
208 x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
209 }
210 pd_bind(&x->x_obj.ob_pd, ctlin_sym);
211 return (x);
212}
213
214static void ctlin_list(t_ctlin *x, t_symbol *s, int argc, t_atom *argv)
215{
216 t_float ctlnumber = atom_getfloatarg(0, argc, argv);
217 t_float value = atom_getfloatarg(1, argc, argv);
218 t_float channel = atom_getfloatarg(2, argc, argv);
219 if (x->x_ctlno >= 0 && x->x_ctlno != ctlnumber) return;
220 if (x->x_channel > 0 && x->x_channel != channel) return;
221 if (x->x_channel == 0) outlet_float(x->x_outlet3, channel);
222 if (x->x_ctlno < 0) outlet_float(x->x_outlet2, ctlnumber);
223 outlet_float(x->x_outlet1, value);
224}
225
226static void ctlin_free(t_ctlin *x)
227{
228 pd_unbind(&x->x_obj.ob_pd, ctlin_sym);
229}
230
231static void ctlin_setup(void)
232{
233 ctlin_class = class_new(gensym("ctlin"), (t_newmethod)ctlin_new,
234 (t_method)ctlin_free, sizeof(t_ctlin),
235 CLASS_NOINLET, A_GIMME, 0);
236 class_addlist(ctlin_class, ctlin_list);
237 class_sethelpsymbol(ctlin_class, gensym("midi"));
238 ctlin_sym = gensym("#ctlin");
239}
240
241void inmidi_controlchange(int portno, int channel, int ctlnumber, int value)
242{
243 if (ctlin_sym->s_thing)
244 {
245 t_atom at[3];
246 SETFLOAT(at, ctlnumber);
247 SETFLOAT(at+1, value);
248 SETFLOAT(at+2, (channel + (portno << 4) + 1));
249 pd_list(ctlin_sym->s_thing, &s_list, 3, at);
250 }
251}
252
253/* ----------------------- pgmin ------------------------- */
254
255static t_symbol *pgmin_sym;
256
257static t_class *pgmin_class;
258
259typedef struct _pgmin
260{
261 t_object x_obj;
262 t_float x_channel;
263 t_outlet *x_outlet1;
264 t_outlet *x_outlet2;
265} t_pgmin;
266
267static void *pgmin_new(t_floatarg f)
268{
269 t_pgmin *x = (t_pgmin *)pd_new(pgmin_class);
270 x->x_channel = f;
271 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
272 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
273 pd_bind(&x->x_obj.ob_pd, pgmin_sym);
274 return (x);
275}
276
277static void pgmin_list(t_pgmin *x, t_symbol *s, int argc, t_atom *argv)
278{
279 float value = atom_getfloatarg(0, argc, argv);
280 float channel = atom_getfloatarg(1, argc, argv);
281 if (x->x_channel != 0)
282 {
283 if (channel != x->x_channel) return;
284 outlet_float(x->x_outlet1, value);
285 }
286 else
287 {
288 outlet_float(x->x_outlet2, channel);
289 outlet_float(x->x_outlet1, value);
290 }
291}
292
293static void pgmin_free(t_pgmin *x)
294{
295 pd_unbind(&x->x_obj.ob_pd, pgmin_sym);
296}
297
298static void pgmin_setup(void)
299{
300 pgmin_class = class_new(gensym("pgmin"), (t_newmethod)pgmin_new,
301 (t_method)pgmin_free, sizeof(t_pgmin),
302 CLASS_NOINLET, A_DEFFLOAT, 0);
303 class_addlist(pgmin_class, pgmin_list);
304 class_sethelpsymbol(pgmin_class, gensym("midi"));
305 pgmin_sym = gensym("#pgmin");
306}
307
308void inmidi_programchange(int portno, int channel, int value)
309{
310 if (pgmin_sym->s_thing)
311 {
312 t_atom at[2];
313 SETFLOAT(at, value + 1);
314 SETFLOAT(at+1, (channel + (portno << 4) + 1));
315 pd_list(pgmin_sym->s_thing, &s_list, 2, at);
316 }
317}
318
319/* ----------------------- bendin ------------------------- */
320
321static t_symbol *bendin_sym;
322
323static t_class *bendin_class;
324
325typedef struct _bendin
326{
327 t_object x_obj;
328 t_float x_channel;
329 t_outlet *x_outlet1;
330 t_outlet *x_outlet2;
331} t_bendin;
332
333static void *bendin_new(t_floatarg f)
334{
335 t_bendin *x = (t_bendin *)pd_new(bendin_class);
336 x->x_channel = f;
337 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
338 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
339 pd_bind(&x->x_obj.ob_pd, bendin_sym);
340 return (x);
341}
342
343static void bendin_list(t_bendin *x, t_symbol *s, int argc, t_atom *argv)
344{
345 t_float value = atom_getfloatarg(0, argc, argv);
346 t_float channel = atom_getfloatarg(1, argc, argv);
347 if (x->x_channel != 0)
348 {
349 if (channel != x->x_channel) return;
350 outlet_float(x->x_outlet1, value);
351 }
352 else
353 {
354 outlet_float(x->x_outlet2, channel);
355 outlet_float(x->x_outlet1, value);
356 }
357}
358
359static void bendin_free(t_bendin *x)
360{
361 pd_unbind(&x->x_obj.ob_pd, bendin_sym);
362}
363
364static void bendin_setup(void)
365{
366 bendin_class = class_new(gensym("bendin"), (t_newmethod)bendin_new,
367 (t_method)bendin_free, sizeof(t_bendin), CLASS_NOINLET, A_DEFFLOAT, 0);
368 class_addlist(bendin_class, bendin_list);
369 class_sethelpsymbol(bendin_class, gensym("midi"));
370 bendin_sym = gensym("#bendin");
371}
372
373void inmidi_pitchbend(int portno, int channel, int value)
374{
375 if (bendin_sym->s_thing)
376 {
377 t_atom at[2];
378 SETFLOAT(at, value);
379 SETFLOAT(at+1, (channel + (portno << 4) + 1));
380 pd_list(bendin_sym->s_thing, &s_list, 2, at);
381 }
382}
383
384/* ----------------------- touchin ------------------------- */
385
386static t_symbol *touchin_sym;
387
388static t_class *touchin_class;
389
390typedef struct _touchin
391{
392 t_object x_obj;
393 t_float x_channel;
394 t_outlet *x_outlet1;
395 t_outlet *x_outlet2;
396} t_touchin;
397
398static void *touchin_new(t_floatarg f)
399{
400 t_touchin *x = (t_touchin *)pd_new(touchin_class);
401 x->x_channel = f;
402 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
403 if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
404 pd_bind(&x->x_obj.ob_pd, touchin_sym);
405 return (x);
406}
407
408static void touchin_list(t_touchin *x, t_symbol *s, int argc, t_atom *argv)
409{
410 t_float value = atom_getfloatarg(0, argc, argv);
411 t_float channel = atom_getfloatarg(1, argc, argv);
412 if (x->x_channel)
413 {
414 if (channel != x->x_channel) return;
415 outlet_float(x->x_outlet1, value);
416 }
417 else
418 {
419 outlet_float(x->x_outlet2, channel);
420 outlet_float(x->x_outlet1, value);
421 }
422}
423
424static void touchin_free(t_touchin *x)
425{
426 pd_unbind(&x->x_obj.ob_pd, touchin_sym);
427}
428
429static void touchin_setup(void)
430{
431 touchin_class = class_new(gensym("touchin"), (t_newmethod)touchin_new,
432 (t_method)touchin_free, sizeof(t_touchin),
433 CLASS_NOINLET, A_DEFFLOAT, 0);
434 class_addlist(touchin_class, touchin_list);
435 class_sethelpsymbol(touchin_class, gensym("midi"));
436 touchin_sym = gensym("#touchin");
437}
438
439void inmidi_aftertouch(int portno, int channel, int value)
440{
441 if (touchin_sym->s_thing)
442 {
443 t_atom at[2];
444 SETFLOAT(at, value);
445 SETFLOAT(at+1, (channel + (portno << 4) + 1));
446 pd_list(touchin_sym->s_thing, &s_list, 2, at);
447 }
448}
449
450/* ----------------------- polytouchin ------------------------- */
451
452static t_symbol *polytouchin_sym;
453
454static t_class *polytouchin_class;
455
456typedef struct _polytouchin
457{
458 t_object x_obj;
459 t_float x_channel;
460 t_outlet *x_outlet1;
461 t_outlet *x_outlet2;
462 t_outlet *x_outlet3;
463} t_polytouchin;
464
465static void *polytouchin_new(t_floatarg f)
466{
467 t_polytouchin *x = (t_polytouchin *)pd_new(polytouchin_class);
468 x->x_channel = f;
469 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
470 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
471 if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
472 pd_bind(&x->x_obj.ob_pd, polytouchin_sym);
473 return (x);
474}
475
476static void polytouchin_list(t_polytouchin *x, t_symbol *s, int argc,
477 t_atom *argv)
478{
479 t_float pitch = atom_getfloatarg(0, argc, argv);
480 t_float value = atom_getfloatarg(1, argc, argv);
481 t_float channel = atom_getfloatarg(2, argc, argv);
482 if (x->x_channel != 0)
483 {
484 if (channel != x->x_channel) return;
485 outlet_float(x->x_outlet2, pitch);
486 outlet_float(x->x_outlet1, value);
487 }
488 else
489 {
490 outlet_float(x->x_outlet3, channel);
491 outlet_float(x->x_outlet2, pitch);
492 outlet_float(x->x_outlet1, value);
493 }
494}
495
496static void polytouchin_free(t_polytouchin *x)
497{
498 pd_unbind(&x->x_obj.ob_pd, polytouchin_sym);
499}
500
501static void polytouchin_setup(void)
502{
503 polytouchin_class = class_new(gensym("polytouchin"),
504 (t_newmethod)polytouchin_new, (t_method)polytouchin_free,
505 sizeof(t_polytouchin), CLASS_NOINLET, A_DEFFLOAT, 0);
506 class_addlist(polytouchin_class, polytouchin_list);
507 class_sethelpsymbol(polytouchin_class, gensym("midi"));
508 polytouchin_sym = gensym("#polytouchin");
509}
510
511void inmidi_polyaftertouch(int portno, int channel, int pitch, int value)
512{
513 if (polytouchin_sym->s_thing)
514 {
515 t_atom at[3];
516 SETFLOAT(at, pitch);
517 SETFLOAT(at+1, value);
518 SETFLOAT(at+2, (channel + (portno << 4) + 1));
519 pd_list(polytouchin_sym->s_thing, &s_list, 3, at);
520 }
521}
522
523/*----------------------- midiclkin--(midi F8 message )---------------------*/
524static t_symbol *midiclkin_sym;
525
526static t_class *midiclkin_class;
527
528
529typedef struct _midiclkin
530{
531 t_object x_obj;
532 t_outlet *x_outlet1;
533 t_outlet *x_outlet2;
534} t_midiclkin;
535
536static void *midiclkin_new(t_floatarg f)
537{
538 t_midiclkin *x = (t_midiclkin *)pd_new(midiclkin_class);
539 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
540 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
541 pd_bind(&x->x_obj.ob_pd, midiclkin_sym);
542 return (x);
543}
544
545static void midiclkin_list(t_midiclkin *x, t_symbol *s, int argc, t_atom *argv)
546{
547 float value = atom_getfloatarg(0, argc, argv);
548 float count = atom_getfloatarg(1, argc, argv);
549 outlet_float(x->x_outlet2, count);
550 outlet_float(x->x_outlet1, value);
551}
552
553static void midiclkin_free(t_midiclkin *x)
554{
555 pd_unbind(&x->x_obj.ob_pd, midiclkin_sym);
556}
557
558static void midiclkin_setup(void)
559{
560 midiclkin_class = class_new(gensym("midiclkin"),
561 (t_newmethod)midiclkin_new, (t_method)midiclkin_free,
562 sizeof(t_midiclkin), CLASS_NOINLET, A_DEFFLOAT, 0);
563 class_addlist(midiclkin_class, midiclkin_list);
564 class_sethelpsymbol(midiclkin_class, gensym("midi"));
565 midiclkin_sym = gensym("#midiclkin");
566}
567
568void inmidi_clk(double timing)
569{
570
571 static float prev = 0;
572 static float count = 0;
573 float cur,diff;
574
575 if (midiclkin_sym->s_thing)
576 {
577 t_atom at[2];
578 diff =timing - prev;
579 count++;
580
581 if (count == 3)
582 { /* 24 count per quoter note */
583 SETFLOAT(at, 1 );
584 count = 0;
585 }
586 else SETFLOAT(at, 0);
587
588 SETFLOAT(at+1, diff);
589 pd_list(midiclkin_sym->s_thing, &s_list, 2, at);
590 prev = timing;
591 }
592}
593
594/*----------midirealtimein (midi FA,FB,FC,FF message )-----------------*/
595
596static t_symbol *midirealtimein_sym;
597
598static t_class *midirealtimein_class;
599
600typedef struct _midirealtimein
601{
602 t_object x_obj;
603 t_outlet *x_outlet1;
604 t_outlet *x_outlet2;
605} t_midirealtimein;
606
607static void *midirealtimein_new( void)
608{
609 t_midirealtimein *x = (t_midirealtimein *)pd_new(midirealtimein_class);
610 x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
611 x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
612 pd_bind(&x->x_obj.ob_pd, midirealtimein_sym);
613#ifndef MSW
614 pd_error(x, "midirealtimein: works under MSW only");
615#endif
616 return (x);
617}
618
619static void midirealtimein_list(t_midirealtimein *x, t_symbol *s,
620 int argc, t_atom *argv)
621{
622 float portno = atom_getfloatarg(0, argc, argv);
623 float byte = atom_getfloatarg(1, argc, argv);
624
625 outlet_float(x->x_outlet2, portno);
626 outlet_float(x->x_outlet1, byte);
627}
628
629static void midirealtimein_free(t_midirealtimein *x)
630{
631 pd_unbind(&x->x_obj.ob_pd, midirealtimein_sym);
632}
633
634static void midirealtimein_setup(void)
635{
636 midirealtimein_class = class_new(gensym("midirealtimein"),
637 (t_newmethod)midirealtimein_new, (t_method)midirealtimein_free,
638 sizeof(t_midirealtimein), CLASS_NOINLET, A_DEFFLOAT, 0);
639 class_addlist(midirealtimein_class, midirealtimein_list);
640 class_sethelpsymbol(midirealtimein_class, gensym("midi"));
641 midirealtimein_sym = gensym("#midirealtimein");
642}
643
644void inmidi_realtimein(int portno, int SysMsg)
645{
646 if (midirealtimein_sym->s_thing)
647 {
648 t_atom at[2];
649 SETFLOAT(at, portno);
650 SETFLOAT(at+1, SysMsg);
651 pd_list(midirealtimein_sym->s_thing, &s_list, 1, at);
652 }
653}
654
655/* -------------------------- midiout -------------------------- */
656
657static t_class *midiout_class;
658
659void sys_putmidibyte(int portno, int byte);
660
661typedef struct _midiout
662{
663 t_object x_obj;
664 t_float x_portno;
665} t_midiout;
666
667static void *midiout_new(t_floatarg portno)
668{
669 t_midiout *x = (t_midiout *)pd_new(midiout_class);
670 if (portno <= 0) portno = 1;
671 x->x_portno = portno;
672 floatinlet_new(&x->x_obj, &x->x_portno);
673#ifdef __irix__
674 post("midiout: unimplemented in IRIX");
675#endif
676 return (x);
677}
678
679static void midiout_float(t_midiout *x, t_floatarg f)
680{
681 sys_putmidibyte(x->x_portno - 1, f);
682}
683
684static void midiout_setup(void)
685{
686 midiout_class = class_new(gensym("midiout"), (t_newmethod)midiout_new, 0,
687 sizeof(t_midiout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
688 class_addfloat(midiout_class, midiout_float);
689 class_sethelpsymbol(midiout_class, gensym("midi"));
690}
691
692/* -------------------------- noteout -------------------------- */
693
694static t_class *noteout_class;
695
696typedef struct _noteout
697{
698 t_object x_obj;
699 t_float x_velo;
700 t_float x_channel;
701} t_noteout;
702
703static void *noteout_new(t_floatarg channel)
704{
705 t_noteout *x = (t_noteout *)pd_new(noteout_class);
706 x->x_velo = 0;
707 if (channel < 1) channel = 1;
708 x->x_channel = channel;
709 floatinlet_new(&x->x_obj, &x->x_velo);
710 floatinlet_new(&x->x_obj, &x->x_channel);
711 return (x);
712}
713
714static void noteout_float(t_noteout *x, t_float f)
715{
716 int binchan = x->x_channel - 1;
717 if (binchan < 0)
718 binchan = 0;
719 outmidi_noteon((binchan >> 4),
720 (binchan & 15), (int)f, (int)x->x_velo);
721}
722
723static void noteout_setup(void)
724{
725 noteout_class = class_new(gensym("noteout"), (t_newmethod)noteout_new, 0,
726 sizeof(t_noteout), 0, A_DEFFLOAT, 0);
727 class_addfloat(noteout_class, noteout_float);
728 class_sethelpsymbol(noteout_class, gensym("midi"));
729}
730
731
732/* -------------------------- ctlout -------------------------- */
733
734static t_class *ctlout_class;
735
736typedef struct _ctlout
737{
738 t_object x_obj;
739 t_float x_ctl;
740 t_float x_channel;
741} t_ctlout;
742
743static void *ctlout_new(t_floatarg ctl, t_floatarg channel)
744{
745 t_ctlout *x = (t_ctlout *)pd_new(ctlout_class);
746 x->x_ctl = ctl;
747 if (channel <= 0) channel = 1;
748 x->x_channel = channel;
749 floatinlet_new(&x->x_obj, &x->x_ctl);
750 floatinlet_new(&x->x_obj, &x->x_channel);
751 return (x);
752}
753
754static void ctlout_float(t_ctlout *x, t_float f)
755{
756 int binchan = x->x_channel - 1;
757 if (binchan < 0)
758 binchan = 0;
759 outmidi_controlchange((binchan >> 4),
760 (binchan & 15), (int)(x->x_ctl), (int)f);
761}
762
763static void ctlout_setup(void)
764{
765 ctlout_class = class_new(gensym("ctlout"), (t_newmethod)ctlout_new, 0,
766 sizeof(t_ctlout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
767 class_addfloat(ctlout_class, ctlout_float);
768 class_sethelpsymbol(ctlout_class, gensym("midi"));
769}
770
771
772/* -------------------------- pgmout -------------------------- */
773
774static t_class *pgmout_class;
775
776typedef struct _pgmout
777{
778 t_object x_obj;
779 t_float x_channel;
780} t_pgmout;
781
782static void *pgmout_new(t_floatarg channel)
783{
784 t_pgmout *x = (t_pgmout *)pd_new(pgmout_class);
785 if (channel <= 0) channel = 1;
786 x->x_channel = channel;
787 floatinlet_new(&x->x_obj, &x->x_channel);
788 return (x);
789}
790
791static void pgmout_float(t_pgmout *x, t_floatarg f)
792{
793 int binchan = x->x_channel - 1;
794 int n = f - 1;
795 if (binchan < 0)
796 binchan = 0;
797 if (n < 0) n = 0;
798 else if (n > 127) n = 127;
799 outmidi_programchange((binchan >> 4),
800 (binchan & 15), n);
801}
802
803static void pgmout_setup(void)
804{
805 pgmout_class = class_new(gensym("pgmout"), (t_newmethod)pgmout_new, 0,
806 sizeof(t_pgmout), 0, A_DEFFLOAT, 0);
807 class_addfloat(pgmout_class, pgmout_float);
808 class_sethelpsymbol(pgmout_class, gensym("midi"));
809}
810
811
812/* -------------------------- bendout -------------------------- */
813
814static t_class *bendout_class;
815
816typedef struct _bendout
817{
818 t_object x_obj;
819 t_float x_channel;
820} t_bendout;
821
822static void *bendout_new(t_floatarg channel)
823{
824 t_bendout *x = (t_bendout *)pd_new(bendout_class);
825 if (channel <= 0) channel = 1;
826 x->x_channel = channel;
827 floatinlet_new(&x->x_obj, &x->x_channel);
828 return (x);
829}
830
831static void bendout_float(t_bendout *x, t_float f)
832{
833 int binchan = x->x_channel - 1;
834 int n = (int)f + 8192;
835 if (binchan < 0)
836 binchan = 0;
837 outmidi_pitchbend((binchan >> 4), (binchan & 15), n);
838}
839
840static void bendout_setup(void)
841{
842 bendout_class = class_new(gensym("bendout"), (t_newmethod)bendout_new, 0,
843 sizeof(t_bendout), 0, A_DEFFLOAT, 0);
844 class_addfloat(bendout_class, bendout_float);
845 class_sethelpsymbol(bendout_class, gensym("midi"));
846}
847
848/* -------------------------- touch -------------------------- */
849
850static t_class *touchout_class;
851
852typedef struct _touchout
853{
854 t_object x_obj;
855 t_float x_channel;
856} t_touchout;
857
858static void *touchout_new(t_floatarg channel)
859{
860 t_touchout *x = (t_touchout *)pd_new(touchout_class);
861 if (channel <= 0) channel = 1;
862 x->x_channel = channel;
863 floatinlet_new(&x->x_obj, &x->x_channel);
864 return (x);
865}
866
867static void touchout_float(t_touchout *x, t_float f)
868{
869 int binchan = x->x_channel - 1;
870 if (binchan < 0)
871 binchan = 0;
872 outmidi_aftertouch((binchan >> 4), (binchan & 15), (int)f);
873}
874
875static void touchout_setup(void)
876{
877 touchout_class = class_new(gensym("touchout"), (t_newmethod)touchout_new, 0,
878 sizeof(t_touchout), 0, A_DEFFLOAT, 0);
879 class_addfloat(touchout_class, touchout_float);
880 class_sethelpsymbol(touchout_class, gensym("midi"));
881}
882
883/* -------------------------- polytouch -------------------------- */
884
885static t_class *polytouchout_class;
886
887typedef struct _polytouchout
888{
889 t_object x_obj;
890 t_float x_channel;
891 t_float x_pitch;
892} t_polytouchout;
893
894static void *polytouchout_new(t_floatarg channel)
895{
896 t_polytouchout *x = (t_polytouchout *)pd_new(polytouchout_class);
897 if (channel <= 0) channel = 1;
898 x->x_channel = channel;
899 x->x_pitch = 0;
900 floatinlet_new(&x->x_obj, &x->x_pitch);
901 floatinlet_new(&x->x_obj, &x->x_channel);
902 return (x);
903}
904
905static void polytouchout_float(t_polytouchout *x, t_float n)
906{
907 int binchan = x->x_channel - 1;
908 if (binchan < 0)
909 binchan = 0;
910 outmidi_polyaftertouch((binchan >> 4), (binchan & 15), x->x_pitch, n);
911}
912
913static void polytouchout_setup(void)
914{
915 polytouchout_class = class_new(gensym("polytouchout"),
916 (t_newmethod)polytouchout_new, 0,
917 sizeof(t_polytouchout), 0, A_DEFFLOAT, 0);
918 class_addfloat(polytouchout_class, polytouchout_float);
919 class_sethelpsymbol(polytouchout_class, gensym("midi"));
920}
921
922/* -------------------------- makenote -------------------------- */
923
924static t_class *makenote_class;
925
926typedef struct _hang
927{
928 t_clock *h_clock;
929 struct _hang *h_next;
930 t_float h_pitch;
931 struct _makenote *h_owner;
932} t_hang;
933
934typedef struct _makenote
935{
936 t_object x_obj;
937 t_float x_velo;
938 t_float x_dur;
939 t_outlet *x_pitchout;
940 t_outlet *x_velout;
941 t_hang *x_hang;
942} t_makenote;
943
944static void *makenote_new(t_floatarg velo, t_floatarg dur)
945{
946 t_makenote *x = (t_makenote *)pd_new(makenote_class);
947 x->x_velo = velo;
948 x->x_dur = dur;
949 floatinlet_new(&x->x_obj, &x->x_velo);
950 floatinlet_new(&x->x_obj, &x->x_dur);
951 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
952 x->x_velout = outlet_new(&x->x_obj, &s_float);
953 x->x_hang = 0;
954 return (x);
955}
956
957static void makenote_tick(t_hang *hang)
958{
959 t_makenote *x = hang->h_owner;
960 t_hang *h2, *h3;
961 outlet_float(x->x_velout, 0);
962 outlet_float(x->x_pitchout, hang->h_pitch);
963 if (x->x_hang == hang) x->x_hang = hang->h_next;
964 else for (h2 = x->x_hang; h3 = h2->h_next; h2 = h3)
965 {
966 if (h3 == hang)
967 {
968 h2->h_next = h3->h_next;
969 break;
970 }
971 }
972 clock_free(hang->h_clock);
973 freebytes(hang, sizeof(*hang));
974}
975
976static void makenote_float(t_makenote *x, t_float f)
977{
978 t_hang *hang;
979 if (!x->x_velo) return;
980 outlet_float(x->x_velout, x->x_velo);
981 outlet_float(x->x_pitchout, f);
982 hang = (t_hang *)getbytes(sizeof *hang);
983 hang->h_next = x->x_hang;
984 x->x_hang = hang;
985 hang->h_pitch = f;
986 hang->h_owner = x;
987 hang->h_clock = clock_new(hang, (t_method)makenote_tick);
988 clock_delay(hang->h_clock, (x->x_dur >= 0 ? x->x_dur : 0));
989}
990
991static void makenote_stop(t_makenote *x)
992{
993 t_hang *hang;
994 while (hang = x->x_hang)
995 {
996 outlet_float(x->x_velout, 0);
997 outlet_float(x->x_pitchout, hang->h_pitch);
998 x->x_hang = hang->h_next;
999 clock_free(hang->h_clock);
1000 freebytes(hang, sizeof(*hang));
1001 }
1002}
1003
1004static void makenote_clear(t_makenote *x)
1005{
1006 t_hang *hang;
1007 while (hang = x->x_hang)
1008 {
1009 x->x_hang = hang->h_next;
1010 clock_free(hang->h_clock);
1011 freebytes(hang, sizeof(*hang));
1012 }
1013}
1014
1015static void makenote_setup(void)
1016{
1017 makenote_class = class_new(gensym("makenote"),
1018 (t_newmethod)makenote_new, (t_method)makenote_clear,
1019 sizeof(t_makenote), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
1020 class_addfloat(makenote_class, makenote_float);
1021 class_addmethod(makenote_class, (t_method)makenote_stop, gensym("stop"),
1022 0);
1023 class_addmethod(makenote_class, (t_method)makenote_clear, gensym("clear"),
1024 0);
1025}
1026
1027/* -------------------------- stripnote -------------------------- */
1028
1029static t_class *stripnote_class;
1030
1031typedef struct _stripnote
1032{
1033 t_object x_obj;
1034 t_float x_velo;
1035 t_outlet *x_pitchout;
1036 t_outlet *x_velout;
1037} t_stripnote;
1038
1039static void *stripnote_new(void )
1040{
1041 t_stripnote *x = (t_stripnote *)pd_new(stripnote_class);
1042 floatinlet_new(&x->x_obj, &x->x_velo);
1043 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
1044 x->x_velout = outlet_new(&x->x_obj, &s_float);
1045 return (x);
1046}
1047
1048static void stripnote_float(t_stripnote *x, t_float f)
1049{
1050 t_hang *hang;
1051 if (!x->x_velo) return;
1052 outlet_float(x->x_velout, x->x_velo);
1053 outlet_float(x->x_pitchout, f);
1054}
1055
1056static void stripnote_setup(void)
1057{
1058 stripnote_class = class_new(gensym("stripnote"),
1059 (t_newmethod)stripnote_new, 0, sizeof(t_stripnote), 0, 0);
1060 class_addfloat(stripnote_class, stripnote_float);
1061}
1062
1063/* -------------------------- poly -------------------------- */
1064
1065static t_class *poly_class;
1066
1067typedef struct voice
1068{
1069 float v_pitch;
1070 int v_used;
1071 unsigned long v_serial;
1072} t_voice;
1073
1074typedef struct poly
1075{
1076 t_object x_obj;
1077 int x_n;
1078 t_voice *x_vec;
1079 float x_vel;
1080 t_outlet *x_pitchout;
1081 t_outlet *x_velout;
1082 unsigned long x_serial;
1083 int x_steal;
1084} t_poly;
1085
1086static void *poly_new(float fnvoice, float fsteal)
1087{
1088 int i, n = fnvoice;
1089 t_poly *x = (t_poly *)pd_new(poly_class);
1090 t_voice *v;
1091 if (n < 1) n = 1;
1092 x->x_n = n;
1093 x->x_vec = (t_voice *)getbytes(n * sizeof(*x->x_vec));
1094 for (v = x->x_vec, i = n; i--; v++)
1095 v->v_pitch = v->v_used = v->v_serial = 0;
1096 x->x_vel = 0;
1097 x->x_steal = (fsteal != 0);
1098 floatinlet_new(&x->x_obj, &x->x_vel);
1099 outlet_new(&x->x_obj, &s_float);
1100 x->x_pitchout = outlet_new(&x->x_obj, &s_float);
1101 x->x_velout = outlet_new(&x->x_obj, &s_float);
1102 x->x_serial = 0;
1103 return (x);
1104}
1105
1106static void poly_float(t_poly *x, t_float f)
1107{
1108 int i;
1109 t_voice *v;
1110 t_voice *firston, *firstoff;
1111 unsigned int serialon, serialoff, onindex = 0, offindex = 0;
1112 if (x->x_vel > 0)
1113 {
1114 /* note on. Look for a vacant voice */
1115 for (v = x->x_vec, i = 0, firston = firstoff = 0,
1116 serialon = serialoff = 0xffffffff; i < x->x_n; v++, i++)
1117 {
1118 if (v->v_used && v->v_serial < serialon)
1119 firston = v, serialon = v->v_serial, onindex = i;
1120 else if (!v->v_used && v->v_serial < serialoff)
1121 firstoff = v, serialoff = v->v_serial, offindex = i;
1122 }
1123 if (firstoff)
1124 {
1125 outlet_float(x->x_velout, x->x_vel);
1126 outlet_float(x->x_pitchout, firstoff->v_pitch = f);
1127 outlet_float(x->x_obj.ob_outlet, offindex+1);
1128 firstoff->v_used = 1;
1129 firstoff->v_serial = x->x_serial++;
1130 }
1131 /* if none, steal one */
1132 else if (firston && x->x_steal)
1133 {
1134 outlet_float(x->x_velout, 0);
1135 outlet_float(x->x_pitchout, firston->v_pitch);
1136 outlet_float(x->x_obj.ob_outlet, onindex+1);
1137 outlet_float(x->x_velout, x->x_vel);
1138 outlet_float(x->x_pitchout, firston->v_pitch = f);
1139 outlet_float(x->x_obj.ob_outlet, onindex+1);
1140 firston->v_serial = x->x_serial++;
1141 }
1142 }
1143 else /* note off. Turn off oldest match */
1144 {
1145 for (v = x->x_vec, i = 0, firston = 0, serialon = 0xffffffff;
1146 i < x->x_n; v++, i++)
1147 if (v->v_used && v->v_pitch == f && v->v_serial < serialon)
1148 firston = v, serialon = v->v_serial, onindex = i;
1149 if (firston)
1150 {
1151 firston->v_used = 0;
1152 firston->v_serial = x->x_serial++;
1153 outlet_float(x->x_velout, 0);
1154 outlet_float(x->x_pitchout, firston->v_pitch);
1155 outlet_float(x->x_obj.ob_outlet, onindex+1);
1156 }
1157 }
1158}
1159
1160static void poly_stop(t_poly *x)
1161{
1162 int i;
1163 t_voice *v;
1164 for (i = 0, v = x->x_vec; i < x->x_n; i++, v++)
1165 if (v->v_used)
1166 {
1167 outlet_float(x->x_velout, 0L);
1168 outlet_float(x->x_pitchout, v->v_pitch);
1169 outlet_float(x->x_obj.ob_outlet, i+1);
1170 v->v_used = 0;
1171 v->v_serial = x->x_serial++;
1172 }
1173}
1174
1175static void poly_clear(t_poly *x)
1176{
1177 int i;
1178 t_voice *v;
1179 for (v = x->x_vec, i = x->x_n; i--; v++) v->v_used = v->v_serial = 0;
1180}
1181
1182static void poly_free(t_poly *x)
1183{
1184 freebytes(x->x_vec, x->x_n * sizeof (*x->x_vec));
1185}
1186
1187static void poly_setup(void)
1188{
1189 poly_class = class_new(gensym("poly"),
1190 (t_newmethod)poly_new, (t_method)poly_clear,
1191 sizeof(t_poly), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
1192 class_addfloat(poly_class, poly_float);
1193 class_addmethod(poly_class, (t_method)poly_stop, gensym("stop"), 0);
1194 class_addmethod(poly_class, (t_method)poly_clear, gensym("clear"), 0);
1195}
1196
1197/* -------------------------- bag -------------------------- */
1198
1199static t_class *bag_class;
1200
1201typedef struct _bagelem
1202{
1203 struct _bagelem *e_next;
1204 t_float e_value;
1205} t_bagelem;
1206
1207typedef struct _bag
1208{
1209 t_object x_obj;
1210 t_float x_velo;
1211 t_bagelem *x_first;
1212} t_bag;
1213
1214static void *bag_new(void )
1215{
1216 t_bag *x = (t_bag *)pd_new(bag_class);
1217 x->x_velo = 0;
1218 floatinlet_new(&x->x_obj, &x->x_velo);
1219 outlet_new(&x->x_obj, &s_float);
1220 x->x_first = 0;
1221 return (x);
1222}
1223
1224static void bag_float(t_bag *x, t_float f)
1225{
1226 t_bagelem *bagelem, *e2, *e3;
1227 if (x->x_velo != 0)
1228 {
1229 bagelem = (t_bagelem *)getbytes(sizeof *bagelem);
1230 bagelem->e_next = 0;
1231 bagelem->e_value = f;
1232 if (!x->x_first) x->x_first = bagelem;
1233 else /* LATER replace with a faster algorithm */
1234 {
1235 for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
1236 ;
1237 e2->e_next = bagelem;
1238 }
1239 }
1240 else
1241 {
1242 if (!x->x_first) return;
1243 if (x->x_first->e_value == f)
1244 {
1245 bagelem = x->x_first;
1246 x->x_first = x->x_first->e_next;
1247 freebytes(bagelem, sizeof(*bagelem));
1248 return;
1249 }
1250 for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
1251 if (e3->e_value == f)
1252 {
1253 e2->e_next = e3->e_next;
1254 freebytes(e3, sizeof(*e3));
1255 return;
1256 }
1257 }
1258}
1259
1260static void bag_flush(t_bag *x)
1261{
1262 t_bagelem *bagelem;
1263 while (bagelem = x->x_first)
1264 {
1265 outlet_float(x->x_obj.ob_outlet, bagelem->e_value);
1266 x->x_first = bagelem->e_next;
1267 freebytes(bagelem, sizeof(*bagelem));
1268 }
1269}
1270
1271static void bag_clear(t_bag *x)
1272{
1273 t_bagelem *bagelem;
1274 while (bagelem = x->x_first)
1275 {
1276 x->x_first = bagelem->e_next;
1277 freebytes(bagelem, sizeof(*bagelem));
1278 }
1279}
1280
1281static void bag_setup(void)
1282{
1283 bag_class = class_new(gensym("bag"),
1284 (t_newmethod)bag_new, (t_method)bag_clear,
1285 sizeof(t_bag), 0, 0);
1286 class_addfloat(bag_class, bag_float);
1287 class_addmethod(bag_class, (t_method)bag_flush, gensym("flush"), 0);
1288 class_addmethod(bag_class, (t_method)bag_clear, gensym("clear"), 0);
1289}
1290
1291void x_midi_setup(void)
1292{
1293 midiin_setup();
1294 midirealtimein_setup();
1295 notein_setup();
1296 ctlin_setup();
1297 pgmin_setup();
1298 bendin_setup();
1299 touchin_setup();
1300 polytouchin_setup();
1301 midiclkin_setup();
1302 midiout_setup();
1303 noteout_setup();
1304 ctlout_setup();
1305 pgmout_setup();
1306 bendout_setup();
1307 touchout_setup();
1308 polytouchout_setup();
1309 makenote_setup();
1310 stripnote_setup();
1311 poly_setup();
1312 bag_setup();
1313}
1314
diff --git a/apps/plugins/pdbox/SOURCES b/apps/plugins/pdbox/SOURCES
index 528372c3aa..f872b017c9 100644
--- a/apps/plugins/pdbox/SOURCES
+++ b/apps/plugins/pdbox/SOURCES
@@ -3,12 +3,21 @@ pdbox-net.c
3pdbox-func.c 3pdbox-func.c
4pdbox-gui.c 4pdbox-gui.c
5 5
6/*
7wfirstfit.c
8*/
9
10PDa/src/s_audio_rockbox.c 6PDa/src/s_audio_rockbox.c
11 7
8PDa/src/d_ugen.c
9PDa/src/d_arithmetic.c
10PDa/src/d_dac.c
11PDa/src/d_misc.c
12PDa/src/d_fft.c
13PDa/src/d_imayer_fft.c
14PDa/src/d_mayer_fft.c
15PDa/src/d_fftroutine.c
16PDa/src/d_global.c
17PDa/src/d_resample.c
18PDa/src/d_ctl.c
19PDa/src/d_soundfile.c
20
12PDa/src/g_canvas.c 21PDa/src/g_canvas.c
13PDa/src/g_graph.c 22PDa/src/g_graph.c
14PDa/src/g_text.c 23PDa/src/g_text.c
@@ -31,57 +40,32 @@ PDa/src/g_toggle.c
31PDa/src/g_vdial.c 40PDa/src/g_vdial.c
32PDa/src/g_vslider.c 41PDa/src/g_vslider.c
33PDa/src/g_vumeter.c 42PDa/src/g_vumeter.c
43
34PDa/src/m_pd.c 44PDa/src/m_pd.c
35PDa/src/m_class.c 45PDa/src/m_class.c
36PDa/src/m_obj.c 46PDa/src/m_obj.c
37PDa/src/m_atom.c 47PDa/src/m_atom.c
38PDa/src/m_memory.c 48PDa/src/m_memory.c
39
40PDa/src/m_binbuf.c 49PDa/src/m_binbuf.c
41PDa/src/m_conf.c 50PDa/src/m_conf.c
42PDa/src/m_glob.c 51PDa/src/m_glob.c
43PDa/src/m_sched.c 52PDa/src/m_sched.c
44/* PDa/src/s_main.c Does not compile, system reasons */ 53PDa/src/m_fixed.c
45/* PDa/src/s_inter.c Does not compile, BSD sockets */ 54
46PDa/src/s_file.c 55PDa/src/s_file.c
47PDa/src/s_print.c 56PDa/src/s_print.c
48PDa/src/s_loader.c 57PDa/src/s_loader.c
49PDa/src/s_path.c 58PDa/src/s_path.c
50/*
51PDa/src/s_entry.c
52*/
53PDa/src/s_audio.c 59PDa/src/s_audio.c
54/* 60
55PDa/src/s_midi.c
56*/
57PDa/src/d_ugen.c
58PDa/src/d_arithmetic.c
59PDa/src/d_dac.c
60PDa/src/d_misc.c
61PDa/src/d_fft.c
62PDa/src/d_mayer_fft.c
63PDa/src/d_fftroutine.c
64PDa/src/d_global.c
65PDa/src/d_resample.c
66PDa/src/d_ctl.c
67PDa/src/d_soundfile.c
68PDa/src/x_arithmetic.c 61PDa/src/x_arithmetic.c
69PDa/src/x_connective.c 62PDa/src/x_connective.c
70PDa/src/x_interface.c 63PDa/src/x_interface.c
71/*
72PDa/src/x_midi.c
73*/
74PDa/src/x_misc.c 64PDa/src/x_misc.c
75PDa/src/x_time.c 65PDa/src/x_time.c
76PDa/src/x_acoustics.c 66PDa/src/x_acoustics.c
77PDa/src/x_net.c 67PDa/src/x_net.c
78PDa/src/x_qlist.c 68PDa/src/x_qlist.c
79/*
80PDa/src/x_gui.c
81*/
82
83PDa/src/d_imayer_fft.c
84PDa/src/m_fixed.c
85 69
86PDa/intern/biquad~.c 70PDa/intern/biquad~.c
87PDa/intern/bp~.c 71PDa/intern/bp~.c
@@ -109,9 +93,6 @@ PDa/intern/rsqrt~.c
109PDa/intern/samphold~.c 93PDa/intern/samphold~.c
110PDa/intern/sfread~.c 94PDa/intern/sfread~.c
111PDa/intern/sfwrite~.c 95PDa/intern/sfwrite~.c
112/*
113PDa/intern/sig~.c
114*/
115PDa/intern/snapshot~.c 96PDa/intern/snapshot~.c
116PDa/intern/sqrt~.c 97PDa/intern/sqrt~.c
117PDa/intern/tabosc4~.c 98PDa/intern/tabosc4~.c
@@ -130,9 +111,7 @@ PDa/intern/vline~.c
130PDa/intern/vsnapshot~.c 111PDa/intern/vsnapshot~.c
131PDa/intern/wrap~.c 112PDa/intern/wrap~.c
132 113
133/* PDa/extra/OSCroute.c */
134PDa/extra/bandpass.c 114PDa/extra/bandpass.c
135/* PDa/extra/dumpOSC.c Does not compile, file handling stuff */
136PDa/extra/equalizer.c 115PDa/extra/equalizer.c
137PDa/extra/gcanvas.c 116PDa/extra/gcanvas.c
138PDa/extra/highpass.c 117PDa/extra/highpass.c
@@ -143,10 +122,4 @@ PDa/extra/lowpass.c
143PDa/extra/lowshelf.c 122PDa/extra/lowshelf.c
144PDa/extra/moog~.c 123PDa/extra/moog~.c
145PDa/extra/notch.c 124PDa/extra/notch.c
146/* PDa/extra/sendOSC.c Does not compile, file handling stuff */
147/*
148PDa/extra/shell.c
149PDa/extra/slider.c
150PDa/extra/sliderh.c
151*/
152PDa/extra/zerox~.c 125PDa/extra/zerox~.c