diff options
author | Wincent Balin <wincent@rockbox.org> | 2010-06-03 00:39:13 +0000 |
---|---|---|
committer | Wincent Balin <wincent@rockbox.org> | 2010-06-03 00:39:13 +0000 |
commit | c1ae4414d4ac6504992434b949b252c30daf0c48 (patch) | |
tree | 696c5781e9a00cea694117eb3ef404d37f10930e /apps | |
parent | 5edd8cf736232a240e2f4f47eb847e1901d18379 (diff) | |
download | rockbox-c1ae4414d4ac6504992434b949b252c30daf0c48.tar.gz rockbox-c1ae4414d4ac6504992434b949b252c30daf0c48.zip |
pdbox: Source cleanup. Removed unneeded files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26497 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
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 | /* | ||
2 | Written by Matt Wright, The Center for New Music and Audio Technologies, | ||
3 | University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03 | ||
4 | The Regents of the University of California (Regents). | ||
5 | |||
6 | Permission to use, copy, modify, distribute, and distribute modified versions | ||
7 | of this software and its documentation without fee and without a signed | ||
8 | licensing agreement, is hereby granted, provided that the above copyright | ||
9 | notice, this paragraph and the following two paragraphs appear in all copies, | ||
10 | modifications, and distributions. | ||
11 | |||
12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | ||
13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING | ||
14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS | ||
15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
16 | |||
17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED | ||
20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE | ||
21 | MAINTENANCE, 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 | |||
73 | OSCTimeTag OSCTT_Immediately(void); | ||
74 | OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset); | ||
75 | OSCTimeTag 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 | |||
90 | typedef 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.) */ | ||
113 | void 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. */ | ||
118 | void 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?) */ | ||
123 | int OSC_isBufferEmpty(OSCbuf *buf); | ||
124 | |||
125 | |||
126 | /* How much space is left in the buffer? */ | ||
127 | int OSC_freeSpaceInBuffer(OSCbuf *buf); | ||
128 | |||
129 | /* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */ | ||
130 | int 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.) */ | ||
136 | char *OSC_getPacket(OSCbuf *buf); | ||
137 | int 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 | |||
172 | int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt); | ||
173 | int OSC_closeBundle(OSCbuf *buf); | ||
174 | int OSC_closeAllBundles(OSCbuf *buf); | ||
175 | |||
176 | int OSC_writeAddress(OSCbuf *buf, char *name); | ||
177 | int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types); | ||
178 | int OSC_writeFloatArg(OSCbuf *buf, float arg); | ||
179 | int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args); | ||
180 | int OSC_writeIntArg(OSCbuf *buf, int4byte arg); | ||
181 | int OSC_writeStringArg(OSCbuf *buf, char *arg); | ||
182 | |||
183 | extern 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. */ | ||
188 | int 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 | /* | ||
2 | Written by Adrian Freed, The Center for New Music and Audio Technologies, | ||
3 | University of California, Berkeley. Copyright (c) 1992,93,94,95,96,97,98,99,2000,01,02,03,04 | ||
4 | The Regents of the University of California (Regents). | ||
5 | |||
6 | Permission to use, copy, modify, distribute, and distribute modified versions | ||
7 | of this software and its documentation without fee and without a signed | ||
8 | licensing agreement, is hereby granted, provided that the above copyright | ||
9 | notice, this paragraph and the following two paragraphs appear in all copies, | ||
10 | modifications, and distributions. | ||
11 | |||
12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | ||
13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING | ||
14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS | ||
15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
16 | |||
17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED | ||
20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE | ||
21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
22 | |||
23 | |||
24 | The 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 | ||
72 | typedef int Boolean; | ||
73 | #define TRUE 1 | ||
74 | #define FALSE 0 | ||
75 | #endif | ||
76 | |||
77 | |||
78 | /* Fixed byte width types */ | ||
79 | typedef int int4; /* 4 byte int */ | ||
80 | |||
81 | Boolean 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 | |||
89 | static t_class *OSCroute_class; | ||
90 | |||
91 | typedef 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 | |||
101 | t_symbol *ps_list, *ps_complain, *ps_emptySymbol; | ||
102 | |||
103 | /* prototypes */ | ||
104 | |||
105 | void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
106 | void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
107 | void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
108 | /* //void *OSCroute_new(t_symbol *s, int argc, atom *argv); */ | ||
109 | void *OSCroute_new(t_symbol *s, int argc, t_atom *argv); | ||
110 | void OSCroute_version (t_OSCroute *x); | ||
111 | /* void OSCroute_assist (OSCroute *x, void *box, long msg, long arg, */ | ||
112 | /* char *dstString); */ | ||
113 | void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
114 | |||
115 | static char *NextSlashOrNull(char *p); | ||
116 | static void StrCopyUntilSlash(char *target, const char *source); | ||
117 | |||
118 | |||
119 | // free | ||
120 | static 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 | ||
134 | void 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 | |||
163 | void *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 | |||
248 | void 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 | |||
262 | void 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 | |||
293 | void 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 | |||
314 | void 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 | |||
323 | void 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 | |||
417 | static char *NextSlashOrNull(char *p) { | ||
418 | while (*p != '/' && *p != '\0') { | ||
419 | p++; | ||
420 | } | ||
421 | return p; | ||
422 | } | ||
423 | |||
424 | static 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 | |||
433 | static 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 | |||
447 | void 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 | |||
478 | static const char *theWholePattern; /* Just for warning messages */ | ||
479 | |||
480 | static Boolean MatchBrackets (const char *pattern, const char *test); | ||
481 | static Boolean MatchList (const char *pattern, const char *test); | ||
482 | |||
483 | Boolean 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 | |||
534 | static 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 | |||
569 | advance: | ||
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 | |||
585 | static 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 | /* | ||
2 | Written by Matt Wright and Adrian Freed, The Center for New Music and | ||
3 | Audio Technologies, University of California, Berkeley. Copyright (c) | ||
4 | 1992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of | ||
5 | California (Regents). | ||
6 | |||
7 | Permission to use, copy, modify, distribute, and distribute modified versions | ||
8 | of this software and its documentation without fee and without a signed | ||
9 | licensing agreement, is hereby granted, provided that the above copyright | ||
10 | notice, this paragraph and the following two paragraphs appear in all copies, | ||
11 | modifications, and distributions. | ||
12 | |||
13 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | ||
14 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING | ||
15 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS | ||
16 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
17 | |||
18 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
19 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
20 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED | ||
21 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE | ||
22 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
23 | |||
24 | |||
25 | The 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); | ||
80 | void 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 | |||
127 | char *htm_error_string; | ||
128 | typedef int Boolean; | ||
129 | typedef void *OBJ; | ||
130 | |||
131 | typedef struct ClientAddressStruct { | ||
132 | struct sockaddr_in cl_addr; | ||
133 | int clilen; | ||
134 | int sockfd; | ||
135 | } *ClientAddr; | ||
136 | |||
137 | typedef unsigned long long osc_time_t; | ||
138 | |||
139 | Boolean ShowBytes = FALSE; | ||
140 | Boolean Silent = FALSE; | ||
141 | |||
142 | /* Declarations */ | ||
143 | #ifndef WIN32 | ||
144 | static int unixinitudp(int chan); | ||
145 | #endif | ||
146 | |||
147 | static int initudp(int chan); | ||
148 | static void closeudp(int sockfd); | ||
149 | Boolean ClientReply(int packetsize, void *packet, int socketfd, | ||
150 | void *clientaddresspointer, int clientaddressbufferlength); | ||
151 | void sgi_CleanExit(void); | ||
152 | Boolean sgi_HaveToQuit(void); | ||
153 | int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy); | ||
154 | static void catch_sigint(); | ||
155 | static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ; | ||
156 | char *DataAfterAlignedString(char *string, char *boundary) ; | ||
157 | Boolean IsNiceString(char *string, char *boundary) ; | ||
158 | void complain(char *s, ...); | ||
159 | |||
160 | #define MAXMESG 32768 | ||
161 | static char mbuf[MAXMESG]; | ||
162 | |||
163 | /* ----------------------------- dumpOSC ------------------------- */ | ||
164 | |||
165 | #define MAXOUTAT 50 | ||
166 | |||
167 | static t_class *dumpOSC_class; | ||
168 | |||
169 | typedef 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 | |||
184 | void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr); | ||
185 | Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd); | ||
186 | static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr); | ||
187 | static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n); | ||
188 | static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma); | ||
189 | |||
190 | static 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 | |||
243 | static 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 | |||
312 | static 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 | ||
323 | OSC_API void dumpOSC_setup(void) | ||
324 | #else | ||
325 | void 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 | |||
365 | static 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 | |||
418 | static void closeudp(int sockfd) { | ||
419 | #ifdef WIN32 | ||
420 | closesocket(sockfd); | ||
421 | #else | ||
422 | close(sockfd); | ||
423 | #endif | ||
424 | } | ||
425 | |||
426 | static Boolean catchupflag=FALSE; | ||
427 | Boolean 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 | |||
435 | static Boolean exitflag= FALSE; | ||
436 | void sgi_CleanExit(void) { | ||
437 | exitflag = TRUE; | ||
438 | } | ||
439 | |||
440 | Boolean sgi_HaveToQuit(void) { | ||
441 | return exitflag; | ||
442 | } | ||
443 | |||
444 | |||
445 | /* file descriptor poll table */ | ||
446 | static int npolldevs =0; | ||
447 | typedef struct polldev | ||
448 | { | ||
449 | int fd; | ||
450 | void (*callbackfunction)(int , void *); | ||
451 | void *dummy; | ||
452 | } polldev; | ||
453 | #define TABMAX 8 | ||
454 | static 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 | */ | ||
466 | int 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 | |||
478 | static int caught_sigint; | ||
479 | |||
480 | static void catch_sigint() { | ||
481 | caught_sigint = 1; | ||
482 | } | ||
483 | static int sockfd, usockfd; | ||
484 | |||
485 | |||
486 | void 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 | |||
509 | void 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 | |||
515 | void WriteMode(char* dst) | ||
516 | { | ||
517 | *(int32_t*)dst = htonl(0); | ||
518 | } | ||
519 | |||
520 | osc_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 | |||
526 | double TimeToSeconds(osc_time_t osctime) | ||
527 | { | ||
528 | return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */; | ||
529 | } | ||
530 | |||
531 | int timeRound(double x) | ||
532 | { | ||
533 | return x >= 0.0 ? x+0.5 : x-0.5; | ||
534 | } | ||
535 | /* | ||
536 | void 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 | |||
554 | void 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 | |||
565 | Boolean 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 | |||
594 | void 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 | |||
681 | static 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 | |||
724 | static 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 | |||
843 | static 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 | |||
908 | char *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 | |||
951 | Boolean 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> | ||
990 | void 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 | |||
9 | typedef 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 | |||
35 | static 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 | |||
78 | static 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 | |||
94 | static 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 | |||
201 | static 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 | |||
225 | static 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 | |||
246 | static 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 | |||
260 | static 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 | |||
280 | static 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 | |||
301 | static 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 | |||
308 | static 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 | |||
315 | static 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 | |||
335 | static void fatom_save(t_gobj *z, t_binbuf *b); | ||
336 | |||
337 | t_widgetbehavior fatom_widgetbehavior; | ||
338 | |||
339 | |||
340 | |||
341 | |||
342 | static 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 | |||
347 | static void fatom_color(t_fatom* x,t_symbol* col) | ||
348 | { | ||
349 | |||
350 | } | ||
351 | |||
352 | |||
353 | static 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 | |||
363 | static 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 | |||
378 | static void fatom_bang(t_fatom* x,t_floatarg f) | ||
379 | { | ||
380 | outlet_float(x->x_obj.ob_outlet,x->x_val); | ||
381 | } | ||
382 | |||
383 | |||
384 | static void fatom_properties(t_gobj *z, t_glist *owner) | ||
385 | { | ||
386 | post("N/I"); | ||
387 | } | ||
388 | |||
389 | |||
390 | static 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 | |||
402 | static 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 | |||
449 | static 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 | |||
2 | VERSION = 0.2 | ||
3 | SOURCE = $(shell ls *.c) | ||
4 | TARGETS = $(SOURCE:.c=.pd_linux) | ||
5 | |||
6 | EXT= pd_linux | ||
7 | |||
8 | AFLAGS = -g -O2 -I./ -DFIXEDPOINT | ||
9 | EFLAGS = -shared -Wl,-export-dynamic | ||
10 | PREFIX = /usr | ||
11 | |||
12 | |||
13 | all: $(TARGETS) | ||
14 | |||
15 | clean: | ||
16 | -rm $(TARGETS) | ||
17 | -rm *.o *~ | ||
18 | |||
19 | tar: clean | ||
20 | cd ..;tar czvf PDa-externals-$(VERSION).tgz PDa-externals | ||
21 | |||
22 | upload: tar | ||
23 | scp ../PDa-externals-$(VERSION).tgz gige@xdv.org:~/www/pda/release | ||
24 | |||
25 | install: | ||
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 | /* | ||
2 | Written by Matt Wright, The Center for New Music and Audio Technologies, | ||
3 | University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03 | ||
4 | The Regents of the University of California (Regents). | ||
5 | |||
6 | Permission to use, copy, modify, distribute, and distribute modified versions | ||
7 | of this software and its documentation without fee and without a signed | ||
8 | licensing agreement, is hereby granted, provided that the above copyright | ||
9 | notice, this paragraph and the following two paragraphs appear in all copies, | ||
10 | modifications, and distributions. | ||
11 | |||
12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | ||
13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING | ||
14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS | ||
15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
16 | |||
17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED | ||
20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE | ||
21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
22 | |||
23 | |||
24 | The 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 | |||
88 | OSCTimeTag OSCTT_Immediately(void) { | ||
89 | OSCTimeTag result; | ||
90 | result.seconds = 0; | ||
91 | result.fraction = 1; | ||
92 | return result; | ||
93 | } | ||
94 | |||
95 | |||
96 | OSCTimeTag OSCTT_CurrentTime(void) { | ||
97 | OSCTimeTag result; | ||
98 | result.seconds = 0; | ||
99 | result.fraction = 1; | ||
100 | return result; | ||
101 | } | ||
102 | |||
103 | OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset) { | ||
104 | OSCTimeTag result; | ||
105 | result.seconds = 0; | ||
106 | result.fraction = 1; | ||
107 | return result; | ||
108 | } | ||
109 | |||
110 | |||
111 | typedef int bool; | ||
112 | |||
113 | typedef 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 */ | ||
130 | void *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 | |||
298 | static 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 | |||
309 | bool 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 | } | ||
314 | void 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 | |||
337 | typedef 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 | |||
347 | void CommandLineMode(int argc, char *argv[], void *htmsocket); | ||
348 | OSCTimeTag ParseTimeTag(char *s); | ||
349 | void ParseInteractiveLine(OSCbuf *buf, char *mesg); | ||
350 | typedArg ParseToken(char *token); | ||
351 | int WriteMessage(OSCbuf *buf, char *messageName, int numArgs, typedArg *args); | ||
352 | void SendBuffer(void *htmsocket, OSCbuf *buf); | ||
353 | void SendData(void *htmsocket, int size, char *data); | ||
354 | /* defined in OSC-system-dependent.c now */ | ||
355 | |||
356 | //static void *htmsocket; | ||
357 | static int exitStatus = 0; | ||
358 | static int useTypeTags = 0; | ||
359 | |||
360 | static char bufferForOSCbuf[SC_BUFFER_SIZE]; | ||
361 | |||
362 | |||
363 | ///////// | ||
364 | // end from sendOSC | ||
365 | |||
366 | static t_class *sendOSC_class; | ||
367 | |||
368 | typedef 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 | |||
379 | static 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 | |||
397 | void 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 | |||
409 | static 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 | |||
431 | static 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 | |||
438 | static 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 | |||
459 | void 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 | |||
473 | void 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 | |||
506 | static 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 | |||
579 | void 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 | |||
594 | static 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 | |||
644 | void 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 | |||
681 | void 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 | |||
739 | OSCTimeTag 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 | |||
798 | void 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 | |||
882 | typedArg 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 | |||
913 | int 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 | |||
1011 | void 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 | |||
1026 | void 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 | |||
1072 | char *OSC_errorMessage; | ||
1073 | |||
1074 | static int OSC_padString(char *dest, char *str); | ||
1075 | static int OSC_padStringWithAnExtraStupidComma(char *dest, char *str); | ||
1076 | static int OSC_WritePadding(char *dest, int i); | ||
1077 | static int CheckTypeTag(OSCbuf *buf, char expectedType); | ||
1078 | |||
1079 | void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray) { | ||
1080 | buf->buffer = byteArray; | ||
1081 | buf->size = size; | ||
1082 | OSC_resetBuffer(buf); | ||
1083 | } | ||
1084 | |||
1085 | void 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 | |||
1094 | int OSC_isBufferEmpty(OSCbuf *buf) { | ||
1095 | return buf->bufptr == buf->buffer; | ||
1096 | } | ||
1097 | |||
1098 | int OSC_freeSpaceInBuffer(OSCbuf *buf) { | ||
1099 | return buf->size - (buf->bufptr - buf->buffer); | ||
1100 | } | ||
1101 | |||
1102 | int OSC_isBufferDone(OSCbuf *buf) { | ||
1103 | return (buf->state == DONE || buf->state == ONE_MSG_ARGS); | ||
1104 | } | ||
1105 | |||
1106 | char *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 | |||
1119 | int 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 | |||
1134 | static void PatchMessageSize(OSCbuf *buf) { | ||
1135 | int4byte size; | ||
1136 | size = buf->bufptr - ((char *) buf->thisMsgSize) - 4; | ||
1137 | *(buf->thisMsgSize) = htonl(size); | ||
1138 | } | ||
1139 | |||
1140 | int 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 | |||
1208 | int 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 | |||
1238 | int 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 | |||
1254 | int 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 | |||
1296 | int 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 | |||
1317 | static 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 | |||
1339 | int 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 | |||
1359 | int 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 | |||
1378 | int 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 | |||
1389 | int 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 | ||
1419 | int 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 | |||
1429 | static 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 | |||
1439 | static 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 | |||
1450 | static 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 | |||
5 | typedef unsigned short uint16; | ||
6 | typedef 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 | |||
14 | typedef 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 | |||
34 | typedef unsigned word; | ||
35 | typedef unsigned long dword; | ||
36 | |||
37 | typedef 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 | |||
18 | void sys_rmpollfn(int fd); | ||
19 | void sys_addpollfn(int fd, void* fn, void *ptr); | ||
20 | |||
21 | /* ------------------------ shell ----------------------------- */ | ||
22 | |||
23 | #define INBUFSIZE 1024 | ||
24 | |||
25 | static t_class *shell_class; | ||
26 | |||
27 | |||
28 | static 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 | |||
39 | typedef 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 | |||
55 | static int shell_pid; | ||
56 | |||
57 | |||
58 | void 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 | |||
74 | void 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 | |||
93 | void shell_bang(t_shell *x) | ||
94 | { | ||
95 | post("bang"); | ||
96 | } | ||
97 | |||
98 | /* snippet from pd's code */ | ||
99 | static 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 | |||
136 | void 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 | |||
180 | static 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 | |||
199 | static 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 | |||
278 | void shell_free(t_shell* x) | ||
279 | { | ||
280 | binbuf_free(x->x_binbuf); | ||
281 | } | ||
282 | |||
283 | static 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 | |||
304 | void 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 | |||
6 | static t_class *slider_class; | ||
7 | |||
8 | static 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 | |||
19 | static 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 | |||
27 | t_widgetbehavior slider_widgetbehavior; | ||
28 | |||
29 | |||
30 | void 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 | |||
14 | static t_class *sliderh_class; | ||
15 | |||
16 | static 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 | |||
28 | static 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 | |||
36 | t_widgetbehavior sliderh_widgetbehavior; | ||
37 | |||
38 | |||
39 | |||
40 | |||
41 | void 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 | |||
4 | static t_class *sig_tilde_class; | ||
5 | |||
6 | typedef struct _sig | ||
7 | { | ||
8 | t_object x_obj; | ||
9 | t_sample x_f; | ||
10 | } t_sig; | ||
11 | |||
12 | static 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 | |||
22 | static 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 | |||
43 | static void sig_tilde_float(t_sig *x, t_float f) | ||
44 | { | ||
45 | x->x_f = ftofix(f); | ||
46 | } | ||
47 | |||
48 | static 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 | |||
53 | static 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 | |||
61 | void 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 | |||
4 | make CFLAGS="-O6 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi " -k ipod | ||
5 | make 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 | |||
14 | static t_class *tabwrite_tilde_class; | ||
15 | |||
16 | typedef 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 | |||
27 | static void tabwrite_tilde_tick(t_tabwrite_tilde *x); | ||
28 | |||
29 | static 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 | |||
39 | static 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 | } | ||
66 | bad: | ||
67 | return (w+4); | ||
68 | } | ||
69 | |||
70 | void 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 | |||
89 | static 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 | |||
95 | static void tabwrite_tilde_bang(t_tabwrite_tilde *x) | ||
96 | { | ||
97 | x->x_phase = 0; | ||
98 | } | ||
99 | |||
100 | static 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 | |||
109 | static 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 | |||
116 | static void tabwrite_tilde_free(t_tabwrite_tilde *x) | ||
117 | { | ||
118 | clock_free(x->x_clock); | ||
119 | } | ||
120 | |||
121 | static 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 | |||
138 | static t_class *tabplay_tilde_class; | ||
139 | |||
140 | typedef 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 | |||
152 | static void tabplay_tilde_tick(t_tabplay_tilde *x); | ||
153 | |||
154 | static 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 | |||
166 | static 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); | ||
194 | zero: | ||
195 | while (n--) *out++ = 0; | ||
196 | return (w+4); | ||
197 | } | ||
198 | |||
199 | void 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 | |||
218 | static 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 | |||
224 | static 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 | |||
237 | static void tabplay_tilde_stop(t_tabplay_tilde *x) | ||
238 | { | ||
239 | x->x_phase = 0x7fffffff; | ||
240 | } | ||
241 | |||
242 | static void tabplay_tilde_tick(t_tabplay_tilde *x) | ||
243 | { | ||
244 | outlet_bang(x->x_bangout); | ||
245 | } | ||
246 | |||
247 | static void tabplay_tilde_free(t_tabplay_tilde *x) | ||
248 | { | ||
249 | clock_free(x->x_clock); | ||
250 | } | ||
251 | |||
252 | static 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 | |||
268 | static t_class *tabread_tilde_class; | ||
269 | |||
270 | typedef 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 | |||
279 | static 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 | |||
289 | static 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 | |||
318 | void 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 | |||
337 | static 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 | |||
346 | static void tabread_tilde_free(t_tabread_tilde *x) | ||
347 | { | ||
348 | } | ||
349 | |||
350 | static 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 | |||
364 | static t_class *tabread4_tilde_class; | ||
365 | |||
366 | typedef 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 | |||
375 | static 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 | |||
385 | static 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 | |||
447 | void 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 | |||
466 | static 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 | |||
475 | static void tabread4_tilde_free(t_tabread4_tilde *x) | ||
476 | { | ||
477 | } | ||
478 | |||
479 | static 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 | |||
551 | union tabfudge | ||
552 | { | ||
553 | double tf_d; | ||
554 | int32 tf_i[2]; | ||
555 | }; | ||
556 | |||
557 | static t_class *tabosc4_tilde_class; | ||
558 | |||
559 | typedef 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 | |||
571 | static 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 | |||
584 | static 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 | |||
638 | void 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 | |||
670 | static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f) | ||
671 | { | ||
672 | x->x_phase = f; | ||
673 | } | ||
674 | |||
675 | static 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 | |||
684 | static 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 | |||
700 | static t_class *tabsend_class; | ||
701 | |||
702 | typedef 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 | |||
713 | static void tabsend_tick(t_tabsend *x); | ||
714 | |||
715 | static 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 | |||
725 | static 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; | ||
747 | bad: | ||
748 | return (w+4); | ||
749 | } | ||
750 | |||
751 | static 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 | |||
776 | static 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 | |||
783 | static void tabsend_free(t_tabsend *x) | ||
784 | { | ||
785 | clock_free(x->x_clock); | ||
786 | } | ||
787 | |||
788 | static 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 | |||
798 | static t_class *tabreceive_class; | ||
799 | |||
800 | typedef struct _tabreceive | ||
801 | { | ||
802 | t_object x_obj; | ||
803 | float *x_vec; | ||
804 | t_symbol *x_arrayname; | ||
805 | } t_tabreceive; | ||
806 | |||
807 | static 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 | |||
818 | static 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 | |||
839 | static 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 | |||
847 | static 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 | |||
859 | static t_class *tabread_class; | ||
860 | |||
861 | typedef struct _tabread | ||
862 | { | ||
863 | t_object x_obj; | ||
864 | t_symbol *x_arrayname; | ||
865 | } t_tabread; | ||
866 | |||
867 | static 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 | |||
886 | static void tabread_set(t_tabread *x, t_symbol *s) | ||
887 | { | ||
888 | x->x_arrayname = s; | ||
889 | } | ||
890 | |||
891 | static 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 | |||
899 | static 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 | |||
910 | static t_class *tabread4_class; | ||
911 | |||
912 | typedef struct _tabread4 | ||
913 | { | ||
914 | t_object x_obj; | ||
915 | t_symbol *x_arrayname; | ||
916 | } t_tabread4; | ||
917 | |||
918 | static 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 | |||
953 | static void tabread4_set(t_tabread4 *x, t_symbol *s) | ||
954 | { | ||
955 | x->x_arrayname = s; | ||
956 | } | ||
957 | |||
958 | static 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 | |||
966 | static 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 | |||
977 | static t_class *tabwrite_class; | ||
978 | |||
979 | typedef 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 | |||
989 | static 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 | |||
998 | static 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 | |||
1030 | static void tabwrite_set(t_tabwrite *x, t_symbol *s) | ||
1031 | { | ||
1032 | x->x_arrayname = s; | ||
1033 | } | ||
1034 | |||
1035 | static void tabwrite_free(t_tabwrite *x) | ||
1036 | { | ||
1037 | clock_free(x->x_clock); | ||
1038 | } | ||
1039 | |||
1040 | static 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 | |||
1051 | void 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 | |||
1061 | void 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" | ||
8 | extern int ugen_getsortno(void); | ||
9 | |||
10 | #define DEFDELVS 64 /* LATER get this from canvas at DSP time */ | ||
11 | static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */ | ||
12 | |||
13 | /* ----------------------------- delwrite~ ----------------------------- */ | ||
14 | static t_class *sigdelwrite_class; | ||
15 | |||
16 | typedef struct delwritectl | ||
17 | { | ||
18 | int c_n; | ||
19 | float *c_vec; | ||
20 | int c_phase; | ||
21 | } t_delwritectl; | ||
22 | |||
23 | typedef 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 */ | ||
38 | static 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 | |||
55 | static 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 | |||
76 | static 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 | |||
104 | static 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 | |||
111 | static 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 | |||
118 | static 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~ ----------------------------- */ | ||
129 | static t_class *sigdelread_class; | ||
130 | |||
131 | typedef 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 | |||
142 | static void sigdelread_float(t_sigdelread *x, t_float f); | ||
143 | |||
144 | static 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 | |||
156 | static 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 | |||
173 | static 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 | |||
192 | static 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 | |||
211 | static 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~ ----------------------------- */ | ||
223 | static t_class *sigvd_class; | ||
224 | |||
225 | typedef 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 | |||
234 | static 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 | |||
246 | static 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 | |||
286 | static 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 | |||
303 | static 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 | |||
313 | void 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 | |||
12 | typedef struct hipctl | ||
13 | { | ||
14 | float c_x; | ||
15 | float c_coef; | ||
16 | } t_hipctl; | ||
17 | |||
18 | typedef 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 | |||
28 | t_class *sighip_class; | ||
29 | static void sighip_ft1(t_sighip *x, t_floatarg f); | ||
30 | |||
31 | static 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 | |||
44 | static 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 | |||
55 | static 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 | |||
85 | static 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 | |||
95 | static void sighip_clear(t_sighip *x, t_floatarg q) | ||
96 | { | ||
97 | x->x_cspace.c_x = 0; | ||
98 | } | ||
99 | |||
100 | void 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 | |||
113 | typedef struct lopctl | ||
114 | { | ||
115 | float c_x; | ||
116 | float c_coef; | ||
117 | } t_lopctl; | ||
118 | |||
119 | typedef 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 | |||
129 | t_class *siglop_class; | ||
130 | |||
131 | static void siglop_ft1(t_siglop *x, t_floatarg f); | ||
132 | |||
133 | static 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 | |||
146 | static 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 | |||
157 | static void siglop_clear(t_siglop *x, t_floatarg q) | ||
158 | { | ||
159 | x->x_cspace.c_x = 0; | ||
160 | } | ||
161 | |||
162 | static 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 | |||
180 | static 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 | |||
190 | void 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 | |||
203 | typedef 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 | |||
212 | typedef 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 | |||
223 | t_class *sigbp_class; | ||
224 | |||
225 | static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q); | ||
226 | |||
227 | static 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 | |||
242 | static 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 | |||
252 | static 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 | |||
271 | static void sigbp_ft1(t_sigbp *x, t_floatarg f) | ||
272 | { | ||
273 | sigbp_docoef(x, f, x->x_q); | ||
274 | } | ||
275 | |||
276 | static void sigbp_ft2(t_sigbp *x, t_floatarg q) | ||
277 | { | ||
278 | sigbp_docoef(x, x->x_freq, q); | ||
279 | } | ||
280 | |||
281 | static void sigbp_clear(t_sigbp *x, t_floatarg q) | ||
282 | { | ||
283 | x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0; | ||
284 | } | ||
285 | |||
286 | static 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 | |||
314 | static 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 | |||
324 | void 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 | |||
339 | typedef 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 | |||
350 | typedef 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 | |||
358 | t_class *sigbiquad_class; | ||
359 | |||
360 | static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv); | ||
361 | |||
362 | static 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 | |||
373 | static 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 | |||
401 | static 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; | ||
427 | stable: | ||
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 | |||
435 | static 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 | |||
442 | static 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 | |||
450 | void 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 | |||
465 | typedef struct sigsamphold | ||
466 | { | ||
467 | t_object x_obj; | ||
468 | float x_f; | ||
469 | float x_lastin; | ||
470 | float x_lastout; | ||
471 | } t_sigsamphold; | ||
472 | |||
473 | t_class *sigsamphold_class; | ||
474 | |||
475 | static 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 | |||
486 | static 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 | |||
508 | static 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 | |||
515 | static void sigsamphold_reset(t_sigsamphold *x) | ||
516 | { | ||
517 | x->x_lastin = 1e20; | ||
518 | } | ||
519 | |||
520 | static void sigsamphold_set(t_sigsamphold *x, t_float f) | ||
521 | { | ||
522 | x->x_lastout = f; | ||
523 | } | ||
524 | |||
525 | void 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 | |||
540 | void 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~ -------------------------- */ | ||
14 | static t_class *clip_class; | ||
15 | |||
16 | typedef 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 | |||
24 | static 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 | |||
36 | static 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 | |||
52 | static 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 | |||
57 | static 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 | |||
70 | static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]; | ||
71 | |||
72 | static 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 | |||
91 | float 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 | |||
99 | float 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 | ||
110 | float qsqrt(float f) {return (q8_sqrt(f)); } | ||
111 | float qrsqrt(float f) {return (q8_rsqrt(f)); } | ||
112 | #endif | ||
113 | |||
114 | |||
115 | |||
116 | typedef struct sigrsqrt | ||
117 | { | ||
118 | t_object x_obj; | ||
119 | float x_f; | ||
120 | } t_sigrsqrt; | ||
121 | |||
122 | static t_class *sigrsqrt_class; | ||
123 | |||
124 | static 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 | |||
132 | static 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 | |||
151 | static 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 | |||
156 | void 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 | |||
170 | typedef struct sigsqrt | ||
171 | { | ||
172 | t_object x_obj; | ||
173 | float x_f; | ||
174 | } t_sigsqrt; | ||
175 | |||
176 | static t_class *sigsqrt_class; | ||
177 | |||
178 | static 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 | |||
186 | t_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 | |||
205 | static 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 | |||
210 | void 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 | |||
221 | typedef struct wrap | ||
222 | { | ||
223 | t_object x_obj; | ||
224 | float x_f; | ||
225 | } t_sigwrap; | ||
226 | |||
227 | t_class *sigwrap_class; | ||
228 | |||
229 | static 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 | |||
237 | static 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 | |||
251 | static 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 | |||
256 | void 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 | |||
266 | typedef struct mtof_tilde | ||
267 | { | ||
268 | t_object x_obj; | ||
269 | float x_f; | ||
270 | } t_mtof_tilde; | ||
271 | |||
272 | t_class *mtof_tilde_class; | ||
273 | |||
274 | static 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 | |||
282 | static 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 | |||
299 | static 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 | |||
304 | void 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 | |||
314 | typedef struct ftom_tilde | ||
315 | { | ||
316 | t_object x_obj; | ||
317 | float x_f; | ||
318 | } t_ftom_tilde; | ||
319 | |||
320 | t_class *ftom_tilde_class; | ||
321 | |||
322 | static 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 | |||
330 | static 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 | |||
342 | static 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 | |||
347 | void 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 | |||
357 | typedef struct dbtorms_tilde | ||
358 | { | ||
359 | t_object x_obj; | ||
360 | float x_f; | ||
361 | } t_dbtorms_tilde; | ||
362 | |||
363 | t_class *dbtorms_tilde_class; | ||
364 | |||
365 | static 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 | |||
373 | static 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 | |||
391 | static 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 | |||
396 | void 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 | |||
406 | typedef struct rmstodb_tilde | ||
407 | { | ||
408 | t_object x_obj; | ||
409 | float x_f; | ||
410 | } t_rmstodb_tilde; | ||
411 | |||
412 | t_class *rmstodb_tilde_class; | ||
413 | |||
414 | static 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 | |||
422 | static 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 | |||
439 | static 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 | |||
444 | void 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 | |||
454 | typedef struct dbtopow_tilde | ||
455 | { | ||
456 | t_object x_obj; | ||
457 | float x_f; | ||
458 | } t_dbtopow_tilde; | ||
459 | |||
460 | t_class *dbtopow_tilde_class; | ||
461 | |||
462 | static 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 | |||
470 | static 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 | |||
488 | static 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 | |||
493 | void 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 | |||
503 | typedef struct powtodb_tilde | ||
504 | { | ||
505 | t_object x_obj; | ||
506 | float x_f; | ||
507 | } t_powtodb_tilde; | ||
508 | |||
509 | t_class *powtodb_tilde_class; | ||
510 | |||
511 | static 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 | |||
519 | static 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 | |||
536 | static 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 | |||
541 | void 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 | |||
552 | void 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 | |||
69 | union tabfudge | ||
70 | { | ||
71 | double tf_d; | ||
72 | int32 tf_i[2]; | ||
73 | }; | ||
74 | |||
75 | |||
76 | /* -------------------------- phasor~ ------------------------------ */ | ||
77 | static t_class *phasor_class, *scalarphasor_class; | ||
78 | |||
79 | #if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */ | ||
80 | |||
81 | typedef 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 | |||
89 | static 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 | |||
100 | static 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 | |||
127 | static 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 | |||
133 | static void phasor_ft1(t_phasor *x, t_float f) | ||
134 | { | ||
135 | x->x_phase = f; | ||
136 | } | ||
137 | |||
138 | static 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 | |||
152 | float *cos_table; | ||
153 | |||
154 | static t_class *cos_class; | ||
155 | |||
156 | typedef struct _cos | ||
157 | { | ||
158 | t_object x_obj; | ||
159 | float x_f; | ||
160 | } t_cos; | ||
161 | |||
162 | static 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 | |||
170 | static 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 | |||
220 | static 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 | |||
225 | static 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 | |||
245 | static 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 | |||
256 | static t_class *osc_class, *scalarosc_class; | ||
257 | |||
258 | typedef 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 | |||
266 | static 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 | |||
277 | static 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 | |||
334 | static 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 | |||
340 | static void osc_ft1(t_osc *x, t_float f) | ||
341 | { | ||
342 | x->x_phase = COSTABSIZE * f; | ||
343 | } | ||
344 | |||
345 | static 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 | |||
358 | typedef struct vcfctl | ||
359 | { | ||
360 | float c_re; | ||
361 | float c_im; | ||
362 | float c_q; | ||
363 | float c_isr; | ||
364 | } t_vcfctl; | ||
365 | |||
366 | typedef 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 | |||
374 | t_class *sigvcf_class; | ||
375 | |||
376 | static 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 | |||
392 | static void sigvcf_ft1(t_sigvcf *x, t_floatarg f) | ||
393 | { | ||
394 | x->x_ctl->c_q = (f > 0 ? f : 0.f); | ||
395 | } | ||
396 | |||
397 | static 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 | |||
460 | static 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 | |||
469 | void 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~ ------------------------------ */ | ||
480 | static t_class *noise_class; | ||
481 | |||
482 | typedef struct _noise | ||
483 | { | ||
484 | t_object x_obj; | ||
485 | int x_val; | ||
486 | } t_noise; | ||
487 | |||
488 | static 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 | |||
497 | static 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 | |||
513 | static 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 | |||
518 | static 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 ---------------- */ | ||
527 | void 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 @@ | |||
1 | PREFIX = /usr/ | ||
2 | EXT = pd_linux | ||
3 | |||
4 | # pd specific | ||
5 | |||
6 | VPATH = ../obj:./ | ||
7 | OBJ_DIR = ../obj | ||
8 | BIN_DIR = ../bin | ||
9 | |||
10 | BROOT=/usr | ||
11 | X11LIB = $(BROOT)/X11R6/lib | ||
12 | |||
13 | DEFINES = -DPD -DUNIX | ||
14 | |||
15 | pd-gui_INCLUDES = -I$(BROOT)/include/tcl8.4 -I$(BROOT)/X11R6/include | ||
16 | pd-gui_LIBS = -ltk8.4 -ltcl8.4 -lX11 -ldl | ||
17 | pd-gui_LDFLAGS = -L$(X11LIB) | ||
18 | pd-gui_DEFINES = $(DEFINES) | ||
19 | |||
20 | pd_LIBS = -lm -lpthread -ldl | ||
21 | pd_LDFLAGS = -Wl,-export-dynamic | ||
22 | pd_DEFINES = $(DEFINES) -DINSTALL_PREFIX=\"$(PREFIX)\" \ | ||
23 | -DFIXEDPOINT -DUSEAPI_OSS -DDL_OPEN | ||
24 | |||
25 | extra_DEFINES = $(DEFINES) -DFIXEDPOINT | ||
26 | extra_INCLUDES = -I../src | ||
27 | extra_LDFLAGS = -shared | ||
28 | |||
29 | # IPOD toolchain | ||
30 | |||
31 | ifeq ($(CC), arm-elf-gcc) | ||
32 | pd_LDFLAGS += -elf2flt | ||
33 | pd_LIBS = -lm -lpthread | ||
34 | pd_DEFINES = $(DEFINES) -DINSTALL_PREFIX=\"$(PREFIX)\" \ | ||
35 | -DFIXEDPOINT -DUSEAPI_OSS -D__linux__ -Dfork=getpid | ||
36 | extra_DEFINES += -D__linux__ -Dfork=getpid | ||
37 | endif | ||
38 | |||
39 | # BLACKFIN toolchain | ||
40 | |||
41 | ifeq ($(CC), bfin-uclinux-gcc) | ||
42 | pd_LIBS = -lm -lpthread | ||
43 | pd_DEFINES = $(DEFINES) -DINSTALL_PREFIX=\"$(PREFIX)\" \ | ||
44 | -DFIXEDPOINT -DUSEAPI_OSS -D__linux__ | ||
45 | extra_DEFINES += -D__linux__ | ||
46 | endif | ||
47 | |||
48 | # the sources | ||
49 | |||
50 | pd_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 | |||
65 | pd_SRC += d_imayer_fft.c m_fixed.c | ||
66 | |||
67 | pd_OBJ = $(pd_SRC:.c=.o) | ||
68 | |||
69 | pd-gui_SRC = t_main.c t_tkcmd.c | ||
70 | pd-gui_OBJ = $(pd-gui_SRC:.c=.o) | ||
71 | |||
72 | extra_SRC = $(shell ls ../intern/*.c) $(shell ls ../extra/*.c) | ||
73 | extra_OBJ = $(extra_SRC:.c=.o) | ||
74 | extra_EXT = $(extra_SRC:.c=.pd_linux) | ||
75 | |||
76 | # | ||
77 | # ------------------ targets ------------------------------------ | ||
78 | # | ||
79 | |||
80 | all: $(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 | |||
88 | pd: $(BIN_DIR)/pd | ||
89 | pd-gui: $(BIN_DIR)/pd-gui | ||
90 | pd-watchdog: $(BIN_DIR)/pd-watchdog | ||
91 | |||
92 | static: | ||
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 | |||
97 | extra: $(extra_EXT) | ||
98 | |||
99 | ipod: | ||
100 | make CC=arm-elf-gcc static | ||
101 | |||
102 | blackfin: | ||
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 | |||
136 | INSTDIR = $(DESTDIR)/$(PREFIX) | ||
137 | |||
138 | install: 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 | |||
170 | clean: | ||
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 | |||
25 | typedef int16_t t_alsa_sample16; | ||
26 | typedef 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 | |||
45 | typedef 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 | |||
53 | t_alsa_dev alsa_device; | ||
54 | static void *alsa_snd_buf = 0; | ||
55 | static void **alsa_buf_ptrs; | ||
56 | static int alsa_samplewidth; | ||
57 | static snd_pcm_status_t* in_status; | ||
58 | static snd_pcm_status_t* out_status; | ||
59 | |||
60 | static int alsa_mode; | ||
61 | static int alsa_buf_samps; /* believed actual ALSA bufsize in sample frames */ | ||
62 | static int alsa_inchannels; | ||
63 | static int alsa_outchannels; | ||
64 | |||
65 | /* Defines */ | ||
66 | #define DEBUG(x) x | ||
67 | #define DEBUG2(x) {x;} | ||
68 | |||
69 | static void alsa_checkiosync( void); | ||
70 | static 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 | |||
79 | static 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 | |||
87 | int 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 | |||
500 | void 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 | |||
517 | int 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 | |||
725 | void 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 | |||
754 | void 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 | |||
777 | void 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 | |||
797 | void 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 */ | ||
813 | static 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 | |||
867 | static int alsa_nnames = 0; | ||
868 | static char **alsa_names = 0; | ||
869 | |||
870 | void 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 | |||
881 | static 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. */ | ||
899 | void 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 | |||
18 | static void nt_close_midiin(void); | ||
19 | static void nt_noresync( void); | ||
20 | |||
21 | static 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 | |||
29 | int 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! */ | ||
34 | static int nt_naudiobuffer = DEFBUFFER; | ||
35 | float sys_dacsr = DEFAULTSRATE; | ||
36 | |||
37 | static int nt_whichapi = API_MMIO; | ||
38 | static int nt_meters; /* true if we're metering */ | ||
39 | static float nt_inmax; /* max input amplitude */ | ||
40 | static float nt_outmax; /* max output amplitude */ | ||
41 | static int nt_nwavein, nt_nwaveout; /* number of WAVE devices in and out */ | ||
42 | |||
43 | typedef 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 | |||
51 | t_sbuf ntsnd_outvec[NAPORTS][MAXBUFFER]; /* circular buffer array */ | ||
52 | HWAVEOUT ntsnd_outdev[NAPORTS]; /* output device */ | ||
53 | static int ntsnd_outphase[NAPORTS]; /* index of next buffer to send */ | ||
54 | |||
55 | t_sbuf ntsnd_invec[NAPORTS][MAXBUFFER]; /* circular buffer array */ | ||
56 | HWAVEIN ntsnd_indev[NAPORTS]; /* input device */ | ||
57 | static int ntsnd_inphase[NAPORTS]; /* index of next buffer to read */ | ||
58 | |||
59 | static void nt_waveinerror(char *s, int err) | ||
60 | { | ||
61 | char t[256]; | ||
62 | waveInGetErrorText(err, t, 256); | ||
63 | fprintf(stderr, s, t); | ||
64 | } | ||
65 | |||
66 | static void nt_waveouterror(char *s, int err) | ||
67 | { | ||
68 | char t[256]; | ||
69 | waveOutGetErrorText(err, t, 256); | ||
70 | fprintf(stderr, s, t); | ||
71 | } | ||
72 | |||
73 | static 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 | |||
118 | static UINT nt_whichdac = WAVE_MAPPER, nt_whichadc = WAVE_MAPPER; | ||
119 | |||
120 | int 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 | |||
222 | void 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 | |||
256 | static int nt_adcjitterbufsallowed = ADCJITTER; | ||
257 | static int nt_dacjitterbufsallowed = DACJITTER; | ||
258 | |||
259 | /* ------------- MIDI time stamping from audio clock ------------ */ | ||
260 | |||
261 | #ifdef MIDI_TIMESTAMP | ||
262 | |||
263 | static double nt_hibuftime; | ||
264 | static double initsystime = -1; | ||
265 | |||
266 | /* call this whenever we reset audio */ | ||
267 | static 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 | |||
277 | static 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 | |||
294 | static 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 | |||
304 | static 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 */ | ||
310 | static 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 | ||
395 | reason the sync testing below gives false positives. */ | ||
396 | |||
397 | static int nt_resync_cancelled; | ||
398 | |||
399 | static void nt_noresync( void) | ||
400 | { | ||
401 | nt_resync_cancelled = 1; | ||
402 | } | ||
403 | |||
404 | static 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 | ||
468 | static int nt_errorcount; | ||
469 | static int nt_resynccount; | ||
470 | static double nt_nextreporttime = -1; | ||
471 | |||
472 | void 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 */ | ||
490 | t_sample *sys_soundout; | ||
491 | t_sample *sys_soundin; | ||
492 | float sys_dacsr; | ||
493 | |||
494 | int 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 | |||
652 | late: | ||
653 | |||
654 | nt_logerror(LATE); | ||
655 | nt_resyncaudio(); | ||
656 | return (1); | ||
657 | |||
658 | idle: | ||
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 | |||
697 | void 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 | |||
731 | void mmio_reportidle(void) | ||
732 | { | ||
733 | } | ||
734 | |||
735 | #if 0 | ||
736 | /* list the audio and MIDI device names */ | ||
737 | void 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 | |||
766 | void 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 */ | ||
38 | typedef int16_t t_oss_int16; | ||
39 | typedef 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 */ | ||
46 | static int linux_meters; /* true if we're metering */ | ||
47 | static float linux_inmax; /* max input amplitude */ | ||
48 | static float linux_outmax; /* max output amplitude */ | ||
49 | static int linux_fragsize = 0; /* for block mode; block size (sample frames) */ | ||
50 | |||
51 | /* our device handles */ | ||
52 | |||
53 | typedef 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 | |||
63 | static t_oss_dev linux_dacs[OSS_MAXDEV]; | ||
64 | static t_oss_dev linux_adcs[OSS_MAXDEV]; | ||
65 | static int linux_noutdevs = 0; | ||
66 | static int linux_nindevs = 0; | ||
67 | |||
68 | /* exported variables */ | ||
69 | float sys_dacsr; | ||
70 | t_sample *sys_soundout; | ||
71 | t_sample *sys_soundin; | ||
72 | |||
73 | /* OSS-specific private variables */ | ||
74 | static int oss_blockmode = 1; /* flag to use "blockmode" */ | ||
75 | static int oss_32bit = 0; /* allow 23 bit transfers in OSS */ | ||
76 | static 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 | |||
86 | static 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 | |||
101 | static 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. */ | ||
108 | void 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 | |||
131 | void oss_set32bit( void) | ||
132 | { | ||
133 | oss_32bit = 1; | ||
134 | } | ||
135 | |||
136 | |||
137 | typedef struct _multidev { | ||
138 | int fd; | ||
139 | int channels; | ||
140 | int format; | ||
141 | } t_multidev; | ||
142 | |||
143 | int 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 | |||
159 | void 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,¶m) >= 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, ¶m) == -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, ¶m) == -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, ¶m) == -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 | |||
269 | static 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, ¶m) == -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 | |||
288 | int 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 | |||
480 | void 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 | |||
492 | static int linux_dacs_write(int fd,void* buf,long bytes) | ||
493 | { | ||
494 | return write(fd, buf, bytes); | ||
495 | } | ||
496 | |||
497 | static 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. */ | ||
503 | static 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 | |||
523 | void 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 | ||
539 | in audio output and/or input. */ | ||
540 | |||
541 | static 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 | |||
619 | int 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 | |||
823 | void oss_listdevs( void) | ||
824 | { | ||
825 | post("device listing not implemented in OSS yet\n"); | ||
826 | } | ||
827 | |||
828 | void 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 */ | ||
28 | static PABLIO_Stream *pa_stream; | ||
29 | static int pa_inchans, pa_outchans; | ||
30 | static float *pa_soundin, *pa_soundout; | ||
31 | |||
32 | #define MAX_PA_CHANS 32 | ||
33 | #define MAX_SAMPLES_PER_FRAME MAX_PA_CHANS * DEFDACBLKSIZE | ||
34 | |||
35 | int 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 | |||
142 | void pa_close_audio( void) | ||
143 | { | ||
144 | if (pa_inchans || pa_outchans) | ||
145 | CloseAudioStream( pa_stream ); | ||
146 | pa_inchans = pa_outchans = 0; | ||
147 | } | ||
148 | |||
149 | int 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 | |||
227 | void 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 | |||
259 | error: | ||
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 */ | ||
267 | void 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 | ||
2 | that externs can link back to functions defined in pd. */ | ||
3 | |||
4 | #include <stdio.h> | ||
5 | |||
6 | int 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 | |||
16 | LONG NTAPI VectoredExceptionHandler(void *PEXCEPTION_POINTERS) | ||
17 | { | ||
18 | fprintf(stderr, "caught exception\n"); | ||
19 | return(EXCEPTION_CONTINUE_SEARCH); | ||
20 | } | ||
21 | |||
22 | |||
23 | int 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 | ||
34 | int 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 */ | ||
47 | int 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 | ||
6 | that 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> | ||
29 | typedef 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 | |||
59 | extern char pd_version[]; | ||
60 | |||
61 | typedef 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 | |||
70 | struct _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 | |||
81 | static int sys_nfdpoll; | ||
82 | static t_fdpoll *sys_fdpoll; | ||
83 | static int sys_maxfd; | ||
84 | static int sys_guisock; | ||
85 | |||
86 | static t_binbuf *inbinbuf; | ||
87 | static t_socketreceiver *sys_socketreceiver; | ||
88 | extern int sys_addhist(int phase); | ||
89 | |||
90 | #ifdef MSW | ||
91 | static LARGE_INTEGER nt_inittime; | ||
92 | static double nt_freq = 0; | ||
93 | |||
94 | static 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 | |||
113 | double 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. */ | ||
123 | t_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 | |||
141 | void 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 | |||
159 | void 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 | |||
174 | void 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 | |||
197 | static 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 | |||
228 | void sys_microsleep(int microsec) | ||
229 | { | ||
230 | sys_domicrosleep(microsec, 1); | ||
231 | } | ||
232 | |||
233 | t_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 | |||
246 | void 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. */ | ||
254 | static 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 | |||
285 | static 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 | |||
327 | static struct termios stored_settings; | ||
328 | EXTERN int sys_stdin; | ||
329 | |||
330 | void 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 | |||
350 | void reset_keypress(void) | ||
351 | { | ||
352 | if (sys_stdin) | ||
353 | tcsetattr(0,TCSANOW,&stored_settings); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | static t_symbol* _ss; | ||
358 | |||
359 | |||
360 | void 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 | |||
372 | void 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 | |||
436 | void sys_closesocket(int fd) | ||
437 | { | ||
438 | #ifdef UNIX | ||
439 | close(fd); | ||
440 | #endif | ||
441 | #ifdef MSW | ||
442 | closesocket(fd); | ||
443 | #endif | ||
444 | } | ||
445 | |||
446 | |||
447 | void 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 | |||
475 | void 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 | ||
493 | typedef void (*sighandler_t)(int); | ||
494 | |||
495 | static 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 | |||
508 | static 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 | |||
521 | static void sys_alarmhandler(int n) | ||
522 | { | ||
523 | fprintf(stderr, "Pd: system call timed out\n"); | ||
524 | } | ||
525 | |||
526 | static 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 | |||
534 | void 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 | |||
558 | void 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 | |||
584 | static int sys_watchfd; | ||
585 | |||
586 | #ifdef __linux__ | ||
587 | void 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 | |||
597 | static 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 | |||
601 | int 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, ¶m); | ||
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 | |||
952 | static int sys_poll_togui(void) | ||
953 | { | ||
954 | /* LATER use this to flush output buffer to gui */ | ||
955 | return (0); | ||
956 | } | ||
957 | |||
958 | int sys_pollgui(void) | ||
959 | { | ||
960 | return (sys_domicrosleep(0, 1) || sys_poll_togui()); | ||
961 | } | ||
962 | |||
963 | |||
964 | /* T.Grill - import clean quit function */ | ||
965 | extern void sys_exit(void); | ||
966 | |||
967 | /* This is called when something bad has happened, like a segfault. | ||
968 | Call glob_quit() below to exit cleanly. | ||
969 | LATER try to save dirty documents even in the bad case. */ | ||
970 | void 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 | |||
989 | void 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 | |||
10 | char pd_version[] = "Pd version 0.37.4\n"; | ||
11 | char pd_compiletime[] = __TIME__; | ||
12 | char 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 | |||
34 | void pd_init(void); | ||
35 | int sys_argparse(int argc, char **argv); | ||
36 | void sys_findprogdir(char *progname); | ||
37 | int sys_startgui(const char *guipath); | ||
38 | int sys_rcfile(void); | ||
39 | int m_scheduler(void); | ||
40 | void sys_addhelppath(char *p); | ||
41 | void alsa_adddev(char *name); | ||
42 | |||
43 | int sys_debuglevel; | ||
44 | int sys_verbose; | ||
45 | int sys_noloadbang; | ||
46 | int sys_nogui; | ||
47 | int sys_stdin = 0; | ||
48 | char *sys_guicmd; | ||
49 | t_symbol *sys_libdir; | ||
50 | static t_symbol *sys_guidir; | ||
51 | static t_namelist *sys_externlist; | ||
52 | static t_namelist *sys_openlist; | ||
53 | static t_namelist *sys_messagelist; | ||
54 | static int sys_version; | ||
55 | int sys_oldtclversion; /* hack to warn g_rtext.c about old text sel */ | ||
56 | |||
57 | int sys_nmidiout = 1; | ||
58 | #ifdef MSW | ||
59 | int sys_nmidiin = 0; | ||
60 | #else | ||
61 | int sys_nmidiin = 1; | ||
62 | #endif | ||
63 | int sys_midiindevlist[MAXMIDIINDEV] = {1}; | ||
64 | int sys_midioutdevlist[MAXMIDIOUTDEV] = {1}; | ||
65 | |||
66 | static int sys_main_srate = DEFAULTSRATE; | ||
67 | static 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. */ | ||
74 | int sys_nsoundin = -1; | ||
75 | int sys_nsoundout = -1; | ||
76 | int sys_soundindevlist[MAXAUDIOINDEV]; | ||
77 | int sys_soundoutdevlist[MAXAUDIOOUTDEV]; | ||
78 | |||
79 | int sys_nchin = -1; | ||
80 | int sys_nchout = -1; | ||
81 | int sys_chinlist[MAXAUDIOINDEV]; | ||
82 | int sys_choutlist[MAXAUDIOOUTDEV]; | ||
83 | /* } IOhannes */ | ||
84 | |||
85 | |||
86 | typedef 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 | |||
99 | static 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: | ||
105 | MSW: | ||
106 | font 8 5 9 8 5 11 | ||
107 | font 10 7 13 10 6 13 | ||
108 | font 12 9 16 14 8 16 | ||
109 | font 16 10 20 16 10 18 | ||
110 | font 24 15 25 16 10 18 | ||
111 | font 36 25 42 36 22 41 | ||
112 | |||
113 | linux: | ||
114 | font 8 5 9 8 5 9 | ||
115 | font 10 7 13 12 7 13 | ||
116 | font 12 9 16 14 9 15 | ||
117 | font 16 10 20 16 10 19 | ||
118 | font 24 15 25 24 15 24 | ||
119 | font 36 25 42 36 22 41 | ||
120 | */ | ||
121 | |||
122 | static 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 | |||
131 | int sys_nearestfontsize(int fontsize) | ||
132 | { | ||
133 | return (sys_findfont(fontsize)->fi_fontsize); | ||
134 | } | ||
135 | |||
136 | int sys_hostfontsize(int fontsize) | ||
137 | { | ||
138 | return (sys_findfont(fontsize)->fi_hostfontsize); | ||
139 | } | ||
140 | |||
141 | int sys_fontwidth(int fontsize) | ||
142 | { | ||
143 | return (sys_findfont(fontsize)->fi_width); | ||
144 | } | ||
145 | |||
146 | int sys_fontheight(int fontsize) | ||
147 | { | ||
148 | return (sys_findfont(fontsize)->fi_height); | ||
149 | } | ||
150 | |||
151 | int sys_defaultfont; | ||
152 | #ifdef MSW | ||
153 | #define DEFAULTFONT 12 | ||
154 | #else | ||
155 | #define DEFAULTFONT 10 | ||
156 | #endif | ||
157 | |||
158 | static 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 | ||
175 | succeeding args give the widths and heights of known fonts. We wait until | ||
176 | these are known to open files and send messages specified on the command line. | ||
177 | We ask the GUI to specify the "cwd" in case we don't have a local OS to get it | ||
178 | from; for instance we could be some kind of RT embedded system. However, to | ||
179 | really make this make sense we would have to implement | ||
180 | open(), read(), etc, calls to be served somehow from the GUI too. */ | ||
181 | |||
182 | void 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 | |||
234 | static void sys_afterargparse(void); | ||
235 | |||
236 | /* this is called from main() in s_entry.c */ | ||
237 | int 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 | |||
268 | static 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 | |||
343 | static 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 | |||
364 | static 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. */ | ||
378 | void 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 | ||
469 | static int sys_mmio = 1; | ||
470 | #else | ||
471 | static int sys_mmio = 0; | ||
472 | #endif | ||
473 | |||
474 | int 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 | |||
793 | int 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. */ | ||
800 | static 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 | |||
835 | static 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 | |||
27 | typedef 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 | |||
39 | t_midiqelem midi_outqueue[MIDIQSIZE]; | ||
40 | int midi_outhead, midi_outtail; | ||
41 | t_midiqelem midi_inqueue[MIDIQSIZE]; | ||
42 | int midi_inhead, midi_intail; | ||
43 | static 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. */ | ||
47 | static double sys_dactimeminusrealtime; | ||
48 | /* same for input, should be schduler advance earlier. */ | ||
49 | static double sys_adctimeminusrealtime; | ||
50 | |||
51 | static double sys_newdactimeminusrealtime = -1e20; | ||
52 | static double sys_newadctimeminusrealtime = -1e20; | ||
53 | static double sys_whenupdate; | ||
54 | |||
55 | void 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. */ | ||
64 | void 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. */ | ||
89 | static double sys_getmidioutrealtime( void) | ||
90 | { | ||
91 | return (sys_getrealtime() + sys_dactimeminusrealtime); | ||
92 | } | ||
93 | |||
94 | static double sys_getmidiinrealtime( void) | ||
95 | { | ||
96 | return (sys_getrealtime() + sys_adctimeminusrealtime); | ||
97 | } | ||
98 | |||
99 | static 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 | |||
112 | void 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 | |||
140 | static 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 | |||
167 | void 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 | |||
176 | void 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 | |||
186 | void 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 | |||
194 | void 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 | |||
202 | void 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 | |||
209 | void 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 | |||
219 | void outmidi_mclk(int portno) | ||
220 | { | ||
221 | sys_queuemidimess(portno, 1, 0xf8, 0,0); | ||
222 | } | ||
223 | |||
224 | /* ------------------------- MIDI input queue handling ------------------ */ | ||
225 | typedef 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 */ | ||
256 | void inmidi_realtimein(int portno, int cmd); | ||
257 | void inmidi_byte(int portno, int byte); | ||
258 | void inmidi_sysex(int portno, int byte); | ||
259 | void inmidi_noteon(int portno, int channel, int pitch, int velo); | ||
260 | void inmidi_controlchange(int portno, int channel, int ctlnumber, int value); | ||
261 | void inmidi_programchange(int portno, int channel, int value); | ||
262 | void inmidi_pitchbend(int portno, int channel, int value); | ||
263 | void inmidi_aftertouch(int portno, int channel, int value); | ||
264 | void inmidi_polyaftertouch(int portno, int channel, int pitch, int value); | ||
265 | |||
266 | static 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 | |||
367 | void 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 | |||
410 | void 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 | |||
435 | void 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 | ||
452 | void midi_oss_init( void); | ||
453 | #endif | ||
454 | |||
455 | /* last requested parameters */ | ||
456 | static int midi_nmidiindev; | ||
457 | static int midi_midiindev[MAXMIDIINDEV]; | ||
458 | static int midi_nmidioutdev; | ||
459 | static int midi_midioutdev[MAXMIDIOUTDEV]; | ||
460 | |||
461 | static 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 | |||
473 | static 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 | |||
486 | void 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 */ | ||
498 | void 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 | |||
515 | void 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 | |||
541 | extern t_class *glob_pdobject; | ||
542 | |||
543 | /* start an midi settings dialog window */ | ||
544 | void 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 */ | ||
609 | void 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 | |||
20 | static int oss_nmidiin; | ||
21 | static int oss_midiinfd[MAXMIDIINDEV]; | ||
22 | static int oss_nmidiout; | ||
23 | static int oss_midioutfd[MAXMIDIOUTDEV]; | ||
24 | |||
25 | static 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 | |||
34 | void 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 | |||
160 | void 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 | |||
182 | void 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.) */ | ||
190 | void 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()" ... */ | ||
229 | void 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 | |||
259 | void 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 | ||
270 | static int oss_nmidiindevs, oss_nmidioutdevs, oss_initted; | ||
271 | |||
272 | void 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 | |||
344 | void 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 | |||
26 | static PmStream *mac_midiindevlist[MAXMIDIINDEV]; | ||
27 | static PmStream *mac_midioutdevlist[MAXMIDIOUTDEV]; | ||
28 | static int mac_nmidiindev; | ||
29 | static int mac_nmidioutdev; | ||
30 | |||
31 | void 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 | |||
89 | void 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 | |||
100 | void 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 | |||
113 | void sys_putmidibyte(int portno, int byte) | ||
114 | { | ||
115 | post("sorry, no byte-by-byte MIDI output implemented in MAC OSX"); | ||
116 | } | ||
117 | |||
118 | void 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 | |||
155 | void 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> | ||
19 | int 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 | |||
33 | static 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 | |||
43 | static MDport sgi_inport[NPORT]; | ||
44 | static MDport sgi_outport[NPORT]; | ||
45 | |||
46 | void 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 | |||
85 | void 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 | |||
101 | void sys_putmidibyte(int portno, int foo) | ||
102 | { | ||
103 | error("MIDI raw byte output not available on SGI"); | ||
104 | } | ||
105 | |||
106 | void inmidi_noteon(int portno, int channel, int pitch, int velo); | ||
107 | void inmidi_controlchange(int portno, int channel, int ctlnumber, int value); | ||
108 | void inmidi_programchange(int portno, int channel, int value); | ||
109 | void inmidi_pitchbend(int portno, int channel, int value); | ||
110 | void inmidi_aftertouch(int portno, int channel, int value); | ||
111 | void inmidi_polyaftertouch(int portno, int channel, int pitch, int value); | ||
112 | |||
113 | void 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 | |||
172 | void sys_open_midi(int nmidiin, int *midiinvec, | ||
173 | int nmidiout, int *midioutvec) | ||
174 | { | ||
175 | sgi_open_midi(nmidiin!=0, nmidiout!=0); | ||
176 | } | ||
177 | |||
178 | |||
179 | void sys_close_midi( void) | ||
180 | { | ||
181 | /* ??? */ | ||
182 | } | ||
183 | |||
184 | void 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 | ||
6 | tries to prevent Pd from locking up the processor if it's at realtime | ||
7 | priority. 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 | |||
15 | int 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 | |||
26 | extern int matherr(void); | ||
27 | int *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 | |||
46 | void pdgui_startup(Tcl_Interp *interp); | ||
47 | void pdgui_setname(char *name); | ||
48 | void pdgui_setsock(int port); | ||
49 | void pdgui_sethost(char *name); | ||
50 | |||
51 | int | ||
52 | main(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 | |||
90 | int | ||
91 | Tcl_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 | |||
40 | void tcl_mess(char *s); | ||
41 | |||
42 | /***************** the socket setup code ********************/ | ||
43 | |||
44 | static 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". */ | ||
49 | char hostname[100] = | ||
50 | #ifdef __linux__ | ||
51 | "127.0.0.1"; | ||
52 | #else | ||
53 | "localhost"; | ||
54 | #endif | ||
55 | |||
56 | void pdgui_setsock(int port) | ||
57 | { | ||
58 | portno = port; | ||
59 | } | ||
60 | |||
61 | void pdgui_sethost(char *name) | ||
62 | { | ||
63 | strncpy(hostname, name, 100); | ||
64 | hostname[99] = 0; | ||
65 | } | ||
66 | |||
67 | static 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 | |||
81 | static 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 | |||
89 | static char pd_tkbuf[SOCKSIZE+1]; | ||
90 | int pd_spillbytes = 0; | ||
91 | |||
92 | static 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. */ | ||
159 | static 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 | |||
167 | void 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"); | ||
233 | gotit: ; | ||
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 ************************/ | ||
242 | static 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 | |||
249 | static 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 | |||
286 | static Tcl_Interp *tk_myinterp; | ||
287 | |||
288 | void 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? */ | ||
299 | void 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 | ||
317 | void 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 | |||
334 | void pdgui_evalfile(char *s) | ||
335 | { | ||
336 | pdgui_doevalfile(tk_myinterp, s); | ||
337 | } | ||
338 | #endif | ||
339 | |||
340 | void 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 | ||
363 | void 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 | |||
381 | int 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 | |||
394 | int 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 @@ | |||
1 | set 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: | ||
18 | set pd_tearoff 0 | ||
19 | set menubar 1 | ||
20 | |||
21 | set File "F" | ||
22 | set Windows "W" | ||
23 | set Edit "E" | ||
24 | set Find "F" | ||
25 | set Put "P" | ||
26 | set Media "M" | ||
27 | set Help "H" | ||
28 | |||
29 | set color grey16 | ||
30 | set lightcolor grey24 | ||
31 | |||
32 | option add *font -*-helvetica-*--bold--9-* | ||
33 | |||
34 | # los colores de la muerte | ||
35 | |||
36 | option add *background $color | ||
37 | option add *activeBackground $lightcolor | ||
38 | |||
39 | option add *foreground white | ||
40 | option add *activeForeground white | ||
41 | |||
42 | option add *troughColor $lightcolor | ||
43 | |||
44 | option add *highlightThickness 0 | ||
45 | option add *relief solid startupFile | ||
46 | |||
47 | if {$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 | |||
57 | if {$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 | |||
69 | if {$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 | |||
81 | bind all <Key-Tab> "" | ||
82 | bind all <<PrevWindow>> "" | ||
83 | bind Text <Control-t> {} | ||
84 | bind Text <Control-s> {} | ||
85 | # puts stderr [bind all] | ||
86 | |||
87 | ################## set up main window ######################### | ||
88 | menu .mbar | ||
89 | canvas .dummy -height 2p -width 6c | ||
90 | |||
91 | frame .controls | ||
92 | pack .controls .dummy -side top -fill x | ||
93 | menu .mbar.file -tearoff $pd_tearoff | ||
94 | .mbar add cascade -label "$File" -menu .mbar.file | ||
95 | menu .mbar.find -tearoff $pd_tearoff | ||
96 | .mbar add cascade -label "$Find" -menu .mbar.find | ||
97 | menu .mbar.windows -postcommand [concat pdtk_fixwindowmenu] -tearoff $pd_tearoff | ||
98 | menu .mbar.audio -tearoff $pd_tearoff | ||
99 | if {$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 | } | ||
107 | menu .mbar.help -tearoff $pd_tearoff | ||
108 | .mbar add cascade -label "$Help" -menu .mbar.help | ||
109 | |||
110 | set ctrls_audio_on 0 | ||
111 | set ctrls_meter_on 0 | ||
112 | set ctrls_inlevel 0 | ||
113 | set ctrls_outlevel 0 | ||
114 | |||
115 | frame .controls.switches | ||
116 | checkbutton .controls.switches.audiobutton -text {compute audio} \ | ||
117 | -variable ctrls_audio_on \ | ||
118 | -anchor w \ | ||
119 | -command {pd [concat pd dsp $ctrls_audio_on \;]} | ||
120 | |||
121 | checkbutton .controls.switches.meterbutton -text {peak meters} \ | ||
122 | -variable ctrls_meter_on \ | ||
123 | -anchor w \ | ||
124 | -command {pd [concat pd meters $ctrls_meter_on \;]} | ||
125 | |||
126 | pack .controls.switches.meterbutton .controls.switches.audiobutton -side left | ||
127 | |||
128 | frame .controls.inout | ||
129 | frame .controls.inout.in | ||
130 | label .controls.inout.in.label -text IN | ||
131 | entry .controls.inout.in.level -textvariable ctrls_inlevel -width 3 | ||
132 | button .controls.inout.in.clip -text {CLIP} -state disabled | ||
133 | pack .controls.inout.in.label .controls.inout.in.level \ | ||
134 | .controls.inout.in.clip -side top -pady 2 | ||
135 | |||
136 | frame .controls.inout.out | ||
137 | label .controls.inout.out.label -text OUT | ||
138 | entry .controls.inout.out.level -textvariable ctrls_outlevel -width 3 | ||
139 | button .controls.inout.out.clip -text {CLIP} -state disabled | ||
140 | pack .controls.inout.out.label .controls.inout.out.level \ | ||
141 | .controls.inout.out.clip -side top -pady 2 | ||
142 | |||
143 | button .controls.dio -text "DIO\nerrors" \ | ||
144 | -command {pd [concat pd audiostatus \;]} | ||
145 | |||
146 | pack .controls.switches -side bottom -pady 12 | ||
147 | pack .controls.inout.in .controls.inout.out -side left -padx 6 | ||
148 | pack .controls.inout -side left -padx 14 | ||
149 | pack .controls.dio -side right -padx 20 | ||
150 | |||
151 | bind . <Control-Key> {pdtk_pd_ctrlkey %W %K 0} | ||
152 | bind . <Control-Shift-Key> {pdtk_pd_ctrlkey %W %K 1} | ||
153 | if {$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 | |||
159 | wm title . "PDa" | ||
160 | . configure -menu .mbar -width 200 -height 150 | ||
161 | |||
162 | ############### set up global variables ################################ | ||
163 | |||
164 | set untitled_number 1 | ||
165 | set untitled_directory [pwd] | ||
166 | set saveas_client doggy | ||
167 | set pd_opendir $untitled_directory | ||
168 | set pd_undoaction no | ||
169 | set pd_redoaction no | ||
170 | set pd_undocanvas no | ||
171 | |||
172 | ################ utility functions ######################### | ||
173 | |||
174 | proc pdtk_enquote {x} { | ||
175 | set foo [string map {"," "" ";" "" \" ""} $x] | ||
176 | set foo2 [string map {" " "\\ "} $foo] | ||
177 | concat $foo2 | ||
178 | } | ||
179 | |||
180 | proc pdtk_debug {x} { | ||
181 | tk_messageBox -message $x -type ok | ||
182 | } | ||
183 | |||
184 | proc pdtk_watchdog {} { | ||
185 | pd [concat pd ping \;] | ||
186 | after 2000 {pdtk_watchdog} | ||
187 | } | ||
188 | |||
189 | proc 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 | |||
196 | set menu_windowlist {} | ||
197 | |||
198 | proc 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 | |||
210 | proc 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 ######################## | ||
228 | proc 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 | |||
241 | proc 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 ######################### | ||
263 | proc 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 ######################### | ||
277 | proc menu_really_quit {} {pd {pd quit;}} | ||
278 | |||
279 | proc menu_quit {} {pd {pd quit;}} | ||
280 | |||
281 | ######### the "Pd" menu command, which puts the Pd window on top ######## | ||
282 | proc menu_pop_pd {} {raise .} | ||
283 | |||
284 | ######### the "audio" menu command ############### | ||
285 | proc menu_audio {flag} {pd [concat pd dsp $flag \;]} | ||
286 | |||
287 | ######### the "documentation" menu command ############### | ||
288 | |||
289 | set doc_number 1 | ||
290 | |||
291 | proc 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 | |||
314 | set help_directory $pd_guidir/doc | ||
315 | |||
316 | proc 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 | |||
351 | proc 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 | |||
366 | proc 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 | |||
421 | proc menu_save {name} { | ||
422 | pdtk_canvas_checkgeometry $name | ||
423 | pd [concat $name menusave \;] | ||
424 | } | ||
425 | |||
426 | proc menu_saveas {name} { | ||
427 | pdtk_canvas_checkgeometry $name | ||
428 | pd [concat $name menusaveas \;] | ||
429 | } | ||
430 | |||
431 | proc 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 | |||
441 | proc menu_close {name} { | ||
442 | pd [concat $name menuclose \;] | ||
443 | } | ||
444 | |||
445 | proc 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 | |||
454 | proc 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 | |||
463 | proc menu_cut {name} { | ||
464 | pd [concat $name cut \;] | ||
465 | } | ||
466 | |||
467 | proc menu_copy {name} { | ||
468 | pd [concat $name copy \;] | ||
469 | } | ||
470 | |||
471 | proc menu_paste {name} { | ||
472 | pd [concat $name paste \;] | ||
473 | } | ||
474 | |||
475 | proc menu_duplicate {name} { | ||
476 | pd [concat $name duplicate \;] | ||
477 | } | ||
478 | |||
479 | proc menu_selectall {name} { | ||
480 | pd [concat $name selectall \;] | ||
481 | } | ||
482 | |||
483 | proc menu_texteditor {name} { | ||
484 | pd [concat $name texteditor \;] | ||
485 | } | ||
486 | |||
487 | proc menu_font {name} { | ||
488 | pd [concat $name menufont \;] | ||
489 | } | ||
490 | |||
491 | proc menu_tidyup {name} { | ||
492 | pd [concat $name tidy \;] | ||
493 | } | ||
494 | |||
495 | proc menu_editmode {name} { | ||
496 | pd [concat $name editmode 0 \;] | ||
497 | } | ||
498 | |||
499 | proc menu_object {name accel} { | ||
500 | pd [concat $name obj $accel \;] | ||
501 | } | ||
502 | |||
503 | proc menu_message {name accel} { | ||
504 | pd [concat $name msg $accel \;] | ||
505 | } | ||
506 | |||
507 | proc menu_floatatom {name accel} { | ||
508 | pd [concat $name floatatom $accel \;] | ||
509 | } | ||
510 | |||
511 | proc menu_symbolatom {name accel} { | ||
512 | pd [concat $name symbolatom $accel \;] | ||
513 | } | ||
514 | |||
515 | proc menu_comment {name accel} { | ||
516 | pd [concat $name text $accel \;] | ||
517 | } | ||
518 | |||
519 | proc menu_graph {name} { | ||
520 | pd [concat $name graph \;] | ||
521 | } | ||
522 | |||
523 | proc menu_array {name} { | ||
524 | pd [concat $name menuarray \;] | ||
525 | } | ||
526 | |||
527 | ############iemlib################## | ||
528 | proc menu_bng {name accel} { | ||
529 | pd [concat $name bng $accel \;] | ||
530 | } | ||
531 | |||
532 | proc menu_toggle {name accel} { | ||
533 | pd [concat $name toggle $accel \;] | ||
534 | } | ||
535 | |||
536 | proc menu_numbox {name accel} { | ||
537 | pd [concat $name numbox $accel \;] | ||
538 | } | ||
539 | |||
540 | proc menu_vslider {name accel} { | ||
541 | pd [concat $name vslider $accel \;] | ||
542 | } | ||
543 | |||
544 | proc menu_hslider {name accel} { | ||
545 | pd [concat $name hslider $accel \;] | ||
546 | } | ||
547 | |||
548 | proc menu_hradio {name accel} { | ||
549 | pd [concat $name hradio $accel \;] | ||
550 | } | ||
551 | |||
552 | proc menu_vradio {name accel} { | ||
553 | pd [concat $name vradio $accel \;] | ||
554 | } | ||
555 | |||
556 | proc menu_vumeter {name accel} { | ||
557 | pd [concat $name vumeter $accel \;] | ||
558 | } | ||
559 | |||
560 | proc 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 | ||
568 | proc 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 | ||
588 | proc 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 | |||
602 | proc menu_windowparent {name} { | ||
603 | pd [concat $name findparent \;] | ||
604 | } | ||
605 | |||
606 | proc menu_findagain {name} { | ||
607 | pd [concat $name findagain \;] | ||
608 | } | ||
609 | |||
610 | proc menu_finderror {} { | ||
611 | pd [concat pd finderror \;] | ||
612 | } | ||
613 | |||
614 | proc menu_domenuwindow {i} { | ||
615 | raise $i | ||
616 | } | ||
617 | |||
618 | proc 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 | |||
639 | set find_canvas nobody | ||
640 | set find_string "" | ||
641 | set find_count 1 | ||
642 | |||
643 | proc 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 | |||
655 | proc find_cancel {name} { | ||
656 | after 50 destroy $name | ||
657 | } | ||
658 | |||
659 | proc 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 | |||
694 | proc 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 ############### | ||
912 | proc 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 | |||
1008 | proc canvastosym {name} { | ||
1009 | string range $name 0 [expr [string length $name] - 3] | ||
1010 | } | ||
1011 | |||
1012 | set pdtk_lastcanvasconfigured "" | ||
1013 | set pdtk_lastcanvasconfiguration "" | ||
1014 | |||
1015 | proc 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 | |||
1028 | proc 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 | |||
1033 | proc pdtk_canvas_shiftclick {name x y b} { | ||
1034 | pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 1 \; | ||
1035 | } | ||
1036 | |||
1037 | proc pdtk_canvas_ctrlclick {name x y b} { | ||
1038 | pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 2 \; | ||
1039 | } | ||
1040 | |||
1041 | proc pdtk_canvas_altclick {name x y b} { | ||
1042 | pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 3 \; | ||
1043 | } | ||
1044 | |||
1045 | proc pdtk_canvas_dblclick {name x y b} { | ||
1046 | pd [canvastosym $name] mouse [$name canvasx $x] [$name canvasy $y] $b 4 \; | ||
1047 | } | ||
1048 | |||
1049 | set pdtk_canvas_mouseup_name 0 | ||
1050 | set pdtk_canvas_mouseup_xminval 0 | ||
1051 | set pdtk_canvas_mouseup_xmaxval 0 | ||
1052 | set pdtk_canvas_mouseup_yminval 0 | ||
1053 | set pdtk_canvas_mouseup_ymaxval 0 | ||
1054 | |||
1055 | proc 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 | |||
1105 | proc 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 | |||
1133 | proc 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 | |||
1143 | proc 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 | |||
1159 | proc 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 | |||
1196 | proc 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. | ||
1204 | proc pdtk_canvas_map {name} { | ||
1205 | # puts stderr [concat map $name] | ||
1206 | pd [canvastosym $name] map 1 \; | ||
1207 | } | ||
1208 | |||
1209 | proc pdtk_canvas_unmap {name} { | ||
1210 | # puts stderr [concat unmap $name] | ||
1211 | pd [canvastosym $name] map 0 \; | ||
1212 | } | ||
1213 | |||
1214 | set saveas_dir nowhere | ||
1215 | |||
1216 | ############ pdtk_canvas_saveas -- run a saveas dialog ############## | ||
1217 | |||
1218 | proc 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 | |||
1236 | set fontsize 0 | ||
1237 | set stretchval 0 | ||
1238 | set whichstretch 0 | ||
1239 | |||
1240 | proc 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 | |||
1249 | proc dofont_cancel {name} { | ||
1250 | set cmd [concat $name cancel \;] | ||
1251 | # puts stderr $cmd | ||
1252 | pd $cmd | ||
1253 | } | ||
1254 | |||
1255 | proc 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 | |||
1324 | proc 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 | |||
1345 | proc 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 | |||
1361 | proc 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 | |||
1395 | proc dogatom_cancel {name} { | ||
1396 | set cmd [concat $name cancel \;] | ||
1397 | # puts stderr $cmd | ||
1398 | pd $cmd | ||
1399 | } | ||
1400 | |||
1401 | proc dogatom_ok {name} { | ||
1402 | dogatom_apply $name | ||
1403 | dogatom_cancel $name | ||
1404 | } | ||
1405 | |||
1406 | proc 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 | |||
1521 | set popup_xpix 0 | ||
1522 | set popup_ypix 0 | ||
1523 | |||
1524 | proc 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 | |||
1531 | proc 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 | |||
1554 | proc 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 | |||
1581 | proc graph_cancel {id} { | ||
1582 | set cmd [concat $id cancel \;] | ||
1583 | # puts stderr $cmd | ||
1584 | pd $cmd | ||
1585 | } | ||
1586 | |||
1587 | proc graph_ok {id} { | ||
1588 | graph_apply $id | ||
1589 | graph_cancel $id | ||
1590 | } | ||
1591 | |||
1592 | proc 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 | |||
1676 | set iemgui_define_min_flashhold 50 | ||
1677 | set iemgui_define_min_flashbreak 10 | ||
1678 | set iemgui_define_min_fontsize 4 | ||
1679 | |||
1680 | proc 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 | |||
1702 | proc 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 | |||
1718 | proc 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 | |||
1755 | proc 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 | |||
1784 | proc 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 | |||
1798 | proc 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 | |||
1828 | proc 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 | |||
1846 | proc 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 | |||
1882 | proc 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 | |||
1905 | proc 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 | |||
1918 | proc 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 | |||
1933 | proc 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 | |||
1948 | proc 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 | |||
2042 | proc iemgui_cancel {id} {pd [concat $id cancel \;]} | ||
2043 | |||
2044 | proc iemgui_ok {id} { | ||
2045 | iemgui_apply $id | ||
2046 | iemgui_cancel $id | ||
2047 | } | ||
2048 | |||
2049 | proc 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 ######### | ||
2390 | proc 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 | |||
2413 | proc array_cancel {id} { | ||
2414 | set cmd [concat $id cancel \;] | ||
2415 | pd $cmd | ||
2416 | } | ||
2417 | |||
2418 | proc array_ok {id} { | ||
2419 | array_apply $id | ||
2420 | array_cancel $id | ||
2421 | } | ||
2422 | |||
2423 | proc 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 ######### | ||
2496 | proc 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 | |||
2515 | proc canvas_cancel {id} { | ||
2516 | set cmd [concat $id cancel \;] | ||
2517 | pd $cmd | ||
2518 | } | ||
2519 | |||
2520 | proc canvas_ok {id} { | ||
2521 | canvas_apply $id | ||
2522 | canvas_cancel $id | ||
2523 | } | ||
2524 | |||
2525 | proc 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 ######### | ||
2587 | proc 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 | |||
2602 | proc dodata_cancel {name} { | ||
2603 | set cmd [concat $name cancel \;] | ||
2604 | # puts stderr $cmd | ||
2605 | pd $cmd | ||
2606 | } | ||
2607 | |||
2608 | proc dodata_ok {name} { | ||
2609 | dodata_send $name | ||
2610 | dodata_cancel $name | ||
2611 | } | ||
2612 | |||
2613 | proc 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####################### | ||
2641 | proc 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########### | ||
2651 | proc 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 ################## | ||
2661 | proc 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 | |||
2668 | proc 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 | |||
2686 | proc 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 ################### | ||
2738 | proc 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 | |||
2744 | proc 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 | |||
2762 | proc 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 ################### | ||
2773 | set edit_number 1 | ||
2774 | |||
2775 | proc 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 | |||
2786 | proc texteditor_ok {name} { | ||
2787 | set topname [string trimright $name .text] | ||
2788 | texteditor_send $name | ||
2789 | destroy $topname | ||
2790 | } | ||
2791 | |||
2792 | |||
2793 | proc 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 | |||
2823 | proc 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 | |||
2836 | proc 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 | |||
2845 | set com1 0 | ||
2846 | set com2 0 | ||
2847 | set com3 0 | ||
2848 | set com4 0 | ||
2849 | |||
2850 | proc 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 | |||
2858 | proc 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 | |||
2868 | if {$pd_nt == 1} { | ||
2869 | proc polleofloop {} { | ||
2870 | pd_pollsocket | ||
2871 | after 20 polleofloop | ||
2872 | } | ||
2873 | |||
2874 | polleofloop | ||
2875 | } | ||
2876 | |||
2877 | ####################### audio dialog ##################3 | ||
2878 | |||
2879 | proc 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 | |||
2908 | proc audio_cancel {id} { | ||
2909 | pd [concat $id cancel \;] | ||
2910 | } | ||
2911 | |||
2912 | proc audio_ok {id} { | ||
2913 | audio_apply $id | ||
2914 | audio_cancel $id | ||
2915 | } | ||
2916 | |||
2917 | # callback from popup menu | ||
2918 | proc 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 | ||
2926 | proc 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 | |||
2945 | proc 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 | |||
3133 | proc 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 | |||
3149 | proc midi_cancel {id} { | ||
3150 | pd [concat $id cancel \;] | ||
3151 | } | ||
3152 | |||
3153 | proc midi_ok {id} { | ||
3154 | midi_apply $id | ||
3155 | midi_cancel $id | ||
3156 | } | ||
3157 | |||
3158 | # callback from popup menu | ||
3159 | proc 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 | ||
3167 | proc 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 | |||
3183 | proc 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 | |||
3314 | proc 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 | |||
3324 | proc path_cancel {id} { | ||
3325 | pd [concat $id cancel \;] | ||
3326 | } | ||
3327 | |||
3328 | proc path_ok {id} { | ||
3329 | path_apply $id | ||
3330 | path_cancel $id | ||
3331 | } | ||
3332 | set pd_path0 sdfgh | ||
3333 | |||
3334 | proc 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 | |||
3364 | proc 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 | ||
6 | from Pd via the netsend/netreceive ("FUDI") protocol, and copies them to | ||
7 | standard 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 | |||
25 | typedef 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 | |||
34 | static int nfdpoll; | ||
35 | static t_fdpoll *fdpoll; | ||
36 | static int maxfd; | ||
37 | static int sockfd; | ||
38 | static int protocol; | ||
39 | |||
40 | static void sockerror(char *s); | ||
41 | static void x_closesocket(int fd); | ||
42 | static void dopoll(void); | ||
43 | #define BUFSIZE 4096 | ||
44 | |||
45 | int 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 | |||
108 | usage: | ||
109 | fprintf(stderr, "usage: pdreceive <portnumber> [udp|tcp]\n"); | ||
110 | fprintf(stderr, "(default is tcp)\n"); | ||
111 | exit(1); | ||
112 | } | ||
113 | |||
114 | static 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 | |||
133 | static 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 | |||
159 | static void doconnect(void) | ||
160 | { | ||
161 | int fd = accept(sockfd, 0, 0); | ||
162 | if (fd < 0) | ||
163 | perror("accept"); | ||
164 | else addport(fd); | ||
165 | } | ||
166 | |||
167 | static 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 | |||
193 | static 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 | |||
229 | static 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 | |||
264 | static 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 | |||
300 | static 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 | |||
317 | static 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 | ||
6 | from 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 | |||
23 | void sockerror(char *s); | ||
24 | void x_closesocket(int fd); | ||
25 | #define BUFSIZE 4096 | ||
26 | |||
27 | int 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); | ||
93 | connected: ; | ||
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 | } | ||
122 | done: | ||
123 | if (ferror(stdin)) | ||
124 | perror("stdin"); | ||
125 | exit (0); | ||
126 | usage: | ||
127 | fprintf(stderr, "usage: pdsend <portnumber> [host] [udp|tcp]\n"); | ||
128 | fprintf(stderr, "(default is localhost and tcp)\n"); | ||
129 | exit(1); | ||
130 | } | ||
131 | |||
132 | void 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 | |||
149 | void 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 | ||
6 | away 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 | ||
18 | protected from getting deleted and then having the dialog call you back. In | ||
19 | this design the calling object doesn't have to keep the address of the dialog | ||
20 | window around; instead we keep a list of all open dialogs. Any object that | ||
21 | might have dialogs, when it is deleted, simply checks down the dialog window | ||
22 | list and breaks off any dialogs that might later have sent messages to it. | ||
23 | Only when the dialog window itself closes do we delete the gfxstub object. */ | ||
24 | |||
25 | static t_class *gfxstub_class; | ||
26 | |||
27 | typedef 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 | |||
36 | static 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 | |||
45 | void 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 | |||
78 | static 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. */ | ||
94 | void 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. */ | ||
118 | static 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. */ | ||
124 | static void gfxstub_signoff(t_gfxstub *x) | ||
125 | { | ||
126 | gfxstub_offlist(x); | ||
127 | pd_free(&x->x_pd); | ||
128 | } | ||
129 | |||
130 | static t_binbuf *gfxstub_binbuf; | ||
131 | |||
132 | /* a series of "data" messages rebuilds a scalar */ | ||
133 | static 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 */ | ||
141 | static 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. */ | ||
151 | static 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 | |||
157 | static void gfxstub_free(t_gfxstub *x) | ||
158 | { | ||
159 | pd_unbind(&x->x_pd, x->x_sym); | ||
160 | } | ||
161 | |||
162 | static 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 | |||
180 | static t_class *openpanel_class; | ||
181 | |||
182 | typedef struct _openpanel | ||
183 | { | ||
184 | t_object x_obj; | ||
185 | t_symbol *x_s; | ||
186 | } t_openpanel; | ||
187 | |||
188 | static 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 | |||
199 | static void openpanel_bang(t_openpanel *x) | ||
200 | { | ||
201 | sys_vgui("pdtk_openpanel %s\n", x->x_s->s_name); | ||
202 | } | ||
203 | |||
204 | static void openpanel_symbol(t_openpanel *x, t_symbol *s) | ||
205 | { | ||
206 | outlet_symbol(x->x_obj.ob_outlet, s); | ||
207 | } | ||
208 | |||
209 | static void openpanel_free(t_openpanel *x) | ||
210 | { | ||
211 | pd_unbind(&x->x_obj.ob_pd, x->x_s); | ||
212 | } | ||
213 | |||
214 | static 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 | |||
225 | static t_class *savepanel_class; | ||
226 | |||
227 | typedef struct _savepanel | ||
228 | { | ||
229 | t_object x_obj; | ||
230 | t_symbol *x_s; | ||
231 | } t_savepanel; | ||
232 | |||
233 | static 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 | |||
244 | static void savepanel_bang(t_savepanel *x) | ||
245 | { | ||
246 | sys_vgui("pdtk_savepanel %s\n", x->x_s->s_name); | ||
247 | } | ||
248 | |||
249 | static void savepanel_symbol(t_savepanel *x, t_symbol *s) | ||
250 | { | ||
251 | outlet_symbol(x->x_obj.ob_outlet, s); | ||
252 | } | ||
253 | |||
254 | static void savepanel_free(t_savepanel *x) | ||
255 | { | ||
256 | pd_unbind(&x->x_obj.ob_pd, x->x_s); | ||
257 | } | ||
258 | |||
259 | static 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 | |||
270 | static t_symbol *key_sym, *keyup_sym, *keyname_sym; | ||
271 | static t_class *key_class, *keyup_class, *keyname_class; | ||
272 | |||
273 | typedef struct _key | ||
274 | { | ||
275 | t_object x_obj; | ||
276 | } t_key; | ||
277 | |||
278 | static 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 | |||
286 | static void key_float(t_key *x, t_floatarg f) | ||
287 | { | ||
288 | outlet_float(x->x_obj.ob_outlet, f); | ||
289 | } | ||
290 | |||
291 | static void key_free(t_key *x) | ||
292 | { | ||
293 | pd_unbind(&x->x_obj.ob_pd, key_sym); | ||
294 | } | ||
295 | |||
296 | typedef struct _keyup | ||
297 | { | ||
298 | t_object x_obj; | ||
299 | } t_keyup; | ||
300 | |||
301 | static 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 | |||
309 | static void keyup_float(t_keyup *x, t_floatarg f) | ||
310 | { | ||
311 | outlet_float(x->x_obj.ob_outlet, f); | ||
312 | } | ||
313 | |||
314 | static void keyup_free(t_keyup *x) | ||
315 | { | ||
316 | pd_unbind(&x->x_obj.ob_pd, keyup_sym); | ||
317 | } | ||
318 | |||
319 | typedef struct _keyname | ||
320 | { | ||
321 | t_object x_obj; | ||
322 | t_outlet *x_outlet1; | ||
323 | t_outlet *x_outlet2; | ||
324 | } t_keyname; | ||
325 | |||
326 | static 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 | |||
335 | static 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 | |||
341 | static void keyname_free(t_keyname *x) | ||
342 | { | ||
343 | pd_unbind(&x->x_obj.ob_pd, keyname_sym); | ||
344 | } | ||
345 | |||
346 | static 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 | |||
371 | void 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" | ||
8 | void outmidi_noteon(int portno, int channel, int pitch, int velo); | ||
9 | void outmidi_controlchange(int portno, int channel, int ctlno, int value); | ||
10 | void outmidi_programchange(int portno, int channel, int value); | ||
11 | void outmidi_pitchbend(int portno, int channel, int value); | ||
12 | void outmidi_aftertouch(int portno, int channel, int value); | ||
13 | void outmidi_polyaftertouch(int portno, int channel, int pitch, int value); | ||
14 | void outmidi_mclk(int portno); | ||
15 | |||
16 | /* ----------------------- midiin and sysexin ------------------------- */ | ||
17 | |||
18 | static t_symbol *midiin_sym, *sysexin_sym; | ||
19 | |||
20 | static t_class *midiin_class, *sysexin_class; | ||
21 | |||
22 | typedef struct _midiin | ||
23 | { | ||
24 | t_object x_obj; | ||
25 | t_outlet *x_outlet1; | ||
26 | t_outlet *x_outlet2; | ||
27 | } t_midiin; | ||
28 | |||
29 | static 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 | |||
41 | static 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 | |||
47 | static void midiin_free(t_midiin *x) | ||
48 | { | ||
49 | pd_unbind(&x->x_obj.ob_pd, midiin_sym); | ||
50 | } | ||
51 | |||
52 | static 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 | |||
64 | static void sysexin_free(t_midiin *x) | ||
65 | { | ||
66 | pd_unbind(&x->x_obj.ob_pd, sysexin_sym); | ||
67 | } | ||
68 | |||
69 | static 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 | |||
86 | void 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 | |||
97 | void 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 | |||
110 | static t_symbol *notein_sym; | ||
111 | |||
112 | static t_class *notein_class; | ||
113 | |||
114 | typedef 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 | |||
123 | static 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 | |||
134 | static 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 | |||
153 | static void notein_free(t_notein *x) | ||
154 | { | ||
155 | pd_unbind(&x->x_obj.ob_pd, notein_sym); | ||
156 | } | ||
157 | |||
158 | static 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 | |||
167 | void 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 | |||
181 | static t_symbol *ctlin_sym; | ||
182 | |||
183 | static t_class *ctlin_class; | ||
184 | |||
185 | typedef 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 | |||
195 | static 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 | |||
214 | static 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 | |||
226 | static void ctlin_free(t_ctlin *x) | ||
227 | { | ||
228 | pd_unbind(&x->x_obj.ob_pd, ctlin_sym); | ||
229 | } | ||
230 | |||
231 | static 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 | |||
241 | void 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 | |||
255 | static t_symbol *pgmin_sym; | ||
256 | |||
257 | static t_class *pgmin_class; | ||
258 | |||
259 | typedef 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 | |||
267 | static 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 | |||
277 | static 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 | |||
293 | static void pgmin_free(t_pgmin *x) | ||
294 | { | ||
295 | pd_unbind(&x->x_obj.ob_pd, pgmin_sym); | ||
296 | } | ||
297 | |||
298 | static 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 | |||
308 | void 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 | |||
321 | static t_symbol *bendin_sym; | ||
322 | |||
323 | static t_class *bendin_class; | ||
324 | |||
325 | typedef 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 | |||
333 | static 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 | |||
343 | static 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 | |||
359 | static void bendin_free(t_bendin *x) | ||
360 | { | ||
361 | pd_unbind(&x->x_obj.ob_pd, bendin_sym); | ||
362 | } | ||
363 | |||
364 | static 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 | |||
373 | void 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 | |||
386 | static t_symbol *touchin_sym; | ||
387 | |||
388 | static t_class *touchin_class; | ||
389 | |||
390 | typedef 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 | |||
398 | static 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 | |||
408 | static 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 | |||
424 | static void touchin_free(t_touchin *x) | ||
425 | { | ||
426 | pd_unbind(&x->x_obj.ob_pd, touchin_sym); | ||
427 | } | ||
428 | |||
429 | static 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 | |||
439 | void 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 | |||
452 | static t_symbol *polytouchin_sym; | ||
453 | |||
454 | static t_class *polytouchin_class; | ||
455 | |||
456 | typedef 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 | |||
465 | static 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 | |||
476 | static 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 | |||
496 | static void polytouchin_free(t_polytouchin *x) | ||
497 | { | ||
498 | pd_unbind(&x->x_obj.ob_pd, polytouchin_sym); | ||
499 | } | ||
500 | |||
501 | static 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 | |||
511 | void 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 )---------------------*/ | ||
524 | static t_symbol *midiclkin_sym; | ||
525 | |||
526 | static t_class *midiclkin_class; | ||
527 | |||
528 | |||
529 | typedef struct _midiclkin | ||
530 | { | ||
531 | t_object x_obj; | ||
532 | t_outlet *x_outlet1; | ||
533 | t_outlet *x_outlet2; | ||
534 | } t_midiclkin; | ||
535 | |||
536 | static 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 | |||
545 | static 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 | |||
553 | static void midiclkin_free(t_midiclkin *x) | ||
554 | { | ||
555 | pd_unbind(&x->x_obj.ob_pd, midiclkin_sym); | ||
556 | } | ||
557 | |||
558 | static 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 | |||
568 | void 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 | |||
596 | static t_symbol *midirealtimein_sym; | ||
597 | |||
598 | static t_class *midirealtimein_class; | ||
599 | |||
600 | typedef struct _midirealtimein | ||
601 | { | ||
602 | t_object x_obj; | ||
603 | t_outlet *x_outlet1; | ||
604 | t_outlet *x_outlet2; | ||
605 | } t_midirealtimein; | ||
606 | |||
607 | static 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 | |||
619 | static 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 | |||
629 | static void midirealtimein_free(t_midirealtimein *x) | ||
630 | { | ||
631 | pd_unbind(&x->x_obj.ob_pd, midirealtimein_sym); | ||
632 | } | ||
633 | |||
634 | static 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 | |||
644 | void 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 | |||
657 | static t_class *midiout_class; | ||
658 | |||
659 | void sys_putmidibyte(int portno, int byte); | ||
660 | |||
661 | typedef struct _midiout | ||
662 | { | ||
663 | t_object x_obj; | ||
664 | t_float x_portno; | ||
665 | } t_midiout; | ||
666 | |||
667 | static 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 | |||
679 | static void midiout_float(t_midiout *x, t_floatarg f) | ||
680 | { | ||
681 | sys_putmidibyte(x->x_portno - 1, f); | ||
682 | } | ||
683 | |||
684 | static 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 | |||
694 | static t_class *noteout_class; | ||
695 | |||
696 | typedef struct _noteout | ||
697 | { | ||
698 | t_object x_obj; | ||
699 | t_float x_velo; | ||
700 | t_float x_channel; | ||
701 | } t_noteout; | ||
702 | |||
703 | static 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 | |||
714 | static 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 | |||
723 | static 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 | |||
734 | static t_class *ctlout_class; | ||
735 | |||
736 | typedef struct _ctlout | ||
737 | { | ||
738 | t_object x_obj; | ||
739 | t_float x_ctl; | ||
740 | t_float x_channel; | ||
741 | } t_ctlout; | ||
742 | |||
743 | static 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 | |||
754 | static 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 | |||
763 | static 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 | |||
774 | static t_class *pgmout_class; | ||
775 | |||
776 | typedef struct _pgmout | ||
777 | { | ||
778 | t_object x_obj; | ||
779 | t_float x_channel; | ||
780 | } t_pgmout; | ||
781 | |||
782 | static 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 | |||
791 | static 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 | |||
803 | static 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 | |||
814 | static t_class *bendout_class; | ||
815 | |||
816 | typedef struct _bendout | ||
817 | { | ||
818 | t_object x_obj; | ||
819 | t_float x_channel; | ||
820 | } t_bendout; | ||
821 | |||
822 | static 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 | |||
831 | static 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 | |||
840 | static 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 | |||
850 | static t_class *touchout_class; | ||
851 | |||
852 | typedef struct _touchout | ||
853 | { | ||
854 | t_object x_obj; | ||
855 | t_float x_channel; | ||
856 | } t_touchout; | ||
857 | |||
858 | static 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 | |||
867 | static 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 | |||
875 | static 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 | |||
885 | static t_class *polytouchout_class; | ||
886 | |||
887 | typedef struct _polytouchout | ||
888 | { | ||
889 | t_object x_obj; | ||
890 | t_float x_channel; | ||
891 | t_float x_pitch; | ||
892 | } t_polytouchout; | ||
893 | |||
894 | static 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 | |||
905 | static 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 | |||
913 | static 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 | |||
924 | static t_class *makenote_class; | ||
925 | |||
926 | typedef 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 | |||
934 | typedef 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 | |||
944 | static 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 | |||
957 | static 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 | |||
976 | static 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 | |||
991 | static 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 | |||
1004 | static 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 | |||
1015 | static 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 | |||
1029 | static t_class *stripnote_class; | ||
1030 | |||
1031 | typedef 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 | |||
1039 | static 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 | |||
1048 | static 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 | |||
1056 | static 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 | |||
1065 | static t_class *poly_class; | ||
1066 | |||
1067 | typedef struct voice | ||
1068 | { | ||
1069 | float v_pitch; | ||
1070 | int v_used; | ||
1071 | unsigned long v_serial; | ||
1072 | } t_voice; | ||
1073 | |||
1074 | typedef 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 | |||
1086 | static 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 | |||
1106 | static 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 | |||
1160 | static 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 | |||
1175 | static 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 | |||
1182 | static void poly_free(t_poly *x) | ||
1183 | { | ||
1184 | freebytes(x->x_vec, x->x_n * sizeof (*x->x_vec)); | ||
1185 | } | ||
1186 | |||
1187 | static 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 | |||
1199 | static t_class *bag_class; | ||
1200 | |||
1201 | typedef struct _bagelem | ||
1202 | { | ||
1203 | struct _bagelem *e_next; | ||
1204 | t_float e_value; | ||
1205 | } t_bagelem; | ||
1206 | |||
1207 | typedef struct _bag | ||
1208 | { | ||
1209 | t_object x_obj; | ||
1210 | t_float x_velo; | ||
1211 | t_bagelem *x_first; | ||
1212 | } t_bag; | ||
1213 | |||
1214 | static 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 | |||
1224 | static 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 | |||
1260 | static 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 | |||
1271 | static 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 | |||
1281 | static 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 | |||
1291 | void 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 | |||
3 | pdbox-func.c | 3 | pdbox-func.c |
4 | pdbox-gui.c | 4 | pdbox-gui.c |
5 | 5 | ||
6 | /* | ||
7 | wfirstfit.c | ||
8 | */ | ||
9 | |||
10 | PDa/src/s_audio_rockbox.c | 6 | PDa/src/s_audio_rockbox.c |
11 | 7 | ||
8 | PDa/src/d_ugen.c | ||
9 | PDa/src/d_arithmetic.c | ||
10 | PDa/src/d_dac.c | ||
11 | PDa/src/d_misc.c | ||
12 | PDa/src/d_fft.c | ||
13 | PDa/src/d_imayer_fft.c | ||
14 | PDa/src/d_mayer_fft.c | ||
15 | PDa/src/d_fftroutine.c | ||
16 | PDa/src/d_global.c | ||
17 | PDa/src/d_resample.c | ||
18 | PDa/src/d_ctl.c | ||
19 | PDa/src/d_soundfile.c | ||
20 | |||
12 | PDa/src/g_canvas.c | 21 | PDa/src/g_canvas.c |
13 | PDa/src/g_graph.c | 22 | PDa/src/g_graph.c |
14 | PDa/src/g_text.c | 23 | PDa/src/g_text.c |
@@ -31,57 +40,32 @@ PDa/src/g_toggle.c | |||
31 | PDa/src/g_vdial.c | 40 | PDa/src/g_vdial.c |
32 | PDa/src/g_vslider.c | 41 | PDa/src/g_vslider.c |
33 | PDa/src/g_vumeter.c | 42 | PDa/src/g_vumeter.c |
43 | |||
34 | PDa/src/m_pd.c | 44 | PDa/src/m_pd.c |
35 | PDa/src/m_class.c | 45 | PDa/src/m_class.c |
36 | PDa/src/m_obj.c | 46 | PDa/src/m_obj.c |
37 | PDa/src/m_atom.c | 47 | PDa/src/m_atom.c |
38 | PDa/src/m_memory.c | 48 | PDa/src/m_memory.c |
39 | |||
40 | PDa/src/m_binbuf.c | 49 | PDa/src/m_binbuf.c |
41 | PDa/src/m_conf.c | 50 | PDa/src/m_conf.c |
42 | PDa/src/m_glob.c | 51 | PDa/src/m_glob.c |
43 | PDa/src/m_sched.c | 52 | PDa/src/m_sched.c |
44 | /* PDa/src/s_main.c Does not compile, system reasons */ | 53 | PDa/src/m_fixed.c |
45 | /* PDa/src/s_inter.c Does not compile, BSD sockets */ | 54 | |
46 | PDa/src/s_file.c | 55 | PDa/src/s_file.c |
47 | PDa/src/s_print.c | 56 | PDa/src/s_print.c |
48 | PDa/src/s_loader.c | 57 | PDa/src/s_loader.c |
49 | PDa/src/s_path.c | 58 | PDa/src/s_path.c |
50 | /* | ||
51 | PDa/src/s_entry.c | ||
52 | */ | ||
53 | PDa/src/s_audio.c | 59 | PDa/src/s_audio.c |
54 | /* | 60 | |
55 | PDa/src/s_midi.c | ||
56 | */ | ||
57 | PDa/src/d_ugen.c | ||
58 | PDa/src/d_arithmetic.c | ||
59 | PDa/src/d_dac.c | ||
60 | PDa/src/d_misc.c | ||
61 | PDa/src/d_fft.c | ||
62 | PDa/src/d_mayer_fft.c | ||
63 | PDa/src/d_fftroutine.c | ||
64 | PDa/src/d_global.c | ||
65 | PDa/src/d_resample.c | ||
66 | PDa/src/d_ctl.c | ||
67 | PDa/src/d_soundfile.c | ||
68 | PDa/src/x_arithmetic.c | 61 | PDa/src/x_arithmetic.c |
69 | PDa/src/x_connective.c | 62 | PDa/src/x_connective.c |
70 | PDa/src/x_interface.c | 63 | PDa/src/x_interface.c |
71 | /* | ||
72 | PDa/src/x_midi.c | ||
73 | */ | ||
74 | PDa/src/x_misc.c | 64 | PDa/src/x_misc.c |
75 | PDa/src/x_time.c | 65 | PDa/src/x_time.c |
76 | PDa/src/x_acoustics.c | 66 | PDa/src/x_acoustics.c |
77 | PDa/src/x_net.c | 67 | PDa/src/x_net.c |
78 | PDa/src/x_qlist.c | 68 | PDa/src/x_qlist.c |
79 | /* | ||
80 | PDa/src/x_gui.c | ||
81 | */ | ||
82 | |||
83 | PDa/src/d_imayer_fft.c | ||
84 | PDa/src/m_fixed.c | ||
85 | 69 | ||
86 | PDa/intern/biquad~.c | 70 | PDa/intern/biquad~.c |
87 | PDa/intern/bp~.c | 71 | PDa/intern/bp~.c |
@@ -109,9 +93,6 @@ PDa/intern/rsqrt~.c | |||
109 | PDa/intern/samphold~.c | 93 | PDa/intern/samphold~.c |
110 | PDa/intern/sfread~.c | 94 | PDa/intern/sfread~.c |
111 | PDa/intern/sfwrite~.c | 95 | PDa/intern/sfwrite~.c |
112 | /* | ||
113 | PDa/intern/sig~.c | ||
114 | */ | ||
115 | PDa/intern/snapshot~.c | 96 | PDa/intern/snapshot~.c |
116 | PDa/intern/sqrt~.c | 97 | PDa/intern/sqrt~.c |
117 | PDa/intern/tabosc4~.c | 98 | PDa/intern/tabosc4~.c |
@@ -130,9 +111,7 @@ PDa/intern/vline~.c | |||
130 | PDa/intern/vsnapshot~.c | 111 | PDa/intern/vsnapshot~.c |
131 | PDa/intern/wrap~.c | 112 | PDa/intern/wrap~.c |
132 | 113 | ||
133 | /* PDa/extra/OSCroute.c */ | ||
134 | PDa/extra/bandpass.c | 114 | PDa/extra/bandpass.c |
135 | /* PDa/extra/dumpOSC.c Does not compile, file handling stuff */ | ||
136 | PDa/extra/equalizer.c | 115 | PDa/extra/equalizer.c |
137 | PDa/extra/gcanvas.c | 116 | PDa/extra/gcanvas.c |
138 | PDa/extra/highpass.c | 117 | PDa/extra/highpass.c |
@@ -143,10 +122,4 @@ PDa/extra/lowpass.c | |||
143 | PDa/extra/lowshelf.c | 122 | PDa/extra/lowshelf.c |
144 | PDa/extra/moog~.c | 123 | PDa/extra/moog~.c |
145 | PDa/extra/notch.c | 124 | PDa/extra/notch.c |
146 | /* PDa/extra/sendOSC.c Does not compile, file handling stuff */ | ||
147 | /* | ||
148 | PDa/extra/shell.c | ||
149 | PDa/extra/slider.c | ||
150 | PDa/extra/sliderh.c | ||
151 | */ | ||
152 | PDa/extra/zerox~.c | 125 | PDa/extra/zerox~.c |