MetaluNet-moonlib-550f1b9/0000775002537200253720000000000015201114445015647 5ustar zmoelnigzmoelnigMetaluNet-moonlib-550f1b9/comma.c0000664002537200253720000000252315201114445017111 0ustar zmoelnigzmoelnig/* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "m_pd.h" static t_atom _commaatom_; typedef struct _comma { t_object x_obj; } t_comma; t_class *comma_class; void comma_setup(void); static void comma_bang(t_comma *x) { outlet_list(x->x_obj.ob_outlet, &s_list, 1, &_commaatom_); } static void *comma_new(void) { t_comma *x = (t_comma *)pd_new(comma_class); outlet_new(&x->x_obj,&s_symbol); return (void *)x; } void comma_setup(void) { comma_class = class_new(gensym("comma"),(t_newmethod)comma_new, 0, sizeof(t_comma), 0, 0); class_addbang(comma_class, comma_bang); SETCOMMA(&_commaatom_); } MetaluNet-moonlib-550f1b9/wac-help.pd0000664002537200253720000000021515201114445017672 0ustar zmoelnigzmoelnig#N canvas 840 624 450 300 10; #X obj 178 120 wac; #X text 122 188 placeholder help patch; #X text 113 52 wacom graphire on serial port only; MetaluNet-moonlib-550f1b9/sarray-help.pd0000664002537200253720000000625615201114445020434 0ustar zmoelnigzmoelnig#N canvas 95 58 934 486 10; #X obj 0 0 cnv 8 100 60 empty empty sarray 10 20 1 18 -262144 -1109 0; #X msg 734 75 1; #X msg 763 75 2; #X msg 791 75 3; #X symbolatom 799 156 10 0 0 0 - - -, f 10; #X msg 263 241 reset; #X text 109 12 shared array of symbols; #X obj 47 146 sarray foo 8; #X text 23 48 1) set the length; #X msg 47 71 setlen 10; #X text 236 43 2) set the nth element; #X msg 266 85 set 2 two; #X msg 274 106 set 3 three; #X obj 258 169 sarray foo; #X msg 129 110 print; #X msg 704 99 get \$1; #X obj 704 120 sarray foo; #X obj 704 139 route bang; #X msg 819 75 4; #X obj 704 159 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 704 75 0; #X obj 263 261 sarray foo; #X text 701 177 (bang when empty); #X obj 29 351 sarray foo; #X msg 29 244 dump; #X obj 29 372 print dump; #X msg 64 297 dump _null_; #X msg 64 317 dump *?!; #X text 45 270 specify a default symbol; #X text 59 281 for empty elements; #X obj 449 170 sarray foo; #X text 471 80 specify a default symbol; #X text 471 92 for empty elements; #X msg 294 147 print; #X msg 405 141 print; #X msg 308 241 print; #X text 6 165 args: sarray name [length]; #X text 219 189 args: set [empty_symbol] first_index sym1 [sym2 [sym3...]]] ; #X text 16 397 args: dump [empty_symbol]; #X msg 258 61 set 0 zero; #X text 430 38 3) set many elements; #X text 510 129 ...erase one element; #X msg 281 127 set 4 four; #X msg 57 93 setlen 4; #X msg 511 144 set _niet_ 3 _niet_; #X msg 476 108 set _ 0 zero un _ trois _ cinq; #X msg 449 55 set 0 zero ein zwei drei; #X obj 253 342 sarray foo2 4; #X msg 253 323 set 0 zero2 one2 two2 three2; #X obj 258 414 sarray; #X msg 258 374 print; #X msg 307 375 setarray foo; #X msg 307 394 setarray foo2; #X text 699 53 4) get the nth symbol (first:0); #X text 28 224 5) dump the whole array; #X text 261 223 7) clear the sarray; #X text 253 305 8) switch to another array; #X text 494 222 9) find a symbol; #X obj 523 305 sarray foo; #X msg 508 240 find zero; #X msg 536 282 find two; #X msg 523 260 find un; #X floatatom 588 325 5 0 0 0 - - -, f 5; #X text 518 339 (-1 if not found); #X obj 698 320 sarray foo; #X floatatom 763 340 5 0 0 0 - - -, f 5; #X msg 683 255 add what; #X msg 698 275 add who; #X msg 711 297 add where; #X text 722 356 (-1 if full); #X text 657 233 (at the first empty place); #X text 668 220 10) add a symbol; #X text 6 447 (c) Moonix: Antoine Rousseau 2003-2005; #X connect 1 0 15 0; #X connect 2 0 15 0; #X connect 3 0 15 0; #X connect 5 0 21 0; #X connect 9 0 7 0; #X connect 11 0 13 0; #X connect 12 0 13 0; #X connect 14 0 7 0; #X connect 15 0 16 0; #X connect 16 0 17 0; #X connect 17 0 19 0; #X connect 17 1 4 0; #X connect 18 0 15 0; #X connect 20 0 15 0; #X connect 23 0 25 0; #X connect 24 0 23 0; #X connect 26 0 23 0; #X connect 27 0 23 0; #X connect 33 0 13 0; #X connect 34 0 30 0; #X connect 35 0 21 0; #X connect 39 0 13 0; #X connect 42 0 13 0; #X connect 43 0 7 0; #X connect 44 0 30 0; #X connect 45 0 30 0; #X connect 46 0 30 0; #X connect 48 0 47 0; #X connect 50 0 49 0; #X connect 51 0 49 0; #X connect 52 0 49 0; #X connect 58 1 62 0; #X connect 59 0 58 0; #X connect 60 0 58 0; #X connect 61 0 58 0; #X connect 64 1 65 0; #X connect 66 0 64 0; #X connect 67 0 64 0; #X connect 68 0 64 0; MetaluNet-moonlib-550f1b9/relativepath.c0000664002537200253720000000732615201114445020513 0ustar zmoelnigzmoelnig#ifndef _WIN32 /* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /*#include */ #include "m_pd.h" #include "g_canvas.h" #include "m_imp.h" #include #include #include #include #include #include #if (PD_MAJOR_VERSION == 0) && (PD_MINOR_VERSION < 46) extern t_canvas *canvas_list; #else #define canvas_list pd_this->pd_canvaslist #endif extern int canvas_getdollarzero( void); struct _canvasenvironment { t_symbol *ce_dir; /* directory patch lives in */ int ce_argc; /* number of "$" arguments */ t_atom *ce_argv; /* array of "$" arguments */ int ce_dollarzero; /* value of "$0" */ }; typedef struct _relativepath { t_object x_obj; t_canvas *x_canvas; int x_dolzero; int x_realized; } t_relativepath; t_class *relativepath_class; void relativepath_setup(void); static t_glist *getcanvas(t_glist *can,int d0) { t_canvas *retcan=0; t_gobj *ob; if((can->gl_env)&&(can->gl_env->ce_dollarzero==d0)) { return can; } ob=can->gl_list; while(ob&&(retcan==0)) { if (pd_class(&ob->g_pd) == canvas_class) retcan=getcanvas((t_glist *)ob,d0); ob=ob->g_next; } if((!retcan)&&(can->gl_next)) retcan=getcanvas((t_glist *)can->gl_next,d0); return retcan; } static void relativepath_symbol(t_relativepath *x,t_symbol *sym) { t_canvas *can=0; t_symbol *s=sym; char *instr=sym->s_name,*outstr=instr, *candir, canname[MAXPDSTRING],totaldir[MAXPDSTRING], *cnamedir; unsigned int n,i=0; if(!x->x_realized) can=(t_canvas *)getcanvas(canvas_list,x->x_dolzero); if(can) { x->x_canvas = can; x->x_realized = 1; //post("found $0 canvas : %x %d ",x->x_canvas, x->x_canvas->gl_env->ce_dollarzero ); } if(!instr) return; candir=canvas_getdir(x->x_canvas)->s_name; if(!candir) candir=""; strcpy(canname,x->x_canvas->gl_name->s_name); //post("canname=%s",canname); cnamedir=dirname(canname); if (strcmp(cnamedir,".")) { sprintf(totaldir,"%s/%s",candir,cnamedir); } else strcpy(totaldir,candir); //post("dir=%s",totaldir); n=strlen(totaldir); if(strlen(instr)<=n) goto end; while(ix_obj.ob_outlet,s); } static void *relativepath_new(t_float dolzero) { t_relativepath *x = (t_relativepath *)pd_new(relativepath_class); int d0; outlet_new(&x->x_obj, 0); x->x_canvas = canvas_getcurrent(); x->x_dolzero = dolzero; x->x_realized=dolzero?0:1; return (void *)x; } void relativepath_setup(void) { relativepath_class = class_new(gensym("relativepath"),(t_newmethod)relativepath_new, 0, sizeof(t_relativepath), 0,A_DEFFLOAT,0); class_addsymbol(relativepath_class, relativepath_symbol); } #endif /* NOT _WIN32 */ MetaluNet-moonlib-550f1b9/tabsort2.c0000664002537200253720000001073415201114445017560 0ustar zmoelnigzmoelnig/* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "m_pd.h" #include "math.h" /* ---------------- tabsort2 - sort a table to a table ----------------- */ typedef struct tabsort2 { t_object x_obj; /* header */ t_symbol *x_arrayname1; t_symbol *x_arrayname2; t_symbol *x_arrayname3; } t_tabsort2; t_class *tabsort2_class; static void *tabsort2_new(t_symbol *tab1,t_symbol *tab2,t_symbol *tab3) { t_tabsort2 *x; x = (t_tabsort2 *)pd_new(tabsort2_class); x->x_arrayname1 = tab1; x->x_arrayname2 = tab2; x->x_arrayname3 = tab3; outlet_new((t_object *)x, &s_float); return (x); } static void tabsort2_set1(t_tabsort2 *x, t_symbol *s) { x->x_arrayname1 = s; } static void tabsort2_set2(t_tabsort2 *x, t_symbol *s) { x->x_arrayname2 = s; } static void tabsort2_set3(t_tabsort2 *x, t_symbol *s) { x->x_arrayname3 = s; } static void tabsort2_float(t_tabsort2 *x, t_floatarg n) { t_garray *a; int n1,n2,n3,i,j,h,sqn; t_word *vec1,*vec2,*vec3; t_float tmp; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname1, garray_class))) { if (*x->x_arrayname1->s_name) pd_error(x, "tabsort2: %s: no such array", x->x_arrayname1->s_name); return; } else if (!garray_getfloatwords(a, &n1, &vec1)) { pd_error(x, "%s: bad template for tabsort2", x->x_arrayname1->s_name); return; } if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname2, garray_class))) { if (*x->x_arrayname2->s_name) pd_error(x, "tabsort2: %s: no such array", x->x_arrayname2->s_name); return; } else if (!garray_getfloatwords(a, &n2, &vec2)) { pd_error(x, "%s: bad template for tabsort2", x->x_arrayname2->s_name); return; } if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname3, garray_class))) { if (*x->x_arrayname3->s_name) pd_error(x, "tabsort2: %s: no such array", x->x_arrayname3->s_name); return; } else if (!garray_getfloatwords(a, &n3, &vec3)) { pd_error(x, "%s: bad template for tabsort2", x->x_arrayname3->s_name); return; } if(n>n1) n=n1; if(n>n2) n=n2; if(n>n3) n=n3; for(i=0; ii; j--) if(vec1[(int)vec3[j-1].w_float].w_floati; j--) if(vec2[(int)vec3[h*sqn+j-1].w_float].w_floatob_outlet,(t_float)sqn); } static void tabsort2_ff(t_tabsort2 *x) /* cleanup on free */ { } void tabsort2_setup(void ) { tabsort2_class = class_new(gensym("tabsort2"), (t_newmethod)tabsort2_new, (t_method)tabsort2_ff, sizeof(t_tabsort2), 0, A_DEFSYM, A_DEFSYM, A_DEFSYM, 0); class_addmethod(tabsort2_class, (t_method)tabsort2_set1, gensym("set1"), A_DEFSYM, 0); class_addmethod(tabsort2_class, (t_method)tabsort2_set2, gensym("set2"), A_DEFSYM, 0); class_addmethod(tabsort2_class, (t_method)tabsort2_set3, gensym("set3"), A_DEFSYM, 0); class_addfloat(tabsort2_class, tabsort2_float); } MetaluNet-moonlib-550f1b9/image.tcl0000664002537200253720000000211515201114445017434 0ustar zmoelnigzmoelnig namespace eval ::moonlib::image:: { } proc ::moonlib::image::configure {obj_id img filename} { if { [catch {$img configure -file $filename} fid]} { ::pdwindow::logpost $obj_id 1 "image: error reading '$filename':\n$fid\n" } } proc ::moonlib::image::create_photo {obj_id img filename} { if { [catch {image create photo $img -file $filename} fid]} { ::pdwindow::logpost $obj_id 1 "image: error reading '$filename':\n$fid\n" } } image create photo ::moonlib::image::noimage -data { R0lGODlhDwARANU8AAAAAP6xDv/yHP6kDP6oCv7FEP/pGUY6J/7KEP7CD//tG/6sCurp6FVLM+/v 7vzhGP7SE/61DtfW05pwG/7ZFXFjOmNWM31yXv65Dv69D/nuIu+9Em5hRmlcO1FELv///1tILLWW I/b29v/kGOubD/7cFteMEYBdJoiAbpKMeJuYjWNXQF9UOrq4stmYEui/FoqEc3VoRZWQfMCBEtbG MO3VHe6qEObUOZiDQ+2wEcJ/EnluWf///wAAAAAAAAAAACH5BAEAADwALAAAAAAPABEAQAa1QJ5Q JIt1Kh1OSiTkNSAQgBRRSEgBgcChKWxdOLsWl5eiKQRoheFBQSQKExjvMsFErtLBYHIRqnAaaAIG axQvFio8Fg94ACWNGB4oIQWVCRFZCwQEeyhCDAcumpwDJgcMXBIVN4FqNSErEkIOCoGCBiNtCBsH DiwPhApqIyUQVRk5HhUUVx8AUVLOASAKGwhUx1mZJAoSFhgZAJgBmgCcILIOBzaYo3okvVwMKycz JjonLKhCQQA7 } MetaluNet-moonlib-550f1b9/sfread2~-help.pd0000664002537200253720000000551615201114445020655 0ustar zmoelnigzmoelnig#N canvas 588 132 708 498 10; #X obj 0 0 cnv 8 100 60 empty empty sfread2~ 10 20 1 18 -262144 -1109 0; #X text 2 459 (c) Moonix: Antoine Rousseau 2003; #X text 66 390 Change "mlockall(MCL_FUTURE)" with "mlockall(MCL_CURRENT) ; #X obj 155 262 sfread2~ 2; #X msg 155 202 open \$1; #X obj 19 151 bng 15 250 50 0 empty empty play 20 8 1 8 -24198 -1 -1 ; #X msg 253 168 loop \$1; #X obj 253 150 tgl 15 1 empty empty loop 20 8 0 8 -241291 -1 -1 1 1 ; #X obj 57 103 tgl 15 1 empty empty interpolation 20 8 1 8 -257472 -1 -1 1 1; #X msg 57 121 interp \$1; #X obj 588 181 vsl 15 128 -8 8 0 0 empty empty speed 0 -8 1 8 -260818 -1 -1 6644 1; #X text 135 12 soundfile reader at variable speed (possibly negative) \, with 4-point interpolation and loop.; #X obj 154 296 dac~; #X obj 155 92 openpanel; #X obj 155 72 bng 15 250 50 0 empty empty open 0 -6 1 8 -166441 -1 -1; #X obj 18 179 bng 15 250 50 0 empty empty stop 20 8 1 8 -1 -1 -1; #X msg 18 196 0; #X obj 148 339 sfread~; #X text 43 341 read manual of; #X text 202 339 for more details...; #X text 354 144 resets sound to position; #X text 353 133 start position in samples; #X msg 357 159 index 20000; #X obj 627 177 loadbang; #X msg 627 196 1; #X msg 261 99 symbol /usr/local/lib/pd/doc/sound/voice.wav; #X msg 261 78 symbol ../../doc/sound/voice.wav; #X text 66 414 If not \, the whole file will be loaded in memory when opened (use of C function mmap()).; #N canvas 592 238 494 344 META 0; #X text 12 25 LICENSE GPL v2; #X text 12 165 AUTHOR Antoine Rousseau; #X text 12 185 HELP_PATCH_AUTHORS Antoine Rousseau. "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 5 KEYWORDS signal soundfile; #X text 12 45 DESCRIPTION soundfile reader at variable speed (possibly negative) \, with 4-point interpolation and loop; #X text 12 85 INLET_0 float bang interp open index loop; #X text 12 105 INLET_1 float; #X text 12 145 comment; #X text 12 125 OUTLET_N signal; #X text 12 145 OUTLET_R float; #X restore 526 459 pd META; #X text 67 365 CAUTION: it's possible to hack pd sources to have real d-t-d working :; #X text 66 401 in s_inter.c; #X obj 199 314 print status; #X obj 222 292 print length; #X msg 357 189 index; #X floatatom 584 140 5 0 0 0 - - -, f 5; #X text 401 188 get current index; #X msg 357 219 state; #X text 401 218 get playing state (0/1); #X msg 357 244 size; #X text 393 242 get file size in samples; #X connect 3 0 12 0; #X connect 3 1 12 1; #X connect 3 2 31 0; #X connect 3 3 32 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 3 0; #X connect 7 0 6 0; #X connect 8 0 9 0; #X connect 9 0 3 0; #X connect 10 0 3 1; #X connect 13 0 4 0; #X connect 14 0 13 0; #X connect 15 0 16 0; #X connect 16 0 3 0; #X connect 22 0 3 0; #X connect 23 0 24 0; #X connect 24 0 10 0; #X connect 25 0 4 0; #X connect 26 0 4 0; #X connect 33 0 3 0; #X connect 34 0 10 0; #X connect 36 0 3 0; #X connect 38 0 3 0; MetaluNet-moonlib-550f1b9/dinlet~.c0000664002537200253720000000622615201114445017476 0ustar zmoelnigzmoelnig/* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* this file is made from parts of m_object.c and g_io.c * it defines a signal inlet named dinlet~ which is the same as inlet~ * exepts you can give a default float value for the case none signal * is connected to this inlet~. */ /***********************************************************************/ #include "m_pd.h" #include "m_imp.h" #include "g_canvas.h" #include /******************** from m_obj.c: **************************/ /* only because inlet_float() is not public... */ union inletunion { t_symbol *iu_symto; t_gpointer *iu_pointerslot; t_float *iu_floatslot; t_symbol **iu_symslot; t_sample iu_floatsignalvalue; }; struct _inlet { t_pd i_pd; struct _inlet *i_next; t_object *i_owner; t_pd *i_dest; t_symbol *i_symfrom; union inletunion i_un; }; #define i_symto i_un.iu_symto static void dinlet_float(t_inlet *x, t_float f) { if (x->i_symfrom == &s_float) pd_vmess(x->i_dest, x->i_symto, "f", (t_floatarg)f); else if (x->i_symfrom == &s_signal) x->i_un.iu_floatsignalvalue = f; else if (!x->i_symfrom) pd_float(x->i_dest, f); /*else inlet_wrong(x, &s_float);*/ } /**************** from g_io.c : *********************************/ void signal_setborrowed(t_signal *sig, t_signal *sig2); void signal_makereusable(t_signal *sig); /* ------------------------- vinlet -------------------------- */ t_class *vinlet_class; typedef struct _vinlet { t_object x_obj; t_canvas *x_canvas; t_inlet *x_inlet; int x_bufsize; t_float *x_buf; /* signal buffer; zero if not a signal */ t_float *x_endbuf; t_float *x_fill; t_float *x_read; int x_hop; /* if not reblocking, the next slot communicates the parent's inlet signal from the prolog to the DSP routine: */ t_signal *x_directsignal; } t_vinlet; static void *dinlet_newsig(t_floatarg f) { t_vinlet *x = (t_vinlet *)pd_new(vinlet_class); x->x_canvas = canvas_getcurrent(); x->x_inlet = canvas_addinlet(x->x_canvas, &x->x_obj.ob_pd, &s_signal); x->x_endbuf = x->x_buf = (t_float *)getbytes(0); x->x_bufsize = 0; x->x_directsignal = 0; x->x_inlet->i_un.iu_floatsignalvalue=f; outlet_new(&x->x_obj, &s_signal); return (x); } void dinlet_tilde_setup(void) { //class_addcreator((t_newmethod)dinlet_newsig, gensym("dinlet~"), A_DEFFLOAT,0); class_new(gensym("dinlet~"), (t_newmethod)dinlet_newsig, 0, 0, 0, A_DEFFLOAT, 0); } MetaluNet-moonlib-550f1b9/Makefile.pdlibbuilder0000664002537200253720000012703115201114445021753 0ustar zmoelnigzmoelnig# Makefile.pdlibbuilder dated 2019-12-21 version = 0.6.0 # Helper makefile for Pure Data external libraries. # Written by Katja Vetter March-June 2015 for the public domain. No warranties. # Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's # ShakeNMake. # # Grab the newest version of Makefile.pdlibbuilder from # https://github.com/pure-data/pd-lib-builder/ # # GNU make version >= 3.81 required. # # #=== characteristics =========================================================== # # # - defines build settings based on autodetected OS and architecture # - defines rules to build Pd class- or lib executables from C or C++ sources # - defines rules for libdir installation # - defines convenience targets for developer and user # - evaluates implicit dependencies for non-clean builds # # #=== basic usage =============================================================== # # # In your Makefile, define your Pd lib name and class files, and include # Makefile.pdlibbuilder at the end of the Makefile. Like so: # # ________________________________________________________________________ # # # Makefile for mylib # # lib.name = mylib # # class.sources = myclass1.c myclass2.c # # datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt # # include Makefile.pdlibbuilder # ________________________________________________________________________ # # # For files in class.sources it is assumed that class basename == source file # basename. The default target builds all classes as individual executables # with Pd's default extension for the platform. For anything more than the # most basic usage, continue reading. # # #=== list of Makefile.pdlibbuilder API variables =============================== # # # Variables available for definition in your library Makefile: # # - lib.name # - lib.setup.sources # - class.sources # - common.sources # - shared.sources # - .class.sources # - .class.ldflags # - .class.ldlibs # - cflags # - ldflags # - ldlibs # - datafiles # - datadirs # - makefiles # - makefiledirs # - externalsdir # # Optional multiline defines evaluated per operating system: # # - forLinux # - forDarwin # - forWindows # # Variables available for your makefile or make command line: # # - make-lib-executable # - suppress-wunused # # Path variables for make command line or environment: # # - PDDIR # - PDINCLUDEDIR # - PDBINDIR # - PDLIBDIR # # Standard make variables for make command line or environment: # # - CPPFLAGS # - CFLAGS # - LDFLAGS # - CC # - CXX # - INSTALL # - STRIP # - DESTDIR # # Optional user variables for make command line or environment: # # - PLATFORM # # Deprecated path variables: # # - pdincludepath # - pdbinpath # - objectsdir # # #=== descriptions of Makefile.pdlibbuilder API variables ======================= # # # lib.name: # Name of the library directory as it will be installed / distributed. Also the # name of the lib executable in the case where all classes are linked into # a single binary. # # lib.setup.sources: # Source file(s) (C or C++) which must be compiled only when linking all classes # into a single lib binary. # # class.sources: # All sources files (C or C++) for which the condition holds that # class name == source file basename. # # .class.sources: # Source file(s) (C or C++) specific to class . Use this for # multiple-source classes or when class name != source file basename. # # common.sources: # Source file(s) which must be statically linked to each class in the library. # # shared.sources: # Source file(s) (C or C++) to build a shared dynamic link lib, to be linked # with all class executables. # # cflags, ldflags, ldlibs: # Define cflags (preprocessor&compiler), ldflags (linker) and ldlibs (dynamic # link libs) for the whole library. These flags are added to platform-specific # flags defined by Makefile.pdlibbuilder. # # .class.ldflags and .class.ldlibs: # Define ldflags resp. ldlibs specific to class . These flags are # added to platform-specific flags defined by Makefile.pdlibbuilder, and flags # defined in your Makefile for the whole library. Note: cflags can not be # defined per class in the current implementation. # # datafiles and datadirs: # All extra files you want to include in binary distributions of the # library: abstractions and help patches, example patches, meta patch, readme # and license texts, manuals, sound files, etcetera. Use 'datafiles' for all # files that should go into your lib rootdir and 'datadirs' for complete # directories you want to copy from source to distribution. # # forLinux, forDarwin, forWindows: # Shorthand for 'variable definitions for Linux only' etc. Use like: # define forLinux # cflags += -DLINUX # class.sources += linuxthing.c # endef # # makefiles and makefiledirs: # Extra makefiles or directories with makefiles that should be made in sub-make # processes. # # make-lib-executable: # When this variable is defined 'yes' in your makefile or as command argument, # Makefile.pdlibbuilder will try to build all classes into a single library # executable (but it will force exit if lib.setup.sources is undefined). # If your makefile defines 'make-lib-executable=yes' as the library default, # this can still be overridden with 'make-lib-executable=no' as command argument # to build individual class executables (the Makefile.pdlibbuilder default.) # # suppress-wunused: # When this variable is defined ('yes' or any other value), -Wunused-variable, # -Wunused-parameter, -Wunused-value and -Wunused-function are suppressed, # but the other warnings from -Wall are retained. # # PDDIR: # Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and # PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin. # # PDINCLUDEDIR: # Directory where Pd API m_pd.h should be found, and other Pd header files. # Overrides the default search path. # # PDBINDIR: # Directory where pd.dll should be found for linking (Windows only). Overrides # the default search path. # # PDLIBDIR: # Root directory for installation of Pd library directories. Overrides the # default install location. # # DESTDIR: # Prepended path component for staged install. # # PLATFORM: # Target platform for cross compilation in the form of GNU triplet: # cpu-vendor-os. Example: x86_64-w64-mingw32. This specifies the tool chain that # pdlibbuilder will use, if installed and locatable. System and architecture # will then be autodefined accordingly. In most cases no other variables need to # be overridden. # # CPPFLAGS: # Preprocessor flags which are not strictly required for building. # # CFLAGS: # Compiler flags which are not strictly required for building. Compiler flags # defined by Makefile.pdlibbuilder for warning, optimization and architecture # specification are overriden by CFLAGS. # # LDFLAGS: # Linker flags which are not strictly required for building. Linker flags # defined by Makefile.pdlibbuilder for architecture specification are overriden # by LDFLAGS. # # CC and CXX: # C and C++ compiler programs as defined in your build environment. # # INSTALL # Definition of install program. # # STRIP # Name of strip program. Default 'strip' can be overridden in cross compilation # environments. # # objectsdir: # Root directory for installation of Pd library directories, like PDLIBDIR but # not overridable by environment. Supported for compatibility with pd-extended # central makefile, but deprecated otherwise. # # pdincludepath, pdbinpath: # As PDINCLUDEDIR and PDBINDIR but not overridable by environment. Deprecated # as user variables. # # #=== paths ===================================================================== # # # Source files in directories other than current working directory must be # prefixed with their relative path. Do not rely on VPATH or vpath. # Object (.o) files are built in the directory of their source files. # Executables are built in current working directory. # # Default search path for m_pd.h and other API header files is platform # dependent, and overridable by PDINCLUDEDIR: # # Linux: /usr/include/pd # # OSX: /Applications/Pd*.app/Contents/Resources/src # # Windows: %PROGRAMFILES%/Pd/src # %PROGRAMFILES(X86)%/Pd/src (32 bit builds on 64 bit Windows) # # Default search path for binary pd.dll (Windows), overridable by PDBINDIR # # %PROGRAMFILES%/Pd/bin # %PROGRAMFILES(X86)%/Pd/bin (32 bit builds on 64 bit Windows) # # Default location to install pd libraries is platform dependent, and # overridable by PDLIBDIR: # # Linux: /usr/local/lib/pd-externals # OSX: ~/Library/Pd # Windows: %APPDATA%/Pd # # https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files # The rationale for not installing to ~/pd-externals by default on Linux # is that some people share the home dir between 32 and 64 bit installations. # # #=== targets =================================================================== # # # all: build $(executables) plus optional post target # post: target to build after $(executables) # alldebug: build all with -g option turned on for debug symbols # : force clean build of an individual class # .pre: make preprocessor output file in current working directory # .lst: make asm/source output file in current working directory # # install: install executables and data files # clean: remove build products from source tree # # help: print help text # vars: print makefile variables # allvars: print all variables # depend: print generated prerequisites # dumpmachine: print compiler output of option '-dumpmachine' # coffee: dummy target # # Variable $(executables) expands to class executables plus optional shared lib, # or alternatively to single lib executable when make-lib-executable=true. # Targets pre and post can be defined by library makefile. Make sure to include # Makefile.pdlibbuilder first so default target all will not be redefined. # # #=== Pd-extended libdir concept ================================================ # # # For libdir layout as conceived by Hans-Christoph Steiner, see: # # https://puredata.info/docs/developer/Libdir # # Files README.txt, LICENSE.txt and -meta.pd are part of the libdir # convention. Help patches for each class and abstraction are supposed to be # available. Makefile.pdlibbuilder does not force the presence of these files # however. It does not automatically include such files in libdir installations. # Data files you want to include in distributions must be defined explicitly in # your Makefile. # # #=== Makefile.pdlibbuilder syntax conventions ================================== # # # Makefile.pdlibbuilder variable names are lower case. Default make variables, # environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR) # are upper case. Use target 'allvars' to print all variables and their values. # # 'Fields' in data variables are separated by dots, like in 'foo.class.sources'. # Words in variables expressing a function or command are separated by dashes, # like in 'make-lib-executable'. # # #=== useful make options ======================================================= # # # Use 'make -d ' to print debug details of the make process. # Use 'make -p ' to print make's database. # # #=== TODO ====================================================================== # # # - decide whether to use -static-libgcc or shared dll in MinGW # - cygwin support # - android support # - figure out how to handle '$' in filenames # - add makefile template targets dpkg-source dist libdir distclean tags? # # #=== end of documentation sections ============================================= # # ################################################################################ ################################################################################ ################################################################################ # GNU make version 3.81 (2006) or higher is required because of the following: # - function 'info' # - variable '.DEFAULT_GOAL' # force exit when make version is < 3.81 ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81) $(error GNU make version 3.81 or higher is required) endif # Relative path to externals root dir in multi-lib source tree like # pd-extended SVN. Default is parent of current working directory. May be # defined differently in including makefile. externalsdir ?= .. # variable you can use to check if Makefile.pdlibbuilder is already included Makefile.pdlibbuilder = true ################################################################################ ### target platform detection ################################################## ################################################################################ #=== target platform =========================================================== # PLATFORM: optional user variable to define target platform for cross # compilation. Redefine build tools accordingly. PLATFORM should match # the exact target prefix of tools present in $PATH, like x86_64-w64-mingw32, # x86_64-apple-darwin12 etc. Tool definitions are exported to ensure submakes # will get the same. ifneq ($(PLATFORM),) ifneq ($(findstring darwin, $(PLATFORM)),) export CC = $(PLATFORM)-cc export CXX = $(PLATFORM)-c++ export CPP = $(PLATFORM)-cc else export CC = $(PLATFORM)-gcc export CXX = $(PLATFORM)-g++ export CPP = $(PLATFORM)-cpp endif STRIP = $(PLATFORM)-strip endif # Let (native or cross-) compiler report target triplet and isolate individual # words therein to facilitate later processing. target.triplet := $(subst -, ,$(shell $(CC) -dumpmachine)) #=== operating system ========================================================== # The following systems are defined: Linux, Darwin, Windows. GNU and # GNU/kFreeBSD are treated as Linux to get the same options. ifneq ($(filter linux gnu% kfreebsd, $(target.triplet)),) system = Linux endif ifneq ($(filter darwin%, $(target.triplet)),) system = Darwin endif ifneq ($(filter mingw% cygwin%, $(target.triplet)),) system = Windows endif # evaluate possible system-specific multiline defines from library makefile $(eval $(for$(system))) # TODO: Cygwin, Android #=== architecture ============================================================== # The following CPU names can be processed by pdlibbuilder: # i*86 Intel 32 bit # x86_64 Intel 64 bit # arm ARM 32 bit # aarch64 ARM 64 bit target.arch := $(firstword $(target.triplet)) ################################################################################ ### variables per platform ##################################################### ################################################################################ #=== flags per architecture ==================================================== # Set architecture-dependent cflags, mainly for Linux. For Mac and Windows, # arch.c.flags are overriden below. To see gcc's default architecture flags: # $ gcc -Q --help=target # ARMv6: Raspberry Pi 1st gen, not detectable from target.arch ifeq ($(shell uname -m), armv6l) arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard # ARMv7: Beagle, Udoo, RPi2 etc. else ifeq ($(target.arch), arm) arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard # ARMv8 64 bit, not tested yet else ifeq ($(target.arch), aarch64) arch.c.flags = -mcpu=cortex-a53 # Intel 32 bit, build with SSE and SSE2 instructions else ifneq ($(filter i%86, $(target.arch)),) arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2 # Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions else ifeq ($(target.arch), x86_64) arch.c.flags = -march=core2 -mfpmath=sse -msse -msse2 -msse3 # if none of the above architectures detected else arch.c.flags = endif #=== flags and paths for Linux ================================================= ifeq ($(system), Linux) prefix = /usr/local libdir := $(prefix)/lib pkglibdir = $(libdir)/pd-externals pdincludepath := $(wildcard /usr/include/pd) extension = pd_linux cpp.flags := -DUNIX c.flags := -fPIC c.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags c.ldlibs := -lc -lm cxx.flags := -fPIC -fcheck-new cxx.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags cxx.ldlibs := -lc -lm -lstdc++ shared.extension = so shared.ldflags = -rdynamic -fPIC -shared -Wl,-soname,$(shared.lib) endif #=== flags and paths for Darwin ================================================ # LLVM-clang doesn't support -fcheck-new, therefore this flag is only used when # compiling with g++. ifeq ($(system), Darwin) pkglibdir = $(HOME)/Library/Pd pdincludepath := $(firstword $(wildcard \ /Applications/Pd*.app/Contents/Resources/src)) extension = pd_darwin cpp.flags := -DUNIX -DMACOSX -I /sw/include c.flags := c.ldflags := -undefined suppress -flat_namespace -bundle c.ldlibs := -lc cxx.ldflags := -undefined suppress -flat_namespace -bundle cxx.ldlibs := -lc shared.extension = dylib shared.ldflags = -dynamiclib -undefined dynamic_lookup \ -install_name @loader_path/$(shared.lib) \ -compatibility_version 1 -current_version 1.0 ifneq ($(filter %g++, $(CXX)),) cxx.flags := -fcheck-new endif ifeq ($(extension), d_fat) arch := i386 x86_64 else arch := $(target.arch) endif ifneq ($(filter -mmacosx-version-min=%, $(cflags)),) version.flag := $(filter -mmacosx-version-min=%, $(cflags)) else version.flag = -mmacosx-version-min=10.6 endif arch.c.flags := $(addprefix -arch , $(arch)) $(version.flag) arch.ld.flags := $(arch.c.flags) endif #=== flags and paths for Windows =============================================== # Standard paths on Windows contain spaces, and GNU make functions treat such # paths as lists, with unintended effects. Therefore we must use shell function # ls instead of make's wildcard when probing for a path, and use double quotes # when specifying a path in a command argument. # Default paths in Mingw / Mingw-w64 environments. 'PROGRAMFILES' is standard # location for builds with native architecture, 'ProgramFiles(x86)' for i686 # builds on x86_64 Windows (detection method by Lucas Cordiviola). Curly braces # required because of parentheses in variable name. ifeq ($(system), Windows) pkglibdir := $(APPDATA)/Pd ifeq ($(target.arch), i686) programfiles := ${ProgramFiles(x86)} else programfiles := $(PROGRAMFILES) endif pdbinpath := $(programfiles)/Pd/bin pdincludepath := $(programfiles)/Pd/src endif # Store default path to pd.dll in PDBINDIR if the latter is not user-defined. # For include path this is done in the platform-independent paths section below, # but for PDBINDIR it is done here so ld flags can be evaluated as immediate # variables. ifeq ($(system), Windows) ifdef PDDIR PDBINDIR := $(PDDIR)/bin endif PDBINDIR ?= $(pdbinpath) endif # TODO: decide whether -mms-bitfields should be specified. ifeq ($(system), Windows) cpp.flags := -DMSW -DNT ifeq ($(target.arch), i686) arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse else ifeq ($(target.arch), x86_64) cpp.flags := -DMSW -DNT -DPD_LONGINTTYPE=__int64 arch.c.flags := -march=core2 -msse -msse2 -msse3 -mfpmath=sse else arch.c.flags = endif extension = dll c.flags := c.ldflags := -static-libgcc -shared \ -Wl,--enable-auto-import "$(PDBINDIR)/pd.dll" c.ldlibs := cxx.flags := -fcheck-new cxx.ldflags := -static-libgcc -static-libstdc++ -shared \ -Wl,--enable-auto-import "$(PDBINDIR)/pd.dll" cxx.ldlibs := shared.extension = dll shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd.dll" stripflags = --strip-all endif #=== paths ===================================================================== # Platform-dependent default paths are specified above, but overridable. # Path variables in upper case can be defined as make command argument or in the # environment. Variable 'objectsdir' is supported for compatibility with # the build system that pd-l2ork has inherited from pd-extended. PDINCLUDEDIR ?= $(pdincludepath) PDLIBDIR ?= $(firstword $(objectsdir) $(pkglibdir)) ifdef PDDIR PDINCLUDEDIR := $(wildcard $(PDDIR)/src) endif # base path where all components of the lib will be installed by default installpath := $(DESTDIR)$(PDLIBDIR)/$(lib.name) # check if include path contains spaces (as is often the case on Windows) # if so, store the path so we can later do checks with it pdincludepathwithspaces := $(if $(word 2, $(PDINCLUDEDIR)), $(PDINCLUDEDIR)) #=== accumulated build flags =================================================== # From GNU make docs: 'Users expect to be able to specify CFLAGS freely # themselves.' So we use CFLAGS to define options which are not strictly # required for compilation: optimizations, architecture specifications, and # warnings. CFLAGS can be safely overriden using a make command argument. # Variables cflags, ldflags and ldlibs may be defined in including makefile. optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer warn.flags = -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing # suppress -Wunused-variable & Co if you don't want to clutter a build log ifdef suppress-wunused warn.flags += $(addprefix -Wno-unused-, function parameter value variable) endif CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags) # preprocessor flags cpp.flags := -DPD -I "$(PDINCLUDEDIR)" $(cpp.flags) $(CPPFLAGS) # flags for dependency checking (cflags from makefile may define -I options) depcheck.flags := $(cpp.flags) $(cflags) # architecture specifications for linker are overridable by LDFLAGS LDFLAGS := $(arch.ld.flags) # now add the same ld flags to shared dynamic lib shared.ldflags += $(LDFLAGS) # accumulated flags for C compiler / linker c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS) c.ldflags := $(c.ldflags) $(ldflags) $(LDFLAGS) c.ldlibs := $(c.ldlibs) $(ldlibs) # accumulated flags for C++ compiler / linker cxx.flags := $(cpp.flags) $(cxx.flags) $(cflags) $(CFLAGS) cxx.ldflags := $(cxx.ldflags) $(ldflags) $(LDFLAGS) cxx.ldlibs := $(cxx.ldlibs) $(ldlibs) ################################################################################ ### variables: library name and version ######################################## ################################################################################ # strip possibles spaces from lib.name, they mess up calculated file names lib.name := $(strip $(lib.name)) # if meta file exists, check library version metafile := $(wildcard $(lib.name)-meta.pd) ifdef metafile lib.version := $(shell sed -n \ 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' \ $(metafile)) endif ################################################################################ ### variables: files ########################################################### ################################################################################ #=== sources =================================================================== # (re)define .class.sources using file names in class.sources define add-class-source $(notdir $(basename $v)).class.sources += $v endef $(foreach v, $(class.sources), $(eval $(add-class-source))) # derive class names from .class.sources variables sourcevariables := $(filter %.class.sources, $(.VARIABLES)) classes := $(basename $(basename $(sourcevariables))) # accumulate all source files specified in makefile classes.sources := $(sort $(foreach v, $(sourcevariables), $($v))) all.sources := $(classes.sources) $(lib.setup.sources) \ $(shared.sources) $(common.sources) #=== object files ============================================================== # construct object filenames from all C and C++ source file names classes.objects := $(addsuffix .o, $(basename $(classes.sources))) common.objects := $(addsuffix .o, $(basename $(common.sources))) shared.objects := $(addsuffix .o, $(basename $(shared.sources))) lib.setup.objects := $(addsuffix .o, $(basename $(lib.setup.sources))) all.objects = $(classes.objects) $(common.objects) $(shared.objects) \ $(lib.setup.objects) #=== executables =============================================================== # construct class executable names from class names classes.executables := $(addsuffix .$(extension), $(classes)) # Construct shared lib executable name if shared sources are defined. If # extension and shared extension are not identical, use both to facilitate co- # installation for different platforms, like .m_i386.dll and .m_amd64.dll. ifdef shared.sources ifeq ($(extension), $(shared.extension)) shared.lib = lib$(lib.name).$(shared.extension) else shared.lib = lib$(lib.name).$(extension).$(shared.extension) endif else shared.lib := endif ################################################################################ ### variables: tools ########################################################### ################################################################################ # aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument compile-c := $(CC) compile-cxx := $(CXX) ################################################################################ ### checks ##################################################################### ################################################################################ # At this point most variables are defined. Now do some checks and info's # before rules begin. # print Makefile.pdlibbuilder version before possible termination $(info ++++ info: using Makefile.pdlibbuilder version $(version)) # Terminate if target triplet remained empty, to avoid all sorts of confusing # scenarios and spurious bugs. ifeq ($(target.triplet),) $(error Command "$(CC) -dumpmachine" did not return a target triplet, \ needed for a build. \ Is compiler "$(CC)" installed in your PATH? ($(PATH)). \ Does compiler "$(CC)" support option "-dumpmachine"?) endif # 'forward declaration' of default target, needed to do checks all: # To avoid unpredictable results, make sure the default target is not redefined # by including makefile. ifneq ($(.DEFAULT_GOAL), all) $(error Default target must be 'all'.) endif # find out which target(s) will be made ifdef MAKECMDGOALS goals := $(MAKECMDGOALS) else goals := all endif # store path to Pd API m_pd.h if it is found ifdef PDINCLUDEDIR mpdh := $(shell ls "$(PDINCLUDEDIR)/m_pd.h") endif # store path to pd.dll; if not found, ls will give a useful error ifeq ($(system), Windows) pddll := $(shell ls "$(PDBINDIR)/pd.dll") endif # when making target all, check if m_pd.h is found and print info about it ifeq ($(goals), all) $(if $(mpdh), \ $(info ++++ info: using Pd API $(mpdh)), \ $(warning Where is Pd API m_pd.h? Do 'make help' for info.)) endif # print target info $(info ++++ info: making target $(goals) $(if $(lib.name),in lib $(lib.name))) # when installing, print installpath info $(if $(filter install install-lib, $(goals)), $(info ++++ info: \ installpath is '$(installpath)')) #=== define executables ======================================================== # By default we build class executables, and optionally a shared dynamic link # lib. When make-lib-executable=yes we build all classes into a single lib # executable, on the condition that variable lib.setup.sources is defined. ifeq ($(make-lib-executable),yes) $(if $(lib.setup.sources), ,\ $(error Can not build library blob because lib.setup.sources is undefined)) executables := $(lib.name).$(extension) else executables := $(classes.executables) $(shared.lib) endif ################################################################################ ### rules: special targets ##################################################### ################################################################################ # Disable built-in rules. If some target can't be built with the specified # rules, it should not be built at all. MAKEFLAGS += --no-builtin-rules .PRECIOUS: .SUFFIXES: .PHONY: all post build-lib \ $(classes) $(makefiledirs) $(makefiles) \ install install-executables install-datafiles install-datadirs \ force clean vars allvars depend help ################################################################################ ### rules: build targets ####################################################### ################################################################################ # Target all forces the build of targets [$(executables) post] in # deterministic order. Target $(executables) builds class executables plus # optional shared lib or alternatively a single lib executable when # make-lib-executable=true. Target post is optionally defined by # library makefile. all: post post: $(executables) all: $(info ++++info: target all in lib $(lib.name) completed) # build all with -g option turned on for debug symbols alldebug: c.flags += -g alldebug: cxx.flags += -g alldebug: all #=== class executable ========================================================== # recipe for linking objects in class executable # argument $1 = compiler type (c or cxx) # argument $2 = class basename define link-class $(compile-$1) \ $($1.ldflags) $($2.class.ldflags) \ -o $2.$(extension) \ $(addsuffix .o, $(basename $($2.class.sources))) \ $(addsuffix .o, $(basename $(common.sources))) \ $($1.ldlibs) $($2.class.ldlibs) $(shared.lib) endef # general rule for linking object files in class executable %.$(extension): $(shared.lib) $(info ++++ info: linking objects in $@ for lib $(lib.name)) $(if $(filter %.cc %.cpp, $($*.class.sources)), \ $(call link-class,cxx,$*), \ $(call link-class,c,$*)) #=== library blob ============================================================== # build all classes into single executable build-lib: $(lib.name).$(extension) $(info ++++ info: library blob $(lib.name).$(extension) completed) # recipe for linking objects in lib executable # argument $1 = compiler type (c or cxx) define link-lib $(compile-$1) \ $($1.ldflags) $(lib.ldflags) \ -o $(lib.name).$(extension) $(all.objects) \ $($1.ldlibs) $(lib.ldlibs) endef # rule for linking objects in lib executable # declared conditionally to avoid name clashes ifeq ($(make-lib-executable),yes) $(lib.name).$(extension): $(all.objects) $(if $(filter %.cc %.cpp, $(all.sources)), \ $(call link-lib,cxx), \ $(call link-lib,c)) endif #=== shared dynamic lib ======================================================== # recipe for linking objects in shared executable # argument $1 = compiler type (c or cxx) define link-shared $(compile-$1) \ $(shared.ldflags) \ -o $(shared.lib) $(shared.objects) \ $($1.ldlibs) $(shared.ldlibs) endef # rule for linking objects in shared executable # build recipe is in macro 'link-shared' $(shared.lib): $(shared.objects) $(info ++++ info: linking objects in shared lib $@) $(if $(filter %.cc %.cpp, $(shared.sources)), \ $(call link-shared,cxx), \ $(call link-shared,c)) #=== object files ============================================================== # recipe to make .o file from source # argument $1 is compiler type (c or cxx) define make-object-file $(info ++++ info: making $@ in lib $(lib.name)) $(compile-$1) \ $($1.flags) \ -o $@ -c $< endef # Three rules to create .o files. These are double colon 'terminal' rules, # meaning they are the last in a rules chain. %.o:: %.c $(call make-object-file,c) %.o:: %.cc $(call make-object-file,cxx) %.o:: %.cpp $(call make-object-file,cxx) #=== explicit prerequisites for class executables ============================== # For class executables, prerequisite rules are declared in run time. Target # 'depend' prints these rules for debugging purposes. # declare explicit prerequisites rule like 'class: class.extension' # argument $v is class basename define declare-class-target $v: $v.$(extension) endef # declare explicit prerequisites rule like 'class.extension: object1.o object2.o' # argument $v is class basename define declare-class-executable-target $v.$(extension): $(addsuffix .o, $(basename $($v.class.sources))) \ $(addsuffix .o, $(basename $(common.sources))) endef # evaluate explicit prerequisite rules for all classes $(foreach v, $(classes), $(eval $(declare-class-target))) $(foreach v, $(classes), $(eval $(declare-class-executable-target))) #=== implicit prerequisites for class executables ============================== # Evaluating implicit prerequisites (header files) with help from the # preprocessor is 'expensive' so this is done conditionally and selectively. # Note that it is also possible to trigger a build via install targets, in # which case implicit prerequisites are not checked. # When the Pd include path contains spaces it will mess up the implicit # prerequisites rules. disable-dependency-tracking := $(strip $(pdincludepathwithspaces)) ifndef disable-dependency-tracking must-build-everything := $(filter all, $(goals)) must-build-class := $(filter $(classes), $(goals)) must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources)) endif # declare implicit prerequisites rule like 'object.o: header1.h header2.h ...' # argument $1 is input source file(s) # dir is explicitly added because option -MM strips it by default define declare-object-target $(dir $1)$(filter %.o: %.h, $(shell $(CPP) $(depcheck.flags) -MM $1)) $(MAKEFILE_LIST) endef # evaluate implicit prerequisite rules when rebuilding everything ifdef must-build-everything $(if $(wildcard $(all.objects)), \ $(info ++++ info: evaluating implicit prerequisites in lib $(lib.name).....) \ $(foreach v, $(all.sources), $(eval $(call declare-object-target, $v)))) endif # evaluate implicit prerequisite rules when selectively building classes ifdef must-build-class $(foreach v, $(must-build-sources), \ $(eval $(call declare-object-target, $v))) $(foreach v, $(shared.sources), \ $(eval $(call declare-object-target, $v))) endif ################################################################################ ### rules: preprocessor and assembly files ##################################### ################################################################################ # Preprocessor and assembly output files for bug tracing etc. They are not part # of the build processes for executables. By default these files are created in # the current working directory. Dependency tracking is not performed, the build # is forced instead to make sure it's up to date. force: #=== preprocessor file ========================================================= # make preprocessor output file with extension .pre # argument $1 = compiler type (c or cxx) define make-preprocessor-file $(info ++++ info: making preprocessor output file $(notdir $*.pre) \ in current working directory) $(compile-$1) -E $< $(c.flags) $($1.flags) -o $(notdir $*.pre) endef %.pre:: %.c force $(call make-preprocessor-file,c) %.pre:: %.cc force $(call make-preprocessor-file,cxx) %.pre:: %.cpp force $(call make-preprocessor-file,cxx) #=== assembly file ============================================================= # make C / assembly interleaved output file with extension .lst # argument $1 = compiler type (c or cxx) define make-assembly-file $(info ++++ info: making assembly output file $(notdir $*.lst) \ in current working directory) $(compile-$1) \ -c -Wa,-a,-ad -fverbose-asm \ $($1.flags) \ $< > $(notdir $*.lst) endef %.lst:: %.c force $(call make-assembly-file,c) %.lst:: %.cc force $(call make-assembly-file,cxx) %.lst:: %.cpp force $(call make-assembly-file,cxx) ################################################################################ ### rules: installation targets ################################################ ################################################################################ #=== strip ===================================================================== # Stripping of installed binaries will only be done when variable 'stripflags' # is defined non-empty. No default definition is provided except for Windows # where the unstripped binaries are large, especially in the case of Mingw-w64. # Note: while stripping all symbols ('-s' or '--strip-all') is possible for # Linux and Windows, in the case of OSX only non-global symbols can be stripped # (option '-x' or '--discard-all'). # Make definition of strip command overridable so it can be defined in an # environment for cross-compilation. STRIP ?= strip # Commands in 'strip-executables' will be executed conditionally in the rule for # target 'install-executables'. strip-executables = cd "$(installpath)" && \ $(foreach v, $(executables), $(STRIP) $(stripflags) '$v';) #=== install =================================================================== # Install targets depend on successful exit status of target all because nothing # must be installed in case of a build error. # -p = preserve time stamps # -m = set permission mode (as in chmod) # -d = create all components of specified directories INSTALL = install INSTALL_PROGRAM := $(INSTALL) -p -m 644 INSTALL_DATA := $(INSTALL) -p -m 644 INSTALL_DIR := $(INSTALL) -m 755 -d # strip spaces from file names executables := $(strip $(executables)) datafiles := $(strip $(datafiles)) datadirs := $(strip $(datadirs)) # Do not make any install sub-target with empty variable definition because the # install program would exit with an error. install: $(if $(executables), install-executables) install: $(if $(datafiles), install-datafiles) install: $(if $(datadirs), install-datadirs) install-executables: all $(INSTALL_DIR) -v "$(installpath)" $(foreach v, $(executables), \ $(INSTALL_PROGRAM) '$v' "$(installpath)";) $(info ++++ info: executables of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) $(if $(stripflags), $(strip-executables),) install-datafiles: all $(INSTALL_DIR) -v "$(installpath)" $(foreach v, $(datafiles), \ $(INSTALL_DATA) '$(v)' "$(installpath)";) $(info ++++ info: data files of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) install-datadirs: all $(foreach v, $(datadirs), $(INSTALL_DIR) "$(installpath)/$v";) $(foreach v, $(datadirs), \ $(INSTALL_DATA) $(wildcard $v/*) "$(installpath)/$v";) $(info ++++ info: data directories of lib $(lib.name) installed \ from $(CURDIR) to $(installpath)) ################################################################################ ### rules: distribution targets ################################################ ################################################################################ # TODO # These targets are implemented in Makefile Template, but I have to figure out # how to do it under the not-so-strict conditions of Makefile.pdlibbuilder. # make source package dist: @echo "target dist not yet implemented" # make Debian source package dpkg-source: @echo "target dpkg-source not yet implemented" $(ORIGDIR): $(DISTDIR): ################################################################################ ### rules: clean targets ####################################################### ################################################################################ # delete build products from build tree clean: rm -f $(all.objects) rm -f $(classes.executables) $(lib.name).$(extension) $(shared.lib) rm -f *.pre *.lst # remove distribution directories and tarballs from build tree distclean: clean @echo "target distclean not yet implemented" ################################################################################ ### rules: submake targets ##################################################### ################################################################################ # Iterate over sub-makefiles or makefiles in other directories. # When 'continue-make=yes' is set, sub-makes will report 'true' to the parent # process regardless of their real exit status. This prevents the parent make # from being aborted by a sub-make error. Useful when you want to quickly find # out which sub-makes from a large set will succeed. ifeq ($(continue-make),yes) continue = || true endif # These targets will trigger sub-make processes for entries in 'makefiledirs' # and 'makefiles'. all alldebug install clean distclean dist dkpg-source: \ $(makefiledirs) $(makefiles) # this expands to identical rules for each entry in 'makefiledirs' $(makefiledirs): $(MAKE) --directory=$@ $(MAKECMDGOALS) $(continue) # this expands to identical rules for each entry in 'makefiles' $(makefiles): $(MAKE) --directory=$(dir $@) --makefile=$(notdir $@) $(MAKECMDGOALS) $(continue) ################################################################################ ### rules: convenience targets ################################################# ################################################################################ #=== show variables ============================================================ # Several 'function' macro's cause errors when expanded within a rule or without # proper arguments. Variables which are set with the define directive are only # shown by name for that reason. functions = \ add-class-source \ declare-class-target \ declare-class-executable-target \ declare-object-target \ link-class \ link-lib \ link-shared \ make-object-file \ make-preprocessor-file \ make-assembly-file # show variables from makefiles vars: $(info ++++ info: showing makefile variables:) $(foreach v,\ $(sort $(filter-out $(functions) functions, $(.VARIABLES))),\ $(if $(filter file, $(origin $v)),\ $(info variable $v = $($v)))) $(foreach v, $(functions), $(info 'function' name: $v)) @echo # show all variables allvars: $(info ++++ info: showing default, automatic and makefile variables:) $(foreach v, \ $(sort $(filter-out $(functions) functions, $(.VARIABLES))), \ $(info variable ($(origin $v)) $v = $($v))) $(foreach v, $(functions), $(info 'function' name: $v)) @echo #=== show dependencies ========================================================= # show generated prerequisites rules depend: $(info ++++ info: generated prerequisite rules) $(foreach v, $(classes), $(info $(declare-class-target))) $(foreach v, $(classes), $(info $(declare-class-executable-target))) $(foreach v, $(all.sources), $(info $(call declare-object-target, $v))) @echo #=== show help text ============================================================ # brief info about targets and paths ifdef mpdh mpdhinfo := $(mpdh) else mpdhinfo := m_pd.h was not found. Is Pd installed? endif help: @echo @echo " Main targets:" @echo " all: build executables (default target)" @echo " install: install all components of the library" @echo " vars: print makefile variables for troubleshooting" @echo " allvars: print all variables for troubleshooting" @echo " help: print this help text" @echo @echo " Pd API m_pd.h:" @echo " $(mpdhinfo)" @echo " You may specify your preferred Pd include directory as argument" @echo " to the make command, like 'PDINCLUDEDIR=path/to/pd/src'." @echo @echo " Path for installation of your libdir(s):" @echo " $(PDLIBDIR)" @echo " Alternatively you may specify your path for installation as argument" @echo " to the make command, like 'PDLIBDIR=path/to/pd-externals'." @echo @echo " Default paths are listed in the doc sections in Makefile.pdlibbuilder." @echo #=== platform test ============================================================= # This target can be used to test if the compiler for specified PLATFORM is # correctly defined and available. dumpmachine: @$(CC) -dumpmachine #=== dummy target ============================================================== coffee: @echo "Makefile.pdlibbuilder: Can not make coffee. Sorry." ################################################################################ ### end of rules sections ###################################################### ################################################################################ # for syntax highlighting in vim and github # vim: set filetype=make: MetaluNet-moonlib-550f1b9/_soundfile.c0000664002537200253720000005776315201114445020164 0ustar zmoelnigzmoelnig/* this file is an extract from d_soundfile.c, from pd master 0.49-0 */ /* Copyright (c) 1997-1999 Miller Puckette. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* this file contains, first, a collection of soundfile access routines, a sort of soundfile library. Second, the "soundfiler" object is defined which uses the routines to read or write soundfiles, synchronously, from garrays. These operations are not to be done in "real time" as they may have to wait for disk accesses (even the write routine.) Finally, the realtime objects readsf~ and writesf~ are defined which confine disk operations to a separate thread so that they can be used in real time. The readsf~ and writesf~ objects use Posix-like threads. */ #ifndef _WIN32 #include #endif #include #ifdef _WIN32 #include #endif #include #include #include #include #include #include #include "m_pd.h" #ifndef MAXSFCHANS #define MAXSFCHANS 64 #endif #ifdef _LARGEFILE64_SOURCE # define open open64 # define lseek lseek64 #define off_t __off64_t #endif /* Microsoft Visual Studio does not define these... arg */ #ifdef _MSC_VER #define off_t long #define O_CREAT _O_CREAT #define O_TRUNC _O_TRUNC #define O_WRONLY _O_WRONLY #endif /***************** soundfile header structures ************************/ typedef union _samplelong { t_sample f; long l; } t_sampleuint; #define FORMAT_WAVE 0 #define FORMAT_AIFF 1 #define FORMAT_NEXT 2 /* the NeXTStep sound header structure; can be big or little endian */ typedef struct _nextstep { char ns_fileid[4]; /* magic number '.snd' if file is big-endian */ uint32_t ns_onset; /* byte offset of first sample */ uint32_t ns_length; /* length of sound in bytes */ uint32_t ns_format; /* format; see below */ uint32_t ns_sr; /* sample rate */ uint32_t ns_nchans; /* number of channels */ char ns_info[4]; /* comment */ } t_nextstep; #define NS_FORMAT_LINEAR_16 3 #define NS_FORMAT_LINEAR_24 4 #define NS_FORMAT_FLOAT 6 #define SCALE (1./(1024. * 1024. * 1024. * 2.)) /* the WAVE header. All Wave files are little endian. We assume the "fmt" chunk comes first which is usually the case but perhaps not always; same for AIFF and the "COMM" chunk. */ typedef unsigned word; typedef unsigned long dword; typedef struct _wave { char w_fileid[4]; /* chunk id 'RIFF' */ uint32_t w_chunksize; /* chunk size */ char w_waveid[4]; /* wave chunk id 'WAVE' */ char w_fmtid[4]; /* format chunk id 'fmt ' */ uint32_t w_fmtchunksize; /* format chunk size */ uint16_t w_fmttag; /* format tag (WAV_INT etc) */ uint16_t w_nchannels; /* number of channels */ uint32_t w_samplespersec; /* sample rate in hz */ uint32_t w_navgbytespersec; /* average bytes per second */ uint16_t w_nblockalign; /* number of bytes per frame */ uint16_t w_nbitspersample; /* number of bits in a sample */ char w_datachunkid[4]; /* data chunk id 'data' */ uint32_t w_datachunksize; /* length of data chunk */ } t_wave; typedef struct _fmt /* format chunk */ { uint16_t f_fmttag; /* format tag, 1 for PCM */ uint16_t f_nchannels; /* number of channels */ uint32_t f_samplespersec; /* sample rate in hz */ uint32_t f_navgbytespersec; /* average bytes per second */ uint16_t f_nblockalign; /* number of bytes per frame */ uint16_t f_nbitspersample; /* number of bits in a sample */ } t_fmt; typedef struct _wavechunk /* ... and the last two items */ { char wc_id[4]; /* data chunk id, e.g., 'data' or 'fmt ' */ uint32_t wc_size; /* length of data chunk */ } t_wavechunk; #define WAV_INT 1 #define WAV_FLOAT 3 /* the AIFF header. I'm assuming AIFC is compatible but don't really know that. */ typedef struct _datachunk { char dc_id[4]; /* data chunk id 'SSND' */ uint32_t dc_size; /* length of data chunk */ uint32_t dc_offset; /* additional offset in bytes */ uint32_t dc_block; /* block size */ } t_datachunk; typedef struct _comm { uint16_t c_nchannels; /* number of channels */ uint16_t c_nframeshi; /* # of sample frames (hi) */ uint16_t c_nframeslo; /* # of sample frames (lo) */ uint16_t c_bitspersamp; /* bits per sample */ unsigned char c_samprate[10]; /* sample rate, 80-bit float! */ } t_comm; /* this version is more convenient for writing them out: */ typedef struct _aiff { char a_fileid[4]; /* chunk id 'FORM' */ uint32_t a_chunksize; /* chunk size */ char a_aiffid[4]; /* aiff chunk id 'AIFF' */ char a_fmtid[4]; /* format chunk id 'COMM' */ uint32_t a_fmtchunksize; /* format chunk size, 18 */ uint16_t a_nchannels; /* number of channels */ uint16_t a_nframeshi; /* # of sample frames (hi) */ uint16_t a_nframeslo; /* # of sample frames (lo) */ uint16_t a_bitspersamp; /* bits per sample */ unsigned char a_samprate[10]; /* sample rate, 80-bit float! */ } t_aiff; #define AIFFHDRSIZE 38 /* probably not what sizeof() gives */ #define AIFFPLUS (AIFFHDRSIZE + 16) /* header size including SSND chunk hdr */ #define WHDR1 sizeof(t_nextstep) #define WHDR2 (sizeof(t_wave) > WHDR1 ? sizeof (t_wave) : WHDR1) #define WRITEHDRSIZE (AIFFPLUS > WHDR2 ? AIFFPLUS : WHDR2) #define READHDRSIZE (16 > WHDR2 + 2 ? 16 : WHDR2 + 2) #define OBUFSIZE MAXPDSTRING /* assume MAXPDSTRING is bigger than headers */ /* this routine returns 1 if the high order byte comes at the lower address on our architecture (big-endianness.). It's 1 for Motorola, 0 for Intel: */ /* (from g_array.c) */ static int garray_ambigendian(void) { unsigned short s = 1; unsigned char c = *(char *)(&s); return (c==0); } /* byte swappers */ static uint32_t swap4(uint32_t n, int doit) { if (doit) return (((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24)); else return (n); } static uint16_t swap2(uint32_t n, int doit) { if (doit) return (((n & 0xff) << 8) | ((n & 0xff00) >> 8)); else return (n); } static void swapstring(char *foo, int doit) { if (doit) { char a = foo[0], b = foo[1], c = foo[2], d = foo[3]; foo[0] = d; foo[1] = c; foo[2] = b; foo[3] = a; } } /* read sample rate from an 80-bit AIFF-compatible number */ static double readaiffsamprate(char * shit, int swap) { unsigned long mantissa, last = 0; unsigned char exp; swapstring(shit+2, swap); mantissa = (unsigned long) *((unsigned long *)(shit+2)); exp = 30 - *(shit+1); while (exp--) { last = mantissa; mantissa >>= 1; } if (last & 0x00000001) mantissa++; return mantissa; } /* write a sample rate as an 80-bit AIFF-compatible number */ static void makeaiffsamprate(double sr, unsigned char *shit) { int exponent; double mantissa = frexp(sr, &exponent); unsigned long fixmantissa = ldexp(mantissa, 32); shit[0] = (exponent+16382)>>8; shit[1] = exponent+16382; shit[2] = fixmantissa >> 24; shit[3] = fixmantissa >> 16; shit[4] = fixmantissa >> 8; shit[5] = fixmantissa; shit[6] = shit[7] = shit[8] = shit[9] = 0; } /******************** soundfile access routines **********************/ typedef struct _soundfile_info { int samplerate; int channels; int bytespersample; int headersize; int bigendian; long bytelimit; } t_soundfile_info; static void outlet_soundfile_info(t_outlet *out, t_soundfile_info *info) { t_atom info_list[5]; SETFLOAT((t_atom *)info_list, (t_float)info->samplerate); SETFLOAT((t_atom *)info_list+1, (t_float)(info->headersize < 0 ? 0 : info->headersize)); SETFLOAT((t_atom *)info_list+2, (t_float)info->channels); SETFLOAT((t_atom *)info_list+3, (t_float)info->bytespersample); SETSYMBOL((t_atom *)info_list+4, gensym((info->bigendian ? "b" : "l"))); outlet_list(out, &s_list, 5, (t_atom *)info_list); } /* This routine opens a file, looks for either a nextstep or "wave" header, * seeks to end of it, and fills in bytes per sample and number of channels. * Only 2- and 3-byte fixed-point samples and 4-byte floating point samples * are supported. If "headersize" is nonzero, the * caller should supply the number of channels, endinanness, and bytes per * sample; the header is ignored. Otherwise, the routine tries to read the * header and fill in the properties. */ static int open_soundfile_via_fd(int fd, t_soundfile_info *p_info, long skipframes) { int nchannels, bigendian, bytespersamp, samprate, swap; int headersize = 0; long sysrtn, bytelimit = 0x7fffffff; errno = 0; if (p_info->headersize >= 0) /* header detection overridden */ { headersize = p_info->headersize; bigendian = p_info->bigendian; nchannels = p_info->channels; bytespersamp = p_info->bytespersample; bytelimit = p_info->bytelimit; samprate = p_info->samplerate; } else { union { char b_c[OBUFSIZE]; t_fmt b_fmt; t_nextstep b_nextstep; t_wavechunk b_wavechunk; t_datachunk b_datachunk; t_comm b_commchunk; } buf; long bytesread = read(fd, buf.b_c, READHDRSIZE); int format; if (bytesread < 4) goto badheader; if (!strncmp(buf.b_c, ".snd", 4)) format = FORMAT_NEXT, bigendian = 1; else if (!strncmp(buf.b_c, "dns.", 4)) format = FORMAT_NEXT, bigendian = 0; else if (!strncmp(buf.b_c, "RIFF", 4)) { if (bytesread < 12 || strncmp(buf.b_c + 8, "WAVE", 4)) goto badheader; format = FORMAT_WAVE, bigendian = 0; } else if (!strncmp(buf.b_c, "FORM", 4)) { if (bytesread < 12 || strncmp(buf.b_c + 8, "AIFF", 4)) goto badheader; format = FORMAT_AIFF, bigendian = 1; } else goto badheader; swap = (bigendian != garray_ambigendian()); if (format == FORMAT_NEXT) /* nextstep header */ { t_nextstep *nsbuf = &buf.b_nextstep; if (bytesread < (int)sizeof(t_nextstep)) goto badheader; nchannels = swap4(nsbuf->ns_nchans, swap); format = swap4(nsbuf->ns_format, swap); headersize = swap4(nsbuf->ns_onset, swap); if (format == NS_FORMAT_LINEAR_16) bytespersamp = 2; else if (format == NS_FORMAT_LINEAR_24) bytespersamp = 3; else if (format == NS_FORMAT_FLOAT) bytespersamp = 4; else goto badheader; bytelimit = 0x7fffffff; samprate = swap4(nsbuf->ns_sr, swap); } else if (format == FORMAT_WAVE) /* wave header */ { t_wavechunk *wavechunk = &buf.b_wavechunk; /* This is awful. You have to skip over chunks, except that if one happens to be a "fmt" chunk, you want to find out the format from that one. The case where the "fmt" chunk comes after the audio isn't handled. */ headersize = 12; if (bytesread < 20) goto badheader; /* First we guess a number of channels, etc., in case there's no "fmt" chunk to follow. */ nchannels = 1; bytespersamp = 2; samprate = 44100; /* copy the first chunk header to beginnning of buffer. */ memcpy(buf.b_c, buf.b_c + headersize, sizeof(t_wavechunk)); /* post("chunk %c %c %c %c", ((t_wavechunk *)buf)->wc_id[0], ((t_wavechunk *)buf)->wc_id[1], ((t_wavechunk *)buf)->wc_id[2], ((t_wavechunk *)buf)->wc_id[3]); */ /* read chunks in loop until we get to the data chunk */ while (strncmp(wavechunk->wc_id, "data", 4)) { long chunksize = swap4(wavechunk->wc_size, swap), seekto = headersize + chunksize + 8, seekout; if (seekto & 1) /* pad up to even number of bytes */ seekto++; if (!strncmp(wavechunk->wc_id, "fmt ", 4)) { long commblockonset = headersize + 8; seekout = (long)lseek(fd, commblockonset, SEEK_SET); if (seekout != commblockonset) goto badheader; if (read(fd, buf.b_c, sizeof(t_fmt)) < (int) sizeof(t_fmt)) goto badheader; nchannels = swap2(buf.b_fmt.f_nchannels, swap); format = swap2(buf.b_fmt.f_nbitspersample, swap); if (format == 16) bytespersamp = 2; else if (format == 24) bytespersamp = 3; else if (format == 32) bytespersamp = 4; else goto badheader; samprate = swap4(buf.b_fmt.f_samplespersec, swap); } seekout = (long)lseek(fd, seekto, SEEK_SET); if (seekout != seekto) goto badheader; if (read(fd, buf.b_c, sizeof(t_wavechunk)) < (int) sizeof(t_wavechunk)) goto badheader; /* post("new chunk %c %c %c %c at %d", wavechunk->wc_id[0], wavechunk->wc_id[1], wavechunk->wc_id[2], wavechunk->wc_id[3], seekto); */ headersize = (int)seekto; } bytelimit = swap4(wavechunk->wc_size, swap); headersize += 8; } else { /* AIFF. same as WAVE; actually predates it. Disgusting. */ t_datachunk *datachunk; headersize = 12; if (bytesread < 20) goto badheader; /* First we guess a number of channels, etc., in case there's no COMM block to follow. */ nchannels = 1; bytespersamp = 2; samprate = 44100; /* copy the first chunk header to beginnning of buffer. */ memcpy(buf.b_c, buf.b_c + headersize, sizeof(t_datachunk)); /* read chunks in loop until we get to the data chunk */ datachunk = &buf.b_datachunk; while (strncmp(datachunk->dc_id, "SSND", 4)) { long chunksize = swap4(datachunk->dc_size, swap), seekto = headersize + chunksize + 8, seekout; if (seekto & 1) /* pad up to even number of bytes */ seekto++; /* post("chunk %c %c %c %c seek %d", datachunk->dc_id[0], datachunk->dc_id[1], datachunk->dc_id[2], datachunk->dc_id[3], seekto); */ if (!strncmp(datachunk->dc_id, "COMM", 4)) { long commblockonset = headersize + 8; t_comm *commchunk; seekout = (long)lseek(fd, commblockonset, SEEK_SET); if (seekout != commblockonset) goto badheader; if (read(fd, buf.b_c, sizeof(t_comm)) < (int) sizeof(t_comm)) goto badheader; commchunk = &buf.b_commchunk; nchannels = swap2(commchunk->c_nchannels, swap); format = swap2(commchunk->c_bitspersamp, swap); if (format == 16) bytespersamp = 2; else if (format == 24) bytespersamp = 3; else goto badheader; samprate = readaiffsamprate((char *)commchunk->c_samprate, swap); } seekout = (long)lseek(fd, seekto, SEEK_SET); if (seekout != seekto) goto badheader; if (read(fd, buf.b_c, sizeof(t_datachunk)) < (int) sizeof(t_datachunk)) goto badheader; headersize = (int)seekto; } bytelimit = swap4(datachunk->dc_size, swap) - 8; headersize += sizeof(t_datachunk); } } /* seek past header and any sample frames to skip */ sysrtn = (long)lseek(fd, ((off_t)nchannels) * bytespersamp * skipframes + headersize, 0); if (sysrtn != nchannels * bytespersamp * skipframes + headersize) return (-1); bytelimit -= nchannels * bytespersamp * skipframes; if (bytelimit < 0) bytelimit = 0; /* copy sample format back to caller */ p_info->headersize = headersize; p_info->bigendian = bigendian; p_info->channels = nchannels; p_info->bytespersample = bytespersamp; p_info->bytelimit = bytelimit; p_info->samplerate = samprate; return (fd); badheader: /* the header wasn't recognized. We're threadable here so let's not print out the error... */ errno = EIO; return (-1); } /* open a soundfile, using open_via_path(). This is used by readsf~ in a not-perfectly-threadsafe way. LATER replace with a thread-hardened version of open_soundfile_via_canvas() */ static int open_soundfile(const char *dirname, const char *filename, t_soundfile_info *p_info, long skipframes) { char buf[OBUFSIZE], *bufptr; int fd, sf_fd; fd = open_via_path(dirname, filename, "", buf, &bufptr, MAXPDSTRING, 1); if (fd < 0) return (-1); sf_fd = open_soundfile_via_fd(fd, p_info, skipframes); if (sf_fd < 0) sys_close(fd); return (sf_fd); } /* open a soundfile, using open_via_canvas(). This is used by readsf~ in a not-perfectly-threadsafe way. LATER replace with a thread-hardened version of open_soundfile_via_canvas() */ static int open_soundfile_via_canvas(t_canvas *canvas, const char *filename, t_soundfile_info *p_info, long skipframes) { char buf[OBUFSIZE], *bufptr; int fd, sf_fd; fd = canvas_open(canvas, filename, "", buf, &bufptr, MAXPDSTRING, 1); if (fd < 0) return (-1); sf_fd = open_soundfile_via_fd(fd, p_info, skipframes); if (sf_fd < 0) sys_close(fd); return (sf_fd); } static void soundfile_xferin_sample(int sfchannels, int nvecs, t_sample **vecs, long itemsread, unsigned char *buf, int nitems, int bytespersamp, int bigendian) { int i, j; unsigned char *sp, *sp2; t_sample *fp; int nchannels = (sfchannels < nvecs ? sfchannels : nvecs); int bytesperframe = bytespersamp * sfchannels; for (i = 0, sp = buf; i < nchannels; i++, sp += bytespersamp) { if (bytespersamp == 2) { if (bigendian) { for (j = 0, sp2 = sp, fp=vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, fp++) *fp = SCALE * ((sp2[0] << 24) | (sp2[1] << 16)); } else { for (j = 0, sp2 = sp, fp=vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, fp++) *fp = SCALE * ((sp2[1] << 24) | (sp2[0] << 16)); } } else if (bytespersamp == 3) { if (bigendian) { for (j = 0, sp2 = sp, fp=vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, fp++) *fp = SCALE * ((sp2[0] << 24) | (sp2[1] << 16) | (sp2[2] << 8)); } else { for (j = 0, sp2 = sp, fp=vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, fp++) *fp = SCALE * ((sp2[2] << 24) | (sp2[1] << 16) | (sp2[0] << 8)); } } else if (bytespersamp == 4) { if (bigendian) { for (j = 0, sp2 = sp, fp=vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, fp++) *(long *)fp = ((sp2[0] << 24) | (sp2[1] << 16) | (sp2[2] << 8) | sp2[3]); } else { for (j = 0, sp2 = sp, fp=vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, fp++) *(long *)fp = ((sp2[3] << 24) | (sp2[2] << 16) | (sp2[1] << 8) | sp2[0]); } } } /* zero out other outputs */ for (i = sfchannels; i < nvecs; i++) for (j = nitems, fp = vecs[i]; j--; ) *fp++ = 0; } static void soundfile_xferin_words(int sfchannels, int nvecs, t_word **vecs, long itemsread, unsigned char *buf, long nitems, int bytespersamp, int bigendian) { int i; long j; unsigned char *sp, *sp2; t_word *wp; int nchannels = (sfchannels < nvecs ? sfchannels : nvecs); int bytesperframe = bytespersamp * sfchannels; union { long long32; float float32; } word32; for (i = 0, sp = buf; i < nchannels; i++, sp += bytespersamp) { if (bytespersamp == 2) { if (bigendian) { for (j = 0, sp2 = sp, wp = vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, wp++) wp->w_float = SCALE * ((sp2[0] << 24) | (sp2[1] << 16)); } else { for (j = 0, sp2 = sp, wp = vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, wp++) wp->w_float = SCALE * ((sp2[1] << 24) | (sp2[0] << 16)); } } else if (bytespersamp == 3) { if (bigendian) { for (j = 0, sp2 = sp, wp = vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, wp++) wp->w_float = SCALE * ((sp2[0] << 24) | (sp2[1] << 16) | (sp2[2] << 8)); } else { for (j = 0, sp2 = sp, wp = vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, wp++) wp->w_float = SCALE * ((sp2[2] << 24) | (sp2[1] << 16) | (sp2[0] << 8)); } } else if (bytespersamp == 4) { if (bigendian) { for (j = 0, sp2 = sp, wp = vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, wp++) { word32.long32 = (sp2[0] << 24) | (sp2[1] << 16) | (sp2[2] << 8) | sp2[3]; wp->w_float = word32.float32; } } else { for (j = 0, sp2 = sp, wp = vecs[i] + itemsread; j < nitems; j++, sp2 += bytesperframe, wp++) { word32.long32 = (sp2[3] << 24) | (sp2[2] << 16) | (sp2[1] << 8) | sp2[0]; wp->w_float = word32.float32; } } } } /* zero out other outputs */ for (i = sfchannels; i < nvecs; i++) for (j = nitems, wp = vecs[i]; j--; ) (wp++)->w_float = 0; } MetaluNet-moonlib-550f1b9/f2char.c0000664002537200253720000000252615201114445017165 0ustar zmoelnigzmoelnig/* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "m_pd.h" typedef struct _f2char { t_object x_obj; } t_f2char; t_class *f2char_class; void f2char_setup(void); static void f2char_float(t_f2char *x,t_floatarg f) { char s[2]= {0}; s[0]=(char)f; outlet_symbol(x->x_obj.ob_outlet,gensym(s)); } static void *f2char_new(void) { t_f2char *x = (t_f2char *)pd_new(f2char_class); outlet_new(&x->x_obj,&s_symbol); return (void *)x; } void f2char_setup(void) { f2char_class = class_new(gensym("f2char"),(t_newmethod)f2char_new, 0, sizeof(t_f2char), 0, 0); class_addfloat(f2char_class, f2char_float); } MetaluNet-moonlib-550f1b9/tabreadl-help.pd0000664002537200253720000000241715201114445020704 0ustar zmoelnigzmoelnig#N canvas 0 31 650 395 10; #X obj 10 11 tabreadl; #X text 22 332 (c) Antoine Rousseau 2004; #X floatatom 15 173 0 0 0 0 - - -; #X floatatom 15 278 0 0 0 0 - - -; #N canvas 0 0 450 300 (subpatch) 0; #X array \$0-array 10 float 0; #X coords 0 0 10 10 250 200 1; #X restore 362 139 graph; #X text 60 276 output = array99[index]; #X text 34 50 click here to initialize; #X text 159 236 creation argument; #X text 155 254 gives array name; #X text 137 204 change array name; #X msg 25 204 set \$0-array99; #X msg 33 65 resize 10 \, bounds 0 0 10 10 \, xlabel -0.5 0 1 2 3 4 5 6 7 8 9 10 \, ylabel -1 0 1 2 3 4 5 6 7 8 9 10 \, 0 1 4 2 8 5 6 1 4 2 8; #X obj 34 139 s \$0-array; #X text 110 8 - linear interpolating read from a table; #X text 46 174 index(float); #X obj 15 245 tabreadl \$0-array; #N canvas 502 150 494 344 META 0; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Antoine Rousseau; #X text 12 125 HELP_PATCH_AUTHORS Antoine Rousseau. "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 85 OUTLET_0 float; #X text 12 45 DESCRIPTION linear interpolating read from a table; #X text 12 5 KEYWORDS control array; #X text 12 65 INLET_0 float set; #X restore 592 367 pd META; #X connect 2 0 15 0; #X connect 10 0 15 0; #X connect 11 0 12 0; #X connect 15 0 3 0; MetaluNet-moonlib-550f1b9/f2s.c0000664002537200253720000000517015201114445016510 0ustar zmoelnigzmoelnig/* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) #define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) static t_class *f2s_class; typedef struct _f2s { t_object x_ob; t_float x_f; int x_type; /*0: p/n/µ/m/./k/M/G with n digits */ int x_n; } t_f2s; static void f2s_bang(t_f2s *x) { char buf[256],delim; float f=x->x_f,fnorm; int ilogf,ilogf3,fh,fl=0,subdigits; if(!f) { sprintf(buf,"0"); goto end; } ilogf=(int)floor(log10(fabs(f))); ilogf3=(int)floor(log10(fabs(f))/3); subdigits=2-ilogf+ilogf3*3; fnorm=f*pow(10,-ilogf3*3); fh=(int)(fnorm); fl=(int)(fabs((fnorm-fh)*pow(10,subdigits))+0.00001); switch(ilogf3){ case -4: delim='p'; break; case -3: delim='n'; break; case -2: delim='u'; break; case -1: delim='m'; break; case 0: delim=subdigits?'.':0; break; case 1: delim='k'; break; case 2: delim='M'; break; case 3: delim='G'; break; case 4: delim='T'; break; default:delim='?'; } if(subdigits) sprintf(buf,"%i%c%0*i",fh,delim,subdigits,fl); else { if(delim=='m') sprintf(buf,"%s%03i",fh<0?"-.":".",abs(fh)); else sprintf(buf,"%i%c",fh,delim); } end: outlet_symbol(((t_object *)x)->ob_outlet,gensym(buf)); } static void f2s_float(t_f2s *x,t_float val) { x->x_f=val; f2s_bang(x); } static void *f2s_new( t_symbol *s, int argc, t_atom *argv) { t_atom *at; t_f2s *x=(t_f2s*)pd_new(f2s_class); x->x_f=0; x->x_type=0; x->x_n=3; outlet_new(&x->x_ob, &s_symbol); if(argc&&IS_A_FLOAT(argv,0)) { x->x_n=atom_getfloat(argv++); argc--; } return (void *)x; } void f2s_setup(void) { f2s_class = class_new(gensym("f2s"),(t_newmethod)f2s_new, 0, sizeof(t_f2s),0,A_GIMME ,0); class_addfloat(f2s_class, (t_method)f2s_float); class_addbang(f2s_class, (t_method)f2s_bang); class_sethelpsymbol(f2s_class, gensym("moonlibs/f2s")); } MetaluNet-moonlib-550f1b9/lcdbitmap.c0000664002537200253720000003554715201114445017770 0ustar zmoelnigzmoelnig/* Copyright (C) 2002 Antoine Rousseau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "g_canvas.h" #ifdef NT #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif /* ------------------------ lcdbitmap ----------------------------- */ #define BACKGROUND "-fill grey" #define BACKGROUNDCOLOR "grey" #define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER) #define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) #define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) //#define DEFAULTSIZE 3 //#define DEFAULTWIDTH 366 //#define DEFAULTHEIGHT 96 //#define DEFAULTWIDTH 244 //#define DEFAULTHEIGHT 64 #define DEFAULTWIDTH 122 #define DEFAULTHEIGHT 32 #define DEFAULTCOLOR "black" #define BLACKCOLOR "black" #define WHITECOLOR "white" #define SELBLACKCOLOR "gold" #define SELWHITECOLOR "yellow" static t_class *lcdbitmap_class; #define te_xpos te_xpix #define te_ypos te_ypix typedef struct _lcdbitmap { t_object x_obj; t_glist * x_glist; int x_width; int x_height; int x_x; int x_page; int x_side; char x_bitmap[122][32]; char *x_bitmapstr; char x_bitstr[65536]; t_int x_localimage; //localimage "img%x" done } t_lcdbitmap; /* widget helper functions */ static char *Hurlo="\ #define BM_width 122\\n\ #define BM_height 32\\n\ static unsigned char BM_bits[] = {\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0xc0, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x0e, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x80, 0x07, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x1c, 0x86, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x00,\n\ 0x00, 0x8f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x86, 0x0f, 0x00,\n\ 0x80, 0x07, 0x00, 0x00, 0x00, 0x9f, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0xfc, 0xc7, 0x0f, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0xff, 0x0d, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc7, 0x0f, 0x00, 0xc0, 0x0f, 0x00, 0x00,\n\ 0x00, 0xfe, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc6, 0x0e, 0x00,\n\ 0xc0, 0x1e, 0x00, 0x03, 0x00, 0xfe, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x0c, 0xc6, 0x0e, 0x00, 0xc0, 0x1e, 0x80, 0x07, 0x00, 0x6e, 0x0c, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x0e, 0x00, 0xc0, 0x1e, 0xc0, 0x8f,\n\ 0x01, 0x6e, 0x0e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x06, 0x00,\n\ 0xc0, 0x1c, 0xe0, 0xcf, 0x00, 0x0e, 0x0e, 0x00, 0x1c, 0x20, 0x00, 0x00,\n\ 0x00, 0xc7, 0x07, 0x00, 0xc0, 0x1c, 0xf0, 0xff, 0x00, 0x0c, 0x0e, 0x00,\n\ 0x1c, 0x70, 0x00, 0x00, 0x00, 0xc7, 0x07, 0xc0, 0xc0, 0x1c, 0xf8, 0x7d,\n\ 0x00, 0x0c, 0x06, 0x00, 0x1c, 0xf8, 0x00, 0x00, 0x00, 0xc7, 0x03, 0xc0,\n\ 0xc0, 0x1c, 0x78, 0x3c, 0x00, 0x0c, 0x06, 0xc0, 0x1c, 0x70, 0x00, 0x00,\n\ 0xe0, 0xff, 0x01, 0xcc, 0x9f, 0x1c, 0x3c, 0x70, 0x00, 0x1c, 0x07, 0xf8,\n\ 0xfc, 0x23, 0xe0, 0x01, 0x60, 0xc3, 0x70, 0xcc, 0x9f, 0x0d, 0x1c, 0x70,\n\ 0x80, 0x1c, 0x67, 0xfe, 0xfc, 0x03, 0xf0, 0x03, 0x00, 0xc3, 0x70, 0x8c,\n\ 0x91, 0x05, 0x1c, 0x60, 0xc0, 0x1d, 0xf7, 0xff, 0x0c, 0x30, 0x78, 0x03,\n\ 0x80, 0xc3, 0x70, 0x8c, 0x19, 0x07, 0x1c, 0x60, 0xe0, 0x1d, 0xf7, 0xe7,\n\ 0x0c, 0x30, 0x3c, 0x00, 0x80, 0xc3, 0x70, 0x8c, 0x19, 0x03, 0x0c, 0x70,\n\ 0x60, 0x1c, 0xf3, 0xc3, 0x0c, 0x30, 0x1c, 0x00, 0x9c, 0xc3, 0x70, 0xcc,\n\ 0x1c, 0xc7, 0x1d, 0x70, 0x67, 0x1c, 0xe3, 0xc1, 0x1c, 0x30, 0x0e, 0x00,\n\ 0x8e, 0xc3, 0x71, 0xcc, 0x9c, 0xc5, 0x39, 0x78, 0xe7, 0x1e, 0xf7, 0xc3,\n\ 0x1d, 0xb8, 0x1f, 0x00, 0x86, 0xc3, 0x73, 0xfe, 0xfc, 0x1d, 0x78, 0x3c,\n\ 0xc0, 0x1f, 0xbf, 0xef, 0xfd, 0xff, 0xf9, 0x01, 0xce, 0x81, 0xff, 0xff,\n\ 0xfc, 0x1c, 0xf0, 0x1f, 0xc0, 0x07, 0x1e, 0xff, 0xff, 0xef, 0xf0, 0x01,\n\ 0xfc, 0x01, 0xef, 0xcf, 0x78, 0x18, 0xf0, 0x1f, 0x80, 0x03, 0x0e, 0xfc,\n\ 0xff, 0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };"; static void draw_inlets(t_lcdbitmap *x, t_glist *glist, int firsttime, int nin, int nout) { int n = nout; int nplus, i; int xpos=text_xpix(&x->x_obj, glist); int ypos=text_ypix(&x->x_obj, glist); nplus = (n == 1 ? 1 : n-1); for (i = 0; i < n; i++) { int onset = xpos + (x->x_width - IOWIDTH) * i / nplus; if (firsttime) sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n", glist_getcanvas(glist), onset, ypos + x->x_height - 1, onset + IOWIDTH, ypos + x->x_height, x, i); else sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n", glist_getcanvas(glist), x, i, onset, ypos + x->x_height - 1, onset + IOWIDTH, ypos + x->x_height); } n = nin; nplus = (n == 1 ? 1 : n-1); for (i = 0; i < n; i++) { int onset = xpos + (x->x_width - IOWIDTH) * i / nplus; if (firsttime) sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n", glist_getcanvas(glist), onset, ypos, onset + IOWIDTH, ypos + 1, x, i); else sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n", glist_getcanvas(glist), x, i, onset, ypos, onset + IOWIDTH, ypos + 1); } } void lcdbitmap_drawme(t_lcdbitmap *x, t_glist *glist, int firsttime) { int i,j; float x1,y1,x2,y2; int xi1,yi1,xi2,yi2; char *color; int xpos=text_xpix(&x->x_obj, glist); int ypos=text_ypix(&x->x_obj, glist); if (firsttime) { sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xS "BACKGROUND"\n", glist_getcanvas(glist), xpos, ypos, xpos + x->x_width, ypos + x->x_height, x); } else { sys_vgui(".x%x.c coords %xS %d %d %d %d\n", glist_getcanvas(glist), x, xpos, ypos, xpos + x->x_width, ypos + x->x_height); } if (firsttime) { if(!x->x_localimage) { sys_vgui("image create bitmap img%x\n",x); sys_vgui("image create bitmap imgnull\n",x); x->x_localimage=1; } sys_vgui("img%x configure -data \"%s\"\n",x,x->x_bitstr); //post("img%x configure -data \" %s \" \n",x,x->x_bitstr); /*char teststr[65536]; sprintf(teststr,"img%x configure -data \"%s\" \n",x,x->x_bitstr); //fprintf(stderr,"%s\n",teststr); sys_vgui(teststr); //post("%s",Hurlo);*/ sys_vgui(".x%x.c create image %d %d -image img%x -tags %xI\n", glist_getcanvas(glist),xpos + x->x_width/2,ypos+ x->x_height/2,x,x); } else { sys_vgui(".x%x.c coords %xI %d %d\n", glist_getcanvas(glist),x,xpos + x->x_width/2 , ypos + x->x_height/2); } draw_inlets(x, glist, firsttime, 1,1); } void lcdbitmap_erase(t_lcdbitmap* x,t_glist* glist) { int n,i,j; t_canvas *canvas=glist_getcanvas(glist); sys_vgui(".x%x.c delete %xS\n",canvas, x); sys_vgui(".x%x.c delete %xI\n",canvas,x); n = 1; while (n--) { sys_vgui(".x%x.c delete %xi%d\n",canvas,x,n); } n = 1; while (n--) { sys_vgui(".x%x.c delete %xo%d\n",canvas,x,n); } } /* ------------------------ lcdbitmap widgetbehaviour----------------------------- */ static void lcdbitmap_getrect(t_gobj *z, t_glist *glist, int *xp1, int *yp1, int *xp2, int *yp2) { t_lcdbitmap *x = (t_lcdbitmap *)z; int width, height; t_lcdbitmap* s = (t_lcdbitmap*)z; width = s->x_width; height = s->x_height; *xp1 = text_xpix(&x->x_obj, glist); *yp1 = text_ypix(&x->x_obj, glist); *xp2 = *xp1 + width; *yp2 = *yp1 + height; } static void lcdbitmap_displace(t_gobj *z, t_glist *glist, int dx, int dy) { t_lcdbitmap *x = (t_lcdbitmap *)z; x->x_obj.te_xpos += dx; x->x_obj.te_ypos += dy; lcdbitmap_drawme(x, glist, 0); canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x); } static void lcdbitmap_select(t_gobj *z, t_glist *glist, int state) { t_lcdbitmap *x = (t_lcdbitmap *)z; /* sys_vgui(".x%x.c itemconfigure %xS -fill %s\n", glist, x, (state? "blue" : BACKGROUNDCOLOR));*/ } static void lcdbitmap_activate(t_gobj *z, t_glist *glist, int state) { /* t_text *x = (t_text *)z; t_rtext *y = glist_findrtext(glist, x); if (z->g_pd != gatom_class) rtext_activate(y, state);*/ } static void lcdbitmap_delete(t_gobj *z, t_glist *glist) { t_text *x = (t_text *)z; canvas_deletelinesfor(glist, x); } static void lcdbitmap_vis(t_gobj *z, t_glist *glist, int vis) { t_lcdbitmap* s = (t_lcdbitmap*)z; if (vis) lcdbitmap_drawme(s, glist, 1); else lcdbitmap_erase(s,glist); } static void lcdbitmap_save(t_gobj *z, t_binbuf *b) { t_lcdbitmap *x = (t_lcdbitmap *)z; binbuf_addv(b, "ssiisii", gensym("#X"),gensym("obj"), (t_int)x->x_obj.te_xpos, (t_int)x->x_obj.te_ypos, gensym("lcdbitmap"),x->x_width,x->x_height); binbuf_addv(b, ";"); } void lcdbitmap_draw_byte(t_lcdbitmap *x,int i,int line) { t_canvas *canvas=glist_getcanvas(x->x_glist); char *color; int j; /*if(glist_isvisible(x->x_glist)) for(j=0;j<8;j++){ color=((x->x_bitmap[i][line])&(1<x_bitstr; // xs[xx],ys:bitstr u,v:real_bits i,j[jj]:lcd s+=sprintf(s,"\ #define BM_width 122\\n\ #define BM_height 32\\n\ static unsigned char BM_bits[] = {\n"); for(ys=0;ysx_bitmap[i][j]>>jj) & 1) << /*(7-xx)*/xx) ; } //bytes_lcd[i]=tmp; s+=sprintf(s," 0x%.2x,",tmp); } //s+=sprintf(s,"\n"); } s+=sprintf(s," };"); if(glist_isvisible(x->x_glist)) { //sys_vgui("img%x blank\n",x); //sys_vgui("img%x configure -data \n",x); sys_vgui("img%x configure -data \"%s\"\n",x,x->x_bitstr); //post("img%x configure -data \"%s\"\n",x,x->x_bitstr); sys_vgui(".x%x.c itemconfigure %xI -image imgnull\n", glist_getcanvas(x->x_glist),x); sys_vgui(".x%x.c itemconfigure %xI -image img%x\n", glist_getcanvas(x->x_glist),x,x); } } void lcdbitmap_float(t_lcdbitmap *x,t_floatarg fbyte) { int i,j=x->x_page,byte=(int)fbyte; if(x->x_x>61) return; i=x->x_x+61*x->x_side; x->x_bitmap[i][j]=byte; //lcdbitmap_draw_byte(x,i,j); x->x_x=x->x_x+1; } void lcdbitmap_locate(t_lcdbitmap *x,t_floatarg side,t_floatarg page,t_floatarg column) { if( (side<0)||(side>1)) post("lcdbitmap_locate ERROR: side=%d",side); else x->x_side=(int)side; if( (page<0)||(page>3)) post("lcdbitmap_locate ERROR: page=%d",page); else x->x_page=(int)page; if( (column<0)||(column>61)) post("lcdbitmap_locate ERROR: column=%d",column); else x->x_x=(int)column; } static void lcdbitmap_click(t_lcdbitmap *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { /* int note; int x0=text_xpix(&x->x_obj, x->x_glist); int y0=text_ypix(&x->x_obj, x->x_glist); note=get_touched_note( (xpos-x0)/x->x_width, (ypos-y0)/x->x_height); if(note>=0) lcdbitmap_set(x,note,!x->x_notes[note]);*/ } static int lcdbitmap_newclick(t_gobj *z, struct _glist *glist, int xpix, int ypix, int shift, int alt, int dbl, int doit) { t_lcdbitmap* x = (t_lcdbitmap *)z; if(doit) { lcdbitmap_click( x, (t_floatarg)xpix, (t_floatarg)ypix, (t_floatarg)shift, 0, (t_floatarg)alt); } return (1); } void lcdbitmap_size(t_lcdbitmap* x,t_floatarg w,t_floatarg h) { x->x_width = w; x->x_height = h; if(glist_isvisible(x->x_glist)) lcdbitmap_drawme(x, x->x_glist, 0); } t_widgetbehavior lcdbitmap_widgetbehavior; static void lcdbitmap_setwidget(void) { lcdbitmap_widgetbehavior.w_getrectfn = lcdbitmap_getrect; lcdbitmap_widgetbehavior.w_displacefn = lcdbitmap_displace; lcdbitmap_widgetbehavior.w_selectfn = lcdbitmap_select; lcdbitmap_widgetbehavior.w_activatefn = lcdbitmap_activate; lcdbitmap_widgetbehavior.w_deletefn = lcdbitmap_delete; lcdbitmap_widgetbehavior.w_visfn = lcdbitmap_vis; lcdbitmap_widgetbehavior.w_clickfn = lcdbitmap_newclick; //lcdbitmap_widgetbehavior.w_propertiesfn = NULL; //lcdbitmap_widgetbehavior.w_savefn = lcdbitmap_save; } static void *lcdbitmap_new(t_symbol *s, int argc, t_atom *argv) { int i,j,err=0; t_lcdbitmap *x = (t_lcdbitmap *)pd_new(lcdbitmap_class); x->x_glist = (t_glist*) canvas_getcurrent(); x->x_width = DEFAULTWIDTH; x->x_height = DEFAULTHEIGHT; //outlet_new(&x->x_obj, &s_float); x->x_side=0; x->x_page=0; x->x_x=0; for(j=0;j<32;j++) for(i=0;i<122;i++) x->x_bitmap[i][j]=0; //x->x_bitstr=strdup(Hurlo); strcpy(x->x_bitstr,Hurlo); if((argc>1)&&IS_A_FLOAT(argv,0)&&IS_A_FLOAT(argv,1)) { if(atom_getfloat(&argv[0])) x->x_width = atom_getfloat(&argv[0]); if(atom_getfloat(&argv[1])) x->x_height = atom_getfloat(&argv[1]); } return (x); } void lcdbitmap_setup(void) { post("lcdbitmap_setup"); lcdbitmap_class = class_new(gensym("lcdbitmap"), (t_newmethod)lcdbitmap_new, 0, sizeof(t_lcdbitmap),0, A_GIMME,0); class_addfloat(lcdbitmap_class,lcdbitmap_float); class_addbang(lcdbitmap_class,lcdbitmap_bang); class_addmethod(lcdbitmap_class, (t_method)lcdbitmap_locate, gensym("locate"), A_FLOAT, A_FLOAT, A_FLOAT,0); class_addmethod(lcdbitmap_class, (t_method)lcdbitmap_click, gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); class_addmethod(lcdbitmap_class, (t_method)lcdbitmap_size, gensym("size"), A_FLOAT, A_FLOAT, 0); lcdbitmap_setwidget(); class_setwidget(lcdbitmap_class,&lcdbitmap_widgetbehavior); //class_setsavefn(lcdbitmap_class, lcdbitmap_save); class_sethelpsymbol(lcdbitmap_class, gensym("moonlibs/lcdbitmap")); } MetaluNet-moonlib-550f1b9/s2f-help.pd0000664002537200253720000000173515201114445017622 0ustar zmoelnigzmoelnig#N canvas 1 82 492 266 10; #X obj 0 0 cnv 8 100 60 empty empty s2f 10 20 1 18 -262144 -1109 0 ; #X text 1 233 (c) Moonix: Antoine Rousseau 2003; #X text 129 8 symbol to float converter; #X obj 197 168 s2f; #X floatatom 197 193 0 0 0 0 - - -; #X symbolatom 197 142 0 0 0 0 - - -; #X msg 19 82 symbol 0.0003125foo; #X msg 146 82 symbol 54.123e-3bar; #X msg 356 81 13.25; #N canvas 380 146 490 344 META 0; #X text 12 25 LICENSE GPL v2; #X text 12 65 INLET_0 symbol; #X text 12 105 AUTHOR Antoine Rousseau; #X text 12 125 HELP_PATCH_AUTHORS Antoine Rousseau. "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 5 KEYWORDS control conversion symbol_op; #X text 12 45 DESCRIPTION symbol to float converter; #X text 12 85 OUTLET_0 float; #X restore 431 233 pd META; #X obj 356 101 makefilename %s; #X msg 276 82 symbol 0x80; #X connect 3 0 4 0; #X connect 5 0 3 0; #X connect 6 0 5 0; #X connect 7 0 5 0; #X connect 8 0 10 0; #X connect 10 0 5 0; #X connect 11 0 5 0; MetaluNet-moonlib-550f1b9/mknob_properties_dialog.tcl0000664002537200253720000007442115201114445023264 0ustar zmoelnigzmoelnig# For information on usage and redistribution, and for a DISCLAIMER OF ALL # WARRANTIES, see the file, "LICENSE.txt," in this distribution. # Copyright (c) 1997-2009 Miller Puckette. # this is an adapted copy of pd/tcl/dialog_iemgui.tcl package provide dialog_mknob 0.1 namespace eval ::dialog_mknob:: { namespace export mknob_properties } # some constants set ::dialog_mknob::min_flashhold 50 set ::dialog_mknob::min_flashbreak 10 set ::dialog_mknob::min_fontsize 4 # arrays to store per-dialog values array set ::dialog_mknob::var_width {} ; array set ::dialog_mknob::var_height {} ; array set ::dialog_mknob::var_minwidth {} ; array set ::dialog_mknob::var_minheight {} ; array set ::dialog_mknob::var_range_max {} ; array set ::dialog_mknob::var_range_min {} ; array set ::dialog_mknob::var_range_checkmode {} ; array set ::dialog_mknob::var_mode {} ; array set ::dialog_mknob::var_loadbang {} ; array set ::dialog_mknob::var_steady {} ; array set ::dialog_mknob::var_number {} ; array set ::dialog_mknob::var_snd {} ; array set ::dialog_mknob::var_rcv {} ; array set ::dialog_mknob::var_label {} ; array set ::dialog_mknob::var_label_dx {} ; array set ::dialog_mknob::var_label_dy {} ; array set ::dialog_mknob::var_label_font {} ; array set ::dialog_mknob::var_label_fontsize {} ; array set ::dialog_mknob::var_color_background {} ; array set ::dialog_mknob::var_color_foreground {} ; array set ::dialog_mknob::var_color_label {} ; array set ::dialog_mknob::var_colortype {} ; #### original values (to fall back from invalid ones)) array set ::dialog_mknob::old_width {} array set ::dialog_mknob::old_height {} array set ::dialog_mknob::old_range_max {} array set ::dialog_mknob::old_range_min {} array set ::dialog_mknob::old_number {} array set ::dialog_mknob::old_label_dx {} array set ::dialog_mknob::old_label_dy {} array set ::dialog_mknob::old_label_font {} array set ::dialog_mknob::old_label_fontsize {} # TODO convert Init/No Init and Steady on click/Jump on click to checkbuttons proc ::dialog_mknob::tonumber val { set x 0 catch { set x [expr $val] } return $x } proc ::dialog_mknob::clip {val min {max {}}} { set val [tonumber $val] if {$min ne {} && $val < $min} {return $min} if {$max ne {} && $val > $max} {return $max} return $val } proc ::dialog_mknob::clip_dim {mytoplevel} { set vid [string trimleft $mytoplevel .] set ::dialog_mknob::var_width($vid) [clip $::dialog_mknob::var_width($vid) $::dialog_mknob::var_minwidth($vid)] set ::dialog_mknob::var_height($vid) [clip $::dialog_mknob::var_height($vid) $::dialog_mknob::var_minheight($vid)] } proc ::dialog_mknob::clip_num {mytoplevel} { set vid [string trimleft $mytoplevel .] set ::dialog_mknob::var_number($vid) [clip $::dialog_mknob::var_number($vid) 1 2000] } proc ::dialog_mknob::sched_rng {mytoplevel} { # TODO: rename this to 'range_check' set vid [string trimleft $mytoplevel .] switch -- $::dialog_mknob::var_range_checkmode($vid) { 2 { # 'range-check' is in 'flash' mode # make sure that min/max are sorted properly and are not smaller than the resp. min values foreach {flashbreak flashhold} [lsort -real [list [tonumber $::dialog_mknob::var_range_min($vid)] [tonumber $::dialog_mknob::var_range_max($vid)]]] {break;} set ::dialog_mknob::var_range_min($vid) [clip $flashbreak $::dialog_mknob::min_flashbreak] set ::dialog_mknob::var_range_max($vid) [clip $flashhold $::dialog_mknob::min_flashhold] } 1 { # 'range-check' is in 'toggle' mode if {[tonumber $::dialog_mknob::var_range_min($vid)] == 0} { # there's little use toggling between 0 and 0, so force it to 1... set ::dialog_mknob::var_range_min($vid) 1 } } } } proc ::dialog_mknob::verify_rng {mytoplevel} { set vid [string trimleft $mytoplevel .] if {$::dialog_mknob::var_mode($vid) == 1} { if {$::dialog_mknob::var_range_max($vid) == 0.0 && $::dialog_mknob::var_range_min($vid) == 0.0} { set ::dialog_mknob::var_range_max($vid) 1.0 } if {$::dialog_mknob::var_range_max($vid) > 0} { if {$::dialog_mknob::var_range_min($vid) <= 0} { set ::dialog_mknob::var_range_min($vid) [expr $::dialog_mknob::var_range_max($vid) * 0.01] } } else { if {$::dialog_mknob::var_range_min($vid) > 0} { set ::dialog_mknob::var_range_max($vid) [expr $::dialog_mknob::var_range_min($vid) * 0.01] } } } } proc ::dialog_mknob::clip_fontsize {mytoplevel} { set vid [string trimleft $mytoplevel .] set ::dialog_mknob::var_label_fontsize($vid) [clip $::dialog_mknob::var_label_fontsize($vid) $::dialog_mknob::min_fontsize] } proc ::dialog_mknob::set_col_example {mytoplevel} { set vid [string trimleft $mytoplevel .] set fgcol $::dialog_mknob::var_color_label($vid) $mytoplevel.colors.sections.exp.lb_bk configure \ -background $::dialog_mknob::var_color_background($vid) \ -activebackground $::dialog_mknob::var_color_background($vid) \ -foreground $fgcol -activeforeground $fgcol set fgcol $::dialog_mknob::var_color_foreground($vid) if { $fgcol eq "none" } { set fgcol $::dialog_mknob::var_color_background($vid) } $mytoplevel.colors.sections.exp.fr_bk configure \ -background $::dialog_mknob::var_color_background($vid) \ -activebackground $::dialog_mknob::var_color_background($vid) \ -foreground $fgcol -activeforeground $fgcol # for OSX live updates ::dialog_mknob::auto_apply_return $mytoplevel } proc ::dialog_mknob::preset_col {mytoplevel presetcol} { set vid [string trimleft $mytoplevel .] switch -- $::dialog_mknob::var_colortype($vid) { 0 { set ::dialog_mknob::var_color_background($vid) $presetcol } 1 { set ::dialog_mknob::var_color_foreground($vid) $presetcol } 2 { set ::dialog_mknob::var_color_label($vid) $presetcol } } ::dialog_mknob::set_col_example $mytoplevel } proc ::dialog_mknob::choose_col_bkfrlb {mytoplevel} { # TODO rename this set vid [string trimleft $mytoplevel .] switch -- $::dialog_mknob::var_colortype($vid) { 0 { set title [_ "Background color" ] set color $::dialog_mknob::var_color_background($vid) } 1 { set title [_ "Foreground color" ] set color $::dialog_mknob::var_color_foreground($vid) } 2 { set title [_ "Label color" ] set color $::dialog_mknob::var_color_label($vid) } } set color [tk_chooseColor -title $title -initialcolor $color] if { $color ne "" } { ::dialog_mknob::preset_col $mytoplevel $color } } proc ::dialog_mknob::popupmenu {path varname labels {command {}}} { upvar 1 $varname var menubutton ${path} -menu ${path}.menu -indicatoron 1 -relief raised -text [lindex $labels $var] menu ${path}.menu -tearoff 0 set idx 0 foreach l $labels { $path.menu add radiobutton -label "$l" -variable $varname -value $idx $path.menu entryconfigure last -command "\{$path\} configure -text \{$l\}; $command" incr idx } } proc ::dialog_mknob::toggle_mode {mytoplevel} { set vid [string trimleft $mytoplevel .] if {$::dialog_mknob::var_mode($vid) != 0} { ::dialog_mknob::verify_rng $mytoplevel ::dialog_mknob::sched_rng $mytoplevel } } proc ::dialog_mknob::toggle_and_activate {mytoplevel activewidget} { ::dialog_mknob::toggle_mode $mytoplevel set vid [string trimleft $mytoplevel .] if {$::dialog_mknob::var_mode($vid) != 0} { $activewidget configure -state normal } else { $activewidget configure -state disabled } } # open popup over source button proc ::dialog_mknob::font_popup {mytoplevel} { $mytoplevel.popup unpost set button $mytoplevel.label.fontpopup_label set x [expr [winfo rootx $button] + ( [winfo width $button] / 2 )] set y [expr [winfo rooty $button] + ( [winfo height $button] / 2 )] tk_popup $mytoplevel.popup $x $y 0 } proc ::dialog_mknob::toggle_font {mytoplevel gn_f} { set vid [string trimleft $mytoplevel .] set ::dialog_mknob::var_label_font($vid) $gn_f switch -- $gn_f { 0 { set current_font $::font_family} 1 { set current_font "Helvetica" } 2 { set current_font "Times" } } set current_font_spec "{$current_font} 14 $::font_weight" $mytoplevel.label.fontpopup_label configure -text $current_font \ -font [list $current_font 16 $::font_weight] $mytoplevel.label.name_entry configure -font $current_font_spec $mytoplevel.colors.sections.exp.fr_bk configure -font $current_font_spec $mytoplevel.colors.sections.exp.lb_bk configure -font $current_font_spec ::dialog_mknob::auto_apply_return $mytoplevel } proc ::dialog_mknob::apply {mytoplevel} { set vid [string trimleft $mytoplevel .] set fallbacks {} set prefix ::dialog_mknob::old_ foreach v [info vars ${prefix}*] { if { ! [array exists $v] } {continue} lappend fallbacks [string range $v [string length $prefix] end] } foreach v ${fallbacks} { if { [lindex [array get ::dialog_mknob::var_${v} ${vid}] 1] eq {} } { array set ::dialog_mknob::var_${v} [array get ::dialog_mknob::old_${v} ${vid}] } } ::dialog_mknob::clip_dim $mytoplevel ::dialog_mknob::clip_num $mytoplevel ::dialog_mknob::sched_rng $mytoplevel ::dialog_mknob::verify_rng $mytoplevel ::dialog_mknob::sched_rng $mytoplevel ::dialog_mknob::clip_fontsize $mytoplevel # TODO wrap the name-mangling ('empty', unspace_text, map) into a helper-proc set sendname empty set receivename empty set labelname empty if {$::dialog_mknob::var_snd($vid) ne ""} {set sendname $::dialog_mknob::var_snd($vid)} if {$::dialog_mknob::var_rcv($vid) ne ""} {set receivename $::dialog_mknob::var_rcv($vid)} if {$::dialog_mknob::var_label($vid) ne ""} {set labelname $::dialog_mknob::var_label($vid)} set labelname [string map { "\\" "" {$} {\$} { } {\ } {,} {\,} {;} {\;} "{" "\{" "}" "\}" } $labelname] # make sure the offset boxes have a value if {$::dialog_mknob::var_label_dx($vid) eq ""} {set ::dialog_mknob::var_label_dx($vid) 0} if {$::dialog_mknob::var_label_dy($vid) eq ""} {set ::dialog_mknob::var_label_dy($vid) 0} pdsend [concat $mytoplevel dialog \ $::dialog_mknob::var_width($vid) \ $::dialog_mknob::var_height($vid) \ $::dialog_mknob::var_range_min($vid) \ $::dialog_mknob::var_range_max($vid) \ $::dialog_mknob::var_mode($vid) \ $::dialog_mknob::var_loadbang($vid) \ $::dialog_mknob::var_number($vid) \ [string map {"$" {\$}} [unspace_text $sendname]] \ [string map {"$" {\$}} [unspace_text $receivename]] \ $labelname \ $::dialog_mknob::var_label_dx($vid) \ $::dialog_mknob::var_label_dy($vid) \ $::dialog_mknob::var_label_font($vid) \ $::dialog_mknob::var_label_fontsize($vid) \ [string tolower $::dialog_mknob::var_color_background($vid)] \ [string tolower $::dialog_mknob::var_color_foreground($vid)] \ [string tolower $::dialog_mknob::var_color_label($vid)] \ $::dialog_mknob::var_steady($vid) \ ] foreach v ${fallbacks} { array set ::dialog_mknob::old_${v} [array get ::dialog_mknob::var_${v} ${vid}] } } proc ::dialog_mknob::cancel {mytoplevel} { pdsend [list $mytoplevel cancel] set vid [string trimleft $mytoplevel .] foreach v [info vars ::dialog_mknob::*] { if { [array exists $v] } { if { [array get $v ${vid}] ne {} } { array unset $v ${vid} } } } } proc ::dialog_mknob::ok {mytoplevel} { ::dialog_mknob::apply $mytoplevel ::dialog_mknob::cancel $mytoplevel } proc ::dialog_mknob::bind_capslock {tag seq_prefix seq_nocase script} { bind $tag <${seq_prefix}-[string tolower ${seq_nocase}]> "::pd_menucommands::scheduleAction $script" bind $tag <${seq_prefix}-[string toupper ${seq_nocase}]> "::pd_menucommands::scheduleAction $script" } proc ::dialog_mknob::mknob_properties {mytoplevel mainheader dim_header_UNUSED \ wdt min_wdt label_width \ hgt min_hgt label_height \ label_range min_rng label_range_min max_rng \ label_range_max rng_sched \ lin0_log1 lilo0_label lilo1_label \ loadbang steady label_number num \ snd rcv \ gui_name \ gn_dx gn_dy gn_f gn_fs \ bcol fcol lcol} { # on macOS, we want live widget updates if {$::windowingsystem eq "aqua"} { proc ::dialog_mknob::auto_apply {mytoplevel} { return [::dialog_mknob::apply ${mytoplevel}] } proc ::dialog_mknob::auto_apply_return {mytoplevel} { return [::dialog_mknob::apply_and_rebind_return ${mytoplevel}] } proc ::dialog_mknob::auto_apply_noreturn {mytoplevel} { return [::dialog_mknob::unbind_return ${mytoplevel}] } } set vid [string trimleft $mytoplevel .] set snd [::pdtk_text::unescape $snd] set rcv [::pdtk_text::unescape $rcv] set gui_name [::pdtk_text::unescape $gui_name] # initialize the array set ::dialog_mknob::var_width($vid) $wdt set ::dialog_mknob::var_height($vid) $hgt set ::dialog_mknob::var_minwidth($vid) $min_wdt set ::dialog_mknob::var_minheight($vid) $min_hgt set ::dialog_mknob::var_range_max($vid) $max_rng set ::dialog_mknob::var_range_min($vid) $min_rng set ::dialog_mknob::var_range_checkmode($vid) $rng_sched set ::dialog_mknob::var_mode($vid) $lin0_log1 set ::dialog_mknob::var_loadbang($vid) $loadbang set ::dialog_mknob::var_steady($vid) $steady set ::dialog_mknob::var_number($vid) $num set ::dialog_mknob::var_snd($vid) $snd set ::dialog_mknob::var_rcv($vid) $rcv set ::dialog_mknob::var_label($vid) $gui_name set ::dialog_mknob::var_label_dx($vid) $gn_dx set ::dialog_mknob::var_label_dy($vid) $gn_dy set ::dialog_mknob::var_label_font($vid) $gn_f set ::dialog_mknob::var_label_fontsize($vid) $gn_fs set ::dialog_mknob::var_color_background($vid) $bcol set ::dialog_mknob::var_color_foreground($vid) $fcol set ::dialog_mknob::var_color_label($vid) $lcol set ::dialog_mknob::var_colortype($vid) 0 # fallback values (in case the user enters garbage) set ::dialog_mknob::old_width($vid) $wdt set ::dialog_mknob::old_height($vid) $hgt set ::dialog_mknob::old_range_max($vid) $max_rng set ::dialog_mknob::old_range_min($vid) $min_rng set ::dialog_mknob::old_number($vid) $num set ::dialog_mknob::old_label_dx($vid) $gn_dx set ::dialog_mknob::old_label_dy($vid) $gn_dy set ::dialog_mknob::old_label_font($vid) $gn_f set ::dialog_mknob::old_label_fontsize($vid) $gn_fs set iemgui_type [_ $mainheader] switch -- $mainheader { "Mknob" { set iemgui_type [_ "Mknob"] set label_width [_ "Size:"] set label_height [_ "Height:"] set label_range [_ "Output Range"] set label_range_min [_ "Lower:"] set label_range_max [_ "Upper:"] } } toplevel $mytoplevel -class DialogWindow #wm title $mytoplevel [_ "%s Properties" $iemgui_type] # only available from Pd 0.55(?) wm title $mytoplevel [string cat [_ "Properties"] " | $iemgui_type"] wm group $mytoplevel . wm resizable $mytoplevel 0 0 wm transient $mytoplevel $::focused_window #::pd_menus::menubar_for_dialog $mytoplevel # seems useless, and not working before Pd 0.55(?) $mytoplevel configure -padx 0 -pady 0 # bindings bind $mytoplevel "dialog_mknob::cancel $mytoplevel; break" bind $mytoplevel "dialog_mknob::ok $mytoplevel; break" bind_capslock $mytoplevel $::modifier-Key w "dialog_mknob::cancel $mytoplevel; break" # these aren't supported in the dialog, so alert the user bind_capslock $mytoplevel $::modifier-Key s {bell; break} bind_capslock $mytoplevel $::modifier-Shift-Key s {bell; break} bind_capslock $mytoplevel $::modifier-Key p {bell; break} bind_capslock $mytoplevel $::modifier-Key t {bell; break} wm protocol $mytoplevel WM_DELETE_WINDOW "dialog_mknob::cancel $mytoplevel" # dimensions frame $mytoplevel.dim -height 7 pack $mytoplevel.dim -side top label $mytoplevel.dim.w_lab -text [_ $label_width] entry $mytoplevel.dim.w_ent -textvariable ::dialog_mknob::var_width($vid) -width 4 label $mytoplevel.dim.dummy1 -text "" -width 1 label $mytoplevel.dim.h_lab -text [_ $label_height] entry $mytoplevel.dim.h_ent -textvariable ::dialog_mknob::var_height($vid) -width 4 pack $mytoplevel.dim.w_lab $mytoplevel.dim.w_ent -side left if { $label_height ne "" } { pack $mytoplevel.dim.dummy1 $mytoplevel.dim.h_lab $mytoplevel.dim.h_ent -side left } # range labelframe $mytoplevel.rng pack $mytoplevel.rng -side top -fill x frame $mytoplevel.rng.min label $mytoplevel.rng.min.lab -text $label_range_min entry $mytoplevel.rng.min.ent -textvariable ::dialog_mknob::var_range_min($vid) -width 7 label $mytoplevel.rng.dummy1 -text "" -width 1 label $mytoplevel.rng.max_lab -text [_ $label_range_max] entry $mytoplevel.rng.max_ent -textvariable ::dialog_mknob::var_range_max($vid) -width 7 if { $label_range ne "" } { $mytoplevel.rng config -borderwidth 1 -pady 4 -text [_ $label_range] if { $label_range_min ne "" } { pack $mytoplevel.rng.min pack $mytoplevel.rng.min.lab $mytoplevel.rng.min.ent -side left } if { $label_range_max ne "" } { $mytoplevel.rng config -padx 26 pack configure $mytoplevel.rng.min -side left pack $mytoplevel.rng.dummy1 $mytoplevel.rng.max_lab $mytoplevel.rng.max_ent -side left} } # parameters labelframe $mytoplevel.para -borderwidth 1 -padx 5 -pady 5 -text [_ "Parameters"] pack $mytoplevel.para -side top -fill x -pady 5 frame $mytoplevel.para.num label $mytoplevel.para.num.lab -text [_ $label_number] entry $mytoplevel.para.num.ent -textvariable ::dialog_mknob::var_number($vid) -width 4 pack $mytoplevel.para.num.ent $mytoplevel.para.num.lab -side right -anchor e set applycmd [list ::dialog_mknob::auto_apply ${mytoplevel}] if {$::dialog_mknob::var_mode($vid) >= 0} { if {$mainheader == "|nbx|" } { set togglecmd "::dialog_mknob::toggle_and_activate $mytoplevel $mytoplevel.para.num.ent" } else { set togglecmd "::dialog_mknob::toggle_mode $mytoplevel" } ::dialog_mknob::popupmenu $mytoplevel.para.lilo \ ::dialog_mknob::var_mode($vid) [list [_ $lilo0_label] [_ $lilo1_label] ] \ "$togglecmd; $applycmd" pack $mytoplevel.para.lilo -side left -expand 1 -ipadx 10 } if {$::dialog_mknob::var_loadbang($vid) >= 0} { ::dialog_mknob::popupmenu $mytoplevel.para.lb \ ::dialog_mknob::var_loadbang($vid) [list [_ "No init"] [_ "Init"] ] \ $applycmd pack $mytoplevel.para.lb -side left -expand 1 -ipadx 10 } if {$::dialog_mknob::var_number($vid) > 0} { pack $mytoplevel.para.num -side left -expand 1 -ipadx 10 } if {$::dialog_mknob::var_steady($vid) >= 0} { ::dialog_mknob::popupmenu $mytoplevel.para.stdy_jmp \ ::dialog_mknob::var_steady($vid) [list [_ "Jump on click"] [_ "Steady on click"] ] \ $applycmd pack $mytoplevel.para.stdy_jmp -side left -expand 1 -ipadx 10 } # messages labelframe $mytoplevel.s_r -borderwidth 1 -padx 5 -pady 5 -text [_ "Messages"] pack $mytoplevel.s_r -side top -fill x frame $mytoplevel.s_r.send pack $mytoplevel.s_r.send -side top -anchor e -padx 5 label $mytoplevel.s_r.send.lab -text [_ "Send symbol:"] entry $mytoplevel.s_r.send.ent -textvariable ::dialog_mknob::var_snd($vid) -width 21 if { $snd ne "nosndno" } { pack $mytoplevel.s_r.send.lab $mytoplevel.s_r.send.ent -side left \ -fill x -expand 1 } frame $mytoplevel.s_r.receive pack $mytoplevel.s_r.receive -side top -anchor e -padx 5 label $mytoplevel.s_r.receive.lab -text [_ "Receive symbol:"] entry $mytoplevel.s_r.receive.ent -textvariable ::dialog_mknob::var_rcv($vid) -width 21 if { $rcv ne "norcvno" } { pack $mytoplevel.s_r.receive.lab $mytoplevel.s_r.receive.ent -side left \ -fill x -expand 1 } # get the current font name from the int given from C-space (gn_f) set current_font $::font_family if {$::dialog_mknob::var_label_font($vid) == 1} \ { set current_font "Helvetica" } if {$::dialog_mknob::var_label_font($vid) == 2} \ { set current_font "Times" } # label labelframe $mytoplevel.label -borderwidth 1 -text [_ "Label"] -padx 5 -pady 5 pack $mytoplevel.label -side top -fill x -pady 5 entry $mytoplevel.label.name_entry -textvariable ::dialog_mknob::var_label($vid) \ -width 30 -font [list $current_font 14 $::font_weight] pack $mytoplevel.label.name_entry -side top -fill both -padx 5 frame $mytoplevel.label.xy -padx 20 -pady 1 pack $mytoplevel.label.xy -side top label $mytoplevel.label.xy.x_lab -text [_ "X offset:"] entry $mytoplevel.label.xy.x_entry -textvariable ::dialog_mknob::var_label_dx($vid) -width 5 label $mytoplevel.label.xy.dummy1 -text " " -width 1 label $mytoplevel.label.xy.y_lab -text [_ "Y offset:"] entry $mytoplevel.label.xy.y_entry -textvariable ::dialog_mknob::var_label_dy($vid) -width 5 pack $mytoplevel.label.xy.x_lab $mytoplevel.label.xy.x_entry $mytoplevel.label.xy.dummy1 \ $mytoplevel.label.xy.y_lab $mytoplevel.label.xy.y_entry -side left button $mytoplevel.label.fontpopup_label -text $current_font \ -font [list $current_font 16 $::font_weight] -pady 4 \ -command "::dialog_mknob::font_popup $mytoplevel" pack $mytoplevel.label.fontpopup_label -side left -anchor w \ -expand 1 -fill x -padx 5 frame $mytoplevel.label.fontsize pack $mytoplevel.label.fontsize -side right -padx 5 -pady 5 label $mytoplevel.label.fontsize.label -text [_ "Size:"] entry $mytoplevel.label.fontsize.entry -textvariable ::dialog_mknob::var_label_fontsize($vid) -width 4 pack $mytoplevel.label.fontsize.entry $mytoplevel.label.fontsize.label \ -side right -anchor e menu $mytoplevel.popup $mytoplevel.popup add command \ -label $::font_family \ -font [format {{%s} 16 %s} $::font_family $::font_weight] \ -command "::dialog_mknob::toggle_font $mytoplevel 0" $mytoplevel.popup add command \ -label "Helvetica" \ -font [format {Helvetica 16 %s} $::font_weight] \ -command "::dialog_mknob::toggle_font $mytoplevel 1" $mytoplevel.popup add command \ -label "Times" \ -font [format {Times 16 %s} $::font_weight] \ -command "::dialog_mknob::toggle_font $mytoplevel 2" # colors labelframe $mytoplevel.colors -borderwidth 1 -text [_ "Colors"] -padx 5 -pady 5 pack $mytoplevel.colors -fill x frame $mytoplevel.colors.select pack $mytoplevel.colors.select -side top radiobutton $mytoplevel.colors.select.radio0 \ -value 0 -variable ::dialog_mknob::var_colortype($vid) \ -text [_ "Background"] -justify left radiobutton $mytoplevel.colors.select.radio1 \ -value 1 -variable ::dialog_mknob::var_colortype($vid) \ -text [_ "Front"] -justify left radiobutton $mytoplevel.colors.select.radio2 \ -value 2 -variable ::dialog_mknob::var_colortype($vid) \ -text [_ "Label"] -justify left if { $::dialog_mknob::var_color_foreground($vid) ne "none" } { pack $mytoplevel.colors.select.radio0 $mytoplevel.colors.select.radio1 \ $mytoplevel.colors.select.radio2 -side left } else { pack $mytoplevel.colors.select.radio0 $mytoplevel.colors.select.radio2 -side left } frame $mytoplevel.colors.sections pack $mytoplevel.colors.sections -side top button $mytoplevel.colors.sections.but -text [_ "Compose color"] \ -command "::dialog_mknob::choose_col_bkfrlb $mytoplevel" pack $mytoplevel.colors.sections.but -side left -anchor w -pady 5 \ -expand yes -fill x frame $mytoplevel.colors.sections.exp pack $mytoplevel.colors.sections.exp -side right -padx 5 if { $::dialog_mknob::var_color_foreground($vid) ne "none" } { label $mytoplevel.colors.sections.exp.fr_bk -text "o=||=o" -width 6 \ -background $::dialog_mknob::var_color_background($vid) \ -activebackground $::dialog_mknob::var_color_background($vid) \ -foreground $::dialog_mknob::var_color_foreground($vid) \ -activeforeground $::dialog_mknob::var_color_foreground($vid) \ -font [list $current_font 14 $::font_weight] -padx 2 -pady 2 -relief ridge } else { label $mytoplevel.colors.sections.exp.fr_bk -text "o=||=o" -width 6 \ -background $::dialog_mknob::var_color_background($vid) \ -activebackground $::dialog_mknob::var_color_background($vid) \ -foreground $::dialog_mknob::var_color_background($vid) \ -activeforeground $::dialog_mknob::var_color_background($vid) \ -font [list $current_font 14 $::font_weight] -padx 2 -pady 2 -relief ridge } label $mytoplevel.colors.sections.exp.lb_bk -text [_ "Test label"] \ -background $::dialog_mknob::var_color_background($vid) \ -activebackground $::dialog_mknob::var_color_background($vid) \ -foreground $::dialog_mknob::var_color_label($vid) \ -activeforeground $::dialog_mknob::var_color_label($vid) \ -font [list $current_font 14 $::font_weight] -padx 2 -pady 2 -relief ridge pack $mytoplevel.colors.sections.exp.lb_bk $mytoplevel.colors.sections.exp.fr_bk \ -side right -anchor e -expand yes -fill both -pady 7 # color scheme by Mary Ann Benedetto http://piR2.org foreach r {r1 r2 r3} hexcols { { "#FFFFFF" "#DFDFDF" "#BBBBBB" "#FFC7C6" "#FFE3C6" "#FEFFC6" "#C6FFC7" "#C6FEFF" "#C7C6FF" "#E3C6FF" } { "#9F9F9F" "#7C7C7C" "#606060" "#FF0400" "#FF8300" "#FAFF00" "#00FF04" "#00FAFF" "#0400FF" "#9C00FF" } { "#404040" "#202020" "#000000" "#551312" "#553512" "#535512" "#0F4710" "#0E4345" "#131255" "#2F004D" } } \ { frame $mytoplevel.colors.$r pack $mytoplevel.colors.$r -side top foreach i { 0 1 2 3 4 5 6 7 8 9} hexcol $hexcols \ { label $mytoplevel.colors.$r.c$i -background $hexcol -activebackground $hexcol -relief ridge -padx 7 -pady 0 -width 1 bind $mytoplevel.colors.$r.c$i