From f40d8c3d61e9ac6a7a4e06f6bfc7a2567c38bb33 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 29 Apr 2003 16:52:44 +0000 Subject: sources from motex_1_1_3.tar.gz svn path=/trunk/externals/motex/; revision=603 --- LICENCE | 66 ++++++++ README | 36 ++++ getenv.c | 99 +++++++++++ getenv.pd | 23 +++ ln~.c | 130 +++++++++++++++ ln~.pd | 15 ++ makefile | 84 ++++++++++ noisegate~.pd | 23 +++ pansig~.c | 136 +++++++++++++++ pansig~.pd | 104 ++++++++++++ pan~.c | 104 ++++++++++++ pan~.pd | 94 +++++++++++ pol2rec~.c | 137 ++++++++++++++++ polvoc.pd | 178 ++++++++++++++++++++ polygate~.c | 518 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ polygate~.pd | 251 ++++++++++++++++++++++++++++ rec2pol~.c | 134 +++++++++++++++ rec2pol~.pd | 44 +++++ shuffle.c | 216 ++++++++++++++++++++++++ shuffle.pd | 28 ++++ system.c | 76 +++++++++ system.pd | 8 + 22 files changed, 2504 insertions(+) create mode 100644 LICENCE create mode 100644 README create mode 100644 getenv.c create mode 100644 getenv.pd create mode 100644 ln~.c create mode 100644 ln~.pd create mode 100644 makefile create mode 100644 noisegate~.pd create mode 100644 pansig~.c create mode 100644 pansig~.pd create mode 100644 pan~.c create mode 100644 pan~.pd create mode 100644 pol2rec~.c create mode 100644 polvoc.pd create mode 100644 polygate~.c create mode 100644 polygate~.pd create mode 100644 rec2pol~.c create mode 100644 rec2pol~.pd create mode 100644 shuffle.c create mode 100644 shuffle.pd create mode 100644 system.c create mode 100644 system.pd diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..085912e --- /dev/null +++ b/LICENCE @@ -0,0 +1,66 @@ +GNU GENERAL PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + +a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS diff --git a/README b/README new file mode 100644 index 0000000..1302ea6 --- /dev/null +++ b/README @@ -0,0 +1,36 @@ +Pd externals by Iain Mott (iain.mott@bigpond.com) + +The makefile for this collection is configured for Linux only - Linux binaries included. + +Each external has a demonstration Pd patch (*.pd) associated with it. + +Source contents: + +polygate~ - switch between multiple signal inputs - variable fade rate both linear & equal power + +shuffle - a no-repeat random generator - outputs numbers within a set range + +pan~ - equal power stereo panning + +system - sends a system message to the console + +ln~ - natural log + inverse + +rec2pol~ - convert rectangular coordinates to polar eg. can be used to + convert sine & cosine rfft~ output to phase & magnitude + +pol2rec~ - inverse of rec2pol~ + +getenv - Sends value of an environment variable argument on bang. + Use a 'set ' message to reset the variable name. + + +two other related patches: + +polvoc.pd - example of pol2rec~ etc + +noisegate~.pd - simple noisegate used in above + + +See also 'sqlsingle.tar.gz' archive for the 'sqlsingle' eternal. This object allows communication +and data retrieval from a PostgreSQL database in Pd. \ No newline at end of file diff --git a/getenv.c b/getenv.c new file mode 100644 index 0000000..dbd31a5 --- /dev/null +++ b/getenv.c @@ -0,0 +1,99 @@ +/*************************************************************************** + * File: shuffle.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd external. Sends value of an environment variable argument on bang. + * Use a 'set ' message to reset the variable name. + * See supporting Pd patch: getenv.pd + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +/* + * getenv - Pd external. Copyright (c) 2001 Iain Mott + * sends value of an environment variable argument on bang + * use a 'set ' message to reset the variable name +*/ + +#include "m_pd.h" +#include + +static t_class *getenv_class; + +typedef struct _getenv +{ + t_object x_obj; + t_symbol *enval; + char *envar; +} t_getenv; + +static void *getenv_new(t_symbol *s, int argc, t_atom *argv) +{ + + t_getenv *x = (t_getenv *)pd_new(getenv_class); + x->envar = NULL; + if(argc != 1 || argv[0].a_type != A_SYMBOL) + post("getenv: One argument (environment variable) required"); + else + { + char *value = getenv(argv[0].a_w.w_symbol->s_name); + if(value) + { + x->envar = argv[0].a_w.w_symbol->s_name; + x->enval = gensym(value); + } + else + post("getenv: Environment variable does not exist"); + } + outlet_new(&x->x_obj, &s_symbol); + return (x); +} + + +void getenv_set(t_getenv *x, t_symbol *f) +{ + char *value = getenv(f->s_name); + if(value) + x->enval = gensym(value); + else + post("getenv: Environment variable does not exist"); +} + +void getenv_bang(t_getenv *x) +{ + if(x->envar) + outlet_symbol(x->x_obj.ob_outlet, x->enval); +} + +void getenv_setup(void) +{ + getenv_class = class_new(gensym("getenv"), (t_newmethod)getenv_new, 0, sizeof(t_getenv), 0, A_GIMME, 0); + class_addmethod(getenv_class, (t_method)getenv_set, gensym("set"), A_SYMBOL, 0); + class_addbang(getenv_class, getenv_bang); +} + + + + + + + + + + + diff --git a/getenv.pd b/getenv.pd new file mode 100644 index 0000000..58ac79d --- /dev/null +++ b/getenv.pd @@ -0,0 +1,23 @@ +#N canvas 597 95 404 421 10; +#X floatatom 445 83 4 0 0; +#X obj 441 107 t b f; +#X obj 593 177 strconcat .wav; +#X obj 517 236 strconcat; +#X symbolatom 360 301 60 0 0; +#X msg 363 108 set HOME; +#X msg 300 87 set SOUNDSTORE; +#X obj 410 190 makefilename %s/sound; +#X floatatom 608 216 4 0 0; +#X msg 305 53 set SUMDAYPLAY; +#X obj 401 149 getenv SUMDAYPLAY; +#X connect 0 0 1 0; +#X connect 1 0 10 0; +#X connect 1 1 2 0; +#X connect 2 0 3 1; +#X connect 3 0 4 0; +#X connect 5 0 10 0; +#X connect 6 0 10 0; +#X connect 7 0 3 0; +#X connect 8 0 3 2; +#X connect 9 0 10 0; +#X connect 10 0 7 0; diff --git a/ln~.c b/ln~.c new file mode 100644 index 0000000..bf5939e --- /dev/null +++ b/ln~.c @@ -0,0 +1,130 @@ +/*************************************************************************** + * File: ln~.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd signal external. Finds natural log of signal. Optional argument '-1' finfs inverse. + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +#include "math.h" +#include + +/* ----------------------------- ln ----------------------------- */ +static t_class *ln_class; + + +#define INVTWOPI 0.15915494f + +typedef struct _ln +{ + t_object x_obj; + int flag; +} t_ln; + +/* static void *ln_new(t_symbol *s, int argc, t_atom *argv) */ +static void *ln_new(t_floatarg f) +{ +/* if (argc > 1) */ +/* post("+~: extra arguments ignored"); */ +/* { */ + t_ln *x = (t_ln *)pd_new(ln_class); + outlet_new(&x->x_obj, &s_signal); + x->flag = f; + return (x); +/* } */ +} + +t_int *ln_perform(t_int *w) +{ + t_float *in1 = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + + int n = (int)(w[3]); + int flag = (int)(w[4]); + if(flag != -1) + while (n--) *out++ = (t_float) log(*in1++); + else + while (n--) *out++ = (t_float) exp(*in1++); + return (w+5); +} + +t_int *ln_perf8(t_int *w) +{ + t_float *in1 = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + int flag = (int)(w[4]); + if(flag != -1) + { + for (; n; n -= 8, in1 += 8, out += 8) + { + float f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3]; + float f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7]; + + out[0] = (t_float) log(f0); + out[1] = (t_float) log(f1); + out[2] = (t_float) log(f2); + out[3] = (t_float) log(f3); + out[4] = (t_float) log(f4); + out[5] = (t_float) log(f5); + out[6] = (t_float) log(f6); + out[7] = (t_float) log(f7); + } + } + else + { + for (; n; n -= 8, in1 += 8, out += 8) + { + float f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3]; + float f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7]; + + out[0] = (t_float) exp(f0); + out[1] = (t_float) exp(f1); + out[2] = (t_float) exp(f2); + out[3] = (t_float) exp(f3); + out[4] = (t_float) exp(f4); + out[5] = (t_float) exp(f5); + out[6] = (t_float) exp(f6); + out[7] = (t_float) exp(f7); + } + } + + return (w+5); +} + +void dsp_add_ln(t_sample *in1, t_sample *out, int n, int flag) +{ + if (n&7) + dsp_add(ln_perform, 4, in1, out, n, flag); + else + dsp_add(ln_perf8, 4, in1, out, n, flag); +} + +static void ln_dsp(t_ln *x, t_signal **sp) +{ + dsp_add_ln(sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n, x->flag); +} + +void ln_tilde_setup(void) +{ + ln_class = class_new(gensym("ln~"), (t_newmethod)ln_new, 0, + sizeof(t_ln), 0, A_DEFFLOAT, 0); + class_addmethod(ln_class, nullfn, gensym("signal"), 0); + class_addmethod(ln_class, (t_method)ln_dsp, gensym("dsp"), 0); +} diff --git a/ln~.pd b/ln~.pd new file mode 100644 index 0000000..ec8a4be --- /dev/null +++ b/ln~.pd @@ -0,0 +1,15 @@ +#N canvas 277 128 450 300 10; +#X obj 145 100 ln~; +#X obj 158 126 ln~ -1; +#X text 23 4 ln~; +#X text 22 23 same as log~ however '-1' argument creates inverse; +#X obj 129 53 sig~ 22; +#X msg 47 94 bang; +#X obj 59 128 print~ log; +#X obj 43 165 print~ alog; +#X connect 0 0 1 0; +#X connect 0 0 6 0; +#X connect 1 0 7 0; +#X connect 4 0 0 0; +#X connect 5 0 6 0; +#X connect 5 0 7 0; diff --git a/makefile b/makefile new file mode 100644 index 0000000..f8050ae --- /dev/null +++ b/makefile @@ -0,0 +1,84 @@ + +#make file for motex Pd externals - Iain Mott + +current: + echo make pd_linux + + +# ----------------------- LINUX i386 ----------------------- + + +pd_linux: pan~.pd_linux pansig~.pd_linux polygate~.pd_linux shuffle.pd_linux system.pd_linux ln~.pd_linux rec2pol~.pd_linux pol2rec~.pd_linux getenv.pd_linux + + +.SUFFIXES: .pd_linux + +# -------------- postgres ---------------------- + +#SRCDIR= /usr/src/pgsql/postgresql-7.0.3/src +#EXTERNALDIR= /home/iain/puredata/summon2/externals/ +TARGDIR= ./ + + +#include Makefile.global #needed for postgresql stuff + +CFLAGS+= -I$(LIBPQDIR) + +LDFLAGS+= -L$(LIBPQDIR) -lpq + +#----------------------------------------------- +EXSRCDIR= . + +LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +# LINUXINCLUDE = -I/home/iain/puredata/pd029/src +LINUXINCLUDE = -I/home/iain/puredata/pd032/src +#LINUXINCLUDE+= -I/usr/include/g++-2 +#------------- +#LINUXCFLAG+=CFLAGS + +#LINUXINCLUDE+= -I/usr/local/pgsql/include +#-------------- + + +.c.pd_linux: + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $(EXSRCDIR)$*.o -c $*.c + ld -export_dynamic -shared -o $(TARGDIR)$*.pd_linux $(EXSRCDIR)$*.o -lc -lm $(LDFLAGS) + strip --strip-unneeded $(TARGDIR)$*.pd_linux + rm $(EXSRCDIR)$*.o +# cp $(TARGDIR)$*.pd_linux $(EXTERNALDIR) + + + +#clean: +# rm -f foo1.pd_linux burstan.pd_linux burstan~.pd_linux + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/noisegate~.pd b/noisegate~.pd new file mode 100644 index 0000000..c5a859f --- /dev/null +++ b/noisegate~.pd @@ -0,0 +1,23 @@ +#N canvas 5 21 499 368 10; +#X obj 149 44 inlet~; +#X obj 149 314 outlet~; +#X obj 188 139 moses \$1; +#X msg 188 167 bang; +#X msg 257 168 bang; +#X obj 257 189 pack 1 \$2; +#X text 328 309 IM 2001; +#X obj 188 189 pack 0 \$3; +#X obj 188 220 line~; +#X obj 149 279 *~; +#X obj 188 110 env~; +#X connect 0 0 9 0; +#X connect 0 0 10 0; +#X connect 2 0 3 0; +#X connect 2 1 4 0; +#X connect 3 0 7 0; +#X connect 4 0 5 0; +#X connect 5 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 9 1; +#X connect 9 0 1 0; +#X connect 10 0 2 0; diff --git a/pansig~.c b/pansig~.c new file mode 100644 index 0000000..346e94b --- /dev/null +++ b/pansig~.c @@ -0,0 +1,136 @@ +#include "m_pd.h" +#include + +static t_class *pansig_class; + +/* #define RADCONST 0.017453293 */ +#define RADCONST 0.785398163 +#define ROOT2DIV2 0.707106781 + +typedef struct _pansig +{ + t_object x_obj; + float x_f; + float pan; + float left; + float right; +} t_pansig; + +static void *pansig_new(t_symbol *s, int argc, t_atom *argv) +{ + t_pansig *x = (t_pansig *)pd_new(pansig_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + // inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("pansigf")); + + x->x_f = 0; + return (x); +} + +static void pansig_getpan(t_floatarg signal, t_floatarg *left, t_floatarg *right) +{ + double tmp, result; + double angle; + signal = signal < -1 ? -1 : signal; + signal = signal > 1 ? 1 : signal; + angle = signal * RADCONST; + *right = ROOT2DIV2 * (cos(angle) + sin(angle)); + *left = ROOT2DIV2 * (cos(angle) - sin(angle)); + +/* if(signal < 0) */ +/* signal = 0; */ +/* if(signal > 0.999) */ +/* signal = 0.999; */ +/* tmp = (tan(1.5866 * signal - 0.785398) + 1) / 2; */ +/* result = sqrt(tmp); */ +/* if (result < 0) */ +/* *right = 0; */ +/* else if (result > 1) */ +/* *right = 1; */ +/* else */ +/* *right = result; */ +/* tmp = tmp * -1 + 1; */ +/* if(tmp < 0) */ +/* tmp = 0; */ +/* result = sqrt(tmp); */ +/* if (result < 0) */ +/* *left = 0; */ +/* else if (result > 1) */ +/* *left = 1; */ +/* else */ +/* *left = result; */ +} + +static t_int *pansig_perform(t_int *w) +{ + float *in1 = (t_float *)(w[1]); + float *in2 = (t_float *)(w[2]); + float *out1 = (t_float *)(w[3]); + float *out2 = (t_float *)(w[4]); + int n = (int)(w[5]); + t_pansig *x = (t_pansig *)(w[6]); + float value, value2, left, right; + while (n--) + { + value = *in1++; + value2 = *in2++; + pansig_getpan(value2, &left, &right); +/* *out1++ = value * x->left; */ +/* *out2++ = value * x->right; */ + *out1++ = value * left; + *out2++ = value * right; +/* *out1++ = value; */ +/* *out2++ = value; */ + } + return (w+7); +} + +static void pansig_dsp(t_pansig *x, t_signal **sp) +{ + int n = sp[0]->s_n; + float *in1 = sp[0]->s_vec; + float *in2 = sp[1]->s_vec; + float *out1 = sp[2]->s_vec; + float *out2 = sp[3]->s_vec; + + dsp_add(pansig_perform, 6, + in1, in2, out1, out2, n, x); +} + +void pansig_f(t_pansig *x, t_floatarg f) +{ + double tmp, result; + if(f < 0) + f = 0; + if(f > 0.999) + f = 0.999; + tmp = (tan(1.5866 * f - 0.785398) + 1) / 2; + result = sqrt(tmp); + if (result < 0) + x->right = 0; + else if (result > 1) + x->right = 1; + else + x->right = result; + tmp = tmp * -1 + 1; + if(tmp < 0) + tmp = 0; + result = sqrt(tmp); + if (result < 0) + x->left = 0; + else if (result > 1) + x->left = 1; + else + x->left = result; +} + +void pansig_tilde_setup(void) +{ + pansig_class = class_new(gensym("pansig~"), (t_newmethod)pansig_new, 0, + sizeof(t_pansig), 0, A_GIMME, 0); + class_addmethod(pansig_class, nullfn, gensym("signal"), 0); + + class_addmethod(pansig_class, (t_method)pansig_dsp, gensym("dsp"), 0); + // class_addmethod(pansig_class, (t_method)pansig_f, gensym("pansigf"), A_FLOAT, 0); +} diff --git a/pansig~.pd b/pansig~.pd new file mode 100644 index 0000000..29e6124 --- /dev/null +++ b/pansig~.pd @@ -0,0 +1,104 @@ +#N canvas 5 21 629 519 10; +#X floatatom 462 138 4 0 0; +#X floatatom 187 239 0 0 0; +#N canvas 184 223 495 266 output 0; +#X obj 338 160 t b; +#X obj 338 110 f; +#X obj 338 60 inlet; +#X text 344 29 mute; +#X obj 338 185 f; +#X msg 425 178 0; +#X msg 338 85 bang; +#X obj 338 135 moses 1; +#X obj 425 153 t b f; +#X obj 397 117 moses 1; +#X obj 83 148 dbtorms; +#X obj 397 92 r master-lvl; +#X obj 83 42 r master-lvl; +#X obj 338 210 s master-lvl; +#X obj -15 176 inlet~; +#X obj 199 41 inlet; +#X text 199 18 level; +#X obj 199 100 s master-lvl; +#X msg 96 65 set \$1; +#X obj 96 89 outlet; +#X msg 214 64 \; pd dsp 1; +#X obj 83 194 line~; +#X obj -15 207 *~; +#X obj -15 236 dac~; +#X obj 83 171 pack 0 50; +#X text -17 153 audio; +#X text 93 110 show level; +#X obj 31 182 inlet~; +#X obj 31 218 *~; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 6 0; +#X connect 4 0 13 0; +#X connect 5 0 13 0; +#X connect 6 0 1 0; +#X connect 7 0 0 0; +#X connect 7 1 8 0; +#X connect 8 0 5 0; +#X connect 9 1 4 1; +#X connect 10 0 24 0; +#X connect 11 0 1 1; +#X connect 11 0 9 0; +#X connect 12 0 10 0; +#X connect 12 0 18 0; +#X connect 14 0 22 0; +#X connect 15 0 17 0; +#X connect 15 0 20 0; +#X connect 18 0 19 0; +#X connect 21 0 22 1; +#X connect 21 0 28 1; +#X connect 22 0 23 0; +#X connect 24 0 21 0; +#X connect 27 0 28 0; +#X connect 28 0 23 1; +#X restore 158 267 pd output; +#X msg 216 239 MUTE; +#X text 250 238 <-- output amplitude; +#N canvas 5 21 600 400 pulse 1; +#X obj 175 203 cos~; +#X obj 175 131 -~ 0.5; +#X obj 175 179 clip~ -0.5 0.5; +#X obj 175 227 hip~ 5; +#X obj 175 155 *~ 82; +#X obj 175 107 phasor~ 16; +#X obj 175 251 outlet~; +#X floatatom 169 61 4 0 0; +#X connect 0 0 3 0; +#X connect 1 0 4 0; +#X connect 2 0 0 0; +#X connect 3 0 6 0; +#X connect 4 0 2 0; +#X connect 5 0 1 0; +#X connect 7 0 5 0; +#X restore 122 46 pd pulse; +#X msg 368 41 \; pd dsp 1; +#X msg 438 41 \; pd dsp 0; +#X text 390 72 ON; +#X text 455 72 OFF; +#X obj 369 16 loadbang; +#X obj 461 162 / 100; +#X msg 461 182 \$1 30; +#X obj 460 206 line; +#X obj 159 151 pansig~; +#X obj 222 113 osc~ 0.01; +#X floatatom 222 61 4 0 0; +#X obj 263 153 noise~; +#X obj 222 86 / 100; +#X connect 0 0 11 0; +#X connect 1 0 2 2; +#X connect 2 0 1 0; +#X connect 3 0 2 3; +#X connect 5 0 14 0; +#X connect 10 0 6 0; +#X connect 11 0 12 0; +#X connect 12 0 13 0; +#X connect 14 0 2 0; +#X connect 14 1 2 1; +#X connect 15 0 14 1; +#X connect 16 0 18 0; +#X connect 18 0 15 0; diff --git a/pan~.c b/pan~.c new file mode 100644 index 0000000..028e8a9 --- /dev/null +++ b/pan~.c @@ -0,0 +1,104 @@ +/*************************************************************************** + * File: pan~.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd signal external. Equal-power stereo panning + * Angle input specified in degrees. -45 left, 0 centre, 45 right. + * See supporting Pd patch: pan~.pd + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + + +#include "m_pd.h" +#include + +static t_class *pan_class; +#define RADCONST 0.017453293 +#define ROOT2DIV2 0.707106781 + +typedef struct _pan +{ + t_object x_obj; + float x_f; + float pan; + float left; + float right; +} t_pan; + +static void *pan_new(t_symbol *s, int argc, t_atom *argv) +{ + t_pan *x = (t_pan *)pd_new(pan_class); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("panf")); + + x->x_f = 0; + x->left = ROOT2DIV2; + x->right = ROOT2DIV2; + return (x); +} + +static t_int *pan_perform(t_int *w) +{ + float *in1 = (t_float *)(w[1]); + float *out1 = (t_float *)(w[2]); + float *out2 = (t_float *)(w[3]); + int n = (int)(w[4]); + t_pan *x = (t_pan *)(w[5]); + float value; + while (n--) + { + value = *in1++; + *out1++ = value * x->left; + *out2++ = value * x->right; + } + return (w+6); +} + +static void pan_dsp(t_pan *x, t_signal **sp) +{ + int n = sp[0]->s_n; + float *in1 = sp[0]->s_vec; + float *out1 = sp[1]->s_vec; + float *out2 = sp[2]->s_vec; + + dsp_add(pan_perform, 5, + in1, out1, out2, n, x); +} + +void pan_f(t_pan *x, t_floatarg f) +{ + double angle; + f = f < -45 ? -45 : f; + f = f > 45 ? 45 : f; + angle = f * RADCONST; // convert degrees to radians + x->right = ROOT2DIV2 * (cos(angle) + sin(angle)); + x->left = ROOT2DIV2 * (cos(angle) - sin(angle)); +/* post("left = %f : right = %f", x->left, x->right); */ +} + +void pan_tilde_setup(void) +{ + pan_class = class_new(gensym("pan~"), (t_newmethod)pan_new, 0, + sizeof(t_pan), 0, A_GIMME, 0); + class_addmethod(pan_class, nullfn, gensym("signal"), 0); + + class_addmethod(pan_class, (t_method)pan_dsp, gensym("dsp"), 0); + class_addmethod(pan_class, (t_method)pan_f, gensym("panf"), A_FLOAT, 0); +} diff --git a/pan~.pd b/pan~.pd new file mode 100644 index 0000000..bf3533a --- /dev/null +++ b/pan~.pd @@ -0,0 +1,94 @@ +#N canvas 5 21 629 519 10; +#X obj 159 151 pan~; +#X floatatom 200 120 4 0 0; +#X floatatom 187 239 0 0 0; +#N canvas 184 223 495 266 output 0; +#X obj 338 160 t b; +#X obj 338 110 f; +#X obj 338 60 inlet; +#X text 344 29 mute; +#X obj 338 185 f; +#X msg 425 178 0; +#X msg 338 85 bang; +#X obj 338 135 moses 1; +#X obj 425 153 t b f; +#X obj 397 117 moses 1; +#X obj 83 148 dbtorms; +#X obj 397 92 r master-lvl; +#X obj 83 42 r master-lvl; +#X obj 338 210 s master-lvl; +#X obj -15 176 inlet~; +#X obj 199 41 inlet; +#X text 199 18 level; +#X obj 199 100 s master-lvl; +#X msg 96 65 set \$1; +#X obj 96 89 outlet; +#X msg 214 64 \; pd dsp 1; +#X obj 83 194 line~; +#X obj -15 207 *~; +#X obj -15 236 dac~; +#X obj 83 171 pack 0 50; +#X text -17 153 audio; +#X text 93 110 show level; +#X obj 31 182 inlet~; +#X obj 31 218 *~; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 6 0; +#X connect 4 0 13 0; +#X connect 5 0 13 0; +#X connect 6 0 1 0; +#X connect 7 0 0 0; +#X connect 7 1 8 0; +#X connect 8 0 5 0; +#X connect 9 1 4 1; +#X connect 10 0 24 0; +#X connect 11 0 1 1; +#X connect 11 0 9 0; +#X connect 12 0 10 0; +#X connect 12 0 18 0; +#X connect 14 0 22 0; +#X connect 15 0 17 0; +#X connect 15 0 20 0; +#X connect 18 0 19 0; +#X connect 21 0 22 1; +#X connect 21 0 28 1; +#X connect 22 0 23 0; +#X connect 24 0 21 0; +#X connect 27 0 28 0; +#X connect 28 0 23 1; +#X restore 158 267 pd output; +#X msg 216 239 MUTE; +#X text 250 238 <-- output amplitude; +#N canvas 5 21 600 400 pulse 0; +#X obj 175 203 cos~; +#X obj 175 131 -~ 0.5; +#X obj 175 179 clip~ -0.5 0.5; +#X obj 175 227 hip~ 5; +#X obj 175 155 *~ 82; +#X obj 175 107 phasor~ 16; +#X obj 175 251 outlet~; +#X connect 0 0 3 0; +#X connect 1 0 4 0; +#X connect 2 0 0 0; +#X connect 3 0 6 0; +#X connect 4 0 2 0; +#X connect 5 0 1 0; +#X restore 122 46 pd pulse; +#X msg 368 41 \; pd dsp 1; +#X msg 438 41 \; pd dsp 0; +#X text 390 72 ON; +#X text 455 72 OFF; +#X obj 369 16 loadbang; +#X text 239 120 angle in degrees range -45 to 45; +#X text 459 335 IM 2001; +#X text -9 32 pan~; +#X text -9 51 equal power panning; +#X connect 0 0 3 0; +#X connect 0 1 3 1; +#X connect 1 0 0 1; +#X connect 2 0 3 2; +#X connect 3 0 2 0; +#X connect 4 0 3 3; +#X connect 6 0 0 0; +#X connect 11 0 7 0; diff --git a/pol2rec~.c b/pol2rec~.c new file mode 100644 index 0000000..ff7f6de --- /dev/null +++ b/pol2rec~.c @@ -0,0 +1,137 @@ +/*************************************************************************** + * File: pol2rec~.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd signal external. Converts polar coordinates into rectangular coordinates. + * Used in conjuction with rec2pol~ (also in motex) and rfft~ + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +#include "m_pd.h" +#include + +static t_class *pol2rec_class; + +#define HALFPI 1.570796327 +#define PI 3.141592654 +#define PIHALF 4.71238898 +typedef struct _pol2rec +{ + t_object x_obj; + float x_f; + float pol2rec; + float left; + float right; +} t_pol2rec; + +static void *pol2rec_new(t_symbol *s, int argc, t_atom *argv) +{ + t_pol2rec *x = (t_pol2rec *)pd_new(pol2rec_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + return (x); +} + +/* static void pol2rec_doit(t_float phase, t_float mag, double *x, double *y) */ +/* { */ +/* *x = mag*cos(phase); */ +/* *y = mag*sin(phase); */ +/* } */ + +static t_int *pol2rec_perform8(t_int *w) +{ + t_float *in1 = (t_float *)(w[1]); + t_float *in2 = (t_float *)(w[2]); + t_float *out1 = (t_float *)(w[3]); + t_float *out2 = (t_float *)(w[4]); + int n = (int)(w[5]); + for (; n; n -= 8, in1 += 8, out1 += 8, in2 += 8, out2 += 8) + { + t_float p0 = in1[0], p1 = in1[1], p2 = in1[2], p3 = in1[3]; + t_float p4 = in1[4], p5 = in1[5], p6 = in1[6], p7 = in1[7]; + t_float m0 = in2[0], m1 = in2[1], m2 = in2[2], m3 = in2[3]; + t_float m4 = in2[4], m5 = in2[5], m6 = in2[6], m7 = in2[7]; + out1[0] = m0*cos(p0); + out1[1] = m1*cos(p1); + out1[2] = m2*cos(p2); + out1[3] = m3*cos(p3); + out1[4] = m4*cos(p4); + out1[5] = m5*cos(p5); + out1[6] = m6*cos(p6); + out1[7] = m7*cos(p7); + out2[0] = m0*sin(p0); + out2[1] = m1*sin(p1); + out2[2] = m2*sin(p2); + out2[3] = m3*sin(p3); + out2[4] = m4*sin(p4); + out2[5] = m5*sin(p5); + out2[6] = m6*sin(p6); + out2[7] = m7*sin(p7); + } + return (w+6); +} + +static t_int *pol2rec_perform(t_int *w) +{ + float *in1 = (t_float *)(w[1]); + float *in2 = (t_float *)(w[2]); + float *out1 = (t_float *)(w[3]); + float *out2 = (t_float *)(w[4]); + int n = (int)(w[5]); + double phase, mag, x, y; + while (n--) + { + phase = *in1++; mag = *in2++; + *out1++ = mag*cos(phase); + *out2++ = mag*sin(phase);; + } + return (w+6); +} + +static void pol2rec_dsp(t_pol2rec *x, t_signal **sp) +{ + int n = sp[0]->s_n; + float *in1 = sp[0]->s_vec; + float *in2 = sp[1]->s_vec; + float *out1 = sp[2]->s_vec; + float *out2 = sp[3]->s_vec; + + if (n&7) + { + dsp_add(pol2rec_perform, 5, in1, in2, out1, out2, n); + post("it's a seven"); + } + else + dsp_add(pol2rec_perform8, 5, in1, in2, out1, out2, n); +} + + + +void pol2rec_tilde_setup(void) +{ + pol2rec_class = class_new(gensym("pol2rec~"), (t_newmethod)pol2rec_new, 0, + sizeof(t_pol2rec), 0, A_GIMME, 0); + class_addmethod(pol2rec_class, nullfn, gensym("signal"), 0); + + class_addmethod(pol2rec_class, (t_method)pol2rec_dsp, gensym("dsp"), 0); + CLASS_MAINSIGNALIN(pol2rec_class, t_pol2rec, x_f); + +} diff --git a/polvoc.pd b/polvoc.pd new file mode 100644 index 0000000..02ea2e1 --- /dev/null +++ b/polvoc.pd @@ -0,0 +1,178 @@ +#N canvas 0 37 876 567 10; +#N canvas 217 33 719 609 fft-analysis 0; +#X obj 213 68 *~; +#X obj 261 23 inlet~; +#X obj 213 91 rfft~; +#X obj 46 403 *~; +#X obj 76 66 *~; +#X obj 113 1 inlet~; +#X obj 61 34 tabreceive~ hanning; +#X obj 78 91 rfft~; +#X obj 77 541 outlet~; +#X obj 81 170 rec2pol~; +#X obj 128 127 *~; +#X obj 88 127 *~; +#X obj 248 118 *~; +#X obj 213 118 *~; +#X obj 97 379 rifft~; +#X obj 170 333 pol2rec~; +#X obj 159 222 *~; +#X obj 191 160 rec2pol~; +#X obj 221 259 *~ 0.02; +#X obj 221 286 *~ 1.4; +#X obj 502 311 block~ 1024 4; +#X obj 141 474 *~ 0.05; +#X text 251 439 noisegate arguments: threshold \, fadein time \, fadeout time; +#X obj 112 441 noisegate~ 80 100 200; +#X obj 302 74 sig~ 0.0097; +#X obj 130 88 sig~ 0.001; +#X connect 0 0 2 0; +#X connect 1 0 0 1; +#X connect 2 0 13 0; +#X connect 2 1 12 0; +#X connect 3 0 23 0; +#X connect 4 0 7 0; +#X connect 5 0 4 1; +#X connect 6 0 4 0; +#X connect 6 0 0 0; +#X connect 6 0 3 0; +#X connect 7 0 11 0; +#X connect 7 1 10 0; +#X connect 9 0 15 0; +#X connect 9 1 16 0; +#X connect 10 0 9 1; +#X connect 11 0 9 0; +#X connect 12 0 17 1; +#X connect 13 0 17 0; +#X connect 14 0 3 1; +#X connect 15 0 14 0; +#X connect 15 1 14 1; +#X connect 16 0 19 0; +#X connect 17 1 16 1; +#X connect 17 1 18 0; +#X connect 18 0 19 0; +#X connect 19 0 15 1; +#X connect 23 0 8 0; +#X connect 23 0 21 0; +#X connect 24 0 12 1; +#X connect 24 0 13 1; +#X connect 25 0 11 1; +#X connect 25 0 10 1; +#X restore 326 407 pd fft-analysis; +#X obj 326 431 *~; +#X obj 474 448 line~; +#X floatatom 680 49 0 0 0; +#N canvas 194 37 397 591 output 0; +#X obj 62 191 t b; +#X obj 62 144 f; +#X obj 62 96 inlet; +#X text 67 76 mute; +#X obj 62 215 f; +#X msg 127 230 0; +#X msg 62 120 bang; +#X obj 62 167 moses 1; +#X obj 127 207 t b f; +#X obj 91 417 outlet; +#X msg 91 393 set \$1; +#X obj 175 154 moses 1; +#X obj 212 419 dbtorms; +#X obj 212 443 pack 0 100; +#X obj 175 130 r master-lvl; +#X obj 91 360 r master-lvl; +#X obj 78 269 s master-lvl; +#X obj 212 467 s master-amp; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 6 0; +#X connect 4 0 16 0; +#X connect 5 0 16 0; +#X connect 6 0 1 0; +#X connect 7 0 0 0; +#X connect 7 1 8 0; +#X connect 8 0 5 0; +#X connect 10 0 9 0; +#X connect 11 1 4 1; +#X connect 12 0 13 0; +#X connect 13 0 17 0; +#X connect 14 0 1 1; +#X connect 14 0 11 0; +#X connect 15 0 10 0; +#X connect 15 0 12 0; +#X restore 680 26 pd output; +#X msg 680 2 mute; +#X text 717 43 MASTER; +#X text 717 57 LEVEL; +#X obj 680 74 s master-lvl; +#X obj 472 421 r master-amp; +#N canvas 275 71 767 761 hanning-window 0; +#X obj 92 206 phasor~; +#X obj 92 234 cos~; +#X obj 23 328 tabwrite~ hanning; +#X obj 30 252 -~; +#X obj 30 218 sig~ 1; +#X msg 37 180 0; +#X text 141 13 CALCULATE HANNING; +#X text 141 27 WINDOW TABLE; +#X graph graph1 0 -1 1024 1 275 581 675 281; +#X array hanning 1024 float; +#X pop; +#X msg 275 547 \; hanning resize 1024; +#X obj 93 131 / 1024; +#X obj 93 171 sig~; +#X text 175 148 sample rate / window size; +#X msg 23 144 bang; +#X obj 66 269 sig~ 0.5; +#X obj 49 300 *~; +#X obj 67 96 samplerate~; +#X obj 25 23 r window-size; +#X obj 25 53 t b f; +#X connect 0 0 1 0; +#X connect 1 0 3 1; +#X connect 3 0 15 0; +#X connect 4 0 3 0; +#X connect 5 0 0 1; +#X connect 10 0 11 0; +#X connect 11 0 0 0; +#X connect 13 0 2 0; +#X connect 13 0 5 0; +#X connect 14 0 15 1; +#X connect 15 0 2 0; +#X connect 16 0 10 0; +#X connect 17 0 18 0; +#X connect 18 0 16 0; +#X connect 18 0 13 0; +#X connect 18 1 10 1; +#X restore 675 143 pd hanning-window; +#X msg 393 66 \; window-size 1024 \; pd dsp 1; +#X text 434 370 filter; +#X text 436 385 input; +#X obj 326 254 phasor~ 220; +#X floatatom 358 151 4 0 0; +#X obj 341 185 mtof; +#X obj 351 293 noise~; +#X obj 351 317 *~ 0.12; +#X obj 201 247 adc~; +#X obj 393 12 loadbang; +#X msg 295 80 36; +#X text 13 81 Example using rec2pol & pol2rec; +#X text 84 245 talk into this:; +#X text 401 150 adjust pitch; +#X text 654 419 IM 2001; +#X obj 322 468 dac~; +#X connect 0 0 1 0; +#X connect 1 0 26 0; +#X connect 1 0 26 1; +#X connect 2 0 1 1; +#X connect 3 0 8 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 9 0 2 0; +#X connect 14 0 0 0; +#X connect 15 0 16 0; +#X connect 16 0 14 0; +#X connect 17 0 18 0; +#X connect 18 0 0 0; +#X connect 19 0 0 1; +#X connect 20 0 11 0; +#X connect 20 0 21 0; +#X connect 21 0 15 0; diff --git a/polygate~.c b/polygate~.c new file mode 100644 index 0000000..eb5771b --- /dev/null +++ b/polygate~.c @@ -0,0 +1,518 @@ +/*************************************************************************** + * File: polygate~.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd signal external. Switches between multiple signal inlets + * with either linear or equal-power crossfade. Polyphonic and with variable fade rate. + * See supporting Pd patch: polygate~.pd + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +#include "m_pd.h" +#include +#include + +#define HALFPI 1.570796327 + +static t_class *polygate_class; + +typedef struct _polygateelement // float outlets - signifying activity status of corresponding signal inlet +{ + t_outlet *e_outlet; +} t_polygateelement; + +#define INPUTLIMIT 10 +#define LINEAR 0 +#define EPOWER 1 +#define EPMIN 0 // minimum crossfade time (msec) for epower crossfade (below this epower fades sound too crunchy) +// NB - now set to zero - as new 'equal power' now used doesn't have this problem + +#define TIMEUNITPERSEC (32.*441000.) + +typedef struct _ip // keeps track of each signal input +{ + int active[INPUTLIMIT]; + int counter[INPUTLIMIT]; + double timeoff[INPUTLIMIT]; + float fade[INPUTLIMIT]; + float *in[INPUTLIMIT]; +} t_ip; + +typedef struct _polygate +{ + t_object x_obj; + float x_f; + int choice; + int lastchoice; + int actuallastchoice; + int ninlets; + int fadetime; + double changetime; + int fadecount; + int fadeticks; + int firsttick; + int fadetype; + int lastfadetype; + int fadealert; + float srate; + t_polygateelement *x_vec; + t_ip ip; +} t_polygate; + +static void *polygate_new(t_symbol *s, int argc, t_atom *argv) +{ + int usedefault = 0, i; + t_polygateelement *e, *b; + t_polygate *x = (t_polygate *)pd_new(polygate_class); + x->srate = sys_getsr(); + if(argc == 0 || argc > 3) + usedefault = 1; + else if(argc == 1 && argv[0].a_type != A_FLOAT) + usedefault = 1; + else if(argc >= 2) + if(argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT) + usedefault = 1; + if(argc == 3) + { + if(argv[2].a_type == A_SYMBOL && !strcmp(argv[2].a_w.w_symbol->s_name, "linear")) + x->fadetype = x->lastfadetype = LINEAR; + else + if(argv[1].a_w.w_float >= EPMIN) + { + post("polygate~: 3rd optional argument should be \"linear\". Reverting to equal power default"); + x->fadetype = x->lastfadetype = EPOWER; + } + else + { + post("polygate~: 3rd optional argument should be \"linear\". \nFade rate less than %d msec - using linear fading", EPMIN); + x->fadetype = x->lastfadetype = LINEAR; + } + } + else + { + if(argv[1].a_w.w_float >= EPMIN) + x->fadetype = x->lastfadetype = EPOWER; + else + { + post("polygate~: fade rate less than %d msec - using linear fading", EPMIN); + x->fadetype = x->lastfadetype = LINEAR; + } + } + if(usedefault) + { + post("polygate~: Incompatible arguments. Using base defaults"); + x->fadetype = x->lastfadetype = LINEAR; + x->ninlets = 1; + x->fadetime = 1; + } + else + { + x->ninlets = argv[0].a_w.w_float < 1 ? 1 : argv[0].a_w.w_float; + if(x->ninlets > INPUTLIMIT) + { + x->ninlets = INPUTLIMIT; + post("polygate~: maximum of %d inlets", INPUTLIMIT); + } + x->fadetime = argv[1].a_w.w_float > 0 ? argv[1].a_w.w_float : 1; + } + x->x_vec = (t_polygateelement *)getbytes(x->ninlets * sizeof(*x->x_vec)); + for(i = 0; i < x->ninlets - 1; i++) + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + for (i = 0, e = x->x_vec; i < x->ninlets; i++, e++) + e->e_outlet = outlet_new(&x->x_obj, &s_float); + x->choice = 0; x->lastchoice = x->actuallastchoice = 0; + x->fadecount = 0; + x->fadeticks = (int)(x->srate / 1000 * x->fadetime); // no. of ticks to reach specified fade 'rate' + x->firsttick = 1; + x->fadealert = 0; + x->x_f = 0; + for(i = 0; i < INPUTLIMIT; i++) + { + x->ip.active[i] = 0; + x->ip.counter[i] = 0; + x->ip.timeoff[i] = 0; + x->ip.fade[i] = 0; + } + return (x); +} + +static void adjustcounters2epower(t_polygate *x); +static void adjustcounters2linear(t_polygate *x); + +void polygate_f(t_polygate *x, t_floatarg f) +{ + f = (int)f; + f = f > x->ninlets ? x->ninlets : f; + f = f < 0 ? 0 : f; + if(f != x->lastchoice) + { + t_polygateelement *e; + if(f == x->actuallastchoice) + x->fadecount = x->fadeticks - x->fadecount; + else + x->fadecount = 0; + x->choice = f; + if(x->choice) + { + e = x->x_vec; + e += x->choice - 1; + outlet_float(e->e_outlet, 1); + x->ip.active[x->choice - 1] = 1; +/* if(x->fadealert) */ +/* { */ +/* x->fadealert = 0; */ +/* adjustcounters2epower(x); */ +/* } */ + } + if(x->lastchoice) + { + x->ip.active[x->lastchoice - 1] = 0; + x->ip.timeoff[x->lastchoice - 1] = clock_getlogicaltime(); + } +/* else if(x->fadetype) // changing from zero as equal power */ +/* { */ +/* // x->fadealert = 1; */ +/* adjustcounters2epower(x); */ +/* } */ +/* if(!x->choice && x->fadetype && x->actuallastchoice) */ +/* adjustcounters2linear(x); */ + x->actuallastchoice = x->lastchoice; + x->lastchoice = x->choice; + } +} + + +static void checkswitchstatus(t_polygate *x) // checks to see which input feeds ought to be "switch~"ed off +{ + int i; + t_polygateelement *e; + for(i = 0; i < x->ninlets; i++) + { + if(!x->ip.active[i]) + if(clock_gettimesince(x->ip.timeoff[i]) > x->fadetime + && x->ip.timeoff[i]) + { + e = x->x_vec; + e += i; + x->ip.timeoff[i] = 0; + outlet_float(e->e_outlet, 0); + x->ip.fade[i] = 0; + } + } +} + +static void updatefades(t_polygate *x) +{ + int i; + for(i = 0; i < x->ninlets; i++) + { + if(!x->ip.counter[i]) + x->ip.fade[i] = 0; + if(x->ip.active[i] && x->ip.counter[i] < x->fadeticks) + { + if(x->ip.counter[i]) + x->ip.fade[i] = x->ip.counter[i] / (float)x->fadeticks; + x->ip.counter[i]++; + } + else if (!x->ip.active[i] && x->ip.counter[i] > 0) + { + x->ip.fade[i] = x->ip.counter[i] / (float)x->fadeticks; + x->ip.counter[i]--; + } + } +} + +static double epower(double rate) +{ + double tmp; + if(rate < 0) + rate = 0; + if(rate > 0.999) + rate = 0.999; +/* tmp = (tan(1.5866 * rate - 0.785398) + 1) / 2; */ + +/* tmp = pow(rate, 0.5); */ + rate *= HALFPI; +/* tmp = sin(HALFPI - rate); */ + tmp = cos(rate - HALFPI); + tmp = tmp < 0 ? 0 : tmp; + tmp = tmp > 1 ? 1 : tmp; +/* return sqrt(tmp); */ + return tmp; +} + +static double aepower(double ep) // convert from equal power to linear rate +{ +/* double answer = (atan(2*ep*ep - 1) + 0.785398) / 1.5866; */ + double answer = (acos(ep) + HALFPI) / HALFPI; + + answer = 2 - answer; // ??? - but does the trick + + answer = answer < 0 ? 0 : answer; + answer = answer > 1 ? 1 : answer; + return answer; +} + +static void adjustcounters2epower(t_polygate *x) // no longer used +{ + // called when shifting from a linear fade-in (from zero) to an equal power crossfade + // adjusts each input counter to smoothly match subsequent equal power scalings + int i; + double ep; + for(i = 0; i < x->ninlets; i++) + { + ep = x->ip.counter[i] / (double)x->fadeticks; + x->ip.counter[i] = aepower(ep) * (double)x->fadeticks; + } +} + +static void adjustcounters2linear(t_polygate *x) // no longer used +{ + // opposite of above + int i; + double rate; + for(i = 0; i < x->ninlets; i++) + { + rate = x->ip.counter[i] / (double)x->fadeticks; + x->ip.counter[i] = epower(rate) * (double)x->fadeticks; + } +} + +static void outputfades(t_int *w, int flag) +{ + t_polygate *x = (t_polygate *)(w[1]); + float *out = (t_float *)(w[3+x->ninlets]); + int n = (int)(w[2]); + int i; + for(i = 0; i < x->ninlets; i++) + x->ip.in[i] = (t_float *)(w[3+i]); + while (n--) + { + float sum = 0; + updatefades(x); + for(i = 0; i < x->ninlets; i++) + if(x->ip.fade[i]) + { + if(flag && x->fadetype == EPOWER) + sum += *x->ip.in[i]++ * epower(x->ip.fade[i]); + else + sum += *x->ip.in[i]++ * x->ip.fade[i]; + } + *out++ = sum; + } +} + +static t_int *polygate_perform(t_int *w) +{ + t_polygate *x = (t_polygate *)(w[1]); + int n = (int)(w[2]); + t_polygateelement *e; + float *out = (t_float *)(w[3+x->ninlets]); + if (x->actuallastchoice == 0 && x->choice == 0 && x->lastchoice == 0) // initial state + { + if(x->firsttick) + { + int i; + for (i = 0, e = x->x_vec; i < x->ninlets; i++, e++) + outlet_float(e->e_outlet, 0); + x->firsttick = 0; + } + while (n--) + *out++ = 0; + } + else if (x->actuallastchoice == 0 && x->choice != 0) // change from zero state to non-zero +/* outputfades(w, LINEAR); */ + outputfades(w, x->fadetype); + else if(x->choice != 0) // change from non-zero to a different non-zero + outputfades(w, EPOWER); + else if (x->actuallastchoice != 0 && x->choice == 0) // change to zero state from non-zero +/* outputfades(w, LINEAR); */ + outputfades(w, x->fadetype); + checkswitchstatus(x); + return (w+4+x->ninlets); +} + +static void polygate_dsp(t_polygate *x, t_signal **sp) +{ + int n = sp[0]->s_n, i; + // must be a smarter way.... + switch (x->ninlets) + { + case 1: dsp_add(polygate_perform, 4, x, n, sp[0]->s_vec, sp[1]->s_vec); + break; + case 2: dsp_add(polygate_perform, 5, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec); + break; + case 3: dsp_add(polygate_perform, 6, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec); + break; + case 4: dsp_add(polygate_perform, 7, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec); + break; + case 5: dsp_add(polygate_perform, 8, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec); + break; + case 6: dsp_add(polygate_perform, 9, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec, sp[6]->s_vec); + break; + case 7: dsp_add(polygate_perform, 10, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec); + break; + case 8: dsp_add(polygate_perform, 11, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, + sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec, sp[8]->s_vec); + break; + case 9: dsp_add(polygate_perform, 12, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, + sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec, sp[8]->s_vec, sp[9]->s_vec); + break; + case 10: dsp_add(polygate_perform, 13, x, n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, + sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec, sp[8]->s_vec, sp[9]->s_vec, sp[10]->s_vec); + break; + } +} + +static void polygate_free(t_polygate *x) +{ + freebytes(x->x_vec, x->ninlets * sizeof(*x->x_vec)); +} + +static void shortcheck(t_polygate *x, int newticks, int shorter) +{ + int i; + for(i = 0; i < x->ninlets; i++) + { + if(shorter && x->ip.timeoff[i]) // correct active timeoffs for new x->fadeticks (newticks) + x->ip.timeoff[i] = clock_getlogicaltime() - ((newticks - x->ip.counter[i]) / (x->srate / 1000.) - 1) * (TIMEUNITPERSEC / 1000.); + } +} +static void adjustcounters_ftimechange(t_polygate *x, int newticks, int shorter) +{ + int i; + shortcheck(x, newticks, shorter); + for(i = 0; i < x->ninlets; i++) + { +/* if(shorter && x->ip.timeoff[i]) // correct active timeoffs for new x->fadeticks (newticks) */ +/* x->ip.timeoff[i] = clock_getlogicaltime() - (newticks - x->ip.counter[i]) / (x->srate / 1000.) * (TIMEUNITPERSEC / 1000.); */ + if(x->ip.counter[i]) + x->ip.counter[i] = x->ip.fade[i] * (float)newticks; + + +/* post("x->ip.fade[i] = %f", x->ip.fade[i]); */ +/* updatefades(x); */ +/* x->ip.fade[i] = x->ip.counter[i] / (float)x->fadeticks; */ + } +} + +void polygate_ftimeepower(t_polygate *x, t_floatarg ftime) +{ + int newticks, i, shorter; + ftime = ftime < 1 ? 1 : ftime; + shorter = ftime < x->fadetime ? 1 : 0; + x->fadetime = (int)ftime; + newticks = (int)(x->srate / 1000 * x->fadetime); // no. of ticks to reach specified fade time + x->fadeticks = newticks; + if(ftime < EPMIN) + { + // NB - if we change to linear as a tone is fading out ----> click + if(x->lastfadetype != LINEAR) // change to linear + { + shortcheck(x, x->fadeticks, shorter); + for(i = 0; i < x->ninlets; i++) + { + if(x->ip.counter[i]) + { + float fade = x->ip.fade[i]; + int oldcounter = x->ip.counter[i]; + x->ip.counter[i] = epower(fade) * x->fadeticks; +/* post("%d fade = %f : epower = %f : oldcounter = %d : new = %d : newfade = %f", */ +/* i, fade, epower(fade), oldcounter, x->ip.counter[i], ( x->ip.counter[i]/ (float)x->fadeticks)); */ + x->ip.fade[i] = x->ip.counter[i]/ (float)x->fadeticks; // ??? + } + } + } + else // plain fade-time change - linear + adjustcounters_ftimechange(x, x->fadeticks, shorter); + x->lastfadetype = x->fadetype = LINEAR; + } + else + { + if(x->lastfadetype != EPOWER) // change to equal power + for(i = 0; i < x->ninlets; i++) + { + if(x->ip.counter[i]) + { + float fade = x->ip.fade[i]; + int oldcounter = x->ip.counter[i]; + x->ip.counter[i] = aepower(fade) * x->fadeticks; +/* post("%d fade = %f : oldcounter = %d : new = %d : epower = %f", */ +/* i, fade, oldcounter, x->ip.counter[i], epower( x->ip.counter[i]/ (float)x->fadeticks)); */ + x->ip.fade[i] = epower(x->ip.counter[i]/ (float)x->fadeticks); // ??? + } + } + else // plain fade-time change - equal power + adjustcounters_ftimechange(x, x->fadeticks, shorter); + x->lastfadetype = x->fadetype = EPOWER; + } +} + +static void polygate_ftimelinear(t_polygate *x, t_floatarg ftime) +{ + int newticks, i, shorter; + ftime = ftime < 1 ? 1 : ftime; + shorter = ftime < x->fadetime ? 1 : 0; + x->fadetime = (int)ftime; + newticks = (int)(x->srate / 1000 * x->fadetime); + x->fadeticks = newticks; + if(x->lastfadetype != LINEAR) + { + shortcheck(x, x->fadeticks, shorter); + for(i = 0; i < x->ninlets; i++) + { +/* float fade = x->ip.fade[i]; */ +/* x->ip.counter[i] = aepower(fade) * (float)newticks; */ + float fade = x->ip.fade[i]; + int oldcounter = x->ip.counter[i]; + x->ip.counter[i] = epower(fade) * x->fadeticks; + // post("%d fade = %f : epower = %f : oldcounter = %d : new = %d : newfade = %f", + // i, fade, epower(fade), oldcounter, x->ip.counter[i], ( x->ip.counter[i]/ (float)x->fadeticks)); + x->ip.fade[i] = x->ip.counter[i]/ (float)x->fadeticks; // ??? + + } + } + else + adjustcounters_ftimechange(x, newticks, shorter); + x->lastfadetype = x->fadetype = LINEAR; +} + +void polygate_tilde_setup(void) +{ + polygate_class = class_new(gensym("polygate~"), (t_newmethod)polygate_new, (t_method)polygate_free, + sizeof(t_polygate), 0, A_GIMME, 0); + class_addmethod(polygate_class, nullfn, gensym("signal"), 0); + class_addmethod(polygate_class, (t_method)polygate_dsp, gensym("dsp"), 0); + CLASS_MAINSIGNALIN(polygate_class, t_polygate, x_f); + class_addmethod(polygate_class, (t_method)polygate_f, gensym("choice"), A_FLOAT, 0); + class_addmethod(polygate_class, (t_method)polygate_ftimeepower, gensym("ftime-epower"), A_FLOAT, (t_atomtype) 0); + class_addmethod(polygate_class, (t_method)polygate_ftimelinear, gensym("ftime-linear"), A_FLOAT, (t_atomtype) 0); +} + + + + + + + + + + + diff --git a/polygate~.pd b/polygate~.pd new file mode 100644 index 0000000..90daa98 --- /dev/null +++ b/polygate~.pd @@ -0,0 +1,251 @@ +#N canvas 25 21 986 603 10; +#X obj 162 342 s tone1; +#N canvas 78 354 600 400 tone2 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 140 r tone2; +#X obj 123 161 osc~ 100; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 146 148 pd tone2; +#N canvas 0 0 600 400 tone3 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone3; +#X obj 123 161 osc~ 150; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 201 148 pd tone3; +#N canvas 32 253 600 400 tone4 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone4; +#X obj 129 162 osc~ 200; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 256 148 pd tone4; +#N canvas 0 0 600 400 tone5 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone5; +#X obj 121 160 osc~ 250; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 313 148 pd tone5; +#X obj 216 342 s tone2; +#X obj 267 342 s tone3; +#X obj 317 342 s tone4; +#X obj 368 342 s tone5; +#X text 312 -14 argument 2: fade time in msec; +#X text 312 -34 argument 1: number of input channels (1-10); +#X text 427 357 switch tones on & off when needed; +#X msg -116 415 \; pd dsp 1; +#X msg -48 416 \; pd dsp 0; +#X text -103 449 ON; +#X text -30 450 OFF; +#N canvas 29 106 600 400 tone6 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 124 162 osc~ 300; +#X obj 265 140 r tone6; +#X connect 2 0 0 0; +#X connect 3 0 1 0; +#X restore 372 148 pd tone6; +#N canvas 0 0 600 400 tone7 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 140 r tone7; +#X obj 124 162 osc~ 350; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 427 148 pd tone7; +#N canvas 0 0 600 400 tone8 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone8; +#X obj 123 162 osc~ 400; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 482 148 pd tone8; +#N canvas 32 253 600 400 tone9 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone9; +#X obj 129 162 osc~ 450; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 537 148 pd tone9; +#N canvas 0 0 600 400 tone10 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone10; +#X obj 123 162 osc~ 500; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 594 148 pd tone10; +#X obj 162 365 s tone6; +#X obj 216 365 s tone7; +#X obj 267 365 s tone8; +#X obj 317 365 s tone9; +#X obj 368 365 s tone10; +#X floatatom -90 333 0 0 0; +#N canvas 159 26 495 270 output 0; +#X obj 338 160 t b; +#X obj 338 110 f; +#X obj 338 60 inlet; +#X text 344 29 mute; +#X obj 338 185 f; +#X msg 425 178 0; +#X msg 338 85 bang; +#X obj 338 135 moses 1; +#X obj 425 153 t b f; +#X obj 397 117 moses 1; +#X obj 83 148 dbtorms; +#X obj 397 92 r master-lvl; +#X obj 83 42 r master-lvl; +#X obj 338 210 s master-lvl; +#X obj 22 182 inlet~; +#X obj 199 41 inlet; +#X text 199 18 level; +#X obj 199 100 s master-lvl; +#X msg 96 65 set \$1; +#X obj 96 89 outlet; +#X msg 214 64 \; pd dsp 1; +#X obj 83 194 line~; +#X obj 22 212 *~; +#X obj 22 241 dac~; +#X obj 83 171 pack 0 50; +#X text 20 159 audio; +#X text 93 110 show level; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 6 0; +#X connect 4 0 13 0; +#X connect 5 0 13 0; +#X connect 6 0 1 0; +#X connect 7 0 0 0; +#X connect 7 1 8 0; +#X connect 8 0 5 0; +#X connect 9 1 4 1; +#X connect 10 0 24 0; +#X connect 11 0 1 1; +#X connect 11 0 9 0; +#X connect 12 0 10 0; +#X connect 12 0 18 0; +#X connect 14 0 22 0; +#X connect 15 0 17 0; +#X connect 15 0 20 0; +#X connect 18 0 19 0; +#X connect 21 0 22 1; +#X connect 22 0 23 0; +#X connect 22 0 23 1; +#X connect 24 0 21 0; +#X restore -118 385 pd output; +#X msg -70 355 MUTE; +#X text -61 332 <-- output amplitude; +#N canvas 0 0 600 400 tone1 0; +#X obj 124 205 outlet~; +#X obj 258 182 switch~ 0; +#X obj 266 141 r tone1; +#X obj 124 162 osc~ 50; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X restore 91 148 pd tone1; +#X text 312 6 argument 3: (optional) "linear"; +#X text 312 -54 polygate~ - switch between signal inputs; +#X text 312 26 If 3rd argument isn't specified \, polygate~ will; +#X text 312 46 perform equal-power crossfades between inputs; +#X text 25 95 zero = off; +#X obj -183 355 loadbang; +#X msg -183 378 86; +#X floatatom -220 72 8 0 0; +#X floatatom -19 90 4 0 10; +#X msg -19 113 choice \$1; +#X floatatom -216 207 8 0 0; +#X msg -220 110 ftime-epower \$1; +#X msg -216 239 ftime-linear \$1; +#X text -220 38 change fade-time; +#X text -220 51 equal power; +#X text -218 172 change fade-time; +#X text -218 185 linear; +#X obj -19 -9 metro 80; +#X floatatom -19 -30 4 0 0; +#X floatatom 36 -29 4 0 0; +#X msg 75 -26 1000; +#X floatatom -237 8 8 0 0; +#X obj -19 14 shuffle 1 10 0.25; +#X msg -252 -26 200; +#X msg -218 -25 199; +#X msg 28 -59 80; +#X msg -234 -53 300; +#X msg -170 -61 3000; +#X msg -211 -87 22; +#X msg -133 207 22; +#X msg -204 -65 198; +#X msg -257 -87 170; +#X msg -185 -100 22; +#X obj 191 280 polygate~ 10 200; +#X obj 388 277 polygate~ 4 8000 linear; +#X text 533 276 example with linear startup; +#X text 26 83 change input channel 1- 10; +#X msg -99 212 3000; +#X text 424 436 IM 2001; +#X msg -162 -86 1000; +#X obj -87 -40 vslider 15 128 0 10 0 1 choice aaa choice 8 -8 1 10 8 18 18 5300; +#X msg -160 -39 10000; +#X floatatom 163 61 4 0 10; +#X obj 142 31 r choice; +#X connect 1 0 64 1; +#X connect 2 0 64 2; +#X connect 3 0 64 3; +#X connect 4 0 64 4; +#X connect 16 0 64 5; +#X connect 17 0 64 6; +#X connect 18 0 64 7; +#X connect 19 0 64 8; +#X connect 20 0 64 9; +#X connect 26 0 27 1; +#X connect 27 0 26 0; +#X connect 28 0 27 2; +#X connect 30 0 64 0; +#X connect 36 0 37 0; +#X connect 37 0 26 0; +#X connect 37 0 12 0; +#X connect 38 0 42 0; +#X connect 39 0 40 0; +#X connect 40 0 64 0; +#X connect 41 0 43 0; +#X connect 42 0 64 0; +#X connect 43 0 64 0; +#X connect 48 0 53 0; +#X connect 49 0 48 0; +#X connect 50 0 48 1; +#X connect 51 0 48 1; +#X connect 52 0 42 0; +#X connect 53 0 39 0; +#X connect 54 0 52 0; +#X connect 55 0 52 0; +#X connect 56 0 48 1; +#X connect 57 0 52 0; +#X connect 58 0 52 0; +#X connect 59 0 52 0; +#X connect 60 0 43 0; +#X connect 61 0 52 0; +#X connect 62 0 52 0; +#X connect 63 0 52 0; +#X connect 64 0 27 0; +#X connect 64 1 0 0; +#X connect 64 2 5 0; +#X connect 64 3 6 0; +#X connect 64 4 7 0; +#X connect 64 5 8 0; +#X connect 64 6 21 0; +#X connect 64 7 22 0; +#X connect 64 8 23 0; +#X connect 64 9 24 0; +#X connect 64 10 25 0; +#X connect 68 0 43 0; +#X connect 70 0 52 0; +#X connect 71 0 39 0; +#X connect 72 0 52 0; +#X connect 74 0 73 0; diff --git a/rec2pol~.c b/rec2pol~.c new file mode 100644 index 0000000..3df03c4 --- /dev/null +++ b/rec2pol~.c @@ -0,0 +1,134 @@ +/*************************************************************************** + * File: rec2pol~.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd signal external. Converts rectangular coordinates to polar. + * Used to convert sine & cosine output of 'rfft~' object to phase and magnitude values. + * Used in conjunction with pol2rec~ external in motex + * See supporting Pd patch: rec2pol~.pd & polcoc~.pd + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +#include "m_pd.h" +#include + +static t_class *rec2pol_class; + +typedef struct _rec2pol +{ + t_object x_obj; + float x_f; +} t_rec2pol; + +static void *rec2pol_new(t_symbol *s, int argc, t_atom *argv) +{ + t_rec2pol *x = (t_rec2pol *)pd_new(rec2pol_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + return (x); +} + +t_int *sigsqrt_perform(t_int *w); + + +static t_int *rec2pol_perform8(t_int *w) +{ + t_float *in1 = (t_float *)(w[1]); + t_float *in2 = (t_float *)(w[2]); + t_float *out1 = (t_float *)(w[3]); + t_float *out2 = (t_float *)(w[4]); + int n = (int)(w[5]); + for (; n; n -= 8, in1 += 8, out1 += 8, in2 += 8, out2 += 8) + { + t_float X0 = in1[0], X1 = in1[1], X2 = in1[2], X3 = in1[3]; + t_float X4 = in1[4], X5 = in1[5], X6 = in1[6], X7 = in1[7]; + t_float Y0 = in2[0], Y1 = in2[1], Y2 = in2[2], Y3 = in2[3]; + t_float Y4 = in2[4], Y5 = in2[5], Y6 = in2[6], Y7 = in2[7]; + out1[0] = atan2(Y0, X0); + out1[1] = atan2(Y1, X1); + out1[2] = atan2(Y2, X2); + out1[3] = atan2(Y3, X3); + out1[4] = atan2(Y4, X4); + out1[5] = atan2(Y5, X5); + out1[6] = atan2(Y6, X6); + out1[7] = atan2(Y7, X7); + out2[0] = X0*X0 + Y0*Y0; + out2[1] = X1*X1 + Y1*Y1; + out2[2] = X2*X2 + Y2*Y2; + out2[3] = X3*X3 + Y3*Y3; + out2[4] = X4*X4 + Y4*Y4; + out2[5] = X5*X5 + Y5*Y5; + out2[6] = X6*X6 + Y6*Y6; + out2[7] = X7*X7 + Y7*Y7; + } + return (w+6); +} + +static t_int *rec2pol_perform(t_int *w) +{ + float *in1 = (t_float *)(w[1]); + float *in2 = (t_float *)(w[2]); + float *out1 = (t_float *)(w[3]); + float *out2 = (t_float *)(w[4]); + int n = (int)(w[5]); + float x, y; + // double angle; + while (n--) + { + x = *in1++; + y = *in2++; + *out1++ = atan2(y, x); + *out2++ = x*x + y*y; + } + return (w+6); +} + +static void rec2pol_dsp(t_rec2pol *x, t_signal **sp) +{ + int n = sp[0]->s_n; + /* int n2 = (n>>1); */ + float *in1 = sp[0]->s_vec; + float *in2 = sp[1]->s_vec; + float *out1 = sp[2]->s_vec; + float *out2 = sp[3]->s_vec; + if (n&7) + dsp_add(rec2pol_perform, 5, in1, in2, out1, out2, n); + else + dsp_add(rec2pol_perform8, 5, in1, in2, out1, out2, n); + dsp_add(sigsqrt_perform, 3, out2, out2, n); +} + + + +void rec2pol_tilde_setup(void) +{ + rec2pol_class = class_new(gensym("rec2pol~"), (t_newmethod)rec2pol_new, 0, + sizeof(t_rec2pol), 0, A_GIMME, 0); + class_addmethod(rec2pol_class, nullfn, gensym("signal"), 0); + + class_addmethod(rec2pol_class, (t_method)rec2pol_dsp, gensym("dsp"), 0); + CLASS_MAINSIGNALIN(rec2pol_class, t_rec2pol, x_f); +} + + + + + diff --git a/rec2pol~.pd b/rec2pol~.pd new file mode 100644 index 0000000..b20693f --- /dev/null +++ b/rec2pol~.pd @@ -0,0 +1,44 @@ +#N canvas 83 81 488 482 10; +#X obj 151 219 sig~ 222; +#X obj 221 225 sig~ 111; +#X obj 133 352 snapshot~; +#X obj 205 352 snapshot~; +#X floatatom 109 392 8 0 0; +#X floatatom 215 396 8 0 0; +#X msg 117 319 bang; +#X floatatom 254 176 4 0 0; +#X floatatom 149 176 4 0 0; +#X obj 180 253 rec2pol~; +#X obj 180 311 pol2rec~; +#X obj 69 243 snapshot~; +#X floatatom 45 283 8 0 0; +#X msg 70 184 bang; +#X obj 315 242 snapshot~; +#X floatatom 291 289 8 0 0; +#X msg 315 225 bang; +#X text 37 6 rec2pol - convert rectangular coords to polar coords; +#X text 97 19 eg - convert sine & cosine output of rfft; +#X text 97 33 to phase and magnitude; +#X text 36 48 pol2rec - convert back; +#X text 400 422 IM 2001; +#X text 34 71 see also polvoc.pd for an example of use; +#X connect 0 0 9 0; +#X connect 1 0 9 1; +#X connect 2 0 4 0; +#X connect 3 0 5 0; +#X connect 6 0 2 0; +#X connect 6 0 3 0; +#X connect 7 0 1 0; +#X connect 8 0 0 0; +#X connect 9 0 11 0; +#X connect 9 0 10 0; +#X connect 9 1 14 0; +#X connect 9 1 10 1; +#X connect 10 0 2 0; +#X connect 10 1 3 0; +#X connect 11 0 12 0; +#X connect 13 0 11 0; +#X connect 13 0 14 0; +#X connect 13 0 6 0; +#X connect 14 0 15 0; +#X connect 16 0 14 0; diff --git a/shuffle.c b/shuffle.c new file mode 100644 index 0000000..a1bc1e8 --- /dev/null +++ b/shuffle.c @@ -0,0 +1,216 @@ +/*************************************************************************** + * File: shuffle.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd control external. a no-repeat random generator. + * Outputs numbers within a set range + * See supporting Pd patch: shuffle.pd + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +/* code for shuffle pd class */ + +#include "m_pd.h" + +#include +#include +#include +#include + + +typedef struct shuffle +{ + t_object t_ob; + float begin; + float end; + int size; /* size of pshuffle */ + int size_ptemp; + float fraction; /* fractional size of ptemp */ + int *pshuffle; + int *ptemp; + int index; +} t_shuffle; + +int itemPresent (t_shuffle *x, int test) +{ + int flag = 0; + int temp_flag = 0; + int i; + for (i = 0; i < x->size; i++) + { + if (test == x->pshuffle[i]) + temp_flag = 1; + flag = flag || temp_flag; + } + return flag; +} + + +void fillWithMin (t_shuffle *x) +{ + int i; + for (i = 0; i < x->size; i++) + { + x->pshuffle[i] = INT_MIN; + } +} + +void srubLastFraction (t_shuffle *x) +{ + int i; + for (i = 0; i < x->size_ptemp; i++) + x->pshuffle[x->size - 1 - i] = INT_MIN; +} + +void shuffleDeck (t_shuffle *x) +{ + double scaled_rand; + int answer; + int i = 0; + int done = 0; + while (i < x->size) + { + if (i >= x->size_ptemp && !done) + { + srubLastFraction(x); + done = 1; + } + scaled_rand = rand () / (float) RAND_MAX ; + scaled_rand *= (x->end - x->begin); + answer = (int) (scaled_rand + 0.5) + (int) x->begin; + if (!itemPresent (x, answer)) + { + x->pshuffle[i] = answer; + i++; + } + } +} + +void shuffle_float(t_shuffle *x, t_floatarg f) +{ + x->begin = f; + if (x->end < x->begin) + { + float tmp = x->begin; + x->begin = x->end; + x->end = tmp; + } + x->size = (int) x->end - (int) x->begin + 1; + x->index = 0; + free(x->pshuffle); + free(x->ptemp); + x->pshuffle = malloc ( x->size * sizeof(int)); + x->size_ptemp = (int) (x->fraction * x->size); + x->ptemp = malloc( x->size_ptemp * sizeof(int)); + fillWithMin (x); + shuffleDeck(x); +} + +void shuffle_ft1(t_shuffle *x, t_floatarg g) +{ + x->end = g; +} + +void shuffle_free(t_shuffle *x) +{ + free(x->pshuffle); + free(x->ptemp); +} + +t_class *shuffle_class; + +void shuffle_ft2(t_shuffle *x, t_floatarg f) +{ + if(f > 0.5) + { + post("Shuffle: fraction too great - set to 0.5"); + f = 0.5; + } + x->fraction = f; +} + + + +void shuffle_bang(t_shuffle *x) +{ + if (x->index == x->size) + { + int i; + for (i = 0; i < x->size_ptemp; i++) + { + x->ptemp[i] = x->pshuffle[x->size - 1 - i]; + } + fillWithMin (x); + for (i = 0; i < x->size_ptemp; i++) + x->pshuffle[x->size - 1 - i] = x->ptemp[i]; + shuffleDeck(x); + x->index = 0; + outlet_float(x->t_ob.ob_outlet, (float) x->pshuffle[x->index]); + } + else + outlet_float(x->t_ob.ob_outlet, (float) x->pshuffle[x->index]); + x->index++; +} + +void *shuffle_new(t_floatarg be, t_floatarg en, t_floatarg frac) +{ + t_shuffle *x = (t_shuffle *)pd_new(shuffle_class); + inlet_new(&x->t_ob, &x->t_ob.ob_pd, gensym("float"), gensym("ft1")); + inlet_new(&x->t_ob, &x->t_ob.ob_pd, gensym("float"), gensym("ft2")); + outlet_new(&x->t_ob, gensym("bang")); + if(frac > 0.5) + { + post("Shuffle: fraction too great - set to 0.5"); + frac = 0.5; + } + x->fraction = frac; + if(be < en) + { + x->end = en; + x->begin = be; + } + else + { + x->end = be; + x->begin = en; + } + x->index = 0; + x->size = (int) x->end - (int) x->begin + 1; + x->size_ptemp = (int) (x->fraction * x->size); + x->pshuffle = malloc (x->size * sizeof(int)); + x->ptemp = malloc (x->size_ptemp * sizeof(int)); + fillWithMin (x); + shuffleDeck(x); + return (void *)x; +} + + + +void shuffle_setup(void) +{ + shuffle_class = class_new(gensym("shuffle"), (t_newmethod)shuffle_new, + (t_method)shuffle_free, sizeof(t_shuffle), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(shuffle_class, (t_method)shuffle_bang, gensym("bang"), (t_atomtype) 0); + class_addmethod(shuffle_class, (t_method)shuffle_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(shuffle_class, (t_method)shuffle_ft2, gensym("ft2"), A_FLOAT, 0); + class_addfloat(shuffle_class, shuffle_float); + srand( (unsigned)time( NULL ) ); +} + + diff --git a/shuffle.pd b/shuffle.pd new file mode 100644 index 0000000..abd47a6 --- /dev/null +++ b/shuffle.pd @@ -0,0 +1,28 @@ +#N canvas 5 21 828 307 10; +#X floatatom 170 127 4 0 0; +#X floatatom 252 124 4 0 0; +#X floatatom 302 124 4 0 0; +#X floatatom 169 210 4 0 0; +#X msg 81 83 bang; +#X text 379 140 Argument 2: upper limit; +#X text 378 63 Shuffle; +#X text 379 158 Argument 3: fraction of the end of a series; +#X text 168 94 lower; +#X text 252 105 upper; +#X text 302 105 frac; +#X text 379 122 Argument 1: lower limit; +#X text 131 105 (activate changes); +#X text 379 176 and beginning of next (after reshuffle); +#X text 55 47 output shuffled; +#X text 55 65 integer series; +#X obj 169 169 shuffle -1 5 0.25; +#X text 379 194 where no repetitions occur (range betwwen 0 & 0.5); +#X text 379 104 comment; +#X text 379 86 A no-repeat random number generator; +#X text 378 105 shuffles a nuber series; +#X text 448 258 IM 2001; +#X connect 0 0 16 0; +#X connect 1 0 16 1; +#X connect 2 0 16 2; +#X connect 4 0 16 0; +#X connect 16 0 3 0; diff --git a/system.c b/system.c new file mode 100644 index 0000000..b52e054 --- /dev/null +++ b/system.c @@ -0,0 +1,76 @@ +/*************************************************************************** + * File: system.c + * Auth: Iain Mott [iain.mott@bigpond.com] + * Maintainer: Iain Mott [iain.mott@bigpond.com] + * Version: Part of motex_1.1.2 + * Date: January 2001 + * + * Description: Pd external. Send a system message to the console + * See supporting Pd patch: system.pd + * + * Copyright (C) 2001 by Iain Mott [iain.mott@bigpond.com] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License, which should be included with this + * program, for more details. + * + ****************************************************************************/ + +/* code for system pd class */ + +#include "m_pd.h" +#include +#include +#include + +typedef struct system +{ + t_object t_ob; +} t_system; + + +void system_anything(t_system *x, t_symbol *s, int ac, t_atom *av, t_floatarg f) +{ + char buf[MAXPDSTRING], message[MAXPDSTRING]; + int i; + strcpy(message, s->s_name); + strcat(message, " "); + for (i = 0; i < ac; i++) + { + atom_string(av+i, buf, MAXPDSTRING); + strcat(message, buf); + if (i < (ac - 1)) + strcat(message, " "); + } + system(message); +} + + +void system_free(void) +{ + /* post("system_free"); */ +} + +t_class *system_class; + +void *system_new(void) +{ + t_system *x = (t_system *)pd_new(system_class); + return (void *)x; +} + +void system_setup(void) +{ + post("system_setup"); + system_class = class_new(gensym("system"), (t_newmethod)system_new, + (t_method)system_free, sizeof(t_system), 0, 0); + class_addanything(system_class, system_anything); +} + diff --git a/system.pd b/system.pd new file mode 100644 index 0000000..867fee1 --- /dev/null +++ b/system.pd @@ -0,0 +1,8 @@ +#N canvas 131 96 450 300 10; +#X obj 151 137 system; +#X text 47 33 send a system message to the console; +#X msg 113 72 echo "Hello my name is" $USERNAME; +#X msg 160 102 ps -ef | grep $USERNAME; +#X text 242 186 IM 2001; +#X connect 2 0 0 0; +#X connect 3 0 0 0; -- cgit v1.2.1