From 8b0873392ad0db55fdb9d0cdfc670366bc96a9c9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 26 Apr 2010 03:10:47 +0000 Subject: converted maxlib to use libdir template, in preparations for debianizing it svn path=/trunk/externals/maxlib/; revision=13476 --- LICENSE | 346 --------- LICENSE.txt | 346 +++++++++ Makefile | 284 ++++++++ README | 38 - README.txt | 38 + allow-help.pd | 21 + allow.c | 112 +++ arbran-help.pd | 28 + arbran.c | 189 +++++ arraycopy-help.pd | 62 ++ arraycopy.c | 284 ++++++++ automata.txt | 178 +++++ average-help.pd | 29 + average.c | 202 +++++ beat-help.pd | 66 ++ beat.c | 403 ++++++++++ beta-help.pd | 14 + beta.c | 107 +++ bilex-help.pd | 12 + bilex.c | 91 +++ borax-help.pd | 86 +++ borax.c | 238 ++++++ cauchy-help.pd | 11 + cauchy.c | 89 +++ chord-help.pd | 37 + chord.c | 1822 ++++++++++++++++++++++++++++++++++++++++++++++ delta-help.pd | 20 + delta.c | 139 ++++ deny-help.pd | 20 + deny.c | 114 +++ dist-help.pd | 36 + dist.c | 279 +++++++ divide-help.pd | 18 + divide.c | 110 +++ divmod-help.pd | 20 + divmod.c | 100 +++ edge-help.pd | 17 + edge.c | 82 +++ examplescore.txt | 25 + expo-help.pd | 12 + expo.c | 86 +++ fifo-help.pd | 13 + fifo.c | 96 +++ gauss-help.pd | 14 + gauss.c | 88 +++ gestalt-help.pd | 51 ++ gestalt.c | 123 ++++ help/allow-help.pd | 21 - help/arbran-help.pd | 28 - help/arraycopy-help.pd | 62 -- help/automata.txt | 178 ----- help/average-help.pd | 29 - help/beat-help.pd | 66 -- help/beta-help.pd | 14 - help/bilex-help.pd | 12 - help/borax-help.pd | 86 --- help/cauchy-help.pd | 11 - help/chord-help.pd | 37 - help/delta-help.pd | 20 - help/deny-help.pd | 20 - help/dist-help.pd | 36 - help/divide-help.pd | 18 - help/divmod-help.pd | 20 - help/edge-help.pd | 17 - help/examplescore.txt | 25 - help/expo-help.pd | 12 - help/fifo-help.pd | 13 - help/gauss-help.pd | 14 - help/gestalt-help.pd | 51 -- help/history-help.pd | 30 - help/ignore-help.pd | 15 - help/iso-help.pd | 54 -- help/lifo-help.pd | 16 - help/limit-help.pd | 25 - help/linear-help.pd | 8 - help/listfifo-help.pd | 26 - help/listfunnel-help.pd | 21 - help/match-help.pd | 68 -- help/maxlib-help.pd | 123 ---- help/minus-help.pd | 17 - help/mlife-help.pd | 56 -- help/multi-help.pd | 17 - help/nchange-help.pd | 31 - help/netclient-help.pd | 51 -- help/netdist-help.pd | 37 - help/netrec-help.pd | 34 - help/netserver-help.pd | 50 -- help/nroute-help.pd | 37 - help/pitch-help.pd | 30 - help/plus-help.pd | 17 - help/poisson-help.pd | 12 - help/pulse-help.pd | 35 - help/remote-help.pd | 20 - help/rewrap-help.pd | 23 - help/rhythm-help.pd | 35 - help/scale-help.pd | 31 - help/score-help.pd | 52 -- help/speedlim-help.pd | 30 - help/split-help.pd | 24 - help/step-help.pd | 22 - help/subst-help.pd | 72 -- help/sync-help.pd | 53 -- help/temperature-help.pd | 16 - help/tilt-help.pd | 26 - help/timebang-help.pd | 17 - help/triang-help.pd | 9 - help/unroute-help.pd | 30 - help/urn-help.pd | 18 - help/velocity-help.pd | 14 - help/weibull-help.pd | 15 - help/wrap-help.pd | 22 - history-help.pd | 30 + history.c | 271 +++++++ ignore-help.pd | 15 + ignore.c | 119 +++ install.bat | 12 - iso-help.pd | 54 ++ iso.c | 219 ++++++ lifo-help.pd | 16 + lifo.c | 109 +++ limit-help.pd | 25 + limit.c | 125 ++++ linear-help.pd | 8 + linear.c | 81 +++ listfifo-help.pd | 26 + listfifo.c | 109 +++ listfunnel-help.pd | 21 + listfunnel.c | 92 +++ makefile | 398 ---------- match-help.pd | 68 ++ match.c | 274 +++++++ maxlib-help.pd | 123 ++++ maxlib-meta.pd | 8 + maxlib.c | 2 +- minus-help.pd | 17 + minus.c | 111 +++ mlife-help.pd | 56 ++ mlife.c | 515 +++++++++++++ multi-help.pd | 17 + multi.c | 110 +++ nchange-help.pd | 31 + nchange.c | 205 ++++++ netclient-help.pd | 51 ++ netclient.c | 396 ++++++++++ netdist-help.pd | 37 + netdist.c | 313 ++++++++ netrec-help.pd | 34 + netrec.c | 447 ++++++++++++ netserver-help.pd | 50 ++ netserver.c | 670 +++++++++++++++++ nroute-help.pd | 37 + nroute.c | 179 +++++ pitch-help.pd | 30 + pitch.c | 114 +++ plus-help.pd | 17 + plus.c | 110 +++ poisson-help.pd | 12 + poisson.c | 91 +++ pong-help.pd | 5 + pong.c | 332 +++++++++ pulse-help.pd | 35 + pulse.c | 301 ++++++++ remote-help.pd | 20 + remote.c | 108 +++ rewrap-help.pd | 23 + rewrap.c | 155 ++++ rhythm-help.pd | 35 + rhythm.c | 343 +++++++++ scale-help.pd | 31 + scale.c | 138 ++++ score-help.pd | 52 ++ score.c | 309 ++++++++ speedlim-help.pd | 30 + speedlim.c | 235 ++++++ split-help.pd | 24 + split.c | 95 +++ src/allow.c | 112 --- src/arbran.c | 189 ----- src/arraycopy.c | 284 -------- src/average.c | 202 ----- src/beat.c | 403 ---------- src/beta.c | 107 --- src/bilex.c | 91 --- src/borax.c | 238 ------ src/cauchy.c | 89 --- src/chord.c | 1822 ---------------------------------------------- src/delta.c | 139 ---- src/deny.c | 114 --- src/dist.c | 279 ------- src/divide.c | 110 --- src/divmod.c | 100 --- src/edge.c | 82 --- src/expo.c | 86 --- src/fifo.c | 96 --- src/gauss.c | 88 --- src/gestalt.c | 123 ---- src/history.c | 271 ------- src/ignore.c | 119 --- src/iso.c | 219 ------ src/lifo.c | 109 --- src/limit.c | 125 ---- src/linear.c | 81 --- src/listfifo.c | 109 --- src/listfunnel.c | 92 --- src/match.c | 274 ------- src/minus.c | 111 --- src/mlife.c | 515 ------------- src/multi.c | 110 --- src/nchange.c | 205 ------ src/netclient.c | 396 ---------- src/netdist.c | 313 -------- src/netrec.c | 447 ------------ src/netserver.c | 670 ----------------- src/nroute.c | 179 ----- src/pitch.c | 114 --- src/plus.c | 110 --- src/poisson.c | 91 --- src/pong.c | 332 --------- src/pulse.c | 301 -------- src/remote.c | 108 --- src/rewrap.c | 155 ---- src/rhythm.c | 343 --------- src/scale.c | 138 ---- src/score.c | 309 -------- src/speedlim.c | 235 ------ src/split.c | 95 --- src/step.c | 179 ----- src/subst.c | 424 ----------- src/sync.c | 294 -------- src/temperature.c | 120 --- src/tilt.c | 189 ----- src/timebang.c | 174 ----- src/triang.c | 80 -- src/unroute.c | 175 ----- src/urn.c | 152 ---- src/velocity.c | 112 --- src/weibull.c | 95 --- src/wrap.c | 142 ---- step-help.pd | 22 + step.c | 179 +++++ subst-help.pd | 72 ++ subst.c | 424 +++++++++++ sync-help.pd | 53 ++ sync.c | 294 ++++++++ temperature-help.pd | 16 + temperature.c | 120 +++ tilt-help.pd | 26 + tilt.c | 189 +++++ timebang-help.pd | 17 + timebang.c | 174 +++++ triang-help.pd | 9 + triang.c | 80 ++ unroute-help.pd | 30 + unroute.c | 175 +++++ urn-help.pd | 18 + urn.c | 152 ++++ velocity-help.pd | 14 + velocity.c | 112 +++ weibull-help.pd | 15 + weibull.c | 95 +++ wrap-help.pd | 22 + wrap.c | 142 ++++ 262 files changed, 16377 insertions(+), 16490 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE.txt create mode 100644 Makefile delete mode 100644 README create mode 100644 README.txt create mode 100644 allow-help.pd create mode 100644 allow.c create mode 100644 arbran-help.pd create mode 100644 arbran.c create mode 100644 arraycopy-help.pd create mode 100644 arraycopy.c create mode 100644 automata.txt create mode 100644 average-help.pd create mode 100644 average.c create mode 100644 beat-help.pd create mode 100644 beat.c create mode 100644 beta-help.pd create mode 100644 beta.c create mode 100644 bilex-help.pd create mode 100644 bilex.c create mode 100644 borax-help.pd create mode 100644 borax.c create mode 100644 cauchy-help.pd create mode 100644 cauchy.c create mode 100644 chord-help.pd create mode 100644 chord.c create mode 100644 delta-help.pd create mode 100644 delta.c create mode 100644 deny-help.pd create mode 100644 deny.c create mode 100644 dist-help.pd create mode 100644 dist.c create mode 100644 divide-help.pd create mode 100644 divide.c create mode 100644 divmod-help.pd create mode 100644 divmod.c create mode 100644 edge-help.pd create mode 100644 edge.c create mode 100644 examplescore.txt create mode 100644 expo-help.pd create mode 100644 expo.c create mode 100644 fifo-help.pd create mode 100644 fifo.c create mode 100644 gauss-help.pd create mode 100644 gauss.c create mode 100644 gestalt-help.pd create mode 100644 gestalt.c delete mode 100644 help/allow-help.pd delete mode 100644 help/arbran-help.pd delete mode 100644 help/arraycopy-help.pd delete mode 100644 help/automata.txt delete mode 100644 help/average-help.pd delete mode 100644 help/beat-help.pd delete mode 100644 help/beta-help.pd delete mode 100644 help/bilex-help.pd delete mode 100644 help/borax-help.pd delete mode 100644 help/cauchy-help.pd delete mode 100644 help/chord-help.pd delete mode 100644 help/delta-help.pd delete mode 100644 help/deny-help.pd delete mode 100644 help/dist-help.pd delete mode 100644 help/divide-help.pd delete mode 100644 help/divmod-help.pd delete mode 100644 help/edge-help.pd delete mode 100644 help/examplescore.txt delete mode 100644 help/expo-help.pd delete mode 100644 help/fifo-help.pd delete mode 100644 help/gauss-help.pd delete mode 100644 help/gestalt-help.pd delete mode 100644 help/history-help.pd delete mode 100644 help/ignore-help.pd delete mode 100644 help/iso-help.pd delete mode 100644 help/lifo-help.pd delete mode 100644 help/limit-help.pd delete mode 100644 help/linear-help.pd delete mode 100644 help/listfifo-help.pd delete mode 100644 help/listfunnel-help.pd delete mode 100644 help/match-help.pd delete mode 100644 help/maxlib-help.pd delete mode 100644 help/minus-help.pd delete mode 100644 help/mlife-help.pd delete mode 100644 help/multi-help.pd delete mode 100644 help/nchange-help.pd delete mode 100644 help/netclient-help.pd delete mode 100644 help/netdist-help.pd delete mode 100644 help/netrec-help.pd delete mode 100644 help/netserver-help.pd delete mode 100644 help/nroute-help.pd delete mode 100644 help/pitch-help.pd delete mode 100644 help/plus-help.pd delete mode 100644 help/poisson-help.pd delete mode 100644 help/pulse-help.pd delete mode 100644 help/remote-help.pd delete mode 100644 help/rewrap-help.pd delete mode 100644 help/rhythm-help.pd delete mode 100644 help/scale-help.pd delete mode 100644 help/score-help.pd delete mode 100644 help/speedlim-help.pd delete mode 100644 help/split-help.pd delete mode 100644 help/step-help.pd delete mode 100644 help/subst-help.pd delete mode 100644 help/sync-help.pd delete mode 100644 help/temperature-help.pd delete mode 100644 help/tilt-help.pd delete mode 100644 help/timebang-help.pd delete mode 100644 help/triang-help.pd delete mode 100644 help/unroute-help.pd delete mode 100644 help/urn-help.pd delete mode 100644 help/velocity-help.pd delete mode 100644 help/weibull-help.pd delete mode 100644 help/wrap-help.pd create mode 100644 history-help.pd create mode 100644 history.c create mode 100644 ignore-help.pd create mode 100644 ignore.c delete mode 100644 install.bat create mode 100644 iso-help.pd create mode 100644 iso.c create mode 100644 lifo-help.pd create mode 100644 lifo.c create mode 100644 limit-help.pd create mode 100644 limit.c create mode 100644 linear-help.pd create mode 100644 linear.c create mode 100644 listfifo-help.pd create mode 100644 listfifo.c create mode 100644 listfunnel-help.pd create mode 100644 listfunnel.c delete mode 100644 makefile create mode 100644 match-help.pd create mode 100644 match.c create mode 100644 maxlib-help.pd create mode 100644 maxlib-meta.pd create mode 100644 minus-help.pd create mode 100644 minus.c create mode 100644 mlife-help.pd create mode 100644 mlife.c create mode 100644 multi-help.pd create mode 100644 multi.c create mode 100644 nchange-help.pd create mode 100644 nchange.c create mode 100644 netclient-help.pd create mode 100644 netclient.c create mode 100644 netdist-help.pd create mode 100644 netdist.c create mode 100644 netrec-help.pd create mode 100644 netrec.c create mode 100644 netserver-help.pd create mode 100644 netserver.c create mode 100644 nroute-help.pd create mode 100644 nroute.c create mode 100644 pitch-help.pd create mode 100644 pitch.c create mode 100644 plus-help.pd create mode 100644 plus.c create mode 100644 poisson-help.pd create mode 100644 poisson.c create mode 100644 pong-help.pd create mode 100644 pong.c create mode 100644 pulse-help.pd create mode 100644 pulse.c create mode 100644 remote-help.pd create mode 100644 remote.c create mode 100644 rewrap-help.pd create mode 100644 rewrap.c create mode 100644 rhythm-help.pd create mode 100644 rhythm.c create mode 100644 scale-help.pd create mode 100644 scale.c create mode 100644 score-help.pd create mode 100644 score.c create mode 100644 speedlim-help.pd create mode 100644 speedlim.c create mode 100644 split-help.pd create mode 100644 split.c delete mode 100644 src/allow.c delete mode 100644 src/arbran.c delete mode 100644 src/arraycopy.c delete mode 100644 src/average.c delete mode 100644 src/beat.c delete mode 100644 src/beta.c delete mode 100644 src/bilex.c delete mode 100644 src/borax.c delete mode 100644 src/cauchy.c delete mode 100644 src/chord.c delete mode 100644 src/delta.c delete mode 100644 src/deny.c delete mode 100644 src/dist.c delete mode 100644 src/divide.c delete mode 100644 src/divmod.c delete mode 100644 src/edge.c delete mode 100644 src/expo.c delete mode 100644 src/fifo.c delete mode 100644 src/gauss.c delete mode 100644 src/gestalt.c delete mode 100644 src/history.c delete mode 100644 src/ignore.c delete mode 100644 src/iso.c delete mode 100644 src/lifo.c delete mode 100644 src/limit.c delete mode 100644 src/linear.c delete mode 100644 src/listfifo.c delete mode 100644 src/listfunnel.c delete mode 100644 src/match.c delete mode 100644 src/minus.c delete mode 100644 src/mlife.c delete mode 100644 src/multi.c delete mode 100644 src/nchange.c delete mode 100644 src/netclient.c delete mode 100644 src/netdist.c delete mode 100644 src/netrec.c delete mode 100644 src/netserver.c delete mode 100644 src/nroute.c delete mode 100644 src/pitch.c delete mode 100644 src/plus.c delete mode 100644 src/poisson.c delete mode 100644 src/pong.c delete mode 100644 src/pulse.c delete mode 100644 src/remote.c delete mode 100644 src/rewrap.c delete mode 100644 src/rhythm.c delete mode 100644 src/scale.c delete mode 100644 src/score.c delete mode 100644 src/speedlim.c delete mode 100644 src/split.c delete mode 100644 src/step.c delete mode 100644 src/subst.c delete mode 100644 src/sync.c delete mode 100644 src/temperature.c delete mode 100644 src/tilt.c delete mode 100644 src/timebang.c delete mode 100644 src/triang.c delete mode 100644 src/unroute.c delete mode 100644 src/urn.c delete mode 100644 src/velocity.c delete mode 100644 src/weibull.c delete mode 100644 src/wrap.c create mode 100644 step-help.pd create mode 100644 step.c create mode 100644 subst-help.pd create mode 100644 subst.c create mode 100644 sync-help.pd create mode 100644 sync.c create mode 100644 temperature-help.pd create mode 100644 temperature.c create mode 100644 tilt-help.pd create mode 100644 tilt.c create mode 100644 timebang-help.pd create mode 100644 timebang.c create mode 100644 triang-help.pd create mode 100644 triang.c create mode 100644 unroute-help.pd create mode 100644 unroute.c create mode 100644 urn-help.pd create mode 100644 urn.c create mode 100644 velocity-help.pd create mode 100644 velocity.c create mode 100644 weibull-help.pd create mode 100644 weibull.c create mode 100644 wrap-help.pd create mode 100644 wrap.c diff --git a/LICENSE b/LICENSE deleted file mode 100644 index b403f69..0000000 --- a/LICENSE +++ /dev/null @@ -1,346 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - - 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 - - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - 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 of the License, 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 for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..b403f69 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,346 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + + 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 + + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 of the License, 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5e14f46 --- /dev/null +++ b/Makefile @@ -0,0 +1,284 @@ +## Pd library template version 1.0 +# For instructions on how to use this template, see: +# http://puredata.info/docs/developer/MakefileTemplate +LIBRARY_NAME = maxlib + +# add your .c source files to the SOURCES variable, help files will be +# included automatically +SOURCES = allow.c arbran.c arraycopy.c average.c beat.c beta.c bilex.c borax.c cauchy.c chord.c delta.c deny.c dist.c divide.c divmod.c edge.c expo.c fifo.c gauss.c gestalt.c history.c ignore.c iso.c lifo.c limit.c linear.c listfifo.c listfunnel.c match.c minus.c mlife.c multi.c nchange.c netclient.c netdist.c netrec.c netserver.c nroute.c pitch.c plus.c poisson.c pong.c pulse.c remote.c rewrap.c rhythm.c scale.c score.c speedlim.c split.c step.c subst.c sync.c temperature.c tilt.c timebang.c triang.c unroute.c urn.c velocity.c weibull.c wrap.c + +# For objects that only build on certain platforms, add those to the SOURCES +# line for the right platforms. +SOURCES_android = +SOURCES_cygwin = +SOURCES_macosx = +SOURCES_iphoneos = +SOURCES_linux = +SOURCES_windows = + +# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will +# be included automatically +PDOBJECTS = + +# example patches and related files, in the 'examples' subfolder +EXAMPLES = + +# manuals and related files, in the 'manual' subfolder +MANUAL = + +# if you want to include any other files in the source and binary tarballs, +# list them here. This can be anything from header files, example patches, +# documentation, etc. README.txt and LICENSE.txt are required and therefore +# automatically included +EXTRA_DIST = HISTORY automata.txt examplescore.txt + + + +#------------------------------------------------------------------------------# +# +# you shouldn't need to edit anything below here, if we did it right :) +# +#------------------------------------------------------------------------------# + +# get library version from meta file +LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd) + +# where Pd lives +PD_PATH = ../../pd +# where to install the library +prefix = /usr/local +libdir = $(prefix)/lib +pkglibdir = $(libdir)/pd-externals +objectsdir = $(pkglibdir) + + +INSTALL = install +INSTALL_FILE = $(INSTALL) -p -m 644 +INSTALL_DIR = $(INSTALL) -p -m 755 -d + +CFLAGS = -DPD -I$(PD_PATH)/src -Wall -W -g +LDFLAGS = +LIBS = +ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ + $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows) + +UNAME := $(shell uname -s) +ifeq ($(UNAME),Darwin) + CPU := $(shell uname -p) + ifeq ($(CPU),arm) # iPhone/iPod Touch + SOURCES += $(SOURCES_iphoneos) + EXTENSION = pd_darwin + OS = iphoneos + IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin + CC=$(IPHONE_BASE)/gcc + CPP=$(IPHONE_BASE)/cpp + CXX=$(IPHONE_BASE)/g++ + ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk + IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6 + OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer + CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS) \ + -I/Applications/Pd-extended.app/Contents/Resources/include + LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT) + LIBS += -lc + STRIP = strip -x + DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) + DISTBINDIR=$(DISTDIR)-$(OS) + else # Mac OS X + SOURCES += $(SOURCES_macosx) + EXTENSION = pd_darwin + OS = macosx + OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast +# build universal 32-bit on 10.4 and 32/64 on newer + ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8) + FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4 + else + FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 + SOURCES += $(SOURCES_iphoneos) + endif + CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include \ + -I/Applications/Pd-extended.app/Contents/Resources/include + LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib + # if the 'pd' binary exists, check the linking against it to aid with stripping + LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd) + LIBS += -lc + STRIP = strip -x + DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) + DISTBINDIR=$(DISTDIR)-$(OS) +# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much + pkglibdir=$(HOME)/Library/Pd + endif +endif +ifeq ($(UNAME),Linux) + SOURCES += $(SOURCES_linux) + EXTENSION = pd_linux + OS = linux + OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer + CFLAGS += -fPIC + LDFLAGS += -Wl,--export-dynamic -shared -fPIC + LIBS += -lc + STRIP = strip --strip-unneeded -R .note -R .comment + DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) + DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) +endif +ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME))) + SOURCES += $(SOURCES_cygwin) + EXTENSION = dll + OS = cygwin + OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer + CFLAGS += + LDFLAGS += -Wl,--export-dynamic -shared -L$(PD_PATH)/src + LIBS += -lc -lpd + STRIP = strip --strip-unneeded -R .note -R .comment + DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) + DISTBINDIR=$(DISTDIR)-$(OS) +endif +ifeq (MINGW,$(findstring MINGW,$(UNAME))) + SOURCES += $(SOURCES_windows) + EXTENSION = dll + OS = windows + OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer -march=i686 -mtune=pentium4 + CFLAGS += -mms-bitfields + LDFLAGS += -s -shared -Wl,--enable-auto-import + LIBS += -L$(PD_PATH)/src -L$(PD_PATH)/bin -L$(PD_PATH)/obj -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 + STRIP = strip --strip-unneeded -R .note -R .comment + DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) + DISTBINDIR=$(DISTDIR)-$(OS) +endif + +CFLAGS += $(OPT_CFLAGS) + + +.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags + +all: $(SOURCES:.c=.$(EXTENSION)) + +%.o: %.c + $(CC) $(CFLAGS) -o "$*.o" -c "$*.c" + +%.$(EXTENSION): %.o + $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS) + chmod a-x "$*.$(EXTENSION)" + +# this links everything into a single binary file +$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o + $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS) + chmod a-x $(LIBRARY_NAME).$(EXTENSION) + + +install: libdir_install + +# The meta and help files are explicitly installed to make sure they are +# actually there. Those files are not optional, then need to be there. +libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_FILE) $(LIBRARY_NAME)-meta.pd \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(SOURCES))" || (\ + $(INSTALL_FILE) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \ + $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION)))) + test -z "$(strip $(PDOBJECTS))" || \ + $(INSTALL_FILE) $(PDOBJECTS) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + +# install library linked as single binary +single_install: $(LIBRARY_NAME) install-doc install-exec + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_FILE) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) + +install-doc: + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(SOURCES))" || \ + $(INSTALL_FILE) $(SOURCES:.c=-help.pd) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(PDOBJECTS))" || \ + $(INSTALL_FILE) $(PDOBJECTS:.pd=-help.pd) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_FILE) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt + $(INSTALL_FILE) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt + +install-examples: + test -z "$(strip $(EXAMPLES))" || \ + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \ + for file in $(EXAMPLES); do \ + $(INSTALL_FILE) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \ + done + +install-manual: + test -z "$(strip $(MANUAL))" || \ + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \ + for file in $(MANUAL); do \ + $(INSTALL_FILE) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \ + done + + +clean: + -rm -f -- $(SOURCES:.c=.o) + -rm -f -- $(SOURCES:.c=.$(EXTENSION)) + -rm -f -- $(LIBRARY_NAME).o + -rm -f -- $(LIBRARY_NAME).$(EXTENSION) + +distclean: clean + -rm -f -- $(DISTBINDIR).tar.gz + -rm -rf -- $(DISTBINDIR) + -rm -f -- $(DISTDIR).tar.gz + -rm -rf -- $(DISTDIR) + + +$(DISTBINDIR): + $(INSTALL_DIR) $(DISTBINDIR) + +libdir: all $(DISTBINDIR) + $(INSTALL_FILE) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR) + $(INSTALL_FILE) $(SOURCES) $(DISTBINDIR) + $(INSTALL_FILE) $(SOURCES:.c=-help.pd) $(DISTBINDIR) + test -z "$(strip $(EXTRA_DIST))" || \ + $(INSTALL_FILE) $(EXTRA_DIST) $(DISTBINDIR) +# tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR) + +$(DISTDIR): + $(INSTALL_DIR) $(DISTDIR) + +dist: $(DISTDIR) + $(INSTALL_FILE) Makefile $(DISTDIR) + $(INSTALL_FILE) README.txt $(DISTDIR) + $(INSTALL_FILE) LICENSE.txt $(DISTDIR) + $(INSTALL_FILE) $(LIBRARY_NAME)-meta.pd $(DISTDIR) + test -z "$(strip $(ALLSOURCES))" || \ + $(INSTALL_FILE) $(ALLSOURCES) $(DISTDIR) + test -z "$(strip $(ALLSOURCES))" || \ + $(INSTALL_FILE) $(ALLSOURCES:.c=-help.pd) $(DISTDIR) + test -z "$(strip $(PDOBJECTS))" || \ + $(INSTALL_FILE) $(PDOBJECTS) $(DISTDIR) + test -z "$(strip $(PDOBJECTS))" || \ + $(INSTALL_FILE) $(PDOBJECTS:.pd=-help.pd) $(DISTDIR) + test -z "$(strip $(EXTRA_DIST))" || \ + $(INSTALL_FILE) $(EXTRA_DIST) $(DISTDIR) + test -z "$(strip $(EXAMPLES))" || \ + $(INSTALL_DIR) $(DISTDIR)/examples && \ + for file in $(EXAMPLES); do \ + $(INSTALL_FILE) examples/$$file $(DISTDIR)/examples; \ + done + test -z "$(strip $(MANUAL))" || \ + $(INSTALL_DIR) $(DISTDIR)/manual && \ + for file in $(MANUAL); do \ + $(INSTALL_FILE) manual/$$file $(DISTDIR)/manual; \ + done + tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR) + + +etags: + etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h + +showsetup: + @echo "PD_PATH: $(PD_PATH)" + @echo "objectsdir: $(objectsdir)" + @echo "LIBRARY_NAME: $(LIBRARY_NAME)" + @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)" + @echo "SOURCES: $(SOURCES)" + @echo "PDOBJECTS: $(PDOBJECTS)" + @echo "ALLSOURCES: $(ALLSOURCES)" + @echo "UNAME: $(UNAME)" + @echo "CPU: $(CPU)" + @echo "pkglibdir: $(pkglibdir)" + diff --git a/README b/README deleted file mode 100644 index b1afdc3..0000000 --- a/README +++ /dev/null @@ -1,38 +0,0 @@ -maxlib - music analysis extensions library, version 1.5.2 -copyright (c) 2002-2003 by Olaf Matthes - -maxlib is a library of non-tilde externals for pd (by Miller Puckette). - -The objects can be very useful to analyse any musical performance. Some -of the objects are 'borrowed' from Max (they are not ported but -rewritten for Pd - cheap immitations). -maxib has recently been extended by objects of more general use and some -which can be use for composition purposes. - -To compile maxlib on win32 (using VC++ 6.0) just type "nmake pd_nt" or use -the MS VC++ project provided. On Linux simply do "make pd_linux" and "make -install". -You have to modify the makefile to make it point to your m_ph.h !!! - -To use maxlib place the file maxlib.dll for win32 or maxlib.pd_linux -in a directory of your choise and start pd with '-lib path/to/maxlib' flag. - -On windows you can run install.bat to copy all files to the apropiate places. -This assumes that you have pd installed in c:\pd\ ! The maxlib directory will -then be c:\pd\externs\maxlib\ - - -This software is published under GPL terms, see file LICENSE. - -This is software with ABSOLUTELY NO WARRANTY. -Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing -due to a bug or for other reasons. - -***************************************************************************** - -included objects: see http://www.akustische-kunst.org/puredata/maxlib/ - -Latest version can be found at: -http://www.akustische-kunst.org/puredata/maxlib/ - -Please report any bugs to olaf.matthes@gmx.de! diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..b1afdc3 --- /dev/null +++ b/README.txt @@ -0,0 +1,38 @@ +maxlib - music analysis extensions library, version 1.5.2 +copyright (c) 2002-2003 by Olaf Matthes + +maxlib is a library of non-tilde externals for pd (by Miller Puckette). + +The objects can be very useful to analyse any musical performance. Some +of the objects are 'borrowed' from Max (they are not ported but +rewritten for Pd - cheap immitations). +maxib has recently been extended by objects of more general use and some +which can be use for composition purposes. + +To compile maxlib on win32 (using VC++ 6.0) just type "nmake pd_nt" or use +the MS VC++ project provided. On Linux simply do "make pd_linux" and "make +install". +You have to modify the makefile to make it point to your m_ph.h !!! + +To use maxlib place the file maxlib.dll for win32 or maxlib.pd_linux +in a directory of your choise and start pd with '-lib path/to/maxlib' flag. + +On windows you can run install.bat to copy all files to the apropiate places. +This assumes that you have pd installed in c:\pd\ ! The maxlib directory will +then be c:\pd\externs\maxlib\ + + +This software is published under GPL terms, see file LICENSE. + +This is software with ABSOLUTELY NO WARRANTY. +Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing +due to a bug or for other reasons. + +***************************************************************************** + +included objects: see http://www.akustische-kunst.org/puredata/maxlib/ + +Latest version can be found at: +http://www.akustische-kunst.org/puredata/maxlib/ + +Please report any bugs to olaf.matthes@gmx.de! diff --git a/allow-help.pd b/allow-help.pd new file mode 100644 index 0000000..084d52f --- /dev/null +++ b/allow-help.pd @@ -0,0 +1,21 @@ +#N canvas 358 305 554 308 12; +#X text 24 17 allow :: lets only 'allowed' floats or symbols through +; +#X text 97 34 written by Olaf Matthes ; +#X msg 125 65 cat; +#X msg 147 97 dog; +#X msg 157 126 bird; +#X floatatom 82 269 5 0 0 0 - - -; +#X symbolatom 151 246 10 0 0 0 - - -; +#X obj 114 156 symbol \$1; +#X floatatom 40 81 5 0 0 0 - - -; +#X obj 82 217 route float symbol; +#X obj 82 189 allow 17 cat dog 23; +#X connect 2 0 7 0; +#X connect 3 0 7 0; +#X connect 4 0 7 0; +#X connect 7 0 10 0; +#X connect 8 0 10 0; +#X connect 9 0 5 0; +#X connect 9 1 6 0; +#X connect 10 0 9 0; diff --git a/allow.c b/allow.c new file mode 100644 index 0000000..a8a6238 --- /dev/null +++ b/allow.c @@ -0,0 +1,112 @@ +/* ---------------------------- allow --------------------------------------- */ +/* */ +/* Lets only floats/symbols through that are allowed to do so. */ +/* Written by Olaf Matthes */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +static char *version = "allow v0.1, written by Olaf Matthes "; + +typedef struct allow +{ + t_object x_obj; + t_outlet *x_out; + t_atom *x_elem; // list of elemets that are allowed to pass + t_int x_numelem; // the number of elemetns in our allow-list +} t_allow; + + /* we got a symbol... */ +static void allow_symbol(t_allow *x, t_symbol *s) +{ + int i; + for(i = 0; i < x->x_numelem; i++) + { + if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list + if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s) + { + outlet_symbol(x->x_out, s); + return; + } + } +} + + /* we got a float... */ +static void allow_float(t_allow *x, t_floatarg f) +{ + int i; + for(i = 0; i < x->x_numelem; i++) + { + if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list + if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f) + { + outlet_float(x->x_out, f); + return; + } + } +} + +static t_class *allow_class; + +static void allow_free(t_allow *x) +{ + freebytes(x->x_elem, x->x_numelem*sizeof(t_atom)); +} + +static void *allow_new(t_symbol *s, int argc, t_atom *argv) +{ + t_allow *x = (t_allow *)pd_new(allow_class); + + x->x_numelem = argc; // get the number of elements + x->x_elem = getbytes(argc*sizeof(t_atom)); + memcpy(x->x_elem, argv, argc*sizeof(t_atom)); + + x->x_out = outlet_new(&x->x_obj, gensym("anything")); + + // post("allow: got %d elements", x->x_numelem); + + return (x); +} + +#ifndef MAXLIB +void allow_setup(void) +{ + /* the object's class: */ + allow_class = class_new(gensym("allow"), (t_newmethod)allow_new, + (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0); +#else +void maxlib_allow_setup(void) +{ + /* the object's class: */ + allow_class = class_new(gensym("maxlib_allow"), (t_newmethod)allow_new, + (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0); + class_addcreator((t_newmethod)allow_new, gensym("allow"), A_GIMME, 0); +#endif + class_addsymbol(allow_class, allow_symbol); + class_addfloat(allow_class, allow_float); +#ifndef MAXLIB + + post(version); +#else + class_sethelpsymbol(allow_class, gensym("maxlib/allow-help.pd")); +#endif +} diff --git a/arbran-help.pd b/arbran-help.pd new file mode 100644 index 0000000..9153bf5 --- /dev/null +++ b/arbran-help.pd @@ -0,0 +1,28 @@ +#N canvas 190 136 663 491 12; +#X obj 41 152 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 41 249 5 0 0; +#N canvas 0 0 450 300 graph1 0; +#X array array1 6 float 1; +#A 0 1.1 2.67143 3.24285 3.1 4.38571 8.67143; +#X coords 0 10 5 0 200 140 1; +#X restore 347 71 graph; +#N canvas 0 0 450 300 graph2 0; +#X array array2 6 float 1; +#A 0 0.0229077 0.204366 0.486501 0.0632986 0.204028 0.025319; +#X coords 0 1 5 0 200 140 1; +#X restore 347 220 graph; +#X obj 41 202 arbran array1 array2; +#X text 39 21 arbran :: generates a random variable that conforms +to the piecewise probability density functions specified in two arrays +; +#X text 40 297 array1 has values between 0 and 10; +#X text 40 317 array2 between 0 and 1 !; +#X msg 99 152 pdfscale; +#X text 41 389 array1 stores the values and array2 the corresponding +probabilities (0 - 1) for each of that values \, use message 'pdfscale' +to check (and adjust) the probability values to correct settings (the +area below the curve has to be 1); +#X connect 0 0 4 0; +#X connect 4 0 1 0; +#X connect 8 0 4 0; diff --git a/arbran.c b/arbran.c new file mode 100644 index 0000000..d708e11 --- /dev/null +++ b/arbran.c @@ -0,0 +1,189 @@ +/* ---------------------------- rand_arbran ----------------------------------- */ +/* */ +/* rand_arbran generates a random variable that conforms to the */ +/* piecewise probability density in two arrays */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code found in Dodge/Jerse "Computer Music" */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define fran() (t_float)rand()/(t_float)RAND_MAX +#ifndef M_PI +#define M_PI 3.1415927 +#endif + +static char *version = "arbran v0.1b, generates a random variable that conforms to the\n" + " piecewise probability density in two arrays\n" + " written by Olaf Matthes "; + +/* -------------------------- rand_arbran ------------------------------ */ + +static t_class *rand_arbran_class; + +typedef struct _rand_arbran +{ + t_object x_obj; + t_symbol *x_x; + t_symbol *x_p; + t_garray *x_bufx; + t_garray *x_bufp; +} t_rand_arbran; + +static void rand_arbran_pdfscale(t_rand_arbran *x) +{ + t_garray *bx = x->x_bufx, *bp = x->x_bufp; + t_float a = 0; + t_int k = 0; + t_float *tx, *tp; + int ix, ip; + if (!garray_getfloatarray(bx, &ix, &tx)) + { + post("arbran: couldn't read from array!"); + return; + } + if (!garray_getfloatarray(bp, &ip, &tp)) + { + post("arbran: couldn't read from array!"); + return; + } + + for(k = 1; k < ix; k++) + { + a += (tx[k]-tx[k-1])*(tp[k]+tp[k-1])/2.0; + } + for(k = 0; k < ix; k++) + { + tp[k] = tp[k]/a; + } + garray_redraw(x->x_bufp); +} + +static void rand_arbran_bang(t_rand_arbran *x) +{ + t_garray *bx = x->x_bufx, *bp = x->x_bufp; + t_float a, u, a0, slope, b, d, r; + t_int k = 0; + t_float *tx, *tp; + int ix, ip; + if (!garray_getfloatarray(bx, &ix, &tx)) + { + post("arbran: couldn't read from array!"); + return; + } + if (!garray_getfloatarray(bp, &ip, &tp)) + { + post("arbran: couldn't read from array!"); + return; + } + + a = 0; + a0 = 0; + u = fran(); + while(u > a) + { + a0 = (tx[k+1]-tx[k])*(tp[k+1]+tp[k])/2.0; + a += a0; + k++; + } + k--; + slope = (tp[k+1]-tp[k])/(tx[k+1]-tx[k]); + if(slope == 0) + { + r = (u-a+a0)/tp[k]+tx[k]; + } + else + { + b=tp[k]/slope-tx[k]; + d=b*b+tx[k]*tx[k]+2*b*tx[k]+2*(u-a+a0)/slope; + if(slope > 0) + r=-b+sqrt(d); + else + r=-b-sqrt(d); + } + outlet_float(x->x_obj.ob_outlet, r); +} + +static void rand_arbran_set(t_rand_arbran *x) +{ + t_garray *b, *b2; + + if ((b = (t_garray *)pd_findbyclass(x->x_x, garray_class))) + { + post("arbran: array set to \"%s\"", x->x_x->s_name); + x->x_bufx = b; + } else { + post("arbran: no array \"%s\" (error %d)", x->x_x->s_name, b); + x->x_bufx = 0; + } + if ((b2 = (t_garray *)pd_findbyclass(x->x_p, garray_class))) + { + post("arbran: array set to \"%s\"", x->x_p->s_name); + x->x_bufp = b2; + } else { + post("arbran: no array \"%s\" (error %d)", x->x_p->s_name, b); + x->x_bufp = 0; + } +} + +static void rand_arbran_setarrays(t_rand_arbran *x, t_symbol *s1, t_symbol *s2) +{ + x->x_x = s1; + x->x_p = s2; + rand_arbran_set(x); +} + +static void *rand_arbran_new(t_symbol *s1, t_symbol *s2) +{ + t_rand_arbran *x = (t_rand_arbran *)pd_new(rand_arbran_class); + srand( (unsigned)time( NULL ) ); + outlet_new(&x->x_obj, &s_float); + x->x_x = s1; + x->x_p = s2; + rand_arbran_set(x); + return (x); +} + +#ifndef MAXLIB +void arbran_setup(void) +{ + rand_arbran_class = class_new(gensym("arbran"), (t_newmethod)rand_arbran_new, 0, + sizeof(t_rand_arbran), 0, A_SYMBOL, A_SYMBOL, 0); +#else +void maxlib_arbran_setup(void) +{ + rand_arbran_class = class_new(gensym("maxlib_arbran"), (t_newmethod)rand_arbran_new, 0, + sizeof(t_rand_arbran), 0, A_SYMBOL, A_SYMBOL, 0); +#endif + class_addbang(rand_arbran_class, rand_arbran_bang); + class_addmethod(rand_arbran_class, (t_method)rand_arbran_pdfscale, gensym("pdfscale"), 0); + class_addmethod(rand_arbran_class, (t_method)rand_arbran_setarrays, gensym("set"), A_SYMBOL, A_SYMBOL, 0); +#ifndef MAXLIB + class_sethelpsymbol(rand_arbran_class, gensym("arbran-help.pd")); + post(version); +#else + class_addcreator((t_newmethod)rand_arbran_new, gensym("arbran"), A_SYMBOL, A_SYMBOL, 0); + class_sethelpsymbol(rand_arbran_class, gensym("maxlib/arbran-help.pd")); +#endif +} diff --git a/arraycopy-help.pd b/arraycopy-help.pd new file mode 100644 index 0000000..6963c69 --- /dev/null +++ b/arraycopy-help.pd @@ -0,0 +1,62 @@ +#N canvas 140 43 934 584 12; +#N canvas 0 0 450 300 graph1 0; +#X array array1 20 float 1; +#A 0 0 0 0.342857 0.542857 0.6 -0.442857 -0.485714 0.0142858 -0.428571 +-0.114286 0.0857143 -0.2 -0.214285 0.314285 -0.157143 -0.314285 -0.142857 +-0.0428571 0.114286 -0.685713; +#X coords 0 1 19 -1 200 140 1; +#X restore 680 27 graph; +#N canvas 0 0 450 300 graph2 0; +#X array array2 20 float 1; +#A 0 -0.214286 -0.171429 0.1 0.614286 0.757143 0.757143 0.542857 0.2 +-0.0285714 -0.271429 -0.414286 -0.514286 -0.528571 -0.485714 -0.371429 +-0.157143 0.214286 0.557143 0.714286 0.757143; +#X coords 0 1 19 -1 200 140 1; +#X restore 681 196 graph; +#N canvas 0 0 450 300 graph3 0; +#X array array3 20 float 1; +#A 0 1.86265e-009 1.86265e-009 1.86265e-009 1.86265e-009 1.86265e-009 +-0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 +-0.0142857 -0.0285714 -0.0285714 -0.0285714 -0.0285714 -0.0142857 -0.0142857 +-0.0142857; +#X coords 0 1 19 -1 200 140 1; +#X restore 680 371 graph; +#X obj 22 500 arraycopy array3; +#X text 339 402 set the destination array; +#X text 41 1 arraycopy :: copy data from one array to another; +#X text 146 22 written by Olaf Matthes ; +#X msg 22 109 copy array1; +#X msg 43 139 copy array1 10 15; +#X text 131 109 copy the whole array; +#X text 200 140 copy from value 10 to 15; +#X msg 60 169 copy array1 10 +5; +#X text 217 170 copy from value 10 the next 5 values; +#X msg 85 359 print \$1; +#X obj 85 333 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X text 116 334 switch console printout on/off; +#X text 281 202 copy from value 10 to 15; +#X msg 73 201 copy array1 10 15 array2; +#X text 280 222 into array2 (starting at 0); +#X text 322 251 copy from value 10 to 15; +#X text 321 271 into array2 starting at 4; +#X msg 92 250 copy array1 10 15 array2 4; +#X msg 368 454 array3; +#X msg 86 414 bang; +#X text 137 412 perform last copy; +#X text 137 429 operation again; +#X text 20 537 creation argument: initial destination array to copy +data to; +#X obj 200 502 symbol; +#X msg 339 428 array2; +#X connect 7 0 3 0; +#X connect 8 0 3 0; +#X connect 11 0 3 0; +#X connect 13 0 3 0; +#X connect 14 0 13 0; +#X connect 17 0 3 0; +#X connect 21 0 3 0; +#X connect 22 0 27 0; +#X connect 23 0 3 0; +#X connect 27 0 3 1; +#X connect 28 0 27 0; diff --git a/arraycopy.c b/arraycopy.c new file mode 100644 index 0000000..ea5f61b --- /dev/null +++ b/arraycopy.c @@ -0,0 +1,284 @@ +/* ------------------------- arraycopy --------------------------------------- */ +/* */ +/* Copy data from one array to another . */ +/* Written by Olaf Matthes */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +static char *version = "arraycopy v0.2, written by Olaf Matthes "; + +typedef struct arraycopy +{ + t_object x_obj; + t_symbol *x_destarray; + t_symbol *x_sourcearray; + t_garray *x_destbuf; + t_garray *x_sourcebuf; + t_int x_start; + t_int x_end; + t_int x_pos; + short x_print; +} t_arraycopy; + + /* choose the destination array to copy to */ +static void arraycopy_setdestarray(t_arraycopy *x, t_symbol *s) +{ + t_garray *b; + + if ((b = (t_garray *)pd_findbyclass(s, garray_class))) + { + // post("arraycopy: destination array set to \"%s\"", s->s_name); + x->x_destbuf = b; + } else { + post("arraycopy: no array \"%s\" (error %d)", s->s_name, b); + x->x_destbuf = 0; + } +} + +static void arraycopy_setdest(t_arraycopy *x, t_symbol *s) +{ + x->x_destarray = s; + arraycopy_setdestarray(x, x->x_destarray); +} + + /* choose the source array to copy from */ +static void arraycopy_setsourcearray(t_arraycopy *x, t_symbol *s) +{ + t_garray *b; + + if ((b = (t_garray *)pd_findbyclass(s, garray_class))) + { + // post("arraycopy: source array set to \"%s\"", s->s_name); + x->x_sourcebuf = b; + } else { + post("arraycopy: no array \"%s\" (error %d)", s->s_name, b); + x->x_sourcebuf = 0; + } +} + + /* this is the routine that actually does the copying */ + /* get's called directly when we get a 'bang' */ +static void arraycopy_docopy(t_arraycopy *x) +{ + t_garray *b; /* make local copy of array */ + t_float *tab; /* the content itselfe */ + int items; + t_int i; + t_garray *A; + int npoints; + t_float *vec; + + if(!x->x_destarray) + { + post("arraycopy: no destination array specified"); + return; + } + if(!x->x_sourcearray) + { + post("arraycopy: no source array specified"); + return; + } + + A = x->x_destbuf; + + if ((b = (t_garray *)pd_findbyclass(x->x_sourcearray, garray_class))) + { + // post("arraycopy: source array set to \"%s\"", x->x_sourcearray->s_name); + } else { + post("arraycopy: no array \"%s\" (error %d)", x->x_sourcearray->s_name, b); + return; + } + + // read from our array + if (!garray_getfloatarray(b, &items, &tab)) + { + post("arraycopy: couldn't read from source array!"); + return; + } + + if (!(A = (t_garray *)pd_findbyclass(x->x_destarray, garray_class))) + error("arraycopy: %s: no such array", x->x_destarray->s_name); + else if (!garray_getfloatarray(A, &npoints, &vec)) + error("arraycopy: %s: bad template ", x->x_destarray->s_name); + else + { + if(x->x_start > items) // check start point + { + post("arraycopy: source start point out of range for the array given"); + return; + } + if(x->x_end) // end point is specified + { + if(x->x_end > items) // check start point + { + post("arraycopy: source end point out of range for the array given"); + x->x_end = items; + } + } + else x->x_end = items; + + if(x->x_pos) + vec += x->x_pos; + + for(i = x->x_start; i < x->x_end; i++) + { + *vec++ = tab[i]; + } + garray_redraw(A); + if(x->x_print)post("arraycopy: copied %d values from array \"%s\" to array \"%s\"", + x->x_end-x->x_start, x->x_sourcearray->s_name, x->x_destarray->s_name); + } +} + +static void arraycopy_list(t_arraycopy *x, t_symbol *s, int argc, t_atom *argv) +{ + if(argc > 1) { + x->x_sourcearray = atom_getsymbolarg(0, argc, argv); + x->x_destarray = atom_getsymbolarg(1, argc, argv); + } +} + +static void arraycopy_source(t_arraycopy *x, t_symbol *s) +{ + x->x_sourcearray = s; + x->x_start = x->x_end = x->x_pos = 0; + arraycopy_docopy(x); +} + +static void arraycopy_print(t_arraycopy *x, t_floatarg f) +{ + if(f) + x->x_print = 1; + else + x->x_print = 0; +} + +static void arraycopy_copy(t_arraycopy *x, t_symbol *s, int argc, t_atom *argv) +{ + if(argc == 1) // source array name supplied + { + x->x_sourcearray = atom_getsymbolarg(0, argc, argv); + x->x_start = x->x_end = x->x_pos = 0; + } + else if(argc == 2) // array name and start point supplied + { + x->x_sourcearray = atom_getsymbolarg(0, argc, argv); + x->x_start = atom_getfloatarg(1, argc, argv); + x->x_end = x->x_pos = 0; + } + else if(argc == 3) // arrayname and start & end point supplied + { + x->x_sourcearray = atom_getsymbolarg(0, argc, argv); + x->x_start = atom_getfloatarg(1, argc, argv); + if(argv[2].a_type == A_FLOAT) // real position + { + x->x_end = atom_getfloatarg(2, argc, argv); + } + else // offset given + { + t_symbol *offset = atom_getsymbolarg(2, argc, argv); + x->x_end = (t_int)atoi(offset->s_name) + x->x_start; + } + x->x_pos = 0; + } + else if(argc == 4) // as above & dest. array + { + x->x_sourcearray = atom_getsymbolarg(0, argc, argv); + x->x_start = atom_getfloatarg(1, argc, argv); + if(argv[2].a_type == A_FLOAT) // real position + { + x->x_end = atom_getfloatarg(2, argc, argv); + } + else // offset given + { + t_symbol *offset = atom_getsymbolarg(2, argc, argv); + x->x_end = (t_int)atoi(offset->s_name) + x->x_start; + } + x->x_destarray = atom_getsymbolarg(3, argc, argv); + arraycopy_setdestarray(x, x->x_destarray); + x->x_pos = 0; + } + else if(argc == 5) // as above & dest. array & pos. in dest. + { + x->x_sourcearray = atom_getsymbolarg(0, argc, argv); + x->x_start = atom_getfloatarg(1, argc, argv); + if(argv[2].a_type == A_FLOAT) // real position + { + x->x_end = atom_getfloatarg(2, argc, argv); + } + else // offset given + { + t_symbol *offset = atom_getsymbolarg(2, argc, argv); + x->x_end = (t_int)atoi(offset->s_name) + x->x_start; + } + x->x_destarray = atom_getsymbolarg(3, argc, argv); + arraycopy_setdestarray(x, x->x_destarray); + x->x_pos = atom_getfloatarg(4, argc, argv); + } + else post("arraycopy: copy: wrong number of arguments"); + + arraycopy_docopy(x); +} + +static t_class *arraycopy_class; + +static void *arraycopy_new(t_symbol *s, int argc, t_atom *argv) +{ + t_arraycopy *x = (t_arraycopy *)pd_new(arraycopy_class); + + if (argc > 0) { + x->x_destarray = atom_getsymbolarg(0, argc, argv); + arraycopy_setdestarray(x, x->x_destarray); + } + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("symbol"), gensym("dest")); + x->x_start = x->x_end = x->x_pos = x->x_print = 0; + return (x); +} + +#ifndef MAXLIB +void arraycopy_setup(void) +{ + /* the object's class: */ + arraycopy_class = class_new(gensym("arraycopy"), (t_newmethod)arraycopy_new, + 0, sizeof(t_arraycopy), 0, A_GIMME, 0); +#else +void maxlib_arraycopy_setup(void) +{ + /* the object's class: */ + arraycopy_class = class_new(gensym("maxlib_arraycopy"), (t_newmethod)arraycopy_new, + 0, sizeof(t_arraycopy), 0, A_GIMME, 0); + class_addcreator((t_newmethod)arraycopy_new, gensym("arraycopy"), A_GIMME, 0); +#endif + class_addmethod(arraycopy_class, (t_method)arraycopy_copy, gensym("copy"), A_GIMME, 0); + class_addmethod(arraycopy_class, (t_method)arraycopy_print, gensym("print"), A_FLOAT, 0); + class_addmethod(arraycopy_class, (t_method)arraycopy_setdest, gensym("dest"), A_SYMBOL, 0); + class_addsymbol(arraycopy_class, arraycopy_source); + class_addbang(arraycopy_class, arraycopy_docopy); + // class_addlist(arraycopy_class, arraycopy_list); +#ifndef MAXLIB + + post(version); +#else + class_sethelpsymbol(arraycopy_class, gensym("maxlib/arraycopy-help.pd")); +#endif +} diff --git a/automata.txt b/automata.txt new file mode 100644 index 0000000..3f5ff21 --- /dev/null +++ b/automata.txt @@ -0,0 +1,178 @@ +[The following note originally appeared on the emusic-l mailing list. It is +reprinted here with the author's permission] + +From xrjdm@FARSIDE.GSFC.NASA.GOV Wed Nov 23 11:26:39 1994 +Date: Tue, 4 Oct 1994 15:09:23 -0500 +From: Joe McMahon +Reply to: Electronic Music Discussion List +To: Multiple recipients of list EMUSIC-L +Subject: Automata: the long-awaited summary + +Back in August, I think, I promised to post a quick intro to cellular +automata and how they can be used as a sound-generation tool. Since I'm +going to take a couple of different sources and sum them up with little or +no direct attribution, combined with my own opinions, I'll give everybody +my references *first* so they can delete the article and draw their own +conclusions if they so prefer. + +The primary reference that got me started on all this is one in the CMJ: +Vol 14, No. 4, Winter 1990: "Digital Synthesis of Self-modifying Waveforms +by Means of Cellular Automata" (Jacques Chareyon). Those who are already +familiar with automata may just skip to that article and forget about the +rest of this one. +Note: the article gives a mail address for M. Chareyon, but he did not +answer an inquiry about any available recordings using this technique in +1990. + +So. Anyone still here? Good. + +Cellular automata are a mathematical concept first introduced in the late +1940's. Generally speaking, a cellular automaton consists of a grid of +cells. Each cell may take on any of a number of values - binary automata +(cell on or cell off) are the most commonly studied. Each cell has a +neighborhood, defined more simply as other cells which influence its state. +The exact nature of this influence is defined by what are called transition +rules. The cellular automaton starts off with some cells in any of the +allowable states. for each "step" in the automaton's history, the +neighborhood of every cell is checked, and the state of the cell is +updated. All updates occur simultaneously. + +The transition rule must describe the resulting state of a cell for every +possible configuration of other cells in the neighborhood. For large +numbers of states, the amount of memory required to hold the transition +rule becomes increasingly large, Therefore, some automata use what is known +as a "totalistic" rule. These rules simply sum the values of the cells in +the neighborhood and then assign a result on this basis. The resulting +tables are far smaller. + +Many readers may already be familiar with John Horton Conway's game of +"Life". This is a two-dimensional binary automaton with a totalistic rule. +This makes for a very small rule set: + + i) If fewer than two filled cells (cells with value 1) surround a cell, + it becomes empty next generation. + ii) If more than three filled cells surround a cell, it becomes empty + next generation. +iii) If exactly three cells filled cells surround a cell, it becomes + filled on the next generation. + +This corresponds to a totalistic rule set with a total of 8(2-1)+1 or 9 +rules (one each for the sum values of 0 (no cells with a value) through 9 +(all cells with a value) ).If the transition rule were represented as a +non-totalistic one, the rule set would need 2**8 or 256 entries. There are +many interesting totalistic automata, so giving up detailed description of +every nuance of the transitions to save memory space isn't a big sacrifice. + +Interesting as two dimensional automata are, they really aren't terribly +useful for music making. There have been some experiments which have +attempted to use a two-dimensional automaton to generate MIDI events - +synthesis at the note level, using : + +Battista, T. and M. Giri, 1988. "Composizione Tramite Automi Cellulari." +Atti del VII Cooloquio di Informatica Musicale. Rome, Italy: Edizione Arti +Grafiche Ambrosini, pp. 181-182. + +Edgar, R. and J. Ryan, 1986. "LINA" Exhibition of the 1986 International +Computer Music Conference, San Francisco: Computer Music Association. + +I have not heard any of the music from these efforts, so I certainly can't +pass any judgement on them. For the purposes of this summary, we'll just +look at one-dimensional automata. These use a linear array of cells, with +the neighborhood generally being one or two cells on either side of each +cell. +(This is the type of automaton dealt with in M. Chareyon's article, which I +will be paraphrasing broadly hereafter). + +M. Chareyon's automata are wavetables. A digitized signal is stored as a +linear array of numbers in memory. A totalistic rule is used to determine a +lookup value which indexes into an array containing the resulting value; +this is saved into a second array. After the first array is completely +processed, the roles of the two are swapped and the process is repeated. + +The limiting factor in this process is the number of bits of resolution +being used to generate the sound. For a totalistic rule using a two-cell +neighborhood and 12-bit individual samples, we have 3*(2*12) = 12288 +entries in the rule table. At 2 bytes each, this is 24K of storage. If we +go to 16-bit sample resolution, we have 196608 entries at 2 bytes each for +a total of 393216 bytes, or 384K. + +The key point of M. Charyeon's method is the use of small neighborhoods +with large numbers of cellular states. Since the computation of the new +wavetable is all table lookup, very complex transition rules can be +precomputed and loaded into the tables, allowing the synthesis to +essentially be a fast sum-and-lookup loop to calculate each new wavesample. +>From the article, it appears that M. Chareyon was able to produce 2 or 3 +voices in realtime on a Mac II with a Digidesign Sound Accelerator board. +It seems that it would probably be possible to use an AV Mac to do it +without the board. + +This LASy (Linear Automaton Synthesis) method is closely related to the +Karplus-Strong plucked-string algorithm, in that a wavesample is run +through an algorithm which recirculates the samples to "self-modify" the +wave. In fact, a judicious choice of table entries allows one to very +simply simulate the K-S algoritm directly. + +So what are the sounds like? Some automata produce waveforms which quickly +"ramp-up" to complex spectra and then drop off quickly. Others move to a +steady state and then remain there. Yet others produce never-ending and +unpredictable waveforms, whose harmonic content is constantly changing. + +Obviously enough, the original wavesample can be obtained mathematically, +or by actual sampling and using LASy as a waveshaper. As M. Chareyon notes, +a quick estimate of the number of possible automata for a 2-neighbor +totalistic rule using a 256-entry wavetable with 12-bit entries is +(2**12)**256 * (2**12)**(3*2**12) or about 10**4500 possible automata. Of +course, many, many of these would not be suitable for music (e.g., the 4096 +automata in which all values go to one vlaue in one step, etc.); however, +the number of musically useful automata is still likely to be an immense +number. + +M. Chareyon provides a number of examples of ways to fill out the rule +tables and a number of hints on creating wave tables - generally speaking, +one can create a function which is used to compute the values to be placed +into the table and then fill it so it can simply be loaded and used by the +basic algorithm. His experience in using LASy is that he manages +approximately 50% of the time to produce sounds with the desired +characteristics, and that about 10% of the remaining time he gets +unexpected but useful results which can be used as starting points for +further exploration. + +Again, the important point is that the basic automaton uses wavesamples at +full resolution, calculating a new wavesample for each step of the +automaton; the next wavesample can be played while the new one is being +calculated. Because of the large number of states, mathematical tools for +the analysis of automata and the construction of automata with specifically +desired qualities require too much storage and compute time to make them +useful for LASy purposes. + +Again, much of this article is paraphrased from M. Chareyon's article; I +take no credit for any of the work in this note. I'm just summarizing. + +The following other articles were referenced by M. Chareyon's article: + +Burks, A., ed. 1970. Essays on Cellular Automata. Champaign/Urbana, IL: +University of Illinois Press. + +Chareyon, J. 1988a. "Sound Synthesis and Processing by Means of Linear +Cellular Automata." Proceedings of the 1988 Internation Computer Music +Conference. San Francisco: Computer Music Association. + +Chareyon, J. 1988b. "Wavetable come Automa Cellulare: una Nuova Tecnica di +Sintesi." Atti del VII Colloquio di Informatica Musicale, Rome, Italy: +Edizioni Arti Grafiche Ambrosini, pp. 174-177. + +Farmer, D., T. Toffoli, and S. Wolfram, eds. 1984. Cellular Automata. +North-Holland Physics Publishing. [One of the definitive works on cellular +automata - fairly heavy math, not a popular presentation - JM] + +Gardner, M. 1970. "The Fantastic Combinations of John Conway's New Solitare +Game 'Life'". Scientific American 223(4) 120-123. [A good introduction to +cellular automata, focusing on 'life' in specific. Useful intro if my +1-paragraph summary of automata was confusing :) - JM] + + --- Joe M. + +-- +"At the end of the hour, we'll have information on the sedatives used by +the artists,,," (MST3K) + diff --git a/average-help.pd b/average-help.pd new file mode 100644 index 0000000..6155716 --- /dev/null +++ b/average-help.pd @@ -0,0 +1,29 @@ +#N canvas 445 253 470 320 12; +#X floatatom 47 39 5 0 0; +#X floatatom 47 276 5 0 0; +#X floatatom 122 191 5 0 0; +#X obj 47 219 average 10; +#X text 177 191 number of items to average; +#X text 139 220 creation argument = number of items; +#X floatatom 122 254 5 0 0; +#X text 105 277 average of last N items; +#X text 125 11 average :: calculates the average of the; +#X text 214 30 last N items (floats); +#X text 176 255 tendency (up = 1 \, down = -1); +#X msg 100 60 reset; +#X text 152 61 forget everything; +#X msg 129 94 linear; +#X msg 147 118 geometric; +#X text 191 93 linear average (dafault); +#X text 230 119 geometric average; +#X msg 158 146 weight; +#X text 217 147 weighted average (giving last; +#X text 218 163 items higher weight); +#X connect 0 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 1 0; +#X connect 3 1 6 0; +#X connect 11 0 3 0; +#X connect 13 0 3 0; +#X connect 14 0 3 0; +#X connect 17 0 3 0; diff --git a/average.c b/average.c new file mode 100644 index 0000000..2ce99ad --- /dev/null +++ b/average.c @@ -0,0 +1,202 @@ +/* -------------------------- average ----------------------------------------- */ +/* */ +/* Calculates the average value of the last N elements. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +#define MAX_ARG 128 /* maximum number of items to average */ + +static char *version = "average v0.1, written by Olaf Matthes "; + +typedef struct average +{ + t_object x_ob; + t_clock *x_clock; + t_inlet *x_inindex; + t_outlet *x_outfloat; /* output the average */ + t_outlet *x_outtendency; /* outputs the tendency of the average */ + t_int x_limit; /* indicates if input is 'blocked' (1) */ + t_int x_index; /* the number of elements to average */ + t_float x_input[MAX_ARG]; /* stores the input values we need for averaging */ + t_int x_inpointer; /* actual position in above array */ + t_float x_average; /* what do you guess ? */ + t_float x_lastaverage; + t_int x_mode; /* how to average: linear or geometric */ + +} t_average; + + /* there must be a function for this in math.h but how is the + german 'Fakultät' called in english ???? */ +static int normalise(int i) +{ + int ret = i; + while(i--) + { + if(i == 0)break; + ret += i; + } + return (ret); +} + +static void average_float(t_average *x, t_floatarg f) +{ + int i, j = 0; + t_float tendency; + t_float geo = 1.0; + + x->x_average = 0; + /* put value into array */ + x->x_input[x->x_inpointer] = f; + /* calulate average */ + for(i = 0; i < x->x_index; i++) + { + if(x->x_mode == 0) /* linear */ + { + x->x_average += x->x_input[i] * (1.0 / (float)x->x_index); + } + else if(x->x_mode == 1) /* geometric */ + { + if(x->x_input[i] == 0)x->x_input[i] = 0.001; /* need to cheat a bit... */ + geo *= x->x_input[i]; + if(i == x->x_index - 1) + x->x_average = pow(geo, (1.0/(float)x->x_index)); + } + else if(x->x_mode == 2) /* weighted */ + { + x->x_average += x->x_input[(j + x->x_inpointer + x->x_index) % x->x_index] * (float)(x->x_index - (i + 1)); + j--; /* go back in array */ + /* normalise output */ + if(i == x->x_index - 1) + x->x_average = x->x_average / (float)normalise(x->x_index - 1); + } else post("average: internal error!"); + } + if(++x->x_inpointer > x->x_index) + { + x->x_inpointer = 0; + if(x->x_lastaverage < x->x_average) + { + tendency = 1; /* getting more */ + } + else if(x->x_lastaverage > x->x_average) + { + tendency = -1; /* getting less */ + } + else tendency = 0; /* nothing has changed */ + outlet_float(x->x_outtendency, tendency); + x->x_lastaverage = x->x_average; + } + outlet_float(x->x_outfloat, x->x_average); +} + +static void average_index(t_average *x, t_floatarg f) +{ + x->x_index = (t_int)f; + if(x->x_index > MAX_ARG)x->x_index = MAX_ARG; +} + +static void average_reset(t_average *x) +{ + int i; + /* zeroe out the array */ + for(i = 0; i < MAX_ARG; i++)x->x_input[i] = 0.0; + x->x_inpointer = 0; + x->x_average = 0; + x->x_lastaverage = 0; + post("average: reset"); +} + +static void average_linear(t_average *x) +{ + x->x_mode = 0; + post("average: linear"); +} + +static void average_geometric(t_average *x) +{ + x->x_mode = 1; + post("average: geometric"); +} + +static void average_weight(t_average *x) +{ + x->x_mode = 2; + post("average: weighted"); +} + +static void average_free(t_average *x) +{ + /* nothing to do */ +} + +static t_class *average_class; + +static void *average_new(t_floatarg f) +{ + int i; + + t_average *x = (t_average *)pd_new(average_class); + x->x_inindex = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("index")); + x->x_outfloat = outlet_new(&x->x_ob, gensym("float")); + x->x_outtendency = outlet_new(&x->x_ob, gensym("float")); + + /* zeroe out the array */ + for(i = 0; i < MAX_ARG; i++)x->x_input[i] = 0.0; + x->x_index = (t_int)f; + if(x->x_index > MAX_ARG) + { + x->x_index = MAX_ARG; + post("average: set number of items to %d", x->x_index); + } + x->x_inpointer = 0; + x->x_average = 0; + x->x_mode = 0; + return (void *)x; +} + +#ifndef MAXLIB +void average_setup(void) +{ + average_class = class_new(gensym("average"), (t_newmethod)average_new, + (t_method)average_free, sizeof(t_average), 0, A_DEFFLOAT, 0); +#else +void maxlib_average_setup(void) +{ + average_class = class_new(gensym("maxlib_average"), (t_newmethod)average_new, + (t_method)average_free, sizeof(t_average), 0, A_DEFFLOAT, 0); +#endif + class_addmethod(average_class, (t_method)average_reset, gensym("reset"), 0); + class_addmethod(average_class, (t_method)average_linear, gensym("linear"), 0); + class_addmethod(average_class, (t_method)average_geometric, gensym("geometric"), 0); + class_addmethod(average_class, (t_method)average_weight, gensym("weight"), 0); + class_addfloat(average_class, average_float); + class_addmethod(average_class, (t_method)average_index, gensym("index"), A_FLOAT, 0); +#ifndef MAXLIB + post(version); + +#else + class_addcreator((t_newmethod)average_new, gensym("average"), A_DEFFLOAT, 0); + class_sethelpsymbol(average_class, gensym("maxlib/average-help.pd")); +#endif +} + diff --git a/beat-help.pd b/beat-help.pd new file mode 100644 index 0000000..55f85ef --- /dev/null +++ b/beat-help.pd @@ -0,0 +1,66 @@ +#N canvas 294 98 628 562 12; +#X floatatom 20 503 8 0 0; +#X obj 20 66 notein; +#X obj 183 376 makenote 100 250; +#X floatatom 41 477 5 0 0; +#X text 43 13 beat :: beat tracker; +#X text 97 505 beats per minute; +#X msg 71 224 reset; +#X obj 183 219 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X msg 183 346 60; +#X msg 53 108 print; +#X obj 63 446 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -258699 +-1; +#X text 93 447 'on beat'; +#X text 96 479 milliseconds; +#X msg 303 336 400; +#X obj 319 299 + 0; +#X text 411 245 <-- adding some jitter; +#X obj 183 271 random 4; +#X obj 183 298 select 0 1 2 3; +#X text 211 218 <-- click here to play random rhythm; +#X obj 338 243 random 3; +#X obj 338 270 - 1; +#X obj 20 414 beat 4; +#X text 88 415 creation: beat ; +#X text 349 456 certain percentage in which; +#X text 350 472 the beats have to lie; +#X msg 262 337 200; +#X msg 222 336 100; +#X obj 183 245 metro 100; +#X text 106 108 print internal data (toggle on/off); +#X text 106 136 prints out: time between current and last event \, +the five best-fitting theories (with likelyhood in brackets) \, the +time of arrival of current event (R) and the expected time of arrival +(E) of the next event; +#X text 213 439 band percentage: creates a critical time band of a +; +#X connect 1 0 21 0; +#X connect 1 1 21 1; +#X connect 2 0 21 0; +#X connect 2 1 21 1; +#X connect 6 0 21 0; +#X connect 7 0 27 0; +#X connect 8 0 2 0; +#X connect 9 0 21 0; +#X connect 13 0 14 0; +#X connect 14 0 27 1; +#X connect 16 0 17 0; +#X connect 17 0 8 0; +#X connect 17 0 26 0; +#X connect 17 1 8 0; +#X connect 17 1 25 0; +#X connect 17 2 13 0; +#X connect 17 2 8 0; +#X connect 17 3 8 0; +#X connect 17 3 13 0; +#X connect 19 0 20 0; +#X connect 20 0 14 1; +#X connect 21 0 0 0; +#X connect 21 1 3 0; +#X connect 21 2 10 0; +#X connect 25 0 14 0; +#X connect 26 0 14 0; +#X connect 27 0 16 0; +#X connect 27 0 19 0; diff --git a/beat.c b/beat.c new file mode 100644 index 0000000..a2f565e --- /dev/null +++ b/beat.c @@ -0,0 +1,403 @@ +/* --------------------------- beat ------------------------------------------ */ +/* */ +/* Detect the beats per minute of a MIDI stream. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code written by Robert Rowe. */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define BEAT_LONG 1500 /* longest time we take into concideration (40 bpm) */ +#define BEAT_SHORT 300 /* shortest time we take into concideration (200 bpm) */ + +static char *version = "beat v0.1, written by Olaf Matthes "; + +typedef struct +{ + t_int points; /* number of points assigned to this theory */ + double expect; /* time of next expected hit */ + t_int onbeat; /* whether (1) or not (0) it was on the beat */ +} beat_theory; + +typedef struct /* used for sorting theories */ +{ + t_int points; + t_int theory; +} beat_sort_record; + + +typedef struct beat +{ + t_object x_ob; + t_clock *x_clock; + t_outlet *x_outbpm; /* beat as MIDI note number */ + t_outlet *x_outms; /* beat in milliseconds */ + t_outlet *x_outbeat; /* send a bang whenever beat is 'on beat' */ + t_int x_print; /* switch printing to console window on / off */ + + t_int x_num_beats; /* number of beats we've received */ + double x_beat_period; /* time in ms until next expected beat / beat pulse */ + beat_theory x_beats[BEAT_LONG]; + double x_beatexpect; /* expected time for next beat */ + t_int x_on_beat; /* indicate if last event was on beat */ + t_int x_band_percent; + + t_int x_pitch; + t_int x_velo; + /* helpers needed to do the time calculations */ + double x_this_input; + double x_last_input; + double x_lasttime; + double x_lastlasttime; +} t_beat; + +/* ---------------- mathematical functions to work with doubles -------------- */ +static double double_abs(double value) +{ + if(value < 0) + return (value * -1); + else + return (value); +} + +/* --------------- beat stuff ------------------------------------------------ */ + /* evaluate results: find theory that is the most likely one and + print out internal data to console window if print is enabled */ +static int beat_evaluate(t_beat *x) +{ + int i, j, K; + char string[256]; + char info[40]; + beat_sort_record theories[BEAT_LONG], *sortp, R; + int value; /* the result of the sorting */ + + for (i = 0; i < BEAT_LONG; i++) + { /* prepare sort records */ + sortp = &(theories[i]); + sortp->points = x->x_beats[i].points; + sortp->theory = i; + } + for (j = 2; j < BEAT_LONG; j++) + { /* sort */ + i = j - 1; + K = theories[j].points; + R = theories[j]; + while (i > 0) + { + if (K >= theories[i].points) + { + theories[i+1] = R; + break; + } + else + { + theories[i+1] = theories[i]; + i -= 1; + } + } + if (i==0) theories[i+1] = R; + } + /* get leading result */ + sortp = &(theories[BEAT_LONG - 1]); + value = sortp->theory; /* get our resulting theory */ + + if(x->x_print) + { + post(" 0 1 2 3 4 R E"); + *string = '\0'; /* print out five leading theories */ + sprintf(info, "%4g", x->x_this_input); + strcat(string, info); + for(i = 1; i < 6; i++) + { + sortp = &(theories[BEAT_LONG - i]); + sprintf(info, " %4d[%3d]", (int) sortp->theory, (int) sortp->points); + strcat(string, info); + } + sprintf(info, " %g %g", clock_getlogicaltime(), x->x_beatexpect); + strcat(string, info); + post(string); + } + + return value; +} + + /* reduce duration to fit into our processing window */ + /* some sort of 'double modulo'... */ +static double beat_reduce_offset(double duration) +{ + double temp = duration; + int divisor = 2; /* first try dividing by two */ + while (temp > BEAT_LONG) /* while duration is too long */ + temp = duration / divisor++; /* divide by progressively higher divisors */ + return temp; /* return a value in bounds */ +} + +/* + * beat_eligible: determine whether an event is eligible for consideration + * as a beat theory + */ +static int beat_eligible(double candidate, int* offsets, int num_offsets) +{ + double diff; + int i; + + if (candidate >= BEAT_LONG) /* if too long try subharmonics */ + candidate = beat_reduce_offset(candidate); + + /* if candidate is close to one already found */ + for(i = 0; i < num_offsets; i++) + { + diff = double_abs((candidate - offsets[i])); + if (diff < offsets[i]/20) { + if (candidate > offsets[i]) + ++offsets[i]; else /* pull existing one */ + if (candidate < offsets[i]) /* toward new candidate */ + --offsets[i]; + return 0; /* declare candidate ineligible */ + } + } + return candidate; /* otherwise return legal candidate */ +} + +static void beat_float(t_beat *x, t_floatarg f) +{ + t_int velo = x->x_velo; + int i, j, indx; + int num_offsets, candidate; + int low_limit, high_limit, width, deviation; + int points, band, center_offset, period; + beat_theory* t; + int offsets[7]; + static int factors[10] = + { 200, 50, 300, 150, 66, 400, 600, 133, 33, 75 }; + double now = clock_getlogicaltime(); + t_float outvalue; + + x->x_pitch = (t_int)f; + x->x_this_input = clock_gettimesince(x->x_last_input); + + if(velo != 0) /* note-on received */ + { + if(++x->x_num_beats == 1) + { + goto time; /* only one event, no beats yet */ + } + + num_offsets = 0; + candidate = beat_eligible(x->x_this_input, offsets, num_offsets); + if(candidate) + offsets[num_offsets++] = candidate; /* offset[0] set to incoming offset */ + + if(x->x_num_beats > 2) + { /* if three events */ + /* check previous for eligibility */ + candidate = beat_eligible(x->x_lasttime, offsets, num_offsets); + if (candidate) + offsets[num_offsets++] = candidate; + candidate = x->x_this_input + x->x_lasttime; /* add current and previous offsets */ + candidate = beat_eligible(candidate, offsets, num_offsets); + if (candidate) /* add to list if eligible */ + offsets[num_offsets++] = candidate; + } + + if(x->x_num_beats > 3) + { + candidate = beat_eligible(x->x_lastlasttime, offsets, num_offsets); + if (candidate) + offsets[num_offsets++] = candidate; + candidate += x->x_lasttime; + candidate = beat_eligible(candidate, offsets, num_offsets); + if (candidate) + offsets[num_offsets++] = candidate; + } + + indx = 0; + for(i = num_offsets; i < 7; i++) + { + offsets[i] = 0; + if (indx >= 10) break; + candidate = 0; + while ((indx < 10) && (!candidate)) + candidate = beat_eligible((x->x_this_input * factors[indx++])/100, offsets, num_offsets); + if (candidate) + offsets[num_offsets++] = candidate; + } + + for(i = 0; i < num_offsets; i++) + { + band = offsets[i] * x->x_band_percent / 100; + if ((low_limit = offsets[i] - band) < 0) /* add points in a critical band */ + low_limit = 0; /* around calculated offset */ + if ((high_limit = offsets[i] + band) > BEAT_LONG) + high_limit = BEAT_LONG; + center_offset = offsets[i]; /* midpoint of increment */ + points = 0; + for (j = low_limit; j < high_limit; j++) + { + if ((points = x->x_beats[j].points) > 0) + { /* if there is already activation */ + deviation = j - center_offset; /* record deviation from midpoint */ + x->x_beats[j].points = 0; + if (deviation < 0) { /* if there is activation below midpoint */ + t = &(x->x_beats[j+1]); /* take theory one above prior */ + } else + if (deviation > 0) { /* if there is activation above midpoint */ + t = &(x->x_beats[j-1]); /* take theory one below prior */ + } else + t = &(x->x_beats[j]); /* landed right on it */ + t->points = points + (num_offsets-i); + break; + } + } + if (!points) + x->x_beats[center_offset].points = num_offsets - i; + } + + /* boost hits, and suppress theories with missed beats */ + period = 0; + points = 0; + for (i = BEAT_SHORT; i < BEAT_LONG; i++) + { + t = &(x->x_beats[i]); + width = 5 > (t->expect / 7) ? 5 : (t->expect / 7); + t->expect -= x->x_this_input; + t->onbeat = 0; + if(double_abs(t->expect) <= width) /* lies within range */ + { + t->expect = i; + t->onbeat = 1; + if (t->points > 0) + t->points += 4; /* add 4 points */ + } + else if(t->expect < 0) + { + t->points -= 8; + t->expect = i; + } + if (t->points < 0) t->points = 0; else + if (t->points > 200) t->points = 200; + if (t->points > points) + { + points = t->points; + period = i; + } + } + + + + x->x_beat_period = (double)period; + t = &(x->x_beats[period]); + x->x_beatexpect = now + (double)t->expect; + x->x_on_beat = t->onbeat; + +time: + x->x_lastlasttime = x->x_lasttime; + x->x_lasttime = x->x_this_input; //now; + x->x_last_input = now; + + if(x->x_on_beat)outlet_bang(x->x_outbeat); + outvalue = (t_float)beat_evaluate(x); + outlet_float(x->x_outms, outvalue); + if(x->x_beat_period)outlet_float(x->x_outbpm, (t_float)(60000.0 / outvalue)); + } + return; +} + +static void beat_ft1(t_beat *x, t_floatarg f) +{ + x->x_velo = (t_int)f; +} + + /* toggle printing on/off */ +static void beat_print(t_beat *x) +{ + if(x->x_print)x->x_print = 0; + else x->x_print = 1; +} + +static void beat_reset(t_beat *x) +{ + int i; + + for(i = 0; i < BEAT_LONG; i++) + { + x->x_beats[i].points = 0; + x->x_beats[i].expect = i; + x->x_beats[i].onbeat = 0; + } + x->x_lastlasttime = 0; + x->x_lasttime = 0; + x->x_num_beats = 0; + x->x_beat_period = 0; + x->x_on_beat = 0; +} + +static t_class *beat_class; + +static void beat_free(t_beat *x) +{ + /* nothing to do */ +} + +static void *beat_new(t_floatarg f) +{ + t_beat *x = (t_beat *)pd_new(beat_class); + inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + x->x_outbpm = outlet_new(&x->x_ob, gensym("float")); + x->x_outms = outlet_new(&x->x_ob, gensym("float")); + x->x_outbeat = outlet_new(&x->x_ob, gensym("bang")); + + beat_reset(x); + x->x_band_percent = 4; /* allow 4% 'jitter' by default */ + if(f)x->x_band_percent = (t_int)f; + + post("beat: band percentage set to %d", x->x_band_percent); + + return (void *)x; +} + +#ifndef MAXLIB +void beat_setup(void) +{ + beat_class = class_new(gensym("beat"), (t_newmethod)beat_new, + (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0); +#else +void maxlib_beat_setup(void) +{ + beat_class = class_new(gensym("maxlib_beat"), (t_newmethod)beat_new, + (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0); +#endif + class_addfloat(beat_class, beat_float); + class_addmethod(beat_class, (t_method)beat_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(beat_class, (t_method)beat_reset, gensym("reset"), 0); + class_addmethod(beat_class, (t_method)beat_print, gensym("print"), 0); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)beat_new, gensym("beat"), A_DEFFLOAT, 0); + class_sethelpsymbol(beat_class, gensym("maxlib/beat-help.pd")); +#endif +} + diff --git a/beta-help.pd b/beta-help.pd new file mode 100644 index 0000000..f4b9edf --- /dev/null +++ b/beta-help.pd @@ -0,0 +1,14 @@ +#N canvas 438 222 487 308 12; +#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 70 192 5 0 0; +#X floatatom 139 94 5 0 0; +#X obj 70 140 beta 0.78 1.3; +#X text 192 95 a; +#X floatatom 209 116 5 0 0; +#X text 262 117 b; +#X text 39 21 beta :: beta distributed random numbers; +#X connect 0 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 1 0; +#X connect 5 0 3 2; diff --git a/beta.c b/beta.c new file mode 100644 index 0000000..c99b538 --- /dev/null +++ b/beta.c @@ -0,0 +1,107 @@ +/* ---------------------------- rand_beta ------------------------------------- */ +/* */ +/* rand_beta generates a beta distributed random variable. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code found in Dodge/Jerse "Computer Music" */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define fran() (t_float)rand()/(t_float)RAND_MAX +#ifndef M_PI +#define M_PI 3.1415927 +#endif + +static char *version = "beta v0.1, generates a beta distributed random variable\n" + " written by Olaf Matthes "; + +/* -------------------------- rand_beta ------------------------------ */ + +static t_class *rand_beta_class; + +typedef struct _rand_beta +{ + t_object x_obj; + t_float x_a; + t_float x_b; +} t_rand_beta; + +static void *rand_beta_new(t_floatarg a, t_floatarg b) +{ + t_rand_beta *x = (t_rand_beta *)pd_new(rand_beta_class); + srand( (unsigned)time( NULL ) ); + floatinlet_new(&x->x_obj, &x->x_a); + floatinlet_new(&x->x_obj, &x->x_b); + outlet_new(&x->x_obj, &s_float); + x->x_a = a; + x->x_b = b; + return (x); +} + +static void rand_beta_bang(t_rand_beta *x) +{ + t_float u1, u2, y01, y2, sum, a, b, ainv, binv; + a = (x->x_a <= 0 ? 0.0001 : x->x_a); + b = (x->x_b <= 0 ? 0.0001 : x->x_b); + ainv = 1/a; + binv = 1/b; + do + { + do + { + u1 = fran(); + } + while(u1 == 0); + do + { + u2 = fran(); + } + while(u2 == 0); + y01 = pow(u1, ainv); + y2 = pow(u2, binv); + sum = y01 + y2; + } + while(sum > 1); + outlet_float(x->x_obj.ob_outlet, y01/sum); +} + +#ifndef MAXLIB +void beta_setup(void) +{ + rand_beta_class = class_new(gensym("beta"), (t_newmethod)rand_beta_new, 0, + sizeof(t_rand_beta), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addbang(rand_beta_class, rand_beta_bang); + class_sethelpsymbol(rand_beta_class, gensym("beta-help.pd")); + post(version); +} +#else +void maxlib_beta_setup(void) +{ + rand_beta_class = class_new(gensym("maxlib_beta"), (t_newmethod)rand_beta_new, 0, + sizeof(t_rand_beta), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addbang(rand_beta_class, rand_beta_bang); + class_addcreator((t_newmethod)rand_beta_new, gensym("beta"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_sethelpsymbol(rand_beta_class, gensym("maxlib/beta-help.pd")); +} +#endif diff --git a/bilex-help.pd b/bilex-help.pd new file mode 100644 index 0000000..4e9961f --- /dev/null +++ b/bilex-help.pd @@ -0,0 +1,12 @@ +#N canvas 370 195 485 306 12; +#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 70 192 5 0 0; +#X floatatom 177 103 5 0 0; +#X text 230 105 lambda; +#X text 13 20 bilex :: bilinear exponetionally distributed random +numbers; +#X obj 70 140 bilex 1.5; +#X connect 0 0 5 0; +#X connect 2 0 5 1; +#X connect 5 0 1 0; diff --git a/bilex.c b/bilex.c new file mode 100644 index 0000000..eb54aa4 --- /dev/null +++ b/bilex.c @@ -0,0 +1,91 @@ +/* ---------------------------- rand_bilex ------------------------------------ */ +/* */ +/* rand_bilex generates a bilinear exponentially distributed random variable. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code found in Dodge/Jerse "Computer Music" */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define fran() (t_float)rand()/(t_float)RAND_MAX + +static char *version = "bilex v0.1, generates bilinear exponentially distributed random\n" + " variable, written by Olaf Matthes "; + +/* -------------------------- rand_bilex ------------------------------ */ + +static t_class *rand_bilex_class; + +typedef struct _rand_bilex +{ + t_object x_obj; + t_float x_lambda; +} t_rand_bilex; + +static void *rand_bilex_new(t_floatarg f) +{ + t_rand_bilex *x = (t_rand_bilex *)pd_new(rand_bilex_class); + srand( (unsigned)time( NULL ) ); + floatinlet_new(&x->x_obj, &x->x_lambda); + outlet_new(&x->x_obj, &s_float); + x->x_lambda = f; + return (x); +} + +static void rand_bilex_bang(t_rand_bilex *x) +{ + t_float u, s = 1, l; + l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda); + do + { + u = 2*fran(); + } + while(u == 0 || u == 2); + if(u > 1) + { + u = 2-u; + s=-1; + } + outlet_float(x->x_obj.ob_outlet, s*log(u)/l); +} + +#ifndef MAXLIB +void bilex_setup(void) +{ + rand_bilex_class = class_new(gensym("bilex"), (t_newmethod)rand_bilex_new, 0, + sizeof(t_rand_bilex), 0, A_DEFFLOAT, 0); + class_addbang(rand_bilex_class, rand_bilex_bang); + class_sethelpsymbol(rand_bilex_class, gensym("bilex-help.pd")); + post(version); +} +#else +void maxlib_bilex_setup(void) +{ + rand_bilex_class = class_new(gensym("maxlib_bilex"), (t_newmethod)rand_bilex_new, 0, + sizeof(t_rand_bilex), 0, A_DEFFLOAT, 0); + class_addbang(rand_bilex_class, rand_bilex_bang); + class_addcreator((t_newmethod)rand_bilex_new, gensym("bilex"), A_DEFFLOAT, 0); + class_sethelpsymbol(rand_bilex_class, gensym("maxlib/bilex-help.pd")); +} +#endif diff --git a/borax-help.pd b/borax-help.pd new file mode 100644 index 0000000..a286a60 --- /dev/null +++ b/borax-help.pd @@ -0,0 +1,86 @@ +#N canvas 281 85 645 549 12; +#X obj 125 230 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 125 298 6 0 0; +#X floatatom 50 451 5 0 0; +#X floatatom 26 502 5 0 0; +#X floatatom 63 425 5 0 0; +#X floatatom 38 476 5 0 0; +#X floatatom 100 349 6 0 0; +#X floatatom 75 399 5 0 0; +#X floatatom 112 323 5 0 0; +#X floatatom 87 374 5 0 0; +#X obj 26 269 borax 0 0 0 0; +#X text 103 452 number of voices currently playing; +#X text 120 422 pitch; +#X text 127 399 velocity; +#X obj 15 54 makenote 100 1500; +#X obj 336 67 metro 100; +#X obj 428 124 + 50; +#X obj 428 147 s time; +#X obj 403 43 r time; +#X obj 260 147 s pitch; +#X obj 15 17 r pitch; +#X obj 80 18 r velo; +#X msg 336 14 1; +#X msg 345 37 0; +#X obj 513 101 random 64; +#X obj 513 124 + 64; +#X obj 513 147 s velo; +#X obj 146 19 r duration; +#X obj 336 147 s duration; +#X obj 336 124 + 250; +#X text 91 477 voice allocation number - each note playing is assigned +a no; +#X obj 45 88 noteout 1; +#X obj 428 101 random 500; +#X obj 260 101 random 88; +#X obj 260 124 + 21; +#X text 120 200 borax :: analyse incoming midi notes; +#X text 363 13 <-- click to play random music; +#X obj 40 125 notein 1; +#X text 186 300 delta time value - time between note-ons; +#X text 160 350 duration value - time between note-on and note-off +; +#X text 79 502 note-on count; +#X text 141 374 duration count; +#X text 164 326 delta time count; +#X obj 336 101 random 1000; +#X text 153 228 <-- reset :: sets counters and clocks to zero and sends +; +#X text 258 243 note-off for all notes currently playing; +#X text 137 273 <--- zeroes only added to make the object larger; +#X connect 0 0 10 2; +#X connect 10 0 3 0; +#X connect 10 1 5 0; +#X connect 10 2 2 0; +#X connect 10 3 4 0; +#X connect 10 4 7 0; +#X connect 10 5 9 0; +#X connect 10 6 6 0; +#X connect 10 7 8 0; +#X connect 10 8 1 0; +#X connect 14 0 10 0; +#X connect 14 0 31 0; +#X connect 14 1 10 1; +#X connect 14 1 31 1; +#X connect 15 0 24 0; +#X connect 15 0 32 0; +#X connect 15 0 33 0; +#X connect 15 0 43 0; +#X connect 16 0 17 0; +#X connect 18 0 15 1; +#X connect 20 0 14 0; +#X connect 21 0 14 1; +#X connect 22 0 15 0; +#X connect 23 0 15 0; +#X connect 24 0 25 0; +#X connect 25 0 26 0; +#X connect 27 0 14 2; +#X connect 29 0 28 0; +#X connect 32 0 16 0; +#X connect 33 0 34 0; +#X connect 34 0 19 0; +#X connect 37 0 10 0; +#X connect 37 1 10 1; +#X connect 43 0 29 0; diff --git a/borax.c b/borax.c new file mode 100644 index 0000000..32979b7 --- /dev/null +++ b/borax.c @@ -0,0 +1,238 @@ +/* ------------------------- borax ------------------------------------------ */ +/* */ +/* "swiss army knife" for music analysis. Inspired by 'borax' for Max. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" + +#define MAX_POLY 128 /* maximum number of notes played at a time */ + +static char *version = "borax v0.1, written by Olaf Matthes "; + +typedef struct borax +{ + t_object x_ob; + t_inlet *x_invelo; /* inlet for velocity */ + t_inlet *x_inreset; /* inlet to reset the object */ + t_outlet *x_outnotecount; /* counts notes */ + t_outlet *x_outvoicealloc; /* assigns every note a unique number */ + t_outlet *x_outpoly; /* number of notes playing (polyphony) */ + t_outlet *x_outpitch; /* pitch of current note */ + t_outlet *x_outvelo; /* velocity of current note */ + t_outlet *x_outdurcount; /* number assigned to duration value */ + t_outlet *x_outdurval; /* duration value */ + t_outlet *x_outtimecount; /* number assigned to delta time value */ + t_outlet *x_outtimeval; /* delta time value */ + + + t_float x_notecount; + t_int x_pitch; + t_int x_velo; + t_float x_voicecount; + t_int x_voicealloc; + t_int x_poly; + t_float x_durcount; + t_float x_durval; + t_float x_timecount; + t_float x_timeval; + /* helpers needed to do the calculations */ + double x_starttime[MAX_POLY]; + double x_laststarttime; + t_int x_alloctable[MAX_POLY]; + +} t_borax; + +static void borax_float(t_borax *x, t_floatarg f) +{ + t_int velo = x->x_velo; + t_int allloc = 0; + int i; + + x->x_pitch = (t_int)f; + + if(velo == 0) + { + /* note off received... */ + if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */ + x->x_durcount++; /* we can calculate the duration */ + for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */ + { + /* search for corresponding alloc number */ + if(x->x_alloctable[i] == x->x_pitch) + { + x->x_voicealloc = i; + x->x_alloctable[i] = 0; /* free the alloc number */ + break; + } + /* couldn't find it ? */ + if(i == MAX_POLY - 1) + { + post("borax: no corresponding note-on found (ignored)"); + return; + } + } + x->x_durval = clock_gettimesince(x->x_starttime[x->x_voicealloc]); + } + else if(velo != 0) + { + /* note on received... */ + x->x_poly++; /* number of currently playing notes has increased */ + x->x_notecount++; /* total number of notes has increased */ + /* assign a voice allocation number */ + for(i = 0; i < MAX_POLY; i++) + { + /* search for free alloc number */ + if(x->x_alloctable[i] == 0) + { + x->x_voicealloc = i; /* take the number */ + x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */ + break; + } + /* couldn't find any ? */ + if(i == MAX_POLY - 1) + { + post("borax: too many note-on messages (ignored)"); + return; + } + } + /* calculate time in case it's not the first note */ + if(x->x_notecount > 1) + { + x->x_timecount++; + x->x_timeval = clock_gettimesince(x->x_laststarttime); + } + /* save the new start time */ + x->x_laststarttime = x->x_starttime[x->x_voicealloc] = clock_getlogicaltime(); + } + /* output values from right to left */ + outlet_float(x->x_outtimeval, x->x_timeval); + outlet_float(x->x_outtimecount, x->x_timecount); + outlet_float(x->x_outdurval, x->x_durval); + outlet_float(x->x_outdurcount, x->x_durcount); + outlet_float(x->x_outvelo, velo); + outlet_float(x->x_outpitch, x->x_pitch); + outlet_float(x->x_outpoly, x->x_poly); + outlet_float(x->x_outvoicealloc, x->x_voicealloc); + outlet_float(x->x_outnotecount, x->x_notecount); +} + +static void borax_ft1(t_borax *x, t_floatarg f) +{ + x->x_velo = (t_int)f; +} + +static void borax_reset(t_borax *x) +{ + int i; + post("borax: reset"); + x->x_notecount = 0; + x->x_pitch = 0; + x->x_velo = 0; + x->x_voicecount = 0; + x->x_voicealloc = 0; + x->x_poly = 0; + x->x_durcount = 0; + x->x_durval = 0; + x->x_timecount = 0; + x->x_timeval = 0; + outlet_float(x->x_outtimeval, x->x_timeval); + outlet_float(x->x_outtimecount, x->x_timecount); + outlet_float(x->x_outdurval, x->x_durval); + outlet_float(x->x_outdurcount, x->x_durcount); + for(i = 0; i < MAX_POLY; i++) + { + if(x->x_alloctable[i] != 0) + { + x->x_poly--; + /* send note-off */ + outlet_float(x->x_outvelo, 0); + outlet_float(x->x_outpitch, x->x_alloctable[i]); + outlet_float(x->x_outpoly, x->x_poly); + outlet_float(x->x_outvoicealloc, i); + } + x->x_alloctable[i] = 0; + } + outlet_float(x->x_outvelo, x->x_velo); + outlet_float(x->x_outpitch, x->x_pitch); + outlet_float(x->x_outpoly, x->x_poly); + outlet_float(x->x_outvoicealloc, x->x_voicealloc); + outlet_float(x->x_outnotecount, x->x_notecount); +} + +static t_class *borax_class; + +static void *borax_new(void) +{ + int i; + + t_borax *x = (t_borax *)pd_new(borax_class); + x->x_invelo = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + x->x_inreset = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("bang"), gensym("ft2")); + x->x_outnotecount = outlet_new(&x->x_ob, gensym("float")); + x->x_outvoicealloc = outlet_new(&x->x_ob, gensym("float")); + x->x_outpoly = outlet_new(&x->x_ob, gensym("float")); + x->x_outpitch = outlet_new(&x->x_ob, gensym("float")); + x->x_outvelo = outlet_new(&x->x_ob, gensym("float")); + x->x_outdurcount = outlet_new(&x->x_ob, gensym("float")); + x->x_outdurval = outlet_new(&x->x_ob, gensym("float")); + x->x_outtimecount = outlet_new(&x->x_ob, gensym("float")); + x->x_outtimeval = outlet_new(&x->x_ob, gensym("float")); + + for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = 0; + x->x_notecount = 0; + x->x_pitch = 0; + x->x_velo = 0; + x->x_voicecount = 0; + x->x_voicealloc = 0; + x->x_poly = 0; + x->x_durcount = 0; + x->x_durval = 0; + x->x_timecount = 0; + x->x_timeval = 0; + + return (void *)x; +} + +#ifndef MAXLIB +void borax_setup(void) +{ + borax_class = class_new(gensym("borax"), (t_newmethod)borax_new, + 0, sizeof(t_borax), 0, 0); +#else +void maxlib_borax_setup(void) +{ + borax_class = class_new(gensym("maxlib_borax"), (t_newmethod)borax_new, + 0, sizeof(t_borax), 0, 0); +#endif + class_addmethod(borax_class, (t_method)borax_reset, gensym("reset"), 0); + class_addmethod(borax_class, (t_method)borax_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(borax_class, (t_method)borax_reset, gensym("ft2"), A_GIMME, 0); + class_addfloat(borax_class, borax_float); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)borax_new, gensym("borax"), 0); + class_sethelpsymbol(borax_class, gensym("maxlib/borax-help.pd")); +#endif +} + diff --git a/cauchy-help.pd b/cauchy-help.pd new file mode 100644 index 0000000..a7dd6f2 --- /dev/null +++ b/cauchy-help.pd @@ -0,0 +1,11 @@ +#N canvas 438 222 487 308 12; +#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 70 192 5 0 0; +#X floatatom 185 103 5 0 0; +#X obj 70 140 cauchy 0.5; +#X text 238 104 alpha - governs spread; +#X text 39 21 cauchy :: Cauchy distributed random numbers; +#X connect 0 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 1 0; diff --git a/cauchy.c b/cauchy.c new file mode 100644 index 0000000..ee64296 --- /dev/null +++ b/cauchy.c @@ -0,0 +1,89 @@ +/* ---------------------------- rand_cauchy ----------------------------------- */ +/* */ +/* rand_cauchy generates a Cauchy distributed random variable. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code found in Dodge/Jerse "Computer Music" */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define fran() (t_float)rand()/(t_float)RAND_MAX +#ifndef M_PI +#define M_PI 3.1415927 +#endif + +static char *version = "cauchy v0.1, generates a Cauchy distributed random variable\n" + " with a spread governed by to parameter 'aplha',\n" + " written by Olaf Matthes "; + +/* -------------------------- rand_cauchy ------------------------------ */ + +static t_class *rand_cauchy_class; + +typedef struct _rand_cauchy +{ + t_object x_obj; + t_float x_alpha; +} t_rand_cauchy; + +static void *rand_cauchy_new(t_floatarg f) +{ + t_rand_cauchy *x = (t_rand_cauchy *)pd_new(rand_cauchy_class); + srand( (unsigned)time( NULL ) ); + floatinlet_new(&x->x_obj, &x->x_alpha); + outlet_new(&x->x_obj, &s_float); + x->x_alpha = f; + return (x); +} + +static void rand_cauchy_bang(t_rand_cauchy *x) +{ + t_float u; + do + { + u = fran(); + } + while(u == 0.5); + u *= M_PI; + outlet_float(x->x_obj.ob_outlet, x->x_alpha*tan(u)); +} + +#ifndef MAXLIB +void cauchy_setup(void) +{ + rand_cauchy_class = class_new(gensym("cauchy"), (t_newmethod)rand_cauchy_new, 0, + sizeof(t_rand_cauchy), 0, A_DEFFLOAT, 0); + class_addbang(rand_cauchy_class, rand_cauchy_bang); + class_sethelpsymbol(rand_cauchy_class, gensym("cauchy-help.pd")); + post(version); +#else +void maxlib_cauchy_setup(void) +{ + rand_cauchy_class = class_new(gensym("maxlib_cauchy"), (t_newmethod)rand_cauchy_new, 0, + sizeof(t_rand_cauchy), 0, A_DEFFLOAT, 0); + class_addbang(rand_cauchy_class, rand_cauchy_bang); + class_addcreator((t_newmethod)rand_cauchy_new, gensym("cauchy"), A_DEFFLOAT, 0); + class_sethelpsymbol(rand_cauchy_class, gensym("maxlib/cauchy-help.pd")); +#endif +} diff --git a/chord-help.pd b/chord-help.pd new file mode 100644 index 0000000..a509840 --- /dev/null +++ b/chord-help.pd @@ -0,0 +1,37 @@ +#N canvas 291 216 458 308 12; +#X floatatom 15 276 5 0 0; +#X symbolatom 44 212 48 0 0; +#X floatatom 74 149 5 0 0; +#X floatatom 131 149 5 0 0; +#X floatatom 189 149 5 0 0; +#X floatatom 248 149 5 0 0; +#X floatatom 59 182 5 0 0; +#X text 71 276 MIDI note number of bass note; +#X text 116 175 root position (0) \, 1st inversion (1); +#X text 115 188 or 2nd inversion (2); +#X floatatom 29 249 5 0 0; +#X text 84 251 class of bass note; +#X text 231 118 list of chord notes; +#X obj 15 51 notein; +#X obj 15 86 chord 59; +#X text 90 86 <-- notes higher than 59 get ignored; +#X text 15 9 chord :: tries to detect chords; +#X text 89 232 notes in chord : chord name; +#X text 89 26 written by Olaf Matthes ; +#X text 89 44 based on code by Rober Rowe; +#X obj 74 118 unpack f f f f f f; +#X floatatom 303 149 5 0 0; +#X floatatom 362 149 5 0 0; +#X connect 13 0 14 0; +#X connect 13 1 14 1; +#X connect 14 0 0 0; +#X connect 14 1 10 0; +#X connect 14 2 1 0; +#X connect 14 3 6 0; +#X connect 14 4 20 0; +#X connect 20 0 2 0; +#X connect 20 1 3 0; +#X connect 20 2 4 0; +#X connect 20 3 5 0; +#X connect 20 4 21 0; +#X connect 20 5 22 0; diff --git a/chord.c b/chord.c new file mode 100644 index 0000000..a1839d3 --- /dev/null +++ b/chord.c @@ -0,0 +1,1822 @@ +/* ------------------------- chord ------------------------------------------ */ +/* */ +/* Tries to detect a chord (or any harmonic relations) of incoming notes. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#ifndef _WIN32 +#include +#endif + + +#define MAX_POLY 32 /* maximum number of notes played at a time */ + +#define kUnison 0 +#define kMaj 1 +#define kMin 2 +#define kDim 3 +#define kAug 4 +#define kMaj7 5 +#define kDom7 6 +#define kMin7 7 +#define kHalfDim7 8 +#define kDim7 9 +#define kMinMaj7 10 +#define kMaj7s5 11 +#define kMaj7b5 12 +#define kDom7s5 13 +#define kDom7b5 14 +#define kDomb9 15 +#define kMaj9 16 +#define kDom9 17 +#define kMin9 18 +#define kHalfDim9 19 +#define kMinMaj9 20 +#define kDimMaj9 21 +#define kMaj9b5 22 +#define kDom9b5 23 +#define kDom9b13 24 +#define kMin9s11 25 +#define kmM9b11 26 +#define kMaj7b9 27 +#define kMaj7s5b9 28 +#define kDom7b9 29 +#define kMin7b9 30 +#define kMinb9s11 31 +#define kHalfDimb9 32 +#define kDim7b9 33 +#define kMinMajb9 34 +#define kDimMajb9 35 +#define kMaj7s9 36 +#define kDom7s9 37 +#define kMaj7s11 38 +#define kMs9s11 39 +#define kHDimb11 40 +#define kMaj11 41 +#define kDom11 42 +#define kMin11 43 +#define kHalfDim11 44 +#define kDim11 45 +#define kMinMaj11 46 +#define kDimMaj11 47 +#define kMaj11b5 48 +#define kMaj11s5 49 +#define kMaj11b9 50 +#define kMaj11s9 51 +#define kMaj11b13 52 +#define kMaj11s13 53 +#define kM11b5b9 54 +#define kDom11b5 55 +#define kDom11b9 56 +#define kDom11s9 57 +#define kHalfDim11b9 58 +#define kDom7s11 59 +#define kMin7s11 60 +#define kDom13s11 61 +#define kM7b913 62 +#define kMaj7s13 63 +#define kMaj9s13 64 +#define kM7b9s13 65 +#define kDom7b13 66 +#define kChrom 67 +#define kNone 68 + +#define kXX -1 + + +static char *version = "chord v0.2, written by Olaf Matthes "; + +static char* pitch_class[13] = {"C ", "Db ", "D ", "Eb ", "E ", "F ", "Gb ", "G ", "Ab ", "A ", "Bb ", "B ", "no root "}; +static char name_class[7] = {'C', 'D', 'E', 'F', 'G', 'A', 'B'}; + +typedef struct { + int type; + int rootMember; +} t_type_root; + +typedef struct chord +{ + t_object x_ob; + t_outlet *x_outchordval; /* chord as MIDI note number of base note */ + t_outlet *x_outchordclass; /* class of chord's bass note */ + t_outlet *x_outchordname; /* chord name, e.g. "Cmajor7" */ + t_outlet *x_outchordinversion; /* inversion of the chord (root = 0, 1st = 1, 2nd = 2) */ + t_outlet *x_outchordnotes; /* list with note numbers belonging to the chord */ + + t_int x_pitch; + t_int x_pc[12]; /* pitch class array */ + t_int x_abs_pc[12]; /* pitch class array: absolute MIDI note numbers */ + t_int x_velo; + t_int x_alloctable[MAX_POLY]; /* a table used to store all playing notes */ + t_int x_poly; /* number of notes currently playing */ + t_atom x_chordlist[12]; /* list that stores the note numbers for output */ + t_int x_split; /* highes note number to process */ + + t_int x_chord_type; /* chord's type (number between 0 and 68) */ + t_int x_chord_root; /* chord's root (pitch class) */ + t_int x_chord_bass; /* chord's bass note (MIDI note number) */ + t_int x_chord_inversion; /* chord's state of inversion (root, 1st, 2nd) */ + +} t_chord; + +/* functions */ +static void chord_kick_out_member(t_chord *x, t_int number, t_int *members); +static void chord_chord_finder(t_chord *x, t_int num_pcs); +static void chord_draw_chord_type(t_chord *x, t_int num_pcs); + + +static void chord_unison(t_chord *x) +{ + int i; + int member = 0; + for(i = 0; i < 12; i++) + if(x->x_pc[i]) + { + member = i; // find pitch class + break; + } + x->x_chord_type = 0; + x->x_chord_root = member; + chord_draw_chord_type(x, 1); // output onto the screen +} + +static void chord_dyad(t_chord *x) +{ + static t_type_root dyads[11] = + {{ kMaj7, 1 }, { kDom7, 1 }, { kMin, 0 }, { kMaj, 0 }, { kMaj, 1 }, + { kDom7 , 0 }, { kMaj, 0 }, { kMaj, 1 }, { kMin, 1 }, { kDom7, 0 }, { kMaj7, 0 }}; + register t_type_root* t; + + int members[2]; + int i, j = 0; + int interval1; + + for(i = 0; i < 12; i++) + if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + t = &(dyads[interval1]); /* find TypeRoot struct for this interval */ + x->x_chord_type = t->type; + if (interval1 == 5) + x->x_chord_root = (members[0]+8)%12; + else + x->x_chord_root = members[t->rootMember]; + x->x_chord_inversion = t->rootMember; /* get state of inversion */ + chord_draw_chord_type(x, 2); /* output results */ +} + +static void chord_triad(t_chord *x) +{ + static t_type_root triads[10][10] = + {/* interval1 is a half step */ + {{ kMaj7b9, 1 }, { kMaj9, 1 }, { kMinMaj7, 1 }, { kMaj7, 1 }, { kDom7s11,2 }, + { kDomb9 , 0 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 2 }, { kMaj7b9, 0 }}, + /* interval1 is a whole step */ + {{ kMin9, 0 }, { kDom9, 0 }, { kMin7, 1 }, { kDom7, 1 }, { kDom9, 0 }, + { kHalfDim7, 1 }, { kDom7, 1 }, { kDom9, 0 }, { kMaj9, 0 }}, + /* interval1 is a minor third */ + {{ kMaj7s5, 2 }, { kDom7, 2 }, { kDim, 0 }, { kMin, 0 }, { kMaj, 2 }, + { kDim, 2 }, { kMin7, 0 }, { kMinMaj7, 0 }}, + /* interval1 is a major third */ + {{ kMaj7, 2 }, { kHalfDim7, 2 }, { kMaj, 0 }, { kAug, 0 }, { kMin, 2 }, + { kDom7, 0 }, { kMaj7, 0 }}, + /* interval1 is a perfect fourth */ + {{ kDomb9, 1 }, { kDom9, 1 }, { kMin, 1 }, { kMaj, 1 }, { kDom9, 2 }, + { kDom7s11, 1 }}, + /* interval1 is an augmented fourth */ + {{ kDom7s11, 0 }, { kDom7, 2 }, { kDim, 1 }, { kHalfDim7, 0 }, { kDomb9, 2 }}, + /* interval1 is a perfect fifth */ + {{ kMaj7, 2 }, { kMin7, 2 }, { kDom7, 0 }, { kMaj7, 0 }}, + /* interval1 is a minor sixth */ + {{ kMinMaj7, 2 }, { kDom9, 1 }, { kMaj7s5, 0 }}, + /* interval1 is a major sixth */ + {{ kMaj9, 2 }, { kMin9, 1 }}, + /* interval1 is a minor seventh */ + {{ kMaj7b9, 2 }} + }; + register t_type_root* t; + + int members[3]; + int i, j = 0; + int interval1, interval2; + + for(i = 0; i < 12; i++) + if(x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval2 = members[2] - members[0]; /* calculate interval between first and third */ + interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + t = &(triads[interval1][interval2]); /* find TypeRoot struct for this interval vector */ + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 3); /* output onto the screen */ +} + +static void chord_quartad(t_chord *x) +{ + static t_type_root quartads[9][9][9] = + { + {/* interval1 is a half step */ + {/* interval2 is a whole step */ + { kM7b9s13, 2 }, { kMinMajb9,1 }, { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kDimMajb9, 1 }, + { kMaj7b9, 1 }, { kMaj7s13, 2 }, { kM7b913, 1 }, { kM7b9s13, 1 }}, + {/* interval2 is a minor third */ + { kMinMaj9, 1 }, { kMaj9, 1 }, { kHalfDimb9,0 }, { kMin7b9, 0 }, { kMaj9, 1 }, + { kDim7b9, 0 }, { kMin7b9, 0 }, { kMinMajb9, 0 }}, + {/* interval2 is a major third */ + { kMaj7s9, 1 }, { kDom7s11, 3 }, { kDomb9, 0 }, { kMinMaj7, 1 }, { kDom7s9, 3 }, + { kDomb9, 0 }, { kMaj7b9, 0 }}, + {/* interval2 is a perfect fourth */ + { kMaj11, 1 }, { kMaj7b5, 1 }, { kMaj7, 1 }, { kMaj7s5, 1 }, { kMin9, 3 }, + { kMaj7s13, 1 }}, + {/* interval2 is a tritone */ + { kDimMaj9, 3 }, { kDom11, 3 }, { kDim7b9, 0 }, { kHalfDimb9,0 }, { kDimMajb9, 0 }}, + {/* interval2 is a perfect fifth */ + { kMaj11, 3 }, { kDom7s9, 3 }, { kDomb9, 0 }, { kMaj7b9, 0 }}, + {/* interval2 is a minor sixth */ + { kMaj7s9, 3 }, { kMin9, 3 }, { kMaj7s13, 1 }}, + {/* interval2 is a major sixth */ + { kMinMaj9, 3 }, { kM7b913, 0 }}, + {/* interval2 is a minor seventh */ + { kM7b9s13, 0 }} + }, + {/* interval1 is a whole step */ + {/* interval2 is a minor third */ + { kM7b913, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMin9, 0 }, { kHalfDimb9,1 }, + { kDomb9, 1 }, { kMin9, 0 }, { kMinMaj9, 0 }}, + {/* interval2 is a major third */ + { kMin9, 1 }, { kDom9, 1 }, { kDom9, 0 }, { kDom7s5, 2 }, { kDom9, 1 }, + { kDom9, 0 }, { kMaj9, 0 }}, + {/* interval2 is a perfect fourth */ + { kDom7s9, 1 }, { kDom11, 3 }, { kHalfDim7, 1 }, { kMin7, 1 }, { kDom9, 3 }, + { kHalfDimb9,3 }}, + {/* interval2 is a tritone */ + { kDom11, 1 }, { kDom7b5, 3 }, { kDom7, 1 }, { kDom7s5, 1 }, { kMin7b9, 3 }}, + {/* interval2 is a perfect fifth */ + { kMaj7b5, 3 }, { kDom11, 1 }, { kDom9, 0 }, { kMaj9, 0 }}, + {/* interval2 is a minor sixth */ + { kDom7s11, 1 }, { kDom9, 3 }, { kDim7b9, 3 }}, + {/* interval2 is a major sixth */ + { kMaj9, 3 }, { kMin7b9, 3 }}, + {/* interval2 is a minor seventh */ + { kMinMajb9, 3 }} + }, + {/* interval1 is a minor third */ + {/* interval2 is a major third */ + { kMaj7s13, 3 }, { kDim7b9, 1 }, { kDom7s9, 0 }, { kMaj7s5, 2 }, { kDim7b9, 1 }, + { kDom7s9, 0 }, { kMaj7s9, 0 }}, + {/* interval2 is a perfect fourth */ + { kDomb9, 2 }, { kDom9, 2 }, { kMin7, 2 }, { kDom7, 2 }, { kDom11, 2 }, + { kDom7s11, 2 }}, + {/* interval2 is a tritone */ + { kDim7b9, 2 }, { kDom7, 3 }, { kDim7, 0 }, { kHalfDim7, 0 }, { kDomb9, 3 }}, + {/* interval2 is a perfect fifth */ + { kMaj7, 3 }, { kHalfDim7,3 }, { kMin7, 0 }, { kMinMaj7, 0 }}, + {/* interval2 is a minor sixth */ + { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }}, + {/* interval2 is a major sixth */ + { kHalfDimb9,2 }, { kDomb9, 3 }}, + {/* interval2 is a minor seventh */ + { kMaj7b9, 3 }} + }, + {/* interval1 is a major third */ + {/* interval2 is a perfect fourth */ + { kMaj7b9, 2 }, { kMaj9, 2 }, { kMinMaj7, 2 }, { kMaj7, 2 }, { kDom11, 0 }, + { kMaj11, 0 }}, + {/* interval2 is a tritone */ + { kHalfDimb9,2 }, { kDom7s5, 3 }, { kHalfDim7, 2 }, { kDom7b5, 0 }, { kMaj7b5, 0 }}, + {/* interval2 is a perfect fifth */ + { kMaj7s5, 3 }, { kMin7, 3 }, { kDom7, 0 }, { kMaj7, 0 }}, + {/* interval2 is a minor sixth */ + { kMinMaj7, 3 }, { kDom7s5, 0 }, { kMaj7s5, 0 }}, + {/* interval2 is a major sixth */ + { kMin7b9, 2 }, { kMin9, 2 }}, + {/* interval2 is a minor seventh */ + { kMaj7s13, 0 }} + }, + {/* interval1 is a perfect fourth */ + {/* interval2 is a tritone */ + { kDimMajb9, 2 }, { kMin7b9, 1 }, { kDomb9, 1 }, { kMaj7b5, 2 }, { kDimMaj9, 0 }}, + {/* interval2 is a perfect fifth */ + { kMin9, 1 }, { kDom9, 1 }, { kDom11, 0 }, { kDom11, 2 }}, + {/* interval2 is a minor sixth */ + { kDom7s9, 1 }, { kDom9, 3 }, { kDim7b9, 3 }}, + {/* interval2 is a major sixth */ + { kMaj9, 3 }, { kHalfDimb9,3 }}, + {/* interval2 is a minor seventh */ + { kDimMajb9, 3 }} + }, + {/* interval1 is a tritone */ + {/* interval2 is a perfect fifth */ + { kMaj7s13, 3 }, { kHalfDimb9,1 }, { kDom7s11, 0 }, { kMaj11, 2 }}, + {/* interval2 is a minor sixth */ + { kDomb9, 2 }, { kDom9, 2 }, { kDom7s9, 2 }}, + {/* interval2 is a major sixth */ + { kDim7b9, 2 }, { kDomb9, 3 }}, + {/* interval2 is a minor seventh */ + { kMaj7b9, 3 }} + }, + {/* interval1 is a perfect fifth */ + {/* interval2 is a minor sixth */ + { kMaj7b9, 2 }, { kMaj9, 2 }, { kMaj7s9, 2 }}, + {/* interval2 is a major sixth */ + { kMin7b9, 2 }, { kMin9, 2 }}, + {/* interval2 is a minor seventh */ + { kMaj7s13, 0 }} + }, + {/* interval1 is a minor sixth */ + {/* interval2 is a major sixth */ + { kMinMajb9, 2 }, { kMinMaj9, 2 }}, + {/* interval2 is a minor seventh */ + { kM7b913, 3 }} + }, + {/* interval1 is a major sixth */ + {/* interval2 is a minor seventh */ + { kM7b9s13, 2 }} + } + }; + + register t_type_root* t; + + int members[4]; + int interval1, interval2, interval3; + int i, j = 0; + for (i=0; i<12; i++) + if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval2 = members[2] - members[0]; /* calculate interval between first and third */ + interval3 = members[3] - members[0]; /* calculate interval between first and third */ + interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */ + interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + + /* find TypeRoot struct for this interval set */ + t = &(quartads[interval1][interval2][interval3]); + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 2; + break; + case 3: + x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 4); /* output results */ +} + +static void chord_fatal_error(char* s1, char* s2) +{ + post("chord: error: %s : %s", s1, s2); +} + +static void chord_quintad(t_chord *x) +{ + static int initialized = 0; + static t_type_root quintads[8][8][8][8]; + register int i, j, k, l; + register t_type_root *t; + t_int members[5]; + int interval1, interval2, interval3, interval4; + int *st; + int maj9[5][4] = {{1,1,2,3}, {0,1,1,2}, {3,0,1,1}, {2,3,0,1}, {1,2,3,0}}; + int dom9[5][4] = {{1,1,2,2}, {1,1,1,2}, {2,1,1,1}, {2,2,1,1}, {1,2,2,1}}; + int min9[5][4] = {{1,0,3,2}, {1,1,0,3}, {2,1,1,0}, {3,2,1,1}, {0,3,2,1}}; + int had9[5][4] = {{1,0,2,3}, {1,1,0,2}, {3,1,1,0}, {2,3,1,1}, {0,2,3,1}}; + int miM9[5][4] = {{1,0,3,3}, {0,1,0,3}, {3,0,1,0}, {3,3,0,1}, {0,3,3,0}}; + int diM9[5][4] = {{1,0,2,4}, {0,1,0,2}, {4,0,1,0}, {2,4,0,1}, {0,2,4,0}}; + int M9b5[5][4] = {{1,1,1,4}, {0,1,1,1}, {4,0,1,1}, {1,4,0,1}, {1,1,4,0}}; + int D9b5[5][4] = {{1,1,1,3}, {1,1,1,1}, {3,1,1,1}, {1,3,1,1}, {1,1,3,1}}; + int mM91[5][4] = {{1,0,0,6}, {0,1,0,0}, {6,0,1,0}, {0,6,0,1}, {0,0,6,0}}; + int M7b9[5][4] = {{0,2,2,3}, {0,0,2,2}, {3,0,0,2}, {2,3,0,0}, {2,2,3,0}}; + int M5b9[5][4] = {{0,2,3,2}, {0,0,2,3}, {2,0,0,2}, {3,2,0,0}, {2,3,2,0}}; + int D7b9[5][4] = {{0,2,2,2}, {1,0,2,2}, {2,1,0,2}, {2,2,1,0}, {2,2,2,1}}; + int m7b9[5][4] = {{0,1,3,2}, {1,0,1,3}, {2,1,0,1}, {3,2,1,0}, {1,3,2,1}}; + int mb51[5][4] = {{0,1,2,0}, {4,0,1,2}, {0,4,0,1}, {2,0,4,0}, {1,2,0,4}}; + int d7b9[5][4] = {{0,1,2,3}, {1,0,1,2}, {3,1,0,1}, {2,3,1,0}, {1,2,3,1}}; + int mMb9[5][4] = {{0,1,3,3}, {0,0,1,3}, {3,0,0,1}, {3,3,0,0}, {1,3,3,0}}; + int dMb9[5][4] = {{0,1,2,4}, {0,0,1,2}, {4,0,0,1}, {2,4,0,0}, {1,2,4,0}}; + int dib9[5][4] = {{0,1,2,2}, {2,0,1,2}, {2,2,0,1}, {2,2,2,0}, {1,2,2,2}}; + int M7s9[5][4] = {{2,0,2,3}, {0,2,0,2}, {3,0,2,0}, {2,3,0,2}, {0,2,3,0}}; + int D7s9[5][4] = {{2,0,2,2}, {1,2,0,2}, {2,1,2,0}, {2,2,1,2}, {0,2,2,1}}; + int M7s1[5][4] = {{3,1,0,3}, {0,3,1,0}, {3,0,3,1}, {0,3,0,3}, {1,0,3,0}}; + int d9b3[5][4] = {{1,1,2,0}, {3,1,1,2}, {0,3,1,1}, {2,0,3,1}, {1,2,0,3}}; + int M9s3[5][4] = {{1,4,2,0}, {0,1,4,2}, {0,0,1,4}, {2,0,0,1}, {4,2,0,0}}; + int M9st[5][4] = {{1,1,5,0}, {0,1,1,5}, {0,0,1,1}, {5,0,0,1}, {1,5,0,0}}; + int s9s1[5][4] = {{2,0,1,0}, {4,2,0,1}, {0,4,2,0}, {1,0,4,2}, {0,1,0,4}}; + int h7b1[5][4] = {{2,0,1,3}, {1,2,0,1}, {3,1,2,0}, {1,3,1,2}, {0,1,3,1}}; + int M711[5][4] = {{3,0,1,3}, {0,3,0,1}, {3,0,3,0}, {1,3,0,3}, {0,1,3,0}}; + int M115[5][4] = {{1,1,0,5}, {0,1,1,0}, {5,0,1,1}, {0,5,0,1}, {1,0,5,0}}; + int d711[5][4] = {{3,0,1,2}, {1,3,0,1}, {2,1,3,0}, {1,2,1,3}, {0,1,2,1}}; + int d712[5][4] = {{1,1,0,1}, {4,1,1,0}, {1,4,1,1}, {0,1,4,1}, {1,0,1,4}}; + int d713[5][4] = {{1,1,0,4}, {1,1,1,0}, {4,1,1,1}, {0,4,1,1}, {1,0,4,1}}; + int m711[5][4] = {{2,1,1,2}, {1,2,1,1}, {2,1,2,1}, {1,2,1,2}, {1,1,2,1}}; + int m712[5][4] = {{1,0,1,1}, {4,1,0,1}, {1,4,1,0}, {1,1,4,1}, {0,1,1,4}}; + int di11[5][4] = {{1,0,1,0}, {5,1,0,1}, {0,5,1,0}, {1,0,5,1}, {0,1,0,5}}; + int mM11[5][4] = {{2,1,1,3}, {0,2,1,1}, {3,0,2,1}, {1,3,0,2}, {1,1,3,0}}; + int dM11[5][4] = {{2,1,0,4}, {0,2,1,0}, {4,0,2,1}, {0,4,0,2}, {1,0,4,0}}; + int Meb5[5][4] = {{3,0,0,4}, {0,3,0,0}, {4,0,3,0}, {0,4,0,3}, {0,0,4,0}}; + int Mes5[5][4] = {{3,0,2,2}, {0,3,0,2}, {2,0,3,0}, {2,2,0,3}, {0,2,2,0}}; + int Meb9[5][4] = {{0,2,0,5}, {0,0,2,0}, {5,0,0,2}, {0,5,0,0}, {2,0,5,0}}; + int Mes9[5][4] = {{2,0,0,5}, {0,2,0,0}, {5,0,2,0}, {0,5,0,2}, {0,0,5,0}}; + int Deb5[5][4] = {{3,0,0,3}, {1,3,0,0}, {3,1,3,0}, {0,3,1,3}, {0,0,3,1}}; + int Mes3[5][4] = {{3,0,4,0}, {0,3,0,4}, {0,0,3,0}, {4,0,0,3}, {0,4,0,0}}; + int Deb9[5][4] = {{0,2,0,4}, {1,0,2,0}, {4,1,0,2}, {0,4,1,0}, {2,0,4,1}}; + int De91[5][4] = {{0,2,0,1}, {4,0,2,0}, {1,4,0,2}, {0,1,4,0}, {2,0,1,4}}; + int Des9[5][4] = {{2,0,0,4}, {1,2,0,0}, {4,1,2,0}, {0,4,1,2}, {0,0,4,1}}; + int Ds11[5][4] = {{3,1,0,2}, {1,3,1,0}, {2,1,3,1}, {0,2,1,3}, {1,0,2,1}}; + int m7s1[5][4] = {{2,2,0,2}, {1,2,2,0}, {2,1,2,2}, {0,2,1,2}, {2,0,2,1}}; + int D3s1[5][4] = {{5,0,1,0}, {1,5,0,1}, {0,1,5,0}, {1,0,1,5}, {0,1,0,1}}; + int Mb9s[5][4] = {{0,2,5,0}, {0,0,2,5}, {0,0,0,2}, {5,0,0,0}, {2,5,0,0}}; + int D7b3[5][4] = {{3,2,0,1}, {1,3,2,0}, {1,1,3,2}, {0,1,1,3}, {2,0,1,1}}; + + if (!initialized) { + for (i=0; i<8; i++) + for (j=0; j<8; j++) + for (k=0; k<8; k++) + for (l=0; l<8; l++) { + quintads[i][j][k][l].type = kNone; + quintads[i][j][k][l].rootMember = kXX; + } + + + // major ninths + for (i=0; i<5; i++) { + st = maj9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + t->type = kMaj9; + t->rootMember = i; + } + + // dominant ninths + for (i=0; i<5; i++) { + st = dom9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dom9"); + t->type = kDom9; + t->rootMember = i; + } + + // minor ninths + for (i=0; i<5; i++) { + st = min9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "min9"); + t->type = kMin9; + t->rootMember = i; + } + + // half diminished ninths + for (i=0; i<5; i++) { + st = had9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "had9"); + t->type = kHalfDim9; + t->rootMember = i; + } + + // minor/major ninths + for (i=0; i<5; i++) { + st = miM9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "miM9"); + t->type = kMinMaj9; + t->rootMember = i; + } + + // diminished/major ninths + for (i=0; i<5; i++) { + st = diM9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "diM9"); + t->type = kDimMaj9; + t->rootMember = i; + } + + // major ninth flat 5 + for (i=0; i<5; i++) { + st = M9b5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M9b5"); + t->type = kMaj9b5; + t->rootMember = i; + } + + // dominant ninth flat 5 + for (i=0; i<5; i++) { + st = D9b5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D9b5"); + t->type = kDom9b5; + t->rootMember = i; + } + + // minor/major ninth flat 11 + for (i=0; i<5; i++) { + st = mM91[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mM91"); + t->type = kmM9b11; + t->rootMember = i; + } + + // major seventh flat nine + for (i=0; i<5; i++) { + st = M7b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M7b9"); + t->type = kMaj7b9; + t->rootMember = i; + } + + // major seventh sharp five flat nine + for (i=0; i<5; i++) { + st = M5b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M5b9"); + t->type = kMaj7s5b9; + t->rootMember = i; + } + + // dominant seventh flat nine + for (i=0; i<5; i++) { + st = D7b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D7b9"); + t->type = kDom7b9; + t->rootMember = i; + } + + // minor seventh flat nine + for (i=0; i<5; i++) { + t = &(quintads[m7b9[i][0]][m7b9[i][1]][m7b9[i][2]][m7b9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m7b9"); + t->type = kMin7b9; + t->rootMember = i; + } + + // minor flat nine sharp eleventh + for (i=0; i<5; i++) { + st = mb51[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mb51"); + t->type = kMinb9s11; + t->rootMember = i; + } + + // half diminished seventh flat nine + for (i=0; i<5; i++) { + st = d7b9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d7b9"); + t->type = kHalfDimb9; + t->rootMember = i; + } + + // minor/major seventh flat nine + for (i=0; i<5; i++) { + st = mMb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mMb9"); + t->type = kMinMajb9; + t->rootMember = i; + } + + // diminished major seventh flat nine + for (i=0; i<5; i++) { + st = dMb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dMb9"); + t->type = kDimMajb9; + t->rootMember = i; + } + + // diminished seventh flat nine + for (i=0; i<5; i++) { + t = &(quintads[dib9[i][0]][dib9[i][1]][dib9[i][2]][dib9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dib9"); + t->type = kDim7b9; + t->rootMember = i; + } + + // major seventh sharp nine + for (i=0; i<5; i++) { + t = &(quintads[M7s9[i][0]][M7s9[i][1]][M7s9[i][2]][M7s9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M7s9"); + t->type = kMaj7s9; + t->rootMember = i; + } + + // dominant seventh sharp nine + for (i=0; i<5; i++) { + t = &(quintads[D7s9[i][0]][D7s9[i][1]][D7s9[i][2]][D7s9[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D7s9"); + t->type = kDom7s9; + t->rootMember = i; + } + + // major seventh sharp eleventh + for (i=0; i<5; i++) { + t = &(quintads[M7s1[i][0]][M7s1[i][1]][M7s1[i][2]][M7s1[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M7s1"); + t->type = kMaj7s11; + t->rootMember = i; + } + + // dominant ninth flat thirteenth + for (i=0; i<5; i++) { + st = d9b3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d9b3"); + t->type = kDom9b13; + t->rootMember = i; + } + + // major ninth sharp thirteenth + for (i=0; i<5; i++) { + st = M9s3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M9s3"); + t->type = kMaj9s13; + t->rootMember = i; + } + + // major ninth sharp thirteenth + for (i=0; i<5; i++) { + t = &(quintads[M9st[i][0]][M9st[i][1]][M9st[i][2]][M9st[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M9st"); + t->type = kMaj9s13; + t->rootMember = i; + } + + // major chord sharp ninth sharp eleventh + for (i=0; i<5; i++) { + st = s9s1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "s9s1"); + t->type = kMs9s11; + t->rootMember = i; + } + + // half diminished seven flat 11 + for (i=0; i<5; i++) { + st = h7b1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "h7b1"); + t->type = kHDimb11; + t->rootMember = i; + } + + // major eleventh + for (i=0; i<5; i++) { + t = &(quintads[M711[i][0]][M711[i][1]][M711[i][2]][M711[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); + t->type = kMaj11; + t->rootMember = i; + } + + // major eleventh + for (i=0; i<5; i++) { + t = &(quintads[M115[i][0]][M115[i][1]][M115[i][2]][M115[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); + t->type = kMaj11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<5; i++) { + t = &(quintads[d711[i][0]][d711[i][1]][d711[i][2]][d711[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d711"); + t->type = kDom11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<5; i++) { + t = &(quintads[d712[i][0]][d712[i][1]][d712[i][2]][d712[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d712"); + t->type = kDom11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<5; i++) { + st = d713[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d713"); + t->type = kDom11; + t->rootMember = i; + } + + // minor eleventh + for (i=0; i<5; i++) { + t = &(quintads[m711[i][0]][m711[i][1]][m711[i][2]][m711[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m711"); + t->type = kMin11; + t->rootMember = i; + } + + // minor eleventh + for (i=0; i<5; i++) { + t = &(quintads[m712[i][0]][m712[i][1]][m712[i][2]][m712[i][3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m712"); + t->type = kMin11; + t->rootMember = i; + } + + // diminished eleventh + for (i=0; i<5; i++) { + st = di11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "di11"); + t->type = kDim11; + t->rootMember = i; + } + + // minor/major eleventh + for (i=0; i<5; i++) { + st = mM11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "mM11"); + t->type = kMinMaj11; + t->rootMember = i; + } + + // diminished major eleventh + for (i=0; i<5; i++) { + st = dM11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "dM11"); + t->type = kDimMaj11; + t->rootMember = i; + } + + // major eleventh flat fifth + for (i=0; i<5; i++) { + st = Meb5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Meb5"); + t->type = kMaj11b5; + t->rootMember = i; + } + + // major eleventh sharp fifth + for (i=0; i<5; i++) { + st = Mes5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mes5"); + t->type = kMaj11s5; + t->rootMember = i; + } + + // major eleventh flat ninth + for (i=0; i<5; i++) { + st = Meb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Meb9"); + t->type = kMaj11b9; + t->rootMember = i; + } + + // major eleventh sharp ninth + for (i=0; i<5; i++) { + st = Mes9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mes9"); + t->type = kMaj11s9; + t->rootMember = i; + } + + // major eleventh sharp thirteenth + for (i=0; i<5; i++) { + st = Mes3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mes3"); + t->type = kMaj11s13; + t->rootMember = i; + } + + // dominant eleventh flat fifth + for (i=0; i<5; i++) { + st = Deb5[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Deb5"); + t->type = kDom11b5; + t->rootMember = i; + } + + // dominant eleventh flat ninth + for (i=0; i<5; i++) { + st = Deb9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Deb9"); + t->type = kDom11b9; + t->rootMember = i; + } + + // dominant eleventh flat ninth + for (i=0; i<5; i++) { + st = De91[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "De91"); + t->type = kDom11b9; + t->rootMember = i; + } + + // dominant eleventh sharp ninth + for (i=0; i<5; i++) { + st = Des9[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Des9"); + t->type = kDom11s9; + t->rootMember = i; + } + + // dominant seventh sharp eleventh + for (i=0; i<5; i++) { + st = Ds11[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Ds11"); + t->type = kDom7s11; + t->rootMember = i; + } + + // minor seventh sharp eleventh + for (i=0; i<5; i++) { + st = m7s1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m7s1"); + t->type = kMin7s11; + t->rootMember = i; + } + + // dominant thirteenth sharp eleventh + for (i=0; i<5; i++) { + st = D3s1[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D3s1"); + t->type = kDom13s11; + t->rootMember = i; + } + + // major seventh flat ninth sharp thirteenth + for (i=0; i<5; i++) { + st = Mb9s[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "Mb9s"); + t->type = kM7b9s13; + t->rootMember = i; + } + + // dominant seventh flat thirteenth + for (i=0; i<5; i++) { + st = D7b3[i]; + t = &(quintads[st[0]][st[1]][st[2]][st[3]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D7b3"); + t->type = kDom7b13; + t->rootMember = i; + } + + initialized = 1; + return; + } + + j = 0; + for (i=0; i<12; i++) + if (x->x_pc[i]) members[j++] = i; /* load members array with chord pitch classes */ + interval1 = members[1] - members[0]; /* calculate interval between first two members */ + interval2 = members[2] - members[0]; /* calculate interval between first and third */ + interval3 = members[3] - members[0]; /* calculate interval between first and third */ + interval4 = members[4] - members[0]; /* calculate interval between first and fourth */ + interval4 = interval4 - interval3 - 1; /* reduce interval4 to start at zero */ + interval3 = interval3 - interval2 - 1; /* reduce interval3 to start at zero */ + interval2 = interval2 - interval1 - 1; /* reduce interval2 to start at zero */ + interval1 = interval1 - 1; /* reduce interval1 to start at zero */ + + // find TypeRoot struct for this interval set + t = &(quintads[interval1][interval2][interval3][interval4]); + if (t->rootMember != kXX) + { + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 2; + break; + case 3: + x->x_chord_inversion = 2; + break; + case 4: + x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 5); /* output result */ + } else + chord_kick_out_member(x, 5, members); +} + +static void chord_sextad(t_chord *x) +{ + static int initialized = 0; + static t_type_root sextads[7][7][7][7][7]; + register int i, j, k, l, m; + register t_type_root *t; + register int* st; + t_int members[6]; + int interval1, interval2, interval3, interval4, interval5; + + int D9b3[6][5] = + {{1,1,2,0,1}, {1,1,1,2,0}, {1,1,1,1,2}, {0,1,1,1,1}, {2,0,1,1,1}, {1,2,0,1,1}}; + int m9s1[6][5] = + {{1,0,2,0,2}, {1,1,0,2,0}, {2,1,1,0,2}, {0,2,1,1,0}, {2,0,2,1,1}, {0,2,0,2,1}}; + int M711[6][5] = + {{1,1,0,1,3}, {0,1,1,0,1}, {3,0,1,1,0}, {1,3,0,1,1}, {0,1,3,0,1}, {1,0,1,3,0}}; + int D711[6][5] = + {{1,1,0,1,2}, {1,1,1,0,1}, {2,1,1,1,0}, {1,2,1,1,1}, {0,1,2,1,1}, {1,0,1,2,1}}; + int hd11[6][5] = + {{1,0,1,0,3}, {1,1,0,1,0}, {3,1,1,0,1}, {0,3,1,1,0}, {1,0,3,1,1}, {0,1,0,3,1}}; + int M1b5[6][5] = + {{1,1,0,0,4}, {0,1,1,0,0}, {4,0,1,1,0}, {0,4,0,1,1}, {0,0,4,0,1}, {1,0,0,4,0}}; + int M159[6][5] = + {{0,2,0,0,4}, {0,0,2,0,0}, {4,0,0,2,0}, {0,4,0,0,2}, {0,0,4,0,0}, {2,0,0,4,0}}; + int M1s3[6][5] = + {{1,1,0,4,0}, {0,1,1,0,4}, {0,0,1,1,0}, {4,0,0,1,1}, {0,4,0,0,1}, {1,0,4,0,0}}; + int hd19[6][5] = + {{0,1,1,0,3}, {1,0,1,1,0}, {3,1,0,1,1}, {0,3,1,0,1}, {1,0,3,1,0}, {1,1,0,3,1}}; + int M1b3[6][5] = + {{3,0,1,0,2}, {0,3,0,1,0}, {2,0,3,0,1}, {0,2,0,3,0}, {1,0,2,0,3}, {0,1,0,2,0}}; + int D1b5[6][5] = + {{1,1,0,0,3}, {1,1,1,0,0}, {3,1,1,1,0}, {0,3,1,1,1}, {0,0,3,1,1}, {1,0,0,3,1}}; + int D1s9[6][5] = + {{2,0,0,1,2}, {1,2,0,0,1}, {2,1,2,0,0}, {1,2,1,2,0}, {0,1,2,1,2}, {0,0,1,2,1}}; + int m791[6][5] = + {{0,1,2,0,2}, {1,0,1,2,0}, {2,1,0,1,2}, {0,2,1,0,1}, {2,0,2,1,0}, {1,2,0,2,1}}; + int d7s1[6][5] = + {{1,1,1,0,2}, {1,1,1,1,0}, {2,1,1,1,1}, {0,2,1,1,1}, {1,0,2,1,1}, {1,1,0,2,1}}; + int d3s1[6][5] = + {{3,1,0,1,0}, {1,3,1,0,1}, {0,1,3,1,0}, {1,0,1,3,1}, {0,1,0,1,3}, {1,0,1,0,1}}; + + + if (!initialized) { + for (i=0; i<7; i++) + for (j=0; j<7; j++) + for (k=0; k<7; k++) + for (l=0; l<7; l++) + for (m=0; m<7; m++) { + sextads[i][j][k][l][m].type = kNone; + sextads[i][j][k][l][m].rootMember = kXX; + } + + // dominant ninth flat thirteen + for (i=0; i<6; i++) { + st = D9b3[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D9b3"); + t->type = kDom9b13; + t->rootMember = i; + } + + // minor ninth sharp eleventh + for (i=0; i<6; i++) { + st = m9s1[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m9s1"); + t->type = kMin9s11; + t->rootMember = i; + } + + // major eleventh + for (i=0; i<6; i++) { + st = M711[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M711"); + t->type = kMaj11; + t->rootMember = i; + } + + // dominant eleventh + for (i=0; i<6; i++) { + st = D711[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D711"); + t->type = kDom11; + t->rootMember = i; + } + + // half diminished eleventh + for (i=0; i<6; i++) { + st = hd11[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "hd11"); + t->type = kHalfDim11; + t->rootMember = i; + } + + // major eleventh flat 5 + for (i=0; i<6; i++) { + st = M1b5[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M1b5"); + t->type = kMaj11b5; + t->rootMember = i; + } + + // major eleventh flat 5 flat 9 + for (i=0; i<6; i++) { + st = M159[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M159"); + t->type = kM11b5b9; + t->rootMember = i; + } + + // major eleventh sharp 13 + for (i=0; i<6; i++) { + st = M1s3[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M1s3"); + t->type = kMaj11s13; + t->rootMember = i; + } + + // half diminished eleventh flat 9 + for (i=0; i<6; i++) { + st = hd19[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "hd19"); + t->type = kHalfDim11b9; + t->rootMember = i; + } + + // major eleventh flat 13 + for (i=0; i<6; i++) { + st = M1b3[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "M1b3"); + t->type = kMaj11b13; + t->rootMember = i; + } + + // dominant eleventh flat five + for (i=0; i<6; i++) { + st = D1b5[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D1b5"); + t->type = kDom11b5; + t->rootMember = i; + } + + // dominant eleventh sharp nine + for (i=0; i<6; i++) { + st = D1s9[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "D1s9"); + t->type = kDom11s9; + t->rootMember = i; + } + + // minor seventh flat 9 sharp 11 + for (i=0; i<6; i++) { + st = m791[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "m791"); + t->type = kMinb9s11; + t->rootMember = i; + } + + // dominant seventh sharp 11 + for (i=0; i<6; i++) { + st = d7s1[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d7s1"); + t->type = kDom7s11; + t->rootMember = i; + } + + // dominant thirteenth sharp 11 + for (i=0; i<6; i++) { + st = d3s1[i]; + t = &(sextads[st[0]][st[1]][st[2]][st[3]][st[4]]); + if (t->type != kNone) chord_fatal_error("redefining chord", "d3s1"); + t->type = kDom13s11; + t->rootMember = i; + } + + initialized = 1; + return; + } + + j = 0; + for (i=0; i<12; i++) + if (x->x_pc[i]) members[j++] = i; // load members array with chord pitch classes + interval1 = members[1] - members[0]; // calculate interval between first two members + interval2 = members[2] - members[0]; // calculate interval between first and third + interval3 = members[3] - members[0]; // calculate interval between first and third + interval4 = members[4] - members[0]; // calculate interval between first and fourth + interval5 = members[5] - members[0]; // calculate interval between first and fifth + interval5 = interval5 - interval4 - 1; // reduce interval5 to start at zero + interval4 = interval4 - interval3 - 1; // reduce interval4 to start at zero + interval3 = interval3 - interval2 - 1; // reduce interval3 to start at zero + interval2 = interval2 - interval1 - 1; // reduce interval2 to start at zero + interval1 = interval1 - 1; // reduce interval1 to start at zero + + // find TypeRoot struct for this interval set + t = &(sextads[interval1][interval2][interval3][interval4][interval5]); + if (t->rootMember != kXX) { + x->x_chord_type = t->type; + x->x_chord_root = members[t->rootMember]; + switch(t->rootMember) { /* get state of inversion */ + case 0: + x->x_chord_inversion = 0; + break; + case 1: + x->x_chord_inversion = 2; + break; + case 2: + x->x_chord_inversion = 2; + break; + case 3: + x->x_chord_inversion = 2; + break; + case 4: + x->x_chord_inversion = 2; + break; + case 5: x->x_chord_inversion = 1; + } + chord_draw_chord_type(x, 6); // output onto the screen + } else + chord_kick_out_member(x, 6, members); +} + +static int chord_accidental(t_int pc) +{ + switch (pc) { + case 0: + case 2: + case 4: + case 5: + case 7: + case 9: + case 11: return 0; + case 1: + case 3: + case 6: + case 8: + case 10: + default: return 1; + } +} + +static int chord_name_third(t_chord *x, char* chord, int c, int rootName) +{ + int third = (x->x_chord_root+4)%12; // look for major third + if (x->x_pc[third]) { // if one is there + x->x_pc[third] = 0; // erase from pcs array + chord[c++] = name_class[(rootName+2)%7]; + if (chord_accidental(third)) { // if it has an chord_accidental + // make it a flat if the root also has an chord_accidental + if (chord_accidental(x->x_chord_root)) + chord[c++] = 'b'; + // otherwise make it a sharp + else + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; // return if major third found + } + + third = (x->x_chord_root+3)%12; // no major, look for minor third + if (x->x_pc[third]) { // if one is there + x->x_pc[third] = 0; // erase from pcs array + chord[c++] = name_class[(rootName+2)%7]; + if (chord_accidental(third)) // if it has an chord_accidental + chord[c++] = 'b'; else // make it a flat + if (chord_accidental(x->x_chord_root)) { // if the root has an chord_accidental + chord[c++] = 'b'; // make the third a flat + if (chord[0] == 'G') // if the root is Gb + chord[c++] = 'b'; // this must be Bbb + } + chord[c++] = ' '; + return c; + } + + return c; // if we get here there was no third +} + +static int chord_name_fifth(t_chord *x, char* chord, int c, int rootName) +{ + int fifth = (x->x_chord_root+7)%12; + if (x->x_pc[fifth]) { + x->x_pc[fifth] = 0; + chord[c++] = name_class[(rootName+4)%7]; + if (chord_accidental(fifth)) { + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + else chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + fifth = (x->x_chord_root+6)%12; + if (x->x_pc[fifth]) { + x->x_pc[fifth] = 0; + chord[c++] = name_class[(rootName+4)%7]; + if (chord[0] != 'B') chord[c++] = 'b'; + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + + fifth = (x->x_chord_root+8)%12; + if (x->x_pc[fifth]) { + x->x_pc[fifth] = 0; + chord[c++] = name_class[(rootName+4)%7]; + if (chord_accidental(fifth)) chord[c++] = '#'; else + if (!chord_accidental(x->x_chord_root)) { + chord[c++] = '#'; + if (chord[0] == 'B') + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + return c; +} + +static int chord_name_seventh(t_chord *x, char* chord, int c, int rootName) +{ + int seventh = (x->x_chord_root+11)%12; + if (x->x_pc[seventh]) { + x->x_pc[seventh] = 0; + chord[c++] = name_class[(rootName+6)%7]; + if (chord_accidental(seventh)) chord[c++] = '#'; + chord[c++] = ' '; + return c; + } + seventh = (x->x_chord_root+10)%12; + if (x->x_pc[seventh]) { + x->x_pc[seventh] = 0; + chord[c++] = name_class[(rootName+6)%7]; + if (chord_accidental(seventh) || chord_accidental(x->x_chord_root)) + chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + seventh = (x->x_chord_root+9)%12; + if (x->x_pc[seventh]) { + x->x_pc[seventh] = 0; + chord[c++] = name_class[(rootName+6)%7]; + chord[c++] = 'b'; + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; else + if (chord_accidental((seventh+1)%12)) chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + return c; +} + +static int chord_name_ninth(t_chord *x, char* chord, int c, int rootName) +{ + int ninth = (x->x_chord_root+2)%12; + if (x->x_pc[ninth]) { + x->x_pc[ninth] = 0; + chord[c++] = name_class[(rootName+1)%7]; + if (chord_accidental(ninth)) { + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + else chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + ninth = (x->x_chord_root+1)%12; + if (x->x_pc[ninth]) { + x->x_pc[ninth] = 0; + chord[c++] = name_class[(rootName+1)%7]; + if (chord_accidental(ninth)) chord[c++] = 'b'; + else { + if (chord_accidental(x->x_chord_root)) { + chord[c++] = 'b'; + if ((x->x_chord_root == 1) || (x->x_chord_root == 6) || (x->x_chord_root == 8)) + chord[c++] = 'b'; + } + } + chord[c++] = ' '; + return c; + } + + ninth = (x->x_chord_root+3)%12; + if (x->x_pc[ninth]) { + x->x_pc[ninth] = 0; + chord[c++] = name_class[(rootName+1)%7]; + if (chord_accidental(ninth)) chord[c++] = '#'; else + if (!chord_accidental(x->x_chord_root)) { + chord[c++] = '#'; + if (chord_accidental((x->x_chord_root+2)%12)) + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + return c; +} + +static int chord_name_eleventh(t_chord *x, char* chord, int c, int rootName) +{ + int eleventh = (x->x_chord_root+5)%12; + if (x->x_pc[eleventh]) { + x->x_pc[eleventh] = 0; + chord[c++] = name_class[(rootName+3)%7]; + if (chord_accidental(eleventh)) chord[c++] = 'b'; else + if (chord_accidental(x->x_chord_root)) chord[c++] = 'b'; + chord[c++] = ' '; + return c; + } + + eleventh = (x->x_chord_root+6)%12; + if (x->x_pc[eleventh]) { + x->x_pc[eleventh] = 0; + chord[c++] = name_class[(rootName+3)%7]; + if (chord_accidental(eleventh)) chord[c++] = '#'; else + if ((!chord_accidental(x->x_chord_root)) && (x->x_chord_root == 11)) + chord[c++] = '#'; + chord[c++] = ' '; + return c; + } + + return c; +} + +static int chord_name_thirteenth(t_chord *x, char* chord, int c, int rootName) +{ + int thirteenth = (x->x_chord_root+9)%12; + if (x->x_pc[thirteenth]) { + x->x_pc[thirteenth] = 0; + chord[c++] = name_class[(rootName+5)%7]; + if (chord_accidental(thirteenth)) { + if (chord_accidental(x->x_chord_root)) + chord[c++] = 'b'; + else + chord[c++] = '#'; + } + + chord[c++] = ' '; + return c; + } + + thirteenth = (x->x_chord_root+10)%12; + if (x->x_pc[thirteenth]) { + x->x_pc[thirteenth] = 0; + chord[c++] = name_class[(rootName+5)%7]; + if (chord_accidental(thirteenth)) chord[c++] = '#'; else + if (!chord_accidental(x->x_chord_root)) { + chord[c++] = '#'; + if (chord_accidental((x->x_chord_root+9)%12)) + chord[c++] = '#'; + } + chord[c++] = ' '; + return c; + } + + thirteenth = (x->x_chord_root+8)%12; + if (x->x_pc[thirteenth]) { + x->x_pc[thirteenth] = 0; + chord[c++] = name_class[(rootName+5)%7]; + if (chord_accidental(thirteenth)) chord[c++] = 'b'; else + if (chord_accidental(x->x_chord_root)) { + chord[c++] = 'b'; + if (chord_accidental(x->x_chord_root+9)%12) + chord[c++] = 'b'; + } + chord[c++] = ' '; + return c; + } + + return c; +} + + + +static void chord_spell_chord(t_chord *x, char *chord, t_int num_pcs) +{ + int rootName = 0; // keep index of root name class + int c = 0; // pointer to current character + int named = 0; // how many members have been named + int mark; + int i; + + // use chordRoot to set rootName index and store characters for name + switch (x->x_chord_root) + { + case 0: chord[c++] = name_class[rootName=0]; break; + case 1: chord[c++] = name_class[rootName=1]; + chord[c++] = 'b'; break; + case 2: chord[c++] = name_class[rootName=1]; break; + case 3: chord[c++] = name_class[rootName=2]; + chord[c++] = 'b'; break; + case 4: chord[c++] = name_class[rootName=2]; break; + case 5: chord[c++] = name_class[rootName=3]; break; + case 6: chord[c++] = name_class[rootName=4]; + chord[c++] = 'b'; break; + case 7: chord[c++] = name_class[rootName=4]; break; + case 8: chord[c++] = name_class[rootName=5]; + chord[c++] = 'b'; break; + case 9: chord[c++] = name_class[rootName=5]; break; + case 10: chord[c++] = name_class[rootName=6]; + chord[c++] = 'b'; break; + case 11: chord[c++] = name_class[rootName=6]; break; + default: break; + } + x->x_pc[x->x_chord_root] = 0; /* set this member to zero */ + + chord[c++] = ' '; // insert space + if (++named == num_pcs) { // if everything is named + chord[c] = '\0'; // terminate the string + return; // and return + } + + mark = c; // use mark to see if new names are added + for (i=0; i<6; i++) { + // advance search by thirds + switch (i) { + case 0: mark = chord_name_third (x, chord, c, rootName); break; + case 1: mark = chord_name_fifth (x, chord, c, rootName); break; + case 2: mark = chord_name_seventh (x, chord, c, rootName); break; + case 3: mark = chord_name_ninth (x, chord, c, rootName); break; + case 4: mark = chord_name_eleventh (x, chord, c, rootName); break; + case 5: mark = chord_name_thirteenth(x, chord, c, rootName); break; + } + if (mark != c) { // if new name is added + ++named; // increment count of named members + c = mark; // update character pointer + } + if (named == num_pcs) { // if everything is named + chord[c] = '\0'; // terminate the string + return; // and return + } + } + + chord[c] = '\0'; +} + + +static void chord_draw_chord_type(t_chord *x, t_int num_pcs) +{ + char chord[255]; /* output string */ + int i, j; + + /* get members of chord */ + j = 0; + for(i = 0; i < 12; i++) + { + if(x->x_pc[i]) + { + SETFLOAT(x->x_chordlist+j, x->x_abs_pc[i]); + j++; + } + } + + if (x->x_chord_type != kNone) + { + chord_spell_chord(x, chord, num_pcs); /* spell chord members */ + } + else + { + post("going..."); + chord[0] = '\0'; + for(i = 0; i < 12; i++) + if (x->x_pc[i]) + strcat(chord, pitch_class[i]); /* output single notes */ + post("did it"); + } + + strcat(chord, ": "); + strcat(chord, pitch_class[x->x_chord_root]); + + /* append name of chord type */ + switch (x->x_chord_type) { + case kUnison: strcat(chord, "unison"); break; + case kMaj: strcat(chord, "major"); break; + case kMin: strcat(chord, "minor"); break; + case kDim: strcat(chord, "diminished"); break; + case kAug: strcat(chord, "augmented"); break; + + case kMaj7: strcat(chord, "major 7th"); break; + case kDom7: strcat(chord, "dominant 7th"); break; + case kMin7: strcat(chord, "minor 7th"); break; + case kHalfDim7: strcat(chord, "half diminished 7th"); break; + case kDim7: strcat(chord, "diminished 7th"); break; + case kMinMaj7: strcat(chord, "minor/major 7th"); break; + + case kMaj7s5: strcat(chord, "major 7th #5"); break; + case kMaj7b5: strcat(chord, "major 7th b5"); break; + case kDom7s5: strcat(chord, "dominant 7th #5"); break; + case kDom7b5: strcat(chord, "dominant 7th b5"); break; + case kDomb9: strcat(chord, "dominant b9"); break; + + case kMaj9: strcat(chord, "major 9th"); break; + case kDom9: strcat(chord, "dominant 9th"); break; + case kMin9: strcat(chord, "minor 9th"); break; + case kHalfDim9: strcat(chord, "half diminished 9th"); break; + case kMinMaj9: strcat(chord, "minor major 9th"); break; + case kDimMaj9: strcat(chord, "diminished major 9th");break; + case kMaj9b5: strcat(chord, "major 9th b5"); break; + case kDom9b5: strcat(chord, "dominant 9th b5"); break; + case kDom9b13: strcat(chord, "dominant 9th b13"); break; + case kMin9s11: strcat(chord, "minor 9th #11"); break; + case kmM9b11: strcat(chord, "minor/maj 9th b11"); break; + + case kMaj7b9: strcat(chord, "major 7th b9"); break; + case kMaj7s5b9: strcat(chord, "major 7th #5 b9"); break; + case kDom7b9: strcat(chord, "dominant 7th b9"); break; + case kMin7b9: strcat(chord, "minor 7th b9"); break; + case kMinb9s11: strcat(chord, "minor b9 #11"); break; + case kHalfDimb9:strcat(chord, "half diminished b9"); break; + case kDim7b9: strcat(chord, "diminished b9"); break; + case kMinMajb9: strcat(chord, "minor/major b9"); break; + case kDimMajb9: strcat(chord, "diminished M7 b9"); break; + + case kMaj7s9: strcat(chord, "major 7th #9"); break; + case kDom7s9: strcat(chord, "dominant #9"); break; + case kMaj7s11: strcat(chord, "major 7th #11"); break; + case kMaj9s13: strcat(chord, "major 9th #13"); break; + case kMs9s11: strcat(chord, "major #9 #11"); break; + case kHDimb11: strcat(chord, "half diminished b11"); break; + + case kMaj11: strcat(chord, "major 11th"); break; + case kDom11: strcat(chord, "dominant 11th"); break; + case kMin11: strcat(chord, "minor 11th"); break; + case kHalfDim11:strcat(chord, "half diminished 11th");break; + case kDim11: strcat(chord, "diminished 11th"); break; + case kMinMaj11: strcat(chord, "minor/major 11th"); break; + case kDimMaj11: strcat(chord, "diminished maj 11th"); break; + + case kMaj11b5: strcat(chord, "major 11th b5"); break; + case kMaj11s5: strcat(chord, "major 11th #5"); break; + case kMaj11b9: strcat(chord, "major 11th b9"); break; + case kMaj11s9: strcat(chord, "major 11th #9"); break; + case kMaj11b13: strcat(chord, "major 11th b13"); break; + case kMaj11s13: strcat(chord, "major 11th #13"); break; + case kM11b5b9: strcat(chord, "major 11th b5 b9"); break; + case kDom11b5: strcat(chord, "dominant 11th b5"); break; + case kDom11b9: strcat(chord, "dominant 11th b9"); break; + case kDom11s9: strcat(chord, "dominant 11th #9"); break; + case kHalfDim11b9:strcat(chord, "half dim 11th b9"); break; + case kDom7s11: strcat(chord, "dominant #11"); break; + case kMin7s11: strcat(chord, "minor 7th #11"); break; + + case kDom13s11: strcat(chord, "dominant 13th #11"); break; + case kM7b913: strcat(chord, "major 7 b9 13"); break; + case kMaj7s13: strcat(chord, "major 7th #13"); break; + case kM7b9s13: strcat(chord, "major 7 b9 #13"); break; + case kDom7b13: strcat(chord, "dominant 7th b13"); break; + case kChrom: strcat(chord, "chromatic"); break; + case kNone: + default: strcat(chord, "unknown"); break; + } + + x->x_chord_bass = x->x_abs_pc[x->x_chord_root]; /* get MIDI note number of bass */ + + /* output results */ + outlet_list(x->x_outchordnotes, NULL, j, x->x_chordlist); + outlet_float(x->x_outchordinversion, x->x_chord_inversion); + outlet_symbol(x->x_outchordname, gensym(chord)); + outlet_float(x->x_outchordclass, x->x_chord_root); + outlet_float(x->x_outchordval, x->x_chord_bass); +} + +static void chord_kick_out_member(t_chord *x, t_int number, t_int *members) +{ + int *distances; + int minDistance = 1000; + int badMember = 0; + int i, j, interval; + + distances = getbytes(number*sizeof(int)); + + for (i=0; i 6) interval = 12 - interval; + // add absolute interval size to total + distances[i] += interval; + } + + // if this is the smallest total distance + if (distances[i] < minDistance) { + // remember it + minDistance = distances[i]; + badMember = i; + } + } + freebytes(distances, number * sizeof(int)); + x->x_pc[members[badMember]] = 0; // cancel out most dissonant member + chord_chord_finder(x, number-1); // call chord finder again without it + x->x_pc[members[badMember]] = 1; // replace most dissonant member +} + +static void chord_chord_finder(t_chord *x, t_int num_pcs) +{ + int i; + x->x_chord_type = kNone; + x->x_chord_root = kXX; /* none */ + switch (num_pcs) { + case 1: chord_unison(x); break; + case 2: chord_dyad(x); break; + case 3: chord_triad(x); break; + case 4: chord_quartad(x); break; + case 5: chord_quintad(x); break; + case 6: chord_sextad(x); break; + default: x->x_chord_type = kChrom; + for(i = 0; i < 12; i++) // 12 was num_pcs !? + { + if(x->x_pc[i]) + { + x->x_chord_root = i; + break; + } + } + } +} + +static void chord_float(t_chord *x, t_floatarg f) +{ + t_int velo = x->x_velo; + t_int allloc = 0; + t_int num_pc = 0; /* number of pitch classes present */ + int i, j, k, l; + + x->x_pitch = (t_int)f; + + if(x->x_pitch <= x->x_split) + { + /* first we need to put the note into the allocation table */ + if(velo == 0) /* got note-off: remove from allocation table */ + { + if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */ + for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */ + { + /* search for corresponding alloc number */ + if(x->x_alloctable[i] == x->x_pitch) + { + x->x_alloctable[i] = -1; /* free the alloc number */ + break; + } + /* couldn't find it ? */ + if(i == MAX_POLY - 1) + { + post("chord: no corresponding note-on found (ignored)"); + return; + } + } + return; /* no need to look for chord */ + } + else /* we got a note-on message */ + { + if(x->x_poly == MAX_POLY) + { + post("chord: too many note-on messages (ignored)"); + return; + } + + x->x_poly++; /* number of currently playing notes has increased */ + /* assign a voice allocation number */ + for(i = 0; i < MAX_POLY; i++) + { + /* search for free alloc number */ + if(x->x_alloctable[i] == -1) + { + x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */ + break; + } + } + /* copy all notes into the pitch class array */ + for(i = 0; i < 12; i++) + { + x->x_pc[i] = 0; /* empty pitch class */ + x->x_abs_pc[i] = -1; /* empty absolute values */ + } + for(i = 0; i < MAX_POLY; i++) + { + /* check for presence of pitch class */ + if(x->x_alloctable[i] != -1) + { + if(!x->x_pc[x->x_alloctable[i]%12]) /* a new pitch class */ + { + x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i]; + } + else if(x->x_abs_pc[x->x_alloctable[i]%12] > x->x_alloctable[i]) /* remember lowest pitch */ + { + x->x_abs_pc[x->x_alloctable[i]%12] = x->x_alloctable[i]; + } + + x->x_pc[x->x_alloctable[i]%12] = 1; /* indicate presence of pc */ + } + } + /* count number of pitch classes */ + for(i = 0; i < 12; i++) + { + num_pc += x->x_pc[i]; + } + // post("%d pitch classes", num_pc); + } + } + + chord_chord_finder(x, num_pc); +} + +static void chord_ft1(t_chord *x, t_floatarg f) +{ + x->x_velo = (t_int)f; +} + +static t_class *chord_class; + +static void *chord_new(t_floatarg f) +{ + int i; + t_chord *x = (t_chord *)pd_new(chord_class); + inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + x->x_outchordval = outlet_new(&x->x_ob, gensym("float")); + x->x_outchordclass = outlet_new(&x->x_ob, gensym("float")); + x->x_outchordname = outlet_new(&x->x_ob, gensym("symbol")); + x->x_outchordinversion = outlet_new(&x->x_ob, gensym("float")); + x->x_outchordnotes = outlet_new(&x->x_ob, gensym("float")); + + x->x_split = (t_int)f; + if(x->x_split == 0)x->x_split = 128; + for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = -1; + + return (void *)x; +} + +#ifndef MAXLIB +void chord_setup(void) +{ + chord_class = class_new(gensym("chord"), (t_newmethod)chord_new, + 0, sizeof(t_chord), 0, A_DEFFLOAT, 0); +#else +void maxlib_chord_setup(void) +{ + chord_class = class_new(gensym("maxlib_chord"), (t_newmethod)chord_new, + 0, sizeof(t_chord), 0, A_DEFFLOAT, 0); +#endif + class_addfloat(chord_class, chord_float); + class_addmethod(chord_class, (t_method)chord_ft1, gensym("ft1"), A_FLOAT, 0); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)chord_new, gensym("chord"), A_DEFFLOAT, 0); + class_sethelpsymbol(chord_class, gensym("maxlib/chord-help.pd")); +#endif +} + diff --git a/delta-help.pd b/delta-help.pd new file mode 100644 index 0000000..fa865e3 --- /dev/null +++ b/delta-help.pd @@ -0,0 +1,20 @@ +#N canvas 328 264 466 318 12; +#X floatatom 54 217 5 0 0; +#X floatatom 54 108 5 0 0; +#X msg 23 83 bang; +#X text 69 82 calculate and output result now; +#X obj 54 172 delta; +#X obj 54 133 * 3; +#X floatatom 127 218 5 0 0; +#X floatatom 127 109 5 0 0; +#X obj 127 134 * 3; +#X obj 127 173 delta 2; +#X text 53 259 use creation arguments to set order (1st or 2nd); +#X text 39 20 delta :: calculate 1st or 2nd order difference; +#X connect 1 0 5 0; +#X connect 2 0 4 0; +#X connect 4 0 0 0; +#X connect 5 0 4 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 6 0; diff --git a/delta.c b/delta.c new file mode 100644 index 0000000..41e9b6e --- /dev/null +++ b/delta.c @@ -0,0 +1,139 @@ +/* ------------------------- delta ------------------------------------------ */ +/* */ +/* Claculate 1st or 2nd order difference. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Inspired by code written by Trond Lossius. */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +#define MAXSIZE 32 + +static char *version = "delta v0.1, written by Olaf Matthes "; + +typedef struct delta +{ + t_object x_ob; + t_outlet *x_out; /* result */ + t_int x_order; /* 1st or second order */ + t_int x_clearflag; + t_float x_delta; /* the result */ + + t_float x_prev; /* previous value */ + t_float x_prev2; /* value previous to previous value */ +} t_delta; + +static void delta_clear(t_delta *x) +{ + if(x->x_order == 2) + x->x_clearflag = 2; + else + x->x_clearflag = 1; + x->x_delta = 0; +} + +static void delta_bang(t_delta *x) +{ + outlet_float(x->x_out, x->x_delta); +} + +static void delta_float(t_delta *x, t_floatarg f) +{ + if(x->x_order != 2) /* first order */ + { + if(x->x_clearflag) + { + x->x_prev = f; + x->x_delta = 0; + x->x_clearflag = 0; + } + else + { + x->x_delta = f - x->x_prev; + x->x_prev = f; + } + } + else + { + switch(x->x_clearflag) + { + case 0: + x->x_delta = f - 2*x->x_prev + x->x_prev2; + x->x_prev2 = x->x_prev; + x->x_prev = f; + break; + case 1: + x->x_prev = f; + x->x_clearflag--; + break; + case 2: + x->x_prev2 = f; + x->x_clearflag--; + break; + } + } + delta_bang(x); +} + +static t_class *delta_class; + +static void *delta_new(t_floatarg f) +{ + int i; + + t_delta *x = (t_delta *)pd_new(delta_class); + x->x_out = outlet_new(&x->x_ob, gensym("float")); + + x->x_order = (int)f; + if(x->x_order == 2) + x->x_clearflag = 2; + else + x->x_clearflag = 1; + x->x_delta = 0; + + return (void *)x; +} + +#ifndef MAXLIB +void delta_setup(void) +{ + delta_class = class_new(gensym("delta"), (t_newmethod)delta_new, + 0, sizeof(t_delta), 0, A_DEFFLOAT, 0); +#else +void maxlib_delta_setup(void) +{ + delta_class = class_new(gensym("maxlib_delta"), (t_newmethod)delta_new, + 0, sizeof(t_delta), 0, A_DEFFLOAT, 0); +#endif + class_addfloat(delta_class, delta_float); + class_addbang(delta_class, (t_method)delta_bang); + class_addmethod(delta_class, (t_method)delta_clear, gensym("clear"), 0); + class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd")); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)delta_new, gensym("delta"), A_DEFFLOAT, 0); + class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd")); +#endif +} + diff --git a/deny-help.pd b/deny-help.pd new file mode 100644 index 0000000..9ca4a29 --- /dev/null +++ b/deny-help.pd @@ -0,0 +1,20 @@ +#N canvas 358 305 556 310 12; +#X text 97 34 written by Olaf Matthes ; +#X msg 125 65 cat; +#X msg 147 97 dog; +#X msg 157 126 bird; +#X floatatom 82 269 5 0 0 0 - - -; +#X symbolatom 151 246 10 0 0 0 - - -; +#X obj 114 156 symbol \$1; +#X floatatom 40 81 5 0 0 0 - - -; +#X obj 82 217 route float symbol; +#X obj 82 189 deny 17 cat dog 23; +#X text 32 18 deny :: blocks 'denyed' floats or symbols; +#X connect 1 0 6 0; +#X connect 2 0 6 0; +#X connect 3 0 6 0; +#X connect 6 0 9 0; +#X connect 7 0 9 0; +#X connect 8 0 4 0; +#X connect 8 1 5 0; +#X connect 9 0 8 0; diff --git a/deny.c b/deny.c new file mode 100644 index 0000000..1ab4de8 --- /dev/null +++ b/deny.c @@ -0,0 +1,114 @@ +/* ---------------------------- deny --------------------------------------- */ +/* */ +/* Lets only floats/symbols through that are denyed to do so. */ +/* Written by Olaf Matthes */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +static char *version = "deny v0.1, written by Olaf Matthes "; + +typedef struct deny +{ + t_object x_obj; + t_outlet *x_out; + t_atom *x_elem; // list of elemets that are denyed to pass + t_int x_numelem; // the number of elemetns in our deny-list +} t_deny; + + /* we got a symbol... */ +static void deny_symbol(t_deny *x, t_symbol *s) +{ + int i, deny = 0; + for(i = 0; i < x->x_numelem; i++) + { + if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list + if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s) + { + deny = 1; + return; + } + } + if(!deny)outlet_symbol(x->x_out, s); +} + + /* we got a float... */ +static void deny_float(t_deny *x, t_floatarg f) +{ + int i, deny = 0; + for(i = 0; i < x->x_numelem; i++) + { + if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list + if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f) + { + deny = 1; // input is in deny-list + return; + } + } + if(!deny)outlet_float(x->x_out, f); +} + +static t_class *deny_class; + +static void deny_free(t_deny *x) +{ + freebytes(x->x_elem, x->x_numelem*sizeof(t_atom)); +} + +static void *deny_new(t_symbol *s, int argc, t_atom *argv) +{ + t_deny *x = (t_deny *)pd_new(deny_class); + + x->x_numelem = argc; // get the number of elements + x->x_elem = getbytes(argc*sizeof(t_atom)); + memcpy(x->x_elem, argv, argc*sizeof(t_atom)); + + x->x_out = outlet_new(&x->x_obj, gensym("anything")); + + // post("deny: got %d elements", x->x_numelem); + + return (x); +} + +#ifndef MAXLIB +void deny_setup(void) +{ + /* the object's class: */ + deny_class = class_new(gensym("deny"), (t_newmethod)deny_new, + (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0); +#else +void maxlib_deny_setup(void) +{ + /* the object's class: */ + deny_class = class_new(gensym("maxlib_deny"), (t_newmethod)deny_new, + (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0); + class_addcreator((t_newmethod)deny_new, gensym("deny"), A_GIMME, 0); +#endif + class_addsymbol(deny_class, deny_symbol); + class_addfloat(deny_class, deny_float); +#ifndef MAXLIB + + post(version); +#else + class_sethelpsymbol(deny_class, gensym("maxlib/deny-help.pd")); +#endif +} diff --git a/dist-help.pd b/dist-help.pd new file mode 100644 index 0000000..608283f --- /dev/null +++ b/dist-help.pd @@ -0,0 +1,36 @@ +#N canvas 450 84 473 453 12; +#X text 33 10 dist :: send data to a list of receive objects; +#X obj 34 364 dist; +#X msg 85 127 connect bla; +#X msg 103 154 connect foo; +#X msg 131 209 disconnect bla; +#X msg 145 237 disconnect foo; +#X msg 158 295 clear; +#X obj 200 374 receive bla; +#X obj 306 374 receive foo; +#X obj 200 400 print bla; +#X obj 306 400 print foo; +#X floatatom 34 69 5 0 0; +#X msg 170 328 print; +#X msg 56 98 send anything 1 2 dog; +#X obj 34 397 d bla foo; +#X msg 122 180 connect dog cat; +#X msg 159 265 disconnect cat dog; +#X text 210 295 empty receiver list; +#X text 218 328 print list of receive names; +#X text 190 126 add 'bla' to list of receivers; +#X text 253 209 remove 'bla' from list; +#X text 238 99 send anything you want; +#X text 97 28 written by Olaf Matthes ; +#X connect 2 0 1 0; +#X connect 3 0 1 0; +#X connect 4 0 1 0; +#X connect 5 0 1 0; +#X connect 6 0 1 0; +#X connect 7 0 9 0; +#X connect 8 0 10 0; +#X connect 11 0 1 0; +#X connect 12 0 1 0; +#X connect 13 0 1 0; +#X connect 15 0 1 0; +#X connect 16 0 1 0; diff --git a/dist.c b/dist.c new file mode 100644 index 0000000..38544d5 --- /dev/null +++ b/dist.c @@ -0,0 +1,279 @@ +/* -------------------------- dist ------------------------------------------ */ +/* */ +/* Distributes incoming data to a changeable list of receive objects. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* + connect : store receive objects in list of receivers + disconnect : remove objects from list of receivers + clear: clear list of receivers + send : send anything to all receives named in the list of receivers */ + +#include "m_pd.h" + +#include +#include + +#define MAX_REC 64 /* maximum number of receive objects */ +#define MAX_ARG 32 /* maximum number of arguments to pass on */ + +static char *version = "dist v0.1, written by Olaf Matthes "; + +static t_class *dist_class; + +typedef struct _dist +{ + t_object x_obj; + t_symbol *x_sym[MAX_REC]; /* names of receiving objects */ + t_int x_rec; /* current number of receiving objects */ + t_int x_verbose; /* set to 0 to turn off detailed output in Pd window */ +} t_dist; + +static void dist_bang(t_dist *x) +{ + int i; + + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) pd_bang(x->x_sym[i]->s_thing); + } +} + +static void dist_float(t_dist *x, t_float f) +{ + int i; + + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) pd_float(x->x_sym[i]->s_thing, f); + } +} + +static void dist_symbol(t_dist *x, t_symbol *s) +{ + int i; + + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) pd_symbol(x->x_sym[i]->s_thing, s); + } +} + +static void dist_pointer(t_dist *x, t_gpointer *gp) +{ + int i; + + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) pd_pointer(x->x_sym[i]->s_thing, gp); + } +} + +static void dist_list(t_dist *x, t_symbol *s, int argc, t_atom *argv) +{ + int i; + + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) pd_list(x->x_sym[i]->s_thing, s, argc, argv); + } +} + +static void dist_anything(t_dist *x, t_symbol *s, int argc, t_atom *argv) +{ + int i; + + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) typedmess(x->x_sym[i]->s_thing, s, argc, argv); + } +} + + /* send 'anything' to receiver */ +static void dist_send(t_dist *x, t_symbol *s, int argc, t_atom *argv) +{ + int i; + t_atom av[MAX_ARG]; /* the 'new' t_atom without first element */ + t_int ac = argc - 1; /* the 'new' number of arguments */ + + if(ac > MAX_ARG) + { + post("dist: too many arguments!"); + return; + } + + for(i = 1; i < argc; i++) + { + av[i - 1] = argv[i]; /* just copy, don't care about types */ + } + /* send only argument-part to receivers */ + for(i = 0; i <= x->x_rec; i++) + { + if (x->x_sym[i]->s_thing) pd_forwardmess(x->x_sym[i]->s_thing, argc, argv); + } +} + +static void dist_connect(t_dist *x, t_symbol *s, int argc, t_atom *argv) +{ + int i, j; + int exist; + t_symbol *name; + /* just append every new receive-name to end of list */ + for(i = 0; i < argc; i++) + { + exist = 0; + if(x->x_rec == MAX_REC - 1) + { + post("dist: too many connections in use!"); + return; + } + name = atom_getsymbolarg(i, argc, argv); + for(j = 0; j <= x->x_rec; j++) + { + /* check if the name already exists */ + if(x->x_sym[j] == name) + { + post("dist: \"%s\" already exists in list of receivers", name->s_name); + exist = 1; /* indicate that it _does_ exist */ + } + } + /* add it in case it's a new one */ + if(!exist) + { + x->x_rec++; + x->x_sym[x->x_rec] = name; + if(x->x_verbose)post("dist: \"%s\" added to list of receivers", x->x_sym[x->x_rec]->s_name); + } + } +} + +static void dist_disconnect(t_dist *x, t_symbol *s, int argc, t_atom *argv) +{ + /* need to rearrange list in order to get rid of empty entries */ + int i, j, k; + int done; + t_symbol *name; + + for(i = 0; i < argc; i++) + { + name = atom_getsymbolarg(i, argc, argv); /* the one we're going to remove */ + done = 0; /* not yet removed */ + for(j = 0; j <= x->x_rec; j++) /* search for it... */ + { + if(x->x_sym[j] == name) + { + x->x_rec--; + if(x->x_verbose)post("dist: \"%s\" removed from list of receivers", x->x_sym[j]->s_name); + x->x_sym[j] = NULL; /* delete entry */ + /* rearrange list now: move entries to close the gap */ + for(k = j; k <= x->x_rec; k++) + { + x->x_sym[k] = x->x_sym[k + 1]; + } + done = 1; /* removed successfully */ + } + } + if(!done)post("dist: \"%s\" not in list of receivers, ignored", name->s_name); + } +} + +static void dist_clear(t_dist *x) +{ + int i; + + for(i = 0; i < MAX_REC; i++) + { + x->x_sym[i] = NULL; + } + x->x_rec = -1; +} + +static void dist_print(t_dist *x) +{ + int i; + + if(x->x_rec == 0) + { + post("dist: there is one object in receiver list:"); + } + else if(x->x_rec > 0) + { + post("dist: there are %d objects in receiver list:", x->x_rec + 1); + } + else + { + post("dist: there are no objects in receiver list"); + return; + } + + for(i = 0; i <= x->x_rec; i++) + { + post(" \"%s\"", x->x_sym[i]->s_name); + } +} + +static void *dist_new(t_symbol *s, int argc, t_atom *argv) +{ + int i; + + t_dist *x = (t_dist *)pd_new(dist_class); + + x->x_rec = -1; + x->x_verbose = 1; /* display info on connect/disconnect */ + for(i = 0; i < argc; i++) + { + x->x_sym[i] = atom_getsymbolarg(i, argc, argv); + x->x_rec++; + } + return (x); +} + +#ifndef MAXLIB +void dist_setup(void) +{ + dist_class = class_new(gensym("dist"), (t_newmethod)dist_new, 0, + sizeof(t_dist), 0, A_GIMME, 0); +#else +void maxlib_dist_setup(void) +{ + dist_class = class_new(gensym("maxlib_dist"), (t_newmethod)dist_new, 0, + sizeof(t_dist), 0, A_GIMME, 0); +#endif + class_addcreator((t_newmethod)dist_new, gensym("d"), A_GIMME, 0); + class_addbang(dist_class, dist_bang); + class_addfloat(dist_class, dist_float); + class_addsymbol(dist_class, dist_symbol); + class_addpointer(dist_class, dist_pointer); + class_addlist(dist_class, dist_list); + class_addmethod(dist_class, (t_method)dist_connect, gensym("connect"), A_GIMME, 0); + class_addmethod(dist_class, (t_method)dist_disconnect, gensym("disconnect"), A_GIMME, 0); + class_addmethod(dist_class, (t_method)dist_clear, gensym("clear"), 0); + class_addmethod(dist_class, (t_method)dist_print, gensym("print"), 0); + class_addmethod(dist_class, (t_method)dist_send, gensym("send"), A_GIMME, 0); + class_addanything(dist_class, dist_anything); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)dist_new, gensym("dist"), A_GIMME, 0); + class_sethelpsymbol(dist_class, gensym("maxlib/dist-help.pd")); +#endif +} diff --git a/divide-help.pd b/divide-help.pd new file mode 100644 index 0000000..a0aea04 --- /dev/null +++ b/divide-help.pd @@ -0,0 +1,18 @@ +#N canvas 328 264 466 318 12; +#X floatatom 54 217 5 0 0; +#X floatatom 54 132 5 0 0; +#X floatatom 108 132 5 0 0; +#X text 39 20 divide :: like '/' but calculates result; +#X text 133 204 use creation arguments to set initial; +#X text 133 220 values for inlets; +#X msg 7 104 bang; +#X text 53 103 calculate and output result now; +#X obj 54 172 divide 8 6 4; +#X text 118 58 allows for up to 32 inlets; +#X floatatom 164 132 5 0 0; +#X text 120 38 when leftmost or second inlet is changed; +#X connect 1 0 8 0; +#X connect 2 0 8 1; +#X connect 6 0 8 0; +#X connect 8 0 0 0; +#X connect 10 0 8 2; diff --git a/divide.c b/divide.c new file mode 100644 index 0000000..b13fefe --- /dev/null +++ b/divide.c @@ -0,0 +1,110 @@ +/* ------------------------- divide ------------------------------------------ */ +/* */ +/* Like '/', but calculates output whenever _any_ of the inlets changes. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +#define MAXSIZE 32 + +static char *version = "divide v0.2, written by Olaf Matthes "; + +typedef struct divide +{ + t_object x_ob; + t_inlet *x_inleft; /* leftmost inlet */ + t_inlet *x_inright; /* right inlet */ + t_outlet *x_outlet; /* result */ + t_int x_numvalues; /* number of values / inlets */ + + t_float x_dividevalue[MAXSIZE]; + +} t_divide; + +static void divide_bang(t_divide *x) +{ + int i; + t_float result = x->x_dividevalue[0]; + for(i = 1; i < x->x_numvalues; i++) + result /= x->x_dividevalue[i]; + outlet_float(x->x_outlet, result); +} + +static void divide_float(t_divide *x, t_floatarg f) +{ + x->x_dividevalue[0] = f; + divide_bang(x); /* calculate result */ +} + +static void divide_ft1(t_divide *x, t_floatarg f) +{ + x->x_dividevalue[1] = f; + divide_bang(x); /* calculate result */ +} + +static t_class *divide_class; + +static void *divide_new(t_symbol *s, t_int argc, t_atom* argv) +{ + int i; + + t_divide *x = (t_divide *)pd_new(divide_class); + x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + for(i = 2; i < argc; i++) /* create additional inlets, if any */ + { + floatinlet_new(&x->x_ob, &x->x_dividevalue[i]); + } + x->x_outlet = outlet_new(&x->x_ob, gensym("float")); + + for(i = 0; i < argc; i++) + { + x->x_dividevalue[i] = atom_getfloatarg(i, argc, argv); + } + x->x_numvalues = i; + + return (void *)x; +} + +#ifndef MAXLIB +void divide_setup(void) +{ + divide_class = class_new(gensym("divide"), (t_newmethod)divide_new, + 0, sizeof(t_divide), 0, A_GIMME, 0); +#else +void maxlib_divide_setup(void) +{ + divide_class = class_new(gensym("maxlib_divide"), (t_newmethod)divide_new, + 0, sizeof(t_divide), 0, A_GIMME, 0); +#endif + class_addfloat(divide_class, divide_float); + class_addmethod(divide_class, (t_method)divide_ft1, gensym("ft1"), A_FLOAT, 0); + class_addbang(divide_class, (t_method)divide_bang); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)divide_new, gensym("divide"), A_GIMME, 0); + class_sethelpsymbol(divide_class, gensym("maxlib/divide-help.pd")); +#endif +} + diff --git a/divmod-help.pd b/divmod-help.pd new file mode 100644 index 0000000..5e0018b --- /dev/null +++ b/divmod-help.pd @@ -0,0 +1,20 @@ +#N canvas 328 264 464 316 12; +#X floatatom 54 239 5 0 0; +#X floatatom 54 127 5 0 0; +#X floatatom 129 127 5 0 0; +#X obj 54 172 divmod 8 6; +#X text 146 170 use creation arguments to set initial; +#X text 146 186 values for inlets; +#X msg 23 83 bang; +#X text 69 82 calculate and output result now; +#X floatatom 129 219 5 0 0; +#X text 182 222 modulo; +#X text 106 242 result of division; +#X text 186 127 takes int's only!; +#X text 12 19 divmod :: calculate division and modulo; +#X text 92 35 outputs results even when right inlet changes; +#X connect 1 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 0 0; +#X connect 3 1 8 0; +#X connect 6 0 3 0; diff --git a/divmod.c b/divmod.c new file mode 100644 index 0000000..07f265e --- /dev/null +++ b/divmod.c @@ -0,0 +1,100 @@ +/* ------------------------- divmod ----------------------------------------- */ +/* */ +/* Calculates / and % together. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +static char *version = "divmod v0.1, written by Olaf Matthes "; + +typedef struct divmod +{ + t_object x_ob; + t_inlet *x_inleft; /* leftmost inlet */ + t_inlet *x_inright; /* right inlet */ + t_outlet *x_outlet1; /* result of division */ + t_outlet *x_outlet2; /* result of modulo */ + + t_int x_leftvalue; + t_int x_rightvalue; + +} t_divmod; + +static void divmod_float(t_divmod *x, t_floatarg f) +{ + x->x_leftvalue = (t_int)f; + outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue); + outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue); +} + +static void divmod_ft1(t_divmod *x, t_floatarg f) +{ + x->x_rightvalue = (t_int)f; + outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue); + outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue); +} + +static void divmod_bang(t_divmod *x) +{ + outlet_float(x->x_outlet1, x->x_leftvalue / x->x_rightvalue); + outlet_float(x->x_outlet2, x->x_leftvalue % x->x_rightvalue); +} + +static t_class *divmod_class; + +static void *divmod_new(t_floatarg fl, t_floatarg fr) +{ + t_divmod *x = (t_divmod *)pd_new(divmod_class); + x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + x->x_outlet1 = outlet_new(&x->x_ob, gensym("float")); + x->x_outlet2 = outlet_new(&x->x_ob, gensym("float")); + + x->x_rightvalue = fr; + x->x_leftvalue = fl; + + return (void *)x; +} + +#ifndef MAXLIB +void divmod_setup(void) +{ + divmod_class = class_new(gensym("divmod"), (t_newmethod)divmod_new, + 0, sizeof(t_divmod), 0, A_DEFFLOAT, A_DEFFLOAT, 0); +#else +void maxlib_divmod_setup(void) +{ + divmod_class = class_new(gensym("maxlib_divmod"), (t_newmethod)divmod_new, + 0, sizeof(t_divmod), 0, A_DEFFLOAT, A_DEFFLOAT, 0); +#endif + class_addfloat(divmod_class, divmod_float); + class_addmethod(divmod_class, (t_method)divmod_ft1, gensym("ft1"), A_FLOAT, 0); + class_addbang(divmod_class, (t_method)divmod_bang); +#ifndef MAXLIB + + post(version); +#else + class_addcreator((t_newmethod)divmod_new, gensym("divmod"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_sethelpsymbol(divmod_class, gensym("maxlib/divmod-help.pd")); +#endif +} + diff --git a/edge-help.pd b/edge-help.pd new file mode 100644 index 0000000..ce85dfb --- /dev/null +++ b/edge-help.pd @@ -0,0 +1,17 @@ +#N canvas 258 208 452 302 12; +#X obj 100 154 edge; +#X obj 100 215 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 127 186 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X text 156 186 falling edge detected; +#X text 128 216 rising edge detected; +#X text 31 16 edge :: detect rising or falling edge in floats; +#X floatatom 126 111 5 0 0; +#X obj 100 79 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X text 94 35 written by ; +#X connect 0 0 1 0; +#X connect 0 1 2 0; +#X connect 6 0 0 0; +#X connect 7 0 0 0; diff --git a/edge.c b/edge.c new file mode 100644 index 0000000..4f32e8a --- /dev/null +++ b/edge.c @@ -0,0 +1,82 @@ +/* --------------------------- edge ----------------------------------------- */ +/* */ +/* Detect rising or falling edge of float input. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include + +static char *version = "edge v0.1, written by Olaf Matthes "; + +typedef struct edge +{ + t_object x_ob; + t_outlet *x_out1; /* bang on rising edge */ + t_outlet *x_out2; /* bang on falling edge */ + t_float x_lastval; /* last input value */ +} t_edge; + +static void edge_float(t_edge *x, t_floatarg f) +{ + if((x->x_lastval <= 0) && (f >= 1)) /* rising edge */ + outlet_bang(x->x_out1); + else if((x->x_lastval >= 1) && (f <= 0)) /* falling edge */ + outlet_bang(x->x_out2); + + x->x_lastval = f; /* save last value */ +} + +static t_class *edge_class; + +static void *edge_new(t_floatarg f) +{ + int i; + + t_edge *x = (t_edge *)pd_new(edge_class); + x->x_out1 = outlet_new(&x->x_ob, gensym("bang")); + x->x_out2 = outlet_new(&x->x_ob, gensym("bang")); + + x->x_lastval = f; + + return (void *)x; +} + +#ifndef MAXLIB +void edge_setup(void) +{ + edge_class = class_new(gensym("edge"), (t_newmethod)edge_new, + 0, sizeof(t_edge), 0, A_DEFFLOAT, 0); + class_addfloat(edge_class, edge_float); + + post(version); +} +#else +void maxlib_edge_setup(void) +{ + edge_class = class_new(gensym("maxlib_edge"), (t_newmethod)edge_new, + 0, sizeof(t_edge), 0, A_DEFFLOAT, 0); + class_addfloat(edge_class, edge_float); + class_addcreator((t_newmethod)edge_new, gensym("edge"), A_DEFFLOAT, 0); + class_sethelpsymbol(edge_class, gensym("maxlib/edge-help.pd")); +} +#endif + diff --git a/examplescore.txt b/examplescore.txt new file mode 100644 index 0000000..27002f1 --- /dev/null +++ b/examplescore.txt @@ -0,0 +1,25 @@ +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +71 +70 +69 +68 +67 +66 +65 +64 +63 +62 +61 +60 \ No newline at end of file diff --git a/expo-help.pd b/expo-help.pd new file mode 100644 index 0000000..922cf4c --- /dev/null +++ b/expo-help.pd @@ -0,0 +1,12 @@ +#N canvas 370 195 454 304 12; +#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 70 192 5 0 0; +#X text 13 20 expo :: exponetionally distributed random numbers +; +#X obj 70 140 expo 0.5; +#X floatatom 169 101 5 0 0; +#X text 222 103 lambda; +#X connect 0 0 3 0; +#X connect 3 0 1 0; +#X connect 4 0 3 1; diff --git a/expo.c b/expo.c new file mode 100644 index 0000000..231a923 --- /dev/null +++ b/expo.c @@ -0,0 +1,86 @@ +/* ---------------------------- rand_expo ------------------------------------- */ +/* */ +/* rand_expo generates a exponentially distributed random variable. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code found in Dodge/Jerse "Computer Music" */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define fran() (t_float)rand()/(t_float)RAND_MAX + +static char *version = "expo v0.1, generates exponentially distributed random variable\n" + " written by Olaf Matthes "; + +/* -------------------------- rand_expo ------------------------------ */ + +static t_class *rand_expo_class; + +typedef struct _rand_expo +{ + t_object x_obj; + t_float x_lambda; +} t_rand_expo; + +static void *rand_expo_new(t_floatarg f) +{ + t_rand_expo *x = (t_rand_expo *)pd_new(rand_expo_class); + srand( (unsigned)time( NULL ) ); + floatinlet_new(&x->x_obj, &x->x_lambda); + outlet_new(&x->x_obj, &s_float); + x->x_lambda = f; + return (x); +} + +static void rand_expo_bang(t_rand_expo *x) +{ + t_float u, l; + l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda); + do + { + u = fran(); + } + while(u == 0); + outlet_float(x->x_obj.ob_outlet, -log(u)/l); +} + +#ifndef MAXLIB +void expo_setup(void) +{ + rand_expo_class = class_new(gensym("expo"), (t_newmethod)rand_expo_new, 0, + sizeof(t_rand_expo), 0, A_DEFFLOAT, 0); + class_addbang(rand_expo_class, rand_expo_bang); + class_sethelpsymbol(rand_expo_class, gensym("expo-help.pd")); + post(version); +} +#else +void maxlib_expo_setup(void) +{ + rand_expo_class = class_new(gensym("maxlib_expo"), (t_newmethod)rand_expo_new, 0, + sizeof(t_rand_expo), 0, A_DEFFLOAT, 0); + class_addbang(rand_expo_class, rand_expo_bang); + class_addcreator((t_newmethod)rand_expo_new, gensym("expo"), A_DEFFLOAT, 0); + class_sethelpsymbol(rand_expo_class, gensym("maxlib/expo-help.pd")); +} +#endif diff --git a/fifo-help.pd b/fifo-help.pd new file mode 100644 index 0000000..581a7b7 --- /dev/null +++ b/fifo-help.pd @@ -0,0 +1,13 @@ +#N canvas 356 196 452 302 12; +#X obj 38 176 fifo 10; +#X floatatom 38 231 5 0 0; +#X floatatom 61 132 5 0 0; +#X msg 38 98 bang; +#X text 83 98 hit to get next number; +#X text 111 176 fifo ; +#X text 92 233 output of fifo; +#X text 42 14 fifo :: first in first out buffer for floats; +#X text 105 32 written for Max by St. Rainstick; +#X connect 0 0 1 0; +#X connect 2 0 0 0; +#X connect 3 0 0 0; diff --git a/fifo.c b/fifo.c new file mode 100644 index 0000000..c932c07 --- /dev/null +++ b/fifo.c @@ -0,0 +1,96 @@ +/* ---------------------------- fifo ------------------------------------------ */ +/* */ +/* Fifo buffer of floats, empties itselfe on every bang (in order of coming in) */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* Fifi-code based St. Rainstick fifi.c for Max, */ +/* copyright St. Rainstick, Amsterdam 1995 */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" + +static char *version = "fifo v0.1, written by Olaf Matthes "; + +typedef struct fifo +{ + t_object d_ob; + t_float *getal; + t_int count, end, size; + t_outlet *out; + +}t_fifo; + +static t_class *fifo_class; + +static void fifo_int(t_fifo *x, t_floatarg n) +{ + x->getal[x->count] = n; + x->count = (x->count + 1) % x->size; +} + +static void fifo_bang(t_fifo *x) +{ + if (x->end != x->count){ + outlet_float(x->out,x->getal[x->end]); + x->end = (x->end + 1) % x->size; + } +} + +static void fifo_free(t_fifo *x) +{ + freebytes(x->getal, x->size * sizeof(t_float)); +} + +static void *fifo_new(t_floatarg n) +{ + + t_fifo *x = (t_fifo *)pd_new(fifo_class); + if (n<10) n = 10; + x->size = (t_int)n; + x->end = 0; + x->count = 0; + x->getal = (t_float *)getbytes(x->size * sizeof(t_float)); + x->out = outlet_new(&x->d_ob, gensym("float")); + + return (x); +} + +#ifndef MAXLIB +void fifo_setup(void) +{ + fifo_class = class_new(gensym("fifo"), (t_newmethod)fifo_new, + (t_method)fifo_free, sizeof(t_fifo), 0, A_DEFFLOAT, 0); + class_addfloat(fifo_class, fifo_int); + class_addbang(fifo_class, fifo_bang); + + post(version); +} +#else +void maxlib_fifo_setup(void) +{ + fifo_class = class_new(gensym("maxlib_fifo"), (t_newmethod)fifo_new, + (t_method)fifo_free, sizeof(t_fifo), 0, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)fifo_new, gensym("fifo"), A_DEFFLOAT, 0); + class_addfloat(fifo_class, fifo_int); + class_addbang(fifo_class, fifo_bang); + class_sethelpsymbol(fifo_class, gensym("maxlib/fifo-help.pd")); +} +#endif diff --git a/gauss-help.pd b/gauss-help.pd new file mode 100644 index 0000000..c4dce4b --- /dev/null +++ b/gauss-help.pd @@ -0,0 +1,14 @@ +#N canvas 438 222 487 308 12; +#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 70 192 5 0 0; +#X floatatom 123 91 5 0 0; +#X obj 70 140 gauss 1 0; +#X floatatom 177 113 5 0 0; +#X text 39 21 gauss :: Gauss distributed random numbers; +#X text 176 92 sigma - standard deviation; +#X text 230 114 mu - mean; +#X connect 0 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 1 0; +#X connect 4 0 3 2; diff --git a/gauss.c b/gauss.c new file mode 100644 index 0000000..c1f32bf --- /dev/null +++ b/gauss.c @@ -0,0 +1,88 @@ +/* ---------------------------- rand_gauss ----------------------------------- */ +/* */ +/* rand_gauss generates a gauss distributed random variable. */ +/* Written by Olaf Matthes (olaf.matthes@gmx.de) */ +/* Based on code found in Dodge/Jerse "Computer Music" */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#include + +#define fran() (t_float)rand()/(t_float)RAND_MAX + +static char *version = "gauss v0.1, generates a Gaussian distributed random variable\n" + " with mean 'mu' and standard deviation 'sigma',\n" + " written by Olaf Matthes "; + +/* -------------------------- rand_gauss ------------------------------ */ + +static t_class *rand_gauss_class; + +typedef struct _rand_gauss +{ + t_object x_obj; + t_float x_sigma; + t_float x_mu; +} t_rand_gauss; + +static void *rand_gauss_new(t_floatarg fs, t_floatarg fm) +{ + t_rand_gauss *x = (t_rand_gauss *)pd_new(rand_gauss_class); + srand( (unsigned)time( NULL ) ); + floatinlet_new(&x->x_obj, &x->x_sigma); + floatinlet_new(&x->x_obj, &x->x_mu); + outlet_new(&x->x_obj, &s_float); + x->x_sigma = fs; + return (x); +} + +static void rand_gauss_bang(t_rand_gauss *x) +{ + t_float u, halfN = 6.0, sum = 0, scale; + t_int k, N = 12; + scale = 1/sqrt(N/12); + for(k = 1; k <= N; k++) + sum += fran(); + outlet_float(x->x_obj.ob_outlet, x->x_sigma*scale*(sum-halfN)+x->x_mu); +} + +#ifndef MAXLIB +void gauss_setup(void) +{ + rand_gauss_class = class_new(gensym("gauss"), (t_newmethod)rand_gauss_new, 0, + sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addbang(rand_gauss_class, rand_gauss_bang); + class_sethelpsymbol(rand_gauss_class, gensym("gauss-help.pd")); + post(version); +} +#else +void maxlib_gauss_setup(void) +{ + rand_gauss_class = class_new(gensym("maxlib_gauss"), (t_newmethod)rand_gauss_new, 0, + sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)rand_gauss_new, gensym("gauss"), A_DEFFLOAT, 0); + class_addbang(rand_gauss_class, rand_gauss_bang); + class_sethelpsymbol(rand_gauss_class, gensym("maxlib/gauss-help.pd")); +} +#endif + diff --git a/gestalt-help.pd b/gestalt-help.pd new file mode 100644 index 0000000..acf09cc --- /dev/null +++ b/gestalt-help.pd @@ -0,0 +1,51 @@ +#N canvas 323 155 599 396 12; +#X text 137 8 gestalt :: gestalt detection for monophonic melodies +; +#X floatatom 58 332 5 0 0; +#X obj 58 176 makenote 100 100; +#X obj 58 53 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 58 76 metro 100; +#X obj 58 100 random 24; +#X obj 58 124 + 60; +#X obj 58 278 gestalt 100; +#X obj 142 100 random 24; +#X obj 142 124 select 0; +#X msg 201 146 100; +#X msg 142 146 400; +#X floatatom 68 154 5 0 0; +#X text 160 282 CREATION ARGUMENT: reference time; +#X obj 219 220 beat; +#X floatatom 232 245 5 0 0; +#X text 87 54 click to play random melody; +#X text 112 350 one could use 'tilt' to detect abrupt changes that +; +#X text 112 367 indicate the start of a new segment; +#X text 111 332 the higher the output the more the gestalt changes +\;; +#X text 161 298 i.e. time in ms expected to be the duration of the +; +#X text 161 314 shortest note (also setable via rightmost inlet); +#X text 281 200 use 'beat' (maxlib) to get the real; +#X text 281 217 reference time from input \, especially; +#X text 282 234 when using; +#X obj 372 235 notein; +#X text 225 26 written by ; +#X connect 2 0 7 0; +#X connect 2 0 14 0; +#X connect 2 1 7 1; +#X connect 2 1 14 1; +#X connect 3 0 4 0; +#X connect 4 0 5 0; +#X connect 4 0 8 0; +#X connect 5 0 6 0; +#X connect 6 0 2 0; +#X connect 6 0 12 0; +#X connect 7 0 1 0; +#X connect 8 0 9 0; +#X connect 9 0 11 0; +#X connect 9 1 10 0; +#X connect 10 0 2 2; +#X connect 11 0 2 2; +#X connect 14 1 15 0; +#X connect 14 1 7 2; diff --git a/gestalt.c b/gestalt.c new file mode 100644 index 0000000..3155206 --- /dev/null +++ b/gestalt.c @@ -0,0 +1,123 @@ +/* ------------------------- gestalt ---------------------------------------- */ +/* */ +/* Find the 'gestalt' of the MIDI input. */ +/* Written by Olaf Matthes */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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 */ +/* of the License, 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#include "m_pd.h" +#include +#include +#ifndef _WIN32 +#include +#endif + +static char *version = "gestalt v0.1, written by Olaf Matthes "; + +typedef struct gestalt +{ + t_object x_ob; + t_inlet *x_invelocity; /* inlet for velocity */ + t_outlet *x_outgestalt; /* calculated 'gestalt'-value */ + + t_float x_lastpitch; + t_float x_velocity; + + t_float x_reftime; + + double x_lastontime; + +} t_gestalt; + +static void gestalt_ft1(t_gestalt *x, t_floatarg f) +{ + x->x_velocity = f; +} + +static void gestalt_ft2(t_gestalt *x, t_floatarg f) +{ + if(f > 0.0) x->x_reftime = f; +} + +static void gestalt_float(t_gestalt *x, t_floatarg f) +{ + + int interval, pitch, gestalt; + double ontime = clock_getlogicaltime(); + + if(x->x_velocity) /* only process note-ons */ + { + + pitch = (t_int)f; + if(pitch < 1) pitch = 0; + if(pitch > 127) pitch = 127; + + interval = abs(pitch - x->x_lastpitch); + gestalt = (clock_gettimesince(x->x_lastontime)/x->x_reftime) + interval; + + x->x_lastpitch = pitch; + x->x_lastontime = ontime; + + /* output values from right to left */ + outlet_float(x->x_outgestalt, gestalt); + } +} + +static t_class *gestalt_class; + +static void *gestalt_new(t_floatarg f) +{ + t_gestalt *x = (t_gestalt *)pd_new(gestalt_class); + inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); + inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft2")); + x->x_outgestalt = outlet_new(&x->x_ob, gensym("float")); + + x->x_lastontime = clock_getlogicaltime(); + + x->x_reftime = f; + if(x->x_reftime < 1) x->x_reftime = 1; + + return (void *)x; +} + +#ifndef MAXLIB +void gestalt_setup(void) +{ + gestalt_class = class_new(gensym("gestalt"), (t_newmethod)gestalt_new, + 0, sizeof(t_gestalt), 0, A_DEFFLOAT, 0); + class_addfloat(gestalt_class, gestalt_float); + class_addmethod(gestalt_class, (t_method)gestalt_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(gestalt_class, (t_method)gestalt_ft2, gensym("ft2"), A_FLOAT, 0); + + post(version); +} +#else +void maxlib_gestalt_setup(void) +{ + gestalt_class = class_new(gensym("maxlib_gestalt"), (t_newmethod)gestalt_new, + 0, sizeof(t_gestalt), 0, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)gestalt_new, gensym("gestalt"), A_DEFFLOAT, 0); + class_addfloat(gestalt_class, gestalt_float); + class_addmethod(gestalt_class, (t_method)gestalt_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(gestalt_class, (t_method)gestalt_ft2, gensym("ft2"), A_FLOAT, 0); + class_sethelpsymbol(gestalt_class, gensym("maxlib/gestalt-help.pd")); +} +#endif + diff --git a/help/allow-help.pd b/help/allow-help.pd deleted file mode 100644 index 084d52f..0000000 --- a/help/allow-help.pd +++ /dev/null @@ -1,21 +0,0 @@ -#N canvas 358 305 554 308 12; -#X text 24 17 allow :: lets only 'allowed' floats or symbols through -; -#X text 97 34 written by Olaf Matthes ; -#X msg 125 65 cat; -#X msg 147 97 dog; -#X msg 157 126 bird; -#X floatatom 82 269 5 0 0 0 - - -; -#X symbolatom 151 246 10 0 0 0 - - -; -#X obj 114 156 symbol \$1; -#X floatatom 40 81 5 0 0 0 - - -; -#X obj 82 217 route float symbol; -#X obj 82 189 allow 17 cat dog 23; -#X connect 2 0 7 0; -#X connect 3 0 7 0; -#X connect 4 0 7 0; -#X connect 7 0 10 0; -#X connect 8 0 10 0; -#X connect 9 0 5 0; -#X connect 9 1 6 0; -#X connect 10 0 9 0; diff --git a/help/arbran-help.pd b/help/arbran-help.pd deleted file mode 100644 index 9153bf5..0000000 --- a/help/arbran-help.pd +++ /dev/null @@ -1,28 +0,0 @@ -#N canvas 190 136 663 491 12; -#X obj 41 152 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 41 249 5 0 0; -#N canvas 0 0 450 300 graph1 0; -#X array array1 6 float 1; -#A 0 1.1 2.67143 3.24285 3.1 4.38571 8.67143; -#X coords 0 10 5 0 200 140 1; -#X restore 347 71 graph; -#N canvas 0 0 450 300 graph2 0; -#X array array2 6 float 1; -#A 0 0.0229077 0.204366 0.486501 0.0632986 0.204028 0.025319; -#X coords 0 1 5 0 200 140 1; -#X restore 347 220 graph; -#X obj 41 202 arbran array1 array2; -#X text 39 21 arbran :: generates a random variable that conforms -to the piecewise probability density functions specified in two arrays -; -#X text 40 297 array1 has values between 0 and 10; -#X text 40 317 array2 between 0 and 1 !; -#X msg 99 152 pdfscale; -#X text 41 389 array1 stores the values and array2 the corresponding -probabilities (0 - 1) for each of that values \, use message 'pdfscale' -to check (and adjust) the probability values to correct settings (the -area below the curve has to be 1); -#X connect 0 0 4 0; -#X connect 4 0 1 0; -#X connect 8 0 4 0; diff --git a/help/arraycopy-help.pd b/help/arraycopy-help.pd deleted file mode 100644 index 6963c69..0000000 --- a/help/arraycopy-help.pd +++ /dev/null @@ -1,62 +0,0 @@ -#N canvas 140 43 934 584 12; -#N canvas 0 0 450 300 graph1 0; -#X array array1 20 float 1; -#A 0 0 0 0.342857 0.542857 0.6 -0.442857 -0.485714 0.0142858 -0.428571 --0.114286 0.0857143 -0.2 -0.214285 0.314285 -0.157143 -0.314285 -0.142857 --0.0428571 0.114286 -0.685713; -#X coords 0 1 19 -1 200 140 1; -#X restore 680 27 graph; -#N canvas 0 0 450 300 graph2 0; -#X array array2 20 float 1; -#A 0 -0.214286 -0.171429 0.1 0.614286 0.757143 0.757143 0.542857 0.2 --0.0285714 -0.271429 -0.414286 -0.514286 -0.528571 -0.485714 -0.371429 --0.157143 0.214286 0.557143 0.714286 0.757143; -#X coords 0 1 19 -1 200 140 1; -#X restore 681 196 graph; -#N canvas 0 0 450 300 graph3 0; -#X array array3 20 float 1; -#A 0 1.86265e-009 1.86265e-009 1.86265e-009 1.86265e-009 1.86265e-009 --0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 --0.0142857 -0.0285714 -0.0285714 -0.0285714 -0.0285714 -0.0142857 -0.0142857 --0.0142857; -#X coords 0 1 19 -1 200 140 1; -#X restore 680 371 graph; -#X obj 22 500 arraycopy array3; -#X text 339 402 set the destination array; -#X text 41 1 arraycopy :: copy data from one array to another; -#X text 146 22 written by Olaf Matthes ; -#X msg 22 109 copy array1; -#X msg 43 139 copy array1 10 15; -#X text 131 109 copy the whole array; -#X text 200 140 copy from value 10 to 15; -#X msg 60 169 copy array1 10 +5; -#X text 217 170 copy from value 10 the next 5 values; -#X msg 85 359 print \$1; -#X obj 85 333 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 -; -#X text 116 334 switch console printout on/off; -#X text 281 202 copy from value 10 to 15; -#X msg 73 201 copy array1 10 15 array2; -#X text 280 222 into array2 (starting at 0); -#X text 322 251 copy from value 10 to 15; -#X text 321 271 into array2 starting at 4; -#X msg 92 250 copy array1 10 15 array2 4; -#X msg 368 454 array3; -#X msg 86 414 bang; -#X text 137 412 perform last copy; -#X text 137 429 operation again; -#X text 20 537 creation argument: initial destination array to copy -data to; -#X obj 200 502 symbol; -#X msg 339 428 array2; -#X connect 7 0 3 0; -#X connect 8 0 3 0; -#X connect 11 0 3 0; -#X connect 13 0 3 0; -#X connect 14 0 13 0; -#X connect 17 0 3 0; -#X connect 21 0 3 0; -#X connect 22 0 27 0; -#X connect 23 0 3 0; -#X connect 27 0 3 1; -#X connect 28 0 27 0; diff --git a/help/automata.txt b/help/automata.txt deleted file mode 100644 index 3f5ff21..0000000 --- a/help/automata.txt +++ /dev/null @@ -1,178 +0,0 @@ -[The following note originally appeared on the emusic-l mailing list. It is -reprinted here with the author's permission] - -From xrjdm@FARSIDE.GSFC.NASA.GOV Wed Nov 23 11:26:39 1994 -Date: Tue, 4 Oct 1994 15:09:23 -0500 -From: Joe McMahon -Reply to: Electronic Music Discussion List -To: Multiple recipients of list EMUSIC-L -Subject: Automata: the long-awaited summary - -Back in August, I think, I promised to post a quick intro to cellular -automata and how they can be used as a sound-generation tool. Since I'm -going to take a couple of different sources and sum them up with little or -no direct attribution, combined with my own opinions, I'll give everybody -my references *first* so they can delete the article and draw their own -conclusions if they so prefer. - -The primary reference that got me started on all this is one in the CMJ: -Vol 14, No. 4, Winter 1990: "Digital Synthesis of Self-modifying Waveforms -by Means of Cellular Automata" (Jacques Chareyon). Those who are already -familiar with automata may just skip to that article and forget about the -rest of this one. -Note: the article gives a mail address for M. Chareyon, but he did not -answer an inquiry about any available recordings using this technique in -1990. - -So. Anyone still here? Good. - -Cellular automata are a mathematical concept first introduced in the late -1940's. Generally speaking, a cellular automaton consists of a grid of -cells. Each cell may take on any of a number of values - binary automata -(cell on or cell off) are the most commonly studied. Each cell has a -neighborhood, defined more simply as other cells which influence its state. -The exact nature of this influence is defined by what are called transition -rules. The cellular automaton starts off with some cells in any of the -allowable states. for each "step" in the automaton's history, the -neighborhood of every cell is checked, and the state of the cell is -updated. All updates occur simultaneously. - -The transition rule must describe the resulting state of a cell for every -possible configuration of other cells in the neighborhood. For large -numbers of states, the amount of memory required to hold the transition -rule becomes increasingly large, Therefore, some automata use what is known -as a "totalistic" rule. These rules simply sum the values of the cells in -the neighborhood and then assign a result on this basis. The resulting -tables are far smaller. - -Many readers may already be familiar with John Horton Conway's game of -"Life". This is a two-dimensional binary automaton with a totalistic rule. -This makes for a very small rule set: - - i) If fewer than two filled cells (cells with value 1) surround a cell, - it becomes empty next generation. - ii) If more than three filled cells surround a cell, it becomes empty - next generation. -iii) If exactly three cells filled cells surround a cell, it becomes - filled on the next generation. - -This corresponds to a totalistic rule set with a total of 8(2-1)+1 or 9 -rules (one each for the sum values of 0 (no cells with a value) through 9 -(all cells with a value) ).If the transition rule were represented as a -non-totalistic one, the rule set would need 2**8 or 256 entries. There are -many interesting totalistic automata, so giving up detailed description of -every nuance of the transitions to save memory space isn't a big sacrifice. - -Interesting as two dimensional automata are, they really aren't terribly -useful for music making. There have been some experiments which have -attempted to use a two-dimensional automaton to generate MIDI events - -synthesis at the note level, using : - -Battista, T. and M. Giri, 1988. "Composizione Tramite Automi Cellulari." -Atti del VII Cooloquio di Informatica Musicale. Rome, Italy: Edizione Arti -Grafiche Ambrosini, pp. 181-182. - -Edgar, R. and J. Ryan, 1986. "LINA" Exhibition of the 1986 International -Computer Music Conference, San Francisco: Computer Music Association. - -I have not heard any of the music from these efforts, so I certainly can't -pass any judgement on them. For the purposes of this summary, we'll just -look at one-dimensional automata. These use a linear array of cells, with -the neighborhood generally being one or two cells on either side of each -cell. -(This is the type of automaton dealt with in M. Chareyon's article, which I -will be paraphrasing broadly hereafter). - -M. Chareyon's automata are wavetables. A digitized signal is stored as a -linear array of numbers in memory. A totalistic rule is used to determine a -lookup value which indexes into an array containing the resulting value; -this is saved into a second array. After the first array is completely -processed, the roles of the two are swapped and the process is repeated. - -The limiting factor in this process is the number of bits of resolution -being used to generate the sound. For a totalistic rule using a two-cell -neighborhood and 12-bit individual samples, we have 3*(2*12) = 12288 -entries in the rule table. At 2 bytes each, this is 24K of storage. If we -go to 16-bit sample resolution, we have 196608 entries at 2 bytes each for -a total of 393216 bytes, or 384K. - -The key point of M. Charyeon's method is the use of small neighborhoods -with large numbers of cellular states. Since the computation of the new -wavetable is all table lookup, very complex transition rules can be -precomputed and loaded into the tables, allowing the synthesis to -essentially be a fast sum-and-lookup loop to calculate each new wavesample. ->From the article, it appears that M. Chareyon was able to produce 2 or 3 -voices in realtime on a Mac II with a Digidesign Sound Accelerator board. -It seems that it would probably be possible to use an AV Mac to do it -without the board. - -This LASy (Linear Automaton Synthesis) method is closely related to the -Karplus-Strong plucked-string algorithm, in that a wavesample is run -through an algorithm which recirculates the samples to "self-modify" the -wave. In fact, a judicious choice of table entries allows one to very -simply simulate the K-S algoritm directly. - -So what are the sounds like? Some automata produce waveforms which quickly -"ramp-up" to complex spectra and then drop off quickly. Others move to a -steady state and then remain there. Yet others produce never-ending and -unpredictable waveforms, whose harmonic content is constantly changing. - -Obviously enough, the original wavesample can be obtained mathematically, -or by actual sampling and using LASy as a waveshaper. As M. Chareyon notes, -a quick estimate of the number of possible automata for a 2-neighbor -totalistic rule using a 256-entry wavetable with 12-bit entries is -(2**12)**256 * (2**12)**(3*2**12) or about 10**4500 possible automata. Of -course, many, many of these would not be suitable for music (e.g., the 4096 -automata in which all values go to one vlaue in one step, etc.); however, -the number of musically useful automata is still likely to be an immense -number. - -M. Chareyon provides a number of examples of ways to fill out the rule -tables and a number of hints on creating wave tables - generally speaking, -one can create a function which is used to compute the values to be placed -into the table and then fill it so it can simply be loaded and used by the -basic algorithm. His experience in using LASy is that he manages -approximately 50% of the time to produce sounds with the desired -characteristics, and that about 10% of the remaining time he gets -unexpected but useful results which can be used as starting points for -further exploration. - -Again, the important point is that the basic automaton uses wavesamples at -full resolution, calculating a new wavesample for each step of the -automaton; the next wavesample can be played while the new one is being -calculated. Because of the large number of states, mathematical tools for -the analysis of automata and the construction of automata with specifically -desired qualities require too much storage and compute time to make them -useful for LASy purposes. - -Again, much of this article is paraphrased from M. Chareyon's article; I -take no credit for any of the work in this note. I'm just summarizing. - -The following other articles were referenced by M. Chareyon's article: - -Burks, A., ed. 1970. Essays on Cellular Automata. Champaign/Urbana, IL: -University of Illinois Press. - -Chareyon, J. 1988a. "Sound Synthesis and Processing by Means of Linear -Cellular Automata." Proceedings of the 1988 Internation Computer Music -Conference. San Francisco: Computer Music Association. - -Chareyon, J. 1988b. "Wavetable come Automa Cellulare: una Nuova Tecnica di -Sintesi." Atti del VII Colloquio di Informatica Musicale, Rome, Italy: -Edizioni Arti Grafiche Ambrosini, pp. 174-177. - -Farmer, D., T. Toffoli, and S. Wolfram, eds. 1984. Cellular Automata. -North-Holland Physics Publishing. [One of the definitive works on cellular -automata - fairly heavy math, not a popular presentation - JM] - -Gardner, M. 1970. "The Fantastic Combinations of John Conway's New Solitare -Game 'Life'". Scientific American 223(4) 120-123. [A good introduction to -cellular automata, focusing on 'life' in specific. Useful intro if my -1-paragraph summary of automata was confusing :) - JM] - - --- Joe M. - --- -"At the end of the hour, we'll have information on the sedatives used by -the artists,,," (MST3K) - diff --git a/help/average-help.pd b/help/average-help.pd deleted file mode 100644 index 6155716..0000000 --- a/help/average-help.pd +++ /dev/null @@ -1,29 +0,0 @@ -#N canvas 445 253 470 320 12; -#X floatatom 47 39 5 0 0; -#X floatatom 47 276 5 0 0; -#X floatatom 122 191 5 0 0; -#X obj 47 219 average 10; -#X text 177 191 number of items to average; -#X text 139 220 creation argument = number of items; -#X floatatom 122 254 5 0 0; -#X text 105 277 average of last N items; -#X text 125 11 average :: calculates the average of the; -#X text 214 30 last N items (floats); -#X text 176 255 tendency (up = 1 \, down = -1); -#X msg 100 60 reset; -#X text 152 61 forget everything; -#X msg 129 94 linear; -#X msg 147 118 geometric; -#X text 191 93 linear average (dafault); -#X text 230 119 geometric average; -#X msg 158 146 weight; -#X text 217 147 weighted average (giving last; -#X text 218 163 items higher weight); -#X connect 0 0 3 0; -#X connect 2 0 3 1; -#X connect 3 0 1 0; -#X connect 3 1 6 0; -#X connect 11 0 3 0; -#X connect 13 0 3 0; -#X connect 14 0 3 0; -#X connect 17 0 3 0; diff --git a/help/beat-help.pd b/help/beat-help.pd deleted file mode 100644 index 55f85ef..0000000 --- a/help/beat-help.pd +++ /dev/null @@ -1,66 +0,0 @@ -#N canvas 294 98 628 562 12; -#X floatatom 20 503 8 0 0; -#X obj 20 66 notein; -#X obj 183 376 makenote 100 250; -#X floatatom 41 477 5 0 0; -#X text 43 13 beat :: beat tracker; -#X text 97 505 beats per minute; -#X msg 71 224 reset; -#X obj 183 219 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 -1; -#X msg 183 346 60; -#X msg 53 108 print; -#X obj 63 446 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -258699 --1; -#X text 93 447 'on beat'; -#X text 96 479 milliseconds; -#X msg 303 336 400; -#X obj 319 299 + 0; -#X text 411 245 <-- adding some jitter; -#X obj 183 271 random 4; -#X obj 183 298 select 0 1 2 3; -#X text 211 218 <-- click here to play random rhythm; -#X obj 338 243 random 3; -#X obj 338 270 - 1; -#X obj 20 414 beat 4; -#X text 88 415 creation: beat ; -#X text 349 456 certain percentage in which; -#X text 350 472 the beats have to lie; -#X msg 262 337 200; -#X msg 222 336 100; -#X obj 183 245 metro 100; -#X text 106 108 print internal data (toggle on/off); -#X text 106 136 prints out: time between current and last event \, -the five best-fitting theories (with likelyhood in brackets) \, the -time of arrival of current event (R) and the expected time of arrival -(E) of the next event; -#X text 213 439 band percentage: creates a critical time band of a -; -#X connect 1 0 21 0; -#X connect 1 1 21 1; -#X connect 2 0 21 0; -#X connect 2 1 21 1; -#X connect 6 0 21 0; -#X connect 7 0 27 0; -#X connect 8 0 2 0; -#X connect 9 0 21 0; -#X connect 13 0 14 0; -#X connect 14 0 27 1; -#X connect 16 0 17 0; -#X connect 17 0 8 0; -#X connect 17 0 26 0; -#X connect 17 1 8 0; -#X connect 17 1 25 0; -#X connect 17 2 13 0; -#X connect 17 2 8 0; -#X connect 17 3 8 0; -#X connect 17 3 13 0; -#X connect 19 0 20 0; -#X connect 20 0 14 1; -#X connect 21 0 0 0; -#X connect 21 1 3 0; -#X connect 21 2 10 0; -#X connect 25 0 14 0; -#X connect 26 0 14 0; -#X connect 27 0 16 0; -#X connect 27 0 19 0; diff --git a/help/beta-help.pd b/help/beta-help.pd deleted file mode 100644 index f4b9edf..0000000 --- a/help/beta-help.pd +++ /dev/null @@ -1,14 +0,0 @@ -#N canvas 438 222 487 308 12; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X floatatom 139 94 5 0 0; -#X obj 70 140 beta 0.78 1.3; -#X text 192 95 a; -#X floatatom 209 116 5 0 0; -#X text 262 117 b; -#X text 39 21 beta :: beta distributed random numbers; -#X connect 0 0 3 0; -#X connect 2 0 3 1; -#X connect 3 0 1 0; -#X connect 5 0 3 2; diff --git a/help/bilex-help.pd b/help/bilex-help.pd deleted file mode 100644 index 4e9961f..0000000 --- a/help/bilex-help.pd +++ /dev/null @@ -1,12 +0,0 @@ -#N canvas 370 195 485 306 12; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X floatatom 177 103 5 0 0; -#X text 230 105 lambda; -#X text 13 20 bilex :: bilinear exponetionally distributed random -numbers; -#X obj 70 140 bilex 1.5; -#X connect 0 0 5 0; -#X connect 2 0 5 1; -#X connect 5 0 1 0; diff --git a/help/borax-help.pd b/help/borax-help.pd deleted file mode 100644 index a286a60..0000000 --- a/help/borax-help.pd +++ /dev/null @@ -1,86 +0,0 @@ -#N canvas 281 85 645 549 12; -#X obj 125 230 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 125 298 6 0 0; -#X floatatom 50 451 5 0 0; -#X floatatom 26 502 5 0 0; -#X floatatom 63 425 5 0 0; -#X floatatom 38 476 5 0 0; -#X floatatom 100 349 6 0 0; -#X floatatom 75 399 5 0 0; -#X floatatom 112 323 5 0 0; -#X floatatom 87 374 5 0 0; -#X obj 26 269 borax 0 0 0 0; -#X text 103 452 number of voices currently playing; -#X text 120 422 pitch; -#X text 127 399 velocity; -#X obj 15 54 makenote 100 1500; -#X obj 336 67 metro 100; -#X obj 428 124 + 50; -#X obj 428 147 s time; -#X obj 403 43 r time; -#X obj 260 147 s pitch; -#X obj 15 17 r pitch; -#X obj 80 18 r velo; -#X msg 336 14 1; -#X msg 345 37 0; -#X obj 513 101 random 64; -#X obj 513 124 + 64; -#X obj 513 147 s velo; -#X obj 146 19 r duration; -#X obj 336 147 s duration; -#X obj 336 124 + 250; -#X text 91 477 voice allocation number - each note playing is assigned -a no; -#X obj 45 88 noteout 1; -#X obj 428 101 random 500; -#X obj 260 101 random 88; -#X obj 260 124 + 21; -#X text 120 200 borax :: analyse incoming midi notes; -#X text 363 13 <-- click to play random music; -#X obj 40 125 notein 1; -#X text 186 300 delta time value - time between note-ons; -#X text 160 350 duration value - time between note-on and note-off -; -#X text 79 502 note-on count; -#X text 141 374 duration count; -#X text 164 326 delta time count; -#X obj 336 101 random 1000; -#X text 153 228 <-- reset :: sets counters and clocks to zero and sends -; -#X text 258 243 note-off for all notes currently playing; -#X text 137 273 <--- zeroes only added to make the object larger; -#X connect 0 0 10 2; -#X connect 10 0 3 0; -#X connect 10 1 5 0; -#X connect 10 2 2 0; -#X connect 10 3 4 0; -#X connect 10 4 7 0; -#X connect 10 5 9 0; -#X connect 10 6 6 0; -#X connect 10 7 8 0; -#X connect 10 8 1 0; -#X connect 14 0 10 0; -#X connect 14 0 31 0; -#X connect 14 1 10 1; -#X connect 14 1 31 1; -#X connect 15 0 24 0; -#X connect 15 0 32 0; -#X connect 15 0 33 0; -#X connect 15 0 43 0; -#X connect 16 0 17 0; -#X connect 18 0 15 1; -#X connect 20 0 14 0; -#X connect 21 0 14 1; -#X connect 22 0 15 0; -#X connect 23 0 15 0; -#X connect 24 0 25 0; -#X connect 25 0 26 0; -#X connect 27 0 14 2; -#X connect 29 0 28 0; -#X connect 32 0 16 0; -#X connect 33 0 34 0; -#X connect 34 0 19 0; -#X connect 37 0 10 0; -#X connect 37 1 10 1; -#X connect 43 0 29 0; diff --git a/help/cauchy-help.pd b/help/cauchy-help.pd deleted file mode 100644 index a7dd6f2..0000000 --- a/help/cauchy-help.pd +++ /dev/null @@ -1,11 +0,0 @@ -#N canvas 438 222 487 308 12; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X floatatom 185 103 5 0 0; -#X obj 70 140 cauchy 0.5; -#X text 238 104 alpha - governs spread; -#X text 39 21 cauchy :: Cauchy distributed random numbers; -#X connect 0 0 3 0; -#X connect 2 0 3 1; -#X connect 3 0 1 0; diff --git a/help/chord-help.pd b/help/chord-help.pd deleted file mode 100644 index a509840..0000000 --- a/help/chord-help.pd +++ /dev/null @@ -1,37 +0,0 @@ -#N canvas 291 216 458 308 12; -#X floatatom 15 276 5 0 0; -#X symbolatom 44 212 48 0 0; -#X floatatom 74 149 5 0 0; -#X floatatom 131 149 5 0 0; -#X floatatom 189 149 5 0 0; -#X floatatom 248 149 5 0 0; -#X floatatom 59 182 5 0 0; -#X text 71 276 MIDI note number of bass note; -#X text 116 175 root position (0) \, 1st inversion (1); -#X text 115 188 or 2nd inversion (2); -#X floatatom 29 249 5 0 0; -#X text 84 251 class of bass note; -#X text 231 118 list of chord notes; -#X obj 15 51 notein; -#X obj 15 86 chord 59; -#X text 90 86 <-- notes higher than 59 get ignored; -#X text 15 9 chord :: tries to detect chords; -#X text 89 232 notes in chord : chord name; -#X text 89 26 written by Olaf Matthes ; -#X text 89 44 based on code by Rober Rowe; -#X obj 74 118 unpack f f f f f f; -#X floatatom 303 149 5 0 0; -#X floatatom 362 149 5 0 0; -#X connect 13 0 14 0; -#X connect 13 1 14 1; -#X connect 14 0 0 0; -#X connect 14 1 10 0; -#X connect 14 2 1 0; -#X connect 14 3 6 0; -#X connect 14 4 20 0; -#X connect 20 0 2 0; -#X connect 20 1 3 0; -#X connect 20 2 4 0; -#X connect 20 3 5 0; -#X connect 20 4 21 0; -#X connect 20 5 22 0; diff --git a/help/delta-help.pd b/help/delta-help.pd deleted file mode 100644 index fa865e3..0000000 --- a/help/delta-help.pd +++ /dev/null @@ -1,20 +0,0 @@ -#N canvas 328 264 466 318 12; -#X floatatom 54 217 5 0 0; -#X floatatom 54 108 5 0 0; -#X msg 23 83 bang; -#X text 69 82 calculate and output result now; -#X obj 54 172 delta; -#X obj 54 133 * 3; -#X floatatom 127 218 5 0 0; -#X floatatom 127 109 5 0 0; -#X obj 127 134 * 3; -#X obj 127 173 delta 2; -#X text 53 259 use creation arguments to set order (1st or 2nd); -#X text 39 20 delta :: calculate 1st or 2nd order difference; -#X connect 1 0 5 0; -#X connect 2 0 4 0; -#X connect 4 0 0 0; -#X connect 5 0 4 0; -#X connect 7 0 8 0; -#X connect 8 0 9 0; -#X connect 9 0 6 0; diff --git a/help/deny-help.pd b/help/deny-help.pd deleted file mode 100644 index 9ca4a29..0000000 --- a/help/deny-help.pd +++ /dev/null @@ -1,20 +0,0 @@ -#N canvas 358 305 556 310 12; -#X text 97 34 written by Olaf Matthes ; -#X msg 125 65 cat; -#X msg 147 97 dog; -#X msg 157 126 bird; -#X floatatom 82 269 5 0 0 0 - - -; -#X symbolatom 151 246 10 0 0 0 - - -; -#X obj 114 156 symbol \$1; -#X floatatom 40 81 5 0 0 0 - - -; -#X obj 82 217 route float symbol; -#X obj 82 189 deny 17 cat dog 23; -#X text 32 18 deny :: blocks 'denyed' floats or symbols; -#X connect 1 0 6 0; -#X connect 2 0 6 0; -#X connect 3 0 6 0; -#X connect 6 0 9 0; -#X connect 7 0 9 0; -#X connect 8 0 4 0; -#X connect 8 1 5 0; -#X connect 9 0 8 0; diff --git a/help/dist-help.pd b/help/dist-help.pd deleted file mode 100644 index 608283f..0000000 --- a/help/dist-help.pd +++ /dev/null @@ -1,36 +0,0 @@ -#N canvas 450 84 473 453 12; -#X text 33 10 dist :: send data to a list of receive objects; -#X obj 34 364 dist; -#X msg 85 127 connect bla; -#X msg 103 154 connect foo; -#X msg 131 209 disconnect bla; -#X msg 145 237 disconnect foo; -#X msg 158 295 clear; -#X obj 200 374 receive bla; -#X obj 306 374 receive foo; -#X obj 200 400 print bla; -#X obj 306 400 print foo; -#X floatatom 34 69 5 0 0; -#X msg 170 328 print; -#X msg 56 98 send anything 1 2 dog; -#X obj 34 397 d bla foo; -#X msg 122 180 connect dog cat; -#X msg 159 265 disconnect cat dog; -#X text 210 295 empty receiver list; -#X text 218 328 print list of receive names; -#X text 190 126 add 'bla' to list of receivers; -#X text 253 209 remove 'bla' from list; -#X text 238 99 send anything you want; -#X text 97 28 written by Olaf Matthes ; -#X connect 2 0 1 0; -#X connect 3 0 1 0; -#X connect 4 0 1 0; -#X connect 5 0 1 0; -#X connect 6 0 1 0; -#X connect 7 0 9 0; -#X connect 8 0 10 0; -#X connect 11 0 1 0; -#X connect 12 0 1 0; -#X connect 13 0 1 0; -#X connect 15 0 1 0; -#X connect 16 0 1 0; diff --git a/help/divide-help.pd b/help/divide-help.pd deleted file mode 100644 index a0aea04..0000000 --- a/help/divide-help.pd +++ /dev/null @@ -1,18 +0,0 @@ -#N canvas 328 264 466 318 12; -#X floatatom 54 217 5 0 0; -#X floatatom 54 132 5 0 0; -#X floatatom 108 132 5 0 0; -#X text 39 20 divide :: like '/' but calculates result; -#X text 133 204 use creation arguments to set initial; -#X text 133 220 values for inlets; -#X msg 7 104 bang; -#X text 53 103 calculate and output result now; -#X obj 54 172 divide 8 6 4; -#X text 118 58 allows for up to 32 inlets; -#X floatatom 164 132 5 0 0; -#X text 120 38 when leftmost or second inlet is changed; -#X connect 1 0 8 0; -#X connect 2 0 8 1; -#X connect 6 0 8 0; -#X connect 8 0 0 0; -#X connect 10 0 8 2; diff --git a/help/divmod-help.pd b/help/divmod-help.pd deleted file mode 100644 index 5e0018b..0000000 --- a/help/divmod-help.pd +++ /dev/null @@ -1,20 +0,0 @@ -#N canvas 328 264 464 316 12; -#X floatatom 54 239 5 0 0; -#X floatatom 54 127 5 0 0; -#X floatatom 129 127 5 0 0; -#X obj 54 172 divmod 8 6; -#X text 146 170 use creation arguments to set initial; -#X text 146 186 values for inlets; -#X msg 23 83 bang; -#X text 69 82 calculate and output result now; -#X floatatom 129 219 5 0 0; -#X text 182 222 modulo; -#X text 106 242 result of division; -#X text 186 127 takes int's only!; -#X text 12 19 divmod :: calculate division and modulo; -#X text 92 35 outputs results even when right inlet changes; -#X connect 1 0 3 0; -#X connect 2 0 3 1; -#X connect 3 0 0 0; -#X connect 3 1 8 0; -#X connect 6 0 3 0; diff --git a/help/edge-help.pd b/help/edge-help.pd deleted file mode 100644 index ce85dfb..0000000 --- a/help/edge-help.pd +++ /dev/null @@ -1,17 +0,0 @@ -#N canvas 258 208 452 302 12; -#X obj 100 154 edge; -#X obj 100 215 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 127 186 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X text 156 186 falling edge detected; -#X text 128 216 rising edge detected; -#X text 31 16 edge :: detect rising or falling edge in floats; -#X floatatom 126 111 5 0 0; -#X obj 100 79 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 -; -#X text 94 35 written by ; -#X connect 0 0 1 0; -#X connect 0 1 2 0; -#X connect 6 0 0 0; -#X connect 7 0 0 0; diff --git a/help/examplescore.txt b/help/examplescore.txt deleted file mode 100644 index 27002f1..0000000 --- a/help/examplescore.txt +++ /dev/null @@ -1,25 +0,0 @@ -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -71 -70 -69 -68 -67 -66 -65 -64 -63 -62 -61 -60 \ No newline at end of file diff --git a/help/expo-help.pd b/help/expo-help.pd deleted file mode 100644 index 922cf4c..0000000 --- a/help/expo-help.pd +++ /dev/null @@ -1,12 +0,0 @@ -#N canvas 370 195 454 304 12; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X text 13 20 expo :: exponetionally distributed random numbers -; -#X obj 70 140 expo 0.5; -#X floatatom 169 101 5 0 0; -#X text 222 103 lambda; -#X connect 0 0 3 0; -#X connect 3 0 1 0; -#X connect 4 0 3 1; diff --git a/help/fifo-help.pd b/help/fifo-help.pd deleted file mode 100644 index 581a7b7..0000000 --- a/help/fifo-help.pd +++ /dev/null @@ -1,13 +0,0 @@ -#N canvas 356 196 452 302 12; -#X obj 38 176 fifo 10; -#X floatatom 38 231 5 0 0; -#X floatatom 61 132 5 0 0; -#X msg 38 98 bang; -#X text 83 98 hit to get next number; -#X text 111 176 fifo ; -#X text 92 233 output of fifo; -#X text 42 14 fifo :: first in first out buffer for floats; -#X text 105 32 written for Max by St. Rainstick; -#X connect 0 0 1 0; -#X connect 2 0 0 0; -#X connect 3 0 0 0; diff --git a/help/gauss-help.pd b/help/gauss-help.pd deleted file mode 100644 index c4dce4b..0000000 --- a/help/gauss-help.pd +++ /dev/null @@ -1,14 +0,0 @@ -#N canvas 438 222 487 308 12; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X floatatom 123 91 5 0 0; -#X obj 70 140 gauss 1 0; -#X floatatom 177 113 5 0 0; -#X text 39 21 gauss :: Gauss distributed random numbers; -#X text 176 92 sigma - standard deviation; -#X text 230 114 mu - mean; -#X connect 0 0 3 0; -#X connect 2 0 3 1; -#X connect 3 0 1 0; -#X connect 4 0 3 2; diff --git a/help/gestalt-help.pd b/help/gestalt-help.pd deleted file mode 100644 index acf09cc..0000000 --- a/help/gestalt-help.pd +++ /dev/null @@ -1,51 +0,0 @@ -#N canvas 323 155 599 396 12; -#X text 137 8 gestalt :: gestalt detection for monophonic melodies -; -#X floatatom 58 332 5 0 0; -#X obj 58 176 makenote 100 100; -#X obj 58 53 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 -; -#X obj 58 76 metro 100; -#X obj 58 100 random 24; -#X obj 58 124 + 60; -#X obj 58 278 gestalt 100; -#X obj 142 100 random 24; -#X obj 142 124 select 0; -#X msg 201 146 100; -#X msg 142 146 400; -#X floatatom 68 154 5 0 0; -#X text 160 282 CREATION ARGUMENT: reference time; -#X obj 219 220 beat; -#X floatatom 232 245 5 0 0; -#X text 87 54 click to play random melody; -#X text 112 350 one could use 'tilt' to detect abrupt changes that -; -#X text 112 367 indicate the start of a new segment; -#X text 111 332 the higher the output the more the gestalt changes -\;; -#X text 161 298 i.e. time in ms expected to be the duration of the -; -#X text 161 314 shortest note (also setable via rightmost inlet); -#X text 281 200 use 'beat' (maxlib) to get the real; -#X text 281 217 reference time from input \, especially; -#X text 282 234 when using; -#X obj 372 235 notein; -#X text 225 26 written by ; -#X connect 2 0 7 0; -#X connect 2 0 14 0; -#X connect 2 1 7 1; -#X connect 2 1 14 1; -#X connect 3 0 4 0; -#X connect 4 0 5 0; -#X connect 4 0 8 0; -#X connect 5 0 6 0; -#X connect 6 0 2 0; -#X connect 6 0 12 0; -#X connect 7 0 1 0; -#X connect 8 0 9 0; -#X connect 9 0 11 0; -#X connect 9 1 10 0; -#X connect 10 0 2 2; -#X connect 11 0 2 2; -#X connect 14 1 15 0; -#X connect 14 1 7 2; diff --git a/help/history-help.pd b/help/history-help.pd deleted file mode 100644 index acd1bc8..0000000 --- a/help/history-help.pd +++ /dev/null @@ -1,30 +0,0 @@ -#N canvas 445 253 480 330 12; -#X floatatom 32 49 5 0 0; -#X floatatom 32 286 5 0 0; -#X floatatom 115 201 5 0 0; -#X floatatom 115 264 5 0 0; -#X text 169 265 tendency (up = 1 \, down = -1); -#X msg 85 70 reset; -#X text 137 71 forget everything; -#X msg 114 104 linear; -#X msg 132 128 geometric; -#X text 176 103 linear average (dafault); -#X text 215 129 geometric average; -#X msg 143 156 weight; -#X text 203 173 items higher weight); -#X text 124 6 history :: calculates the average of the; -#X text 212 23 items (floats) that came in; -#X obj 32 229 history 250; -#X text 202 157 weighted average (giving newer; -#X text 130 229 creation argument = ms to look back; -#X text 171 201 milliseconds to look back; -#X text 214 40 within the last N milliseconds; -#X text 90 287 average over last N milliseconds; -#X connect 0 0 15 0; -#X connect 2 0 15 1; -#X connect 5 0 15 0; -#X connect 7 0 15 0; -#X connect 8 0 15 0; -#X connect 11 0 15 0; -#X connect 15 0 1 0; -#X connect 15 1 3 0; diff --git a/help/ignore-help.pd b/help/ignore-help.pd deleted file mode 100644 index fc6314a..0000000 --- a/help/ignore-help.pd +++ /dev/null @@ -1,15 +0,0 @@ -#N canvas 445 253 464 314 12; -#X floatatom 47 107 5 0 0; -#X floatatom 47 225 5 0 0; -#X text 122 197 creation argument = time in ms; -#X floatatom 122 136 5 0 0; -#X obj 47 167 ignore 500; -#X text 177 136 time in ms a value has to; -#X text 178 152 be present in order to get through; -#X text 75 24 ignore :: lets information through; -#X text 154 41 only when it was presente; -#X text 155 59 at input longer than N ms; -#X text 73 258 note: input gets delayed by N milliseconds; -#X connect 0 0 4 0; -#X connect 3 0 4 1; -#X connect 4 0 1 0; diff --git a/help/iso-help.pd b/help/iso-help.pd deleted file mode 100644 index 79559ab..0000000 --- a/help/iso-help.pd +++ /dev/null @@ -1,54 +0,0 @@ -#N canvas 438 64 464 535 12; -#X obj 16 407 iso; -#X floatatom 16 434 5 0 0; -#X floatatom 69 434 10 0 0; -#X msg 72 156 bang; -#X msg 96 207 stop; -#X msg 106 233 pause; -#X msg 117 259 resume; -#X msg 128 285 loop; -#X msg 139 311 unloop; -#X text 214 100 list of pitches; -#X text 273 129 list of attacks [ms]; -#X text 170 284 turn loopin back on; -#X text 198 309 turn looping off; -#X obj 16 460 makenote 0 100; -#X obj 16 487 noteout; -#X text 112 156 start from beginning; -#X text 149 183 start at item specyfied; -#X text 281 145 (inter-note onsets); -#X text 88 45 ported to Pd by Olaf Matthes; -#X text 216 337 global time multiplier; -#X text 163 435 duration in ms; -#X msg 152 337 hook 2; -#X msg 161 368 duty 1.5; -#X text 234 369 duration multiplier; -#X obj 16 69 loadbang; -#X msg 82 182 start 4; -#X text 251 350 (speed adjustment); -#X text 237 389 duty < 1 - staccato; -#X text 237 404 duty > 1 - legato; -#X text 169 198 (item count starts with 0); -#X text 88 26 written for Max by Charlie Baker; -#X text 31 6 iso :: queues up lists of pitches and attack points; -#X msg 16 100 60 61 62 66 67 68 69 70; -#X msg 35 128 240 10 500 375 15 15 375 500; -#X connect 0 0 1 0; -#X connect 0 1 2 0; -#X connect 1 0 13 0; -#X connect 2 0 13 1; -#X connect 3 0 0 0; -#X connect 4 0 0 0; -#X connect 5 0 0 0; -#X connect 6 0 0 0; -#X connect 7 0 0 0; -#X connect 8 0 0 0; -#X connect 13 0 14 0; -#X connect 13 1 14 1; -#X connect 21 0 0 0; -#X connect 22 0 0 0; -#X connect 24 0 32 0; -#X connect 24 0 33 0; -#X connect 25 0 0 0; -#X connect 32 0 0 0; -#X connect 33 0 0 1; diff --git a/help/lifo-help.pd b/help/lifo-help.pd deleted file mode 100644 index c5ec758..0000000 --- a/help/lifo-help.pd +++ /dev/null @@ -1,16 +0,0 @@ -#N canvas 356 196 454 304 12; -#X obj 38 176 lifo 10; -#X floatatom 38 231 5 0 0; -#X floatatom 61 110 5 0 0; -#X msg 38 76 bang; -#X text 83 76 hit to get next number; -#X text 111 176 lifo ; -#X text 42 14 lifo :: last in first out buffer for floats; -#X text 108 33 written for Max by St. Rainstick; -#X msg 76 140 clear; -#X text 127 139 clear buffer; -#X text 92 233 output of buffer; -#X connect 0 0 1 0; -#X connect 2 0 0 0; -#X connect 3 0 0 0; -#X connect 8 0 0 0; diff --git a/help/limit-help.pd b/help/limit-help.pd deleted file mode 100644 index 4ee74da..0000000 --- a/help/limit-help.pd +++ /dev/null @@ -1,25 +0,0 @@ -#N canvas 328 32 558 365 12; -#X floatatom 27 277 8 0 0; -#X floatatom 27 73 5 0 0; -#X text 215 46 written by ; -#X floatatom 54 131 5 0 0; -#X floatatom 82 152 5 0 0; -#X floatatom 110 173 5 0 0; -#X text 84 71 input value; -#X text 57 104 creation arguments can be changed dynamically:; -#X obj 27 249 limit 0 9 5; -#X text 35 316 creation arguments:; -#X text 170 172 0 = limit \, others: compression ratio; -#X text 35 340 limit ; -#X text 324 195 values between 0 and 1; -#X text 325 213 result in expansion !; -#X text 106 278 limited / compressed output value; -#X text 141 11 limit :: limits input to lie between boundaries; -#X text 213 27 allows for compression / expansion; -#X text 114 129 lower boundary; -#X text 144 151 upper boundary; -#X connect 1 0 8 0; -#X connect 3 0 8 1; -#X connect 4 0 8 2; -#X connect 5 0 8 3; -#X connect 8 0 0 0; diff --git a/help/linear-help.pd b/help/linear-help.pd deleted file mode 100644 index adcf043..0000000 --- a/help/linear-help.pd +++ /dev/null @@ -1,8 +0,0 @@ -#N canvas 206 71 452 302 12; -#X obj 70 140 linear; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X text 23 20 linear :: linearly distributed random numbers; -#X connect 0 0 2 0; -#X connect 1 0 0 0; diff --git a/help/listfifo-help.pd b/help/listfifo-help.pd deleted file mode 100644 index a40a609..0000000 --- a/help/listfifo-help.pd +++ /dev/null @@ -1,26 +0,0 @@ -#N canvas 476 153 456 307 12; -#X floatatom 104 231 5 0 0 0 - - -; -#X msg 38 46 bang; -#X text 146 152 fifo ; -#X obj 38 152 listfifo 10; -#X text 42 14 listfifo :: first in first out buffer for lists; -#X obj 104 187 unpack f f; -#X floatatom 179 230 5 0 0 0 - - -; -#X obj 38 263 print listfifo_output; -#X text 204 185 output of listfifo; -#X msg 66 76 17.3 23; -#X obj 166 101 pack f f; -#X floatatom 166 70 5 0 0 0 - - -; -#X floatatom 225 70 5 0 0 0 - - -; -#X msg 84 125 \$1 \$2; -#X text 83 46 hit to get next number out of the fifo; -#X connect 1 0 3 0; -#X connect 3 0 5 0; -#X connect 3 0 7 0; -#X connect 5 0 0 0; -#X connect 5 1 6 0; -#X connect 9 0 3 0; -#X connect 10 0 13 0; -#X connect 11 0 10 0; -#X connect 12 0 10 1; -#X connect 13 0 3 0; diff --git a/help/listfunnel-help.pd b/help/listfunnel-help.pd deleted file mode 100644 index 2d309a8..0000000 --- a/help/listfunnel-help.pd +++ /dev/null @@ -1,21 +0,0 @@ -#N canvas 280 185 452 302 12; -#X obj 47 160 listfunnel; -#X floatatom 47 89 5 0 0; -#X obj 47 219 unpack f f; -#X floatatom 47 244 5 0 0; -#X floatatom 122 246 5 0 0; -#X obj 61 194 print listfunnel; -#X msg 73 114 17.3 23 147 11; -#X text 37 23 listfunnel :: send values out as a list with; -#X text 149 38 source index; -#X text 149 55 based on code found on the web; -#X msg 210 113 99 \$1 12; -#X floatatom 210 86 5 0 0; -#X connect 0 0 2 0; -#X connect 0 0 5 0; -#X connect 1 0 0 0; -#X connect 2 0 3 0; -#X connect 2 1 4 0; -#X connect 6 0 0 0; -#X connect 10 0 0 0; -#X connect 11 0 10 0; diff --git a/help/match-help.pd b/help/match-help.pd deleted file mode 100644 index 8d2fbd7..0000000 --- a/help/match-help.pd +++ /dev/null @@ -1,68 +0,0 @@ -#N canvas 90 142 874 407 12; -#X obj 50 350 bng 24 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X msg 148 212 reset; -#X obj 50 95 random 5; -#X msg 50 5 0; -#X msg 65 32 1; -#X obj 50 65 metro 100; -#X text 203 212 reset internal data storage; -#X text 182 26 input values matches the creation; -#X text 183 42 arguments; -#X text 185 82 this can be changed in the sources !; -#X text 83 351 <-- 'bang' when input matches arguments; -#X obj 62 122 hdl 20 1 0 5 empty empty empty 0 -6 0 8 -262144 -1 -1 -0; -#X floatatom 50 154 5 0 0; -#X text 228 229 -> forget all old values; -#X obj 50 243 match 3 4; -#X floatatom 81 325 5 0 0; -#X floatatom 156 324 5 0 0; -#X obj 81 294 unpack f f; -#X text 111 11 match :: outputs a list when a list of; -#X msg 93 178 1 3 4 7; -#X msg 160 178 1 2 4 5; -#X text 230 179 send a list of floats; -#X symbolatom 688 312 10 0 0; -#X symbolatom 616 336 10 0 0; -#X symbolatom 581 356 10 0 0; -#X obj 540 349 bng 24 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 540 244 match dog bytes 2 cats; -#X msg 553 186 dog bytes 2 cats; -#X msg 564 214 cat bytes 2 dogs; -#X text 384 114 same works for symbols and mixtures of floats and symbols: -; -#X obj 581 285 unpack s s f s; -#X floatatom 635 313 5 0 0; -#X text 89 271 sends out the list when a match is found; -#X msg 459 151 dog; -#X msg 494 143 cats; -#X msg 519 170 2; -#X msg 471 195 bytes; -#X text 183 68 a maximum of 16 arguments is allowed; -#X connect 1 0 14 0; -#X connect 2 0 12 0; -#X connect 3 0 5 0; -#X connect 4 0 5 0; -#X connect 5 0 2 0; -#X connect 11 0 12 0; -#X connect 12 0 14 0; -#X connect 14 0 0 0; -#X connect 14 0 17 0; -#X connect 17 0 15 0; -#X connect 17 1 16 0; -#X connect 19 0 14 0; -#X connect 20 0 14 0; -#X connect 26 0 25 0; -#X connect 26 0 30 0; -#X connect 27 0 26 0; -#X connect 28 0 26 0; -#X connect 30 0 24 0; -#X connect 30 1 23 0; -#X connect 30 2 31 0; -#X connect 30 3 22 0; -#X connect 33 0 26 0; -#X connect 34 0 26 0; -#X connect 35 0 26 0; -#X connect 36 0 26 0; diff --git a/help/maxlib-help.pd b/help/maxlib-help.pd deleted file mode 100644 index 4beb23d..0000000 --- a/help/maxlib-help.pd +++ /dev/null @@ -1,123 +0,0 @@ -#N canvas 75 -12 1161 819 10; -#X obj 307 260 average; -#X obj 18 150 beat; -#X obj 18 175 borax; -#X obj 18 125 chord; -#X obj 14 588 dist; -#X obj 307 155 divide; -#X obj 307 129 divmod; -#X obj 656 148 fifo; -#X obj 307 286 history; -#X obj 403 577 ignore; -#X obj 403 552 iso; -#X obj 655 122 lifo; -#X obj 307 312 match; -#X obj 307 180 minus; -#X obj 660 343 mlife; -#X obj 307 207 multi; -#X obj 14 613 netdist; -#X obj 18 251 pitch; -#X obj 307 234 plus; -#X obj 403 499 pulse; -#X obj 14 637 remote; -#X obj 18 200 rhythm; -#X obj 18 225 score array01; -#X obj 403 525 speedlim; -#X obj 403 603 step; -#X obj 660 318 subst; -#X text 140 44 written by Olaf Matthes ; -#X text 71 125 chord detection; -#X text 68 150 beat tracking; -#X text 77 201 beat detection; -#X text 72 176 music analysis; -#X text 135 225 score following; -#X text 72 251 pitch information; -#X text 19 94 MUSIC / MIDI ANALYSIS; -#X text 310 91 MATH; -#X text 374 130 calculate / and %; -#X text 372 155 / for several inputs; -#X text 366 235 + for several inputs; -#X text 366 207 * for several inputs; -#X text 370 181 - for several inputs; -#X text 378 259 average of last N values; -#X text 379 285 average over last N seconds; -#X text 362 312 match input to list of numbers; -#X text 403 473 TIME; -#X text 480 526 lets input through every N milliseconds; -#X text 442 553 play sequence of MIDI notes; -#X text 464 578 ignore too fast changing input; -#X text 62 587 send to list of receive objects; -#X text 83 611 same for netreceive; -#X text 73 636 send to one receive object; -#X text 654 95 BUFFER; -#X text 450 605 a line object that steps; -#X text 659 294 OTHER / EXPERIMENTAL; -#X text 717 317 self-similar substitution; -#X text 716 343 cellular automaton; -#X obj 307 338 scale; -#X text 458 499 a 'better' metro; -#X obj 403 629 history; -#X obj 403 655 velocity; -#X text 472 629 average over last N milliseconds; -#X text 479 655 velocity of input in digits per second; -#X obj 14 661 netrec; -#X text 73 662 netreceive with extra info about sender; -#X obj 307 364 delta; -#X text 139 61 download at http://www.akustische-kunst.org/puredata/maxlib -; -#X obj 656 173 listfifo; -#X text 734 172 first in first out for lists; -#X text 703 147 first in first out for floats; -#X text 700 122 last in first out for floats; -#X obj 402 681 sync; -#X text 447 683 extended trigger object; -#X text 361 338 scale input to output range; -#X text 12 565 (REMOTE)CONTROL; -#X obj 15 686 netserver; -#X obj 15 713 netclient; -#X text 102 691 bidirectional communication; -#X text 111 706 (client / server based); -#X obj 307 392 wrap; -#X obj 307 419 rewrap; -#X text 353 392 warp a number in a range; -#X text 370 420 warp it back and forth; -#X text 361 364 calculate 1st or 2nd order diff.; -#X text 660 374 RANDOM; -#X obj 660 398 gauss; -#X obj 660 423 poisson; -#X obj 726 398 linear; -#X obj 726 423 bilex; -#X obj 796 397 expo; -#X obj 845 397 beta; -#X obj 894 398 cauchy; -#X obj 797 424 arbran array01 array02; -#X obj 18 278 gestalt; -#X obj 18 303 edge; -#X text 66 307 detect rising/falling edge; -#X text 84 278 'gestalt' of music; -#X obj 659 452 urn; -#X text 692 452 urn selection model; -#X obj 403 709 timebang; -#X text 482 709 send a bang at given time of day; -#X obj 15 390 split; -#X obj 15 439 unroute; -#X text 81 440 opposit to route; -#X text 74 392 split according to range; -#X obj 15 463 limit; -#X text 63 464 limiter for floats; -#X obj 15 415 nroute; -#X text 80 414 r. according to Nth elem.; -#X text 24 363 ROUTING / CHECKING; -#X obj 402 735 pong; -#X obj 18 330 tilt; -#X obj 402 760 temperature; -#X text 500 761 amount of input changes per time; -#X text 448 736 a bouncing ball model; -#X text 66 333 meassure tilt of input; -#X obj 16 489 listfunnel; -#X text 107 490 Max's funnel for lists; -#X text 30 26 maxlib 1.5 :: Music Analysis eXtensions LIBrary; -#X obj 656 201 arraycopy; -#X text 741 202 copy from one array to another; -#X obj 17 525 nchange s; -#X text 89 526 change that exepts any kind of input; diff --git a/help/minus-help.pd b/help/minus-help.pd deleted file mode 100644 index 64e45f3..0000000 --- a/help/minus-help.pd +++ /dev/null @@ -1,17 +0,0 @@ -#N canvas 328 264 464 316 12; -#X floatatom 54 217 5 0 0; -#X floatatom 54 127 5 0 0; -#X floatatom 107 127 5 0 0; -#X text 39 20 minus :: like '-' but calculates result; -#X text 133 204 use creation arguments to set initial; -#X text 133 220 values for inlets; -#X msg 23 83 bang; -#X text 69 82 calculate and output result now; -#X obj 54 172 minus 8 6 4; -#X floatatom 161 127 5 0 0; -#X text 120 38 when leftmost or second inlet is changed; -#X connect 1 0 8 0; -#X connect 2 0 8 1; -#X connect 6 0 8 0; -#X connect 8 0 0 0; -#X connect 9 0 8 2; diff --git a/help/mlife-help.pd b/help/mlife-help.pd deleted file mode 100644 index d12e1fc..0000000 --- a/help/mlife-help.pd +++ /dev/null @@ -1,56 +0,0 @@ -#N canvas 309 47 454 459 12; -#X floatatom 23 424 5 0 0; -#X floatatom 39 397 5 0 0; -#X floatatom 76 424 5 0 0; -#X floatatom 93 397 5 0 0; -#X floatatom 129 424 5 0 0; -#X floatatom 147 397 5 0 0; -#X floatatom 183 425 5 0 0; -#X floatatom 200 398 5 0 0; -#X msg 22 33 bang; -#X msg 69 123 randfill; -#X msg 84 150 fill 0; -#X msg 100 177 lo 2; -#X msg 108 204 hi 3; -#X msg 120 231 nset 3; -#X msg 161 312 display; -#X text 178 233 set neighbourhood; -#X text 151 205 set high; -#X text 146 176 set low; -#X text 151 150 fill cells with 0; -#X text 145 123 fill cells with random value; -#X text 226 312 display state of cells; -#X msg 35 72 1; -#X text 63 33 calculate next generation and output; -#X text 64 50 bangs on every cell that is alife; -#X text 68 72 calculate next generation and output; -#X text 68 89 1 if cell is alife \, 0 if dead; -#X text 227 329 in Pd console window; -#X text 142 355 mlife ; -#X text 189 370 ; -#X text 279 395 closed universe if; -#X text 279 409 = 1; -#X msg 134 258 randseed 4; -#X text 225 258 seed array with random no.; -#X text 225 284 seed array with a number; -#X msg 149 285 seed 1 4; -#X obj 23 356 mlife 8 1 8 0; -#X text 44 5 mlife :: a cellular automata object; -#X connect 8 0 35 0; -#X connect 9 0 35 0; -#X connect 10 0 35 0; -#X connect 11 0 35 0; -#X connect 12 0 35 0; -#X connect 13 0 35 0; -#X connect 14 0 35 0; -#X connect 21 0 35 0; -#X connect 31 0 35 0; -#X connect 34 0 35 0; -#X connect 35 0 0 0; -#X connect 35 1 1 0; -#X connect 35 2 2 0; -#X connect 35 3 3 0; -#X connect 35 4 4 0; -#X connect 35 5 5 0; -#X connect 35 6 6 0; -#X connect 35 7 7 0; diff --git a/help/multi-help.pd b/help/multi-help.pd deleted file mode 100644 index 86e6a5c..0000000 --- a/help/multi-help.pd +++ /dev/null @@ -1,17 +0,0 @@ -#N canvas 328 264 464 316 12; -#X floatatom 54 217 5 0 0; -#X floatatom 54 127 5 0 0; -#X floatatom 108 128 5 0 0; -#X text 39 20 multi :: like '*' but calculates result; -#X text 133 204 use creation arguments to set initial; -#X text 133 220 values for inlets; -#X msg 23 83 bang; -#X text 69 82 calculate and output result now; -#X obj 54 172 multi 8 6 2; -#X floatatom 163 129 5 0 0; -#X text 120 38 when leftmost or second inlet is changed; -#X connect 1 0 8 0; -#X connect 2 0 8 1; -#X connect 6 0 8 0; -#X connect 8 0 0 0; -#X connect 9 0 8 2; diff --git a/help/nchange-help.pd b/help/nchange-help.pd deleted file mode 100644 index cfcf00b..0000000 --- a/help/nchange-help.pd +++ /dev/null @@ -1,31 +0,0 @@ -#N canvas 271 238 519 310 12; -#X obj 30 213 nchange f; -#X obj 371 215 nchange l; -#X msg 367 144 bla foo dog; -#X msg 387 169 bla foo 23; -#X msg 348 121 bla foo dog 17; -#X obj 200 214 nchange s; -#X obj 200 185 symbol; -#X msg 200 126 dog; -#X msg 216 153 cat; -#X obj 162 15 change; -#X obj 371 253 print list; -#X obj 200 255 print symbol; -#X msg 30 152 0; -#X msg 43 180 1; -#X obj 30 257 print float; -#X text 100 34 written by Olaf Matthes ; -#X text 12 15 nchange :: a 'new'; -#X text 22 77 The creation argument specifies whether nchange works -for floats \, symbols or lists.; -#X connect 0 0 14 0; -#X connect 1 0 10 0; -#X connect 2 0 1 0; -#X connect 3 0 1 0; -#X connect 4 0 1 0; -#X connect 5 0 11 0; -#X connect 6 0 5 0; -#X connect 7 0 6 0; -#X connect 8 0 6 0; -#X connect 12 0 0 0; -#X connect 13 0 0 0; diff --git a/help/netclient-help.pd b/help/netclient-help.pd deleted file mode 100644 index 46e5b52..0000000 --- a/help/netclient-help.pd +++ /dev/null @@ -1,51 +0,0 @@ -#N canvas 246 114 752 474 12; -#X floatatom 49 333 5 0 0; -#X floatatom 87 298 5 0 0; -#X symbolatom 164 251 10 0 0; -#X text 102 332 received data; -#X text 140 298 number of connections; -#X msg 49 54 print; -#X floatatom 125 272 5 0 0; -#X text 183 276 socket number; -#X msg 103 179 broadcast hallo world!; -#X text 288 179 send to all clients; -#X text 143 49 written by Olaf Matthes ; -#X obj 49 223 netserver 3000; -#X text 137 120 send message to client no. 1; -#X text 256 251 client's IP address; -#X obj 477 189 netclient; -#X msg 498 116 connect localhost 3000; -#X msg 511 143 disconnect; -#X msg 477 84 send 23; -#X floatatom 544 218 5 0 0; -#X msg 83 91 send 380 17.3; -#X floatatom 477 296 5 0 0; -#X obj 600 281 print anything; -#X obj 538 309 print list; -#X obj 477 245 route float list; -#X msg 98 142 client 1 23; -#X text 204 91 "send "; -#X text 110 70 send message on specified socket; -#X text 200 143 "client "; -#X text 48 379 This example demonstrates how to set up a client/server -connection. Data sent by the client get's received and displayed by -the server imediately. Or just try it the other way round...; -#X text 38 15 netclient :: simple client that connects to netserver -or; -#X text 142 32 to pd's native netreceive object; -#X connect 5 0 11 0; -#X connect 8 0 11 0; -#X connect 11 0 0 0; -#X connect 11 1 1 0; -#X connect 11 2 6 0; -#X connect 11 3 2 0; -#X connect 14 0 23 0; -#X connect 14 1 18 0; -#X connect 15 0 14 0; -#X connect 16 0 14 0; -#X connect 17 0 14 0; -#X connect 19 0 11 0; -#X connect 23 0 20 0; -#X connect 23 1 22 0; -#X connect 23 2 21 0; -#X connect 24 0 11 0; diff --git a/help/netdist-help.pd b/help/netdist-help.pd deleted file mode 100644 index 84cd2e2..0000000 --- a/help/netdist-help.pd +++ /dev/null @@ -1,37 +0,0 @@ -#N canvas 374 142 458 370 12; -#X obj 23 299 netdist; -#X obj 275 249 netreceive 3000; -#X floatatom 275 275 5 0 0; -#X floatatom 390 275 5 0 0; -#X msg 23 64 connect localhost 3000; -#X floatatom 276 328 5 0 0; -#X floatatom 391 328 5 0 0; -#X obj 276 302 netreceive 3001; -#X msg 67 120 disconnect localhost 3000; -#X msg 42 93 connect localhost 3001; -#X msg 88 147 disconnect localhost 3001; -#X msg 102 177 print; -#X msg 113 203 clear; -#X floatatom 23 326 5 0 0; -#X msg 120 232 send 23; -#X msg 146 259 send 17.3; -#X text 151 178 print list of connections; -#X text 164 202 disconnect all; -#X text 189 232 send values; -#X text 213 64 add connection to list; -#X text 278 119 remove connection; -#X text 33 8 netdist :: distribute data to several netreceive; -#X text 122 24 written by Olaf Matthes; -#X connect 0 0 13 0; -#X connect 1 0 2 0; -#X connect 1 1 3 0; -#X connect 4 0 0 0; -#X connect 7 0 5 0; -#X connect 7 1 6 0; -#X connect 8 0 0 0; -#X connect 9 0 0 0; -#X connect 10 0 0 0; -#X connect 11 0 0 0; -#X connect 12 0 0 0; -#X connect 14 0 0 0; -#X connect 15 0 0 0; diff --git a/help/netrec-help.pd b/help/netrec-help.pd deleted file mode 100644 index 80be695..0000000 --- a/help/netrec-help.pd +++ /dev/null @@ -1,34 +0,0 @@ -#N canvas 315 121 600 364 12; -#X obj 49 189 netrec 3000; -#X obj 57 130 netsend; -#X msg 57 18 connect localhost 3000; -#X msg 78 44 disconnect localhost 3000; -#X floatatom 49 297 5 0 0; -#X floatatom 76 270 5 0 0; -#X floatatom 93 73 5 0 0; -#X msg 93 99 send \$1; -#X symbolatom 132 217 10 0 0; -#X text 224 217 IP address; -#X text 100 298 received data; -#X text 129 270 number of connections; -#X obj 295 128 netsend; -#X msg 295 16 connect localhost 3000; -#X msg 316 42 disconnect localhost 3000; -#X floatatom 331 71 5 0 0; -#X msg 331 97 send \$1; -#X msg 49 162 print; -#X floatatom 104 243 5 0 0; -#X text 162 247 socket number; -#X connect 0 0 4 0; -#X connect 0 1 5 0; -#X connect 0 2 18 0; -#X connect 0 3 8 0; -#X connect 2 0 1 0; -#X connect 3 0 1 0; -#X connect 6 0 7 0; -#X connect 7 0 1 0; -#X connect 13 0 12 0; -#X connect 14 0 12 0; -#X connect 15 0 16 0; -#X connect 16 0 12 0; -#X connect 17 0 0 0; diff --git a/help/netserver-help.pd b/help/netserver-help.pd deleted file mode 100644 index a849bd5..0000000 --- a/help/netserver-help.pd +++ /dev/null @@ -1,50 +0,0 @@ -#N canvas 246 114 752 474 12; -#X floatatom 49 333 5 0 0; -#X floatatom 87 298 5 0 0; -#X symbolatom 164 251 10 0 0; -#X text 102 332 received data; -#X text 140 298 number of connections; -#X msg 49 54 print; -#X floatatom 125 272 5 0 0; -#X text 183 276 socket number; -#X msg 103 179 broadcast hallo world!; -#X text 288 179 send to all clients; -#X text 144 33 written by Olaf Matthes ; -#X obj 49 223 netserver 3000; -#X text 137 120 send message to client no. 1; -#X text 256 251 client's IP address; -#X obj 477 189 netclient; -#X msg 498 116 connect localhost 3000; -#X msg 511 143 disconnect; -#X msg 477 84 send 23; -#X floatatom 544 218 5 0 0; -#X msg 83 91 send 380 17.3; -#X floatatom 477 296 5 0 0; -#X obj 600 281 print anything; -#X obj 538 309 print list; -#X obj 477 245 route float list; -#X msg 98 142 client 1 23; -#X text 204 91 "send "; -#X text 110 70 send message on specified socket; -#X text 200 143 "client "; -#X text 48 379 This example demonstrates how to set up a client/server -connection. Data sent by the client get's received and displayed by -the server imediately. Or just try it the other way round...; -#X text 38 15 netclient :: simple client that connects to netserver -; -#X connect 5 0 11 0; -#X connect 8 0 11 0; -#X connect 11 0 0 0; -#X connect 11 1 1 0; -#X connect 11 2 6 0; -#X connect 11 3 2 0; -#X connect 14 0 23 0; -#X connect 14 1 18 0; -#X connect 15 0 14 0; -#X connect 16 0 14 0; -#X connect 17 0 14 0; -#X connect 19 0 11 0; -#X connect 23 0 20 0; -#X connect 23 1 22 0; -#X connect 23 2 21 0; -#X connect 24 0 11 0; diff --git a/help/nroute-help.pd b/help/nroute-help.pd deleted file mode 100644 index 0831363..0000000 --- a/help/nroute-help.pd +++ /dev/null @@ -1,37 +0,0 @@ -#N canvas 252 37 630 380 12; -#X floatatom 116 199 5 0 0; -#X obj 41 290 print matched; -#X obj 116 256 print failed; -#X msg 78 151 8; -#X obj 41 226 nroute 8 2; -#X msg 41 77 0 8 15; -#X msg 56 105 17 3 45; -#X msg 116 153 3; -#X text 170 197 position to match; -#X floatatom 427 204 5 0 0; -#X obj 336 293 print matched; -#X obj 427 259 print failed; -#X obj 336 229 nroute fly 2; -#X msg 381 178 go; -#X msg 417 178 walk; -#X msg 336 80 swifts fly high; -#X msg 351 108 dogs walk slow; -#X msg 363 141 please go go; -#X text 153 152 what to match; -#X text 54 8 nroute :: route if Nth argument is matched; -#X text 135 24 written by Olaf Matthes ; -#X connect 0 0 4 2; -#X connect 3 0 4 1; -#X connect 4 0 1 0; -#X connect 4 1 2 0; -#X connect 5 0 4 0; -#X connect 6 0 4 0; -#X connect 7 0 4 1; -#X connect 9 0 12 2; -#X connect 12 0 10 0; -#X connect 12 1 11 0; -#X connect 13 0 12 1; -#X connect 14 0 12 1; -#X connect 15 0 12 0; -#X connect 16 0 12 0; -#X connect 17 0 12 0; diff --git a/help/pitch-help.pd b/help/pitch-help.pd deleted file mode 100644 index 781fd4c..0000000 --- a/help/pitch-help.pd +++ /dev/null @@ -1,30 +0,0 @@ -#N canvas 166 313 439 308 12; -#X floatatom 83 266 5 0 0; -#X obj 83 35 notein; -#X floatatom 112 217 5 0 0; -#X floatatom 127 191 5 0 0; -#X floatatom 142 166 5 0 0; -#X floatatom 24 33 5 0 0; -#X symbolatom 97 242 7 0 0; -#X text 139 267 MIDI note number; -#X text 166 217 pitch class; -#X text 181 191 interval to last note; -#X text 197 166 register; -#X text 153 33 pitch :: get info about pitch; -#X text 169 243 note name (symbol); -#X text 221 54 use creation argument to; -#X text 221 71 set assumed first note; -#X text 227 104 of the first interval ); -#X text 218 89 ( needed for calculation; -#X obj 83 94 stripnote; -#X obj 83 137 pitch 72; -#X connect 1 0 17 0; -#X connect 1 1 17 1; -#X connect 5 0 18 0; -#X connect 17 0 18 0; -#X connect 17 1 18 1; -#X connect 18 0 0 0; -#X connect 18 1 6 0; -#X connect 18 2 2 0; -#X connect 18 3 3 0; -#X connect 18 4 4 0; diff --git a/help/plus-help.pd b/help/plus-help.pd deleted file mode 100644 index 3a0e442..0000000 --- a/help/plus-help.pd +++ /dev/null @@ -1,17 +0,0 @@ -#N canvas 328 264 464 316 12; -#X floatatom 54 217 5 0 0; -#X floatatom 54 127 5 0 0; -#X floatatom 107 127 5 0 0; -#X text 133 204 use creation arguments to set initial; -#X text 133 220 values for inlets; -#X text 26 20 plus :: like '+' but calculates result; -#X msg 23 83 bang; -#X text 69 82 calculate and output result now; -#X obj 54 172 plus 8 6 2; -#X floatatom 161 127 5 0 0; -#X text 91 40 whenever leftmost or second inlet is changed; -#X connect 1 0 8 0; -#X connect 2 0 8 1; -#X connect 6 0 8 0; -#X connect 8 0 0 0; -#X connect 9 0 8 2; diff --git a/help/poisson-help.pd b/help/poisson-help.pd deleted file mode 100644 index ab6fe4b..0000000 --- a/help/poisson-help.pd +++ /dev/null @@ -1,12 +0,0 @@ -#N canvas 438 222 487 308 12; -#X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X floatatom 70 192 5 0 0; -#X floatatom 193 112 5 0 0; -#X text 39 21 poisson :: Poisson distributed random numbers; -#X obj 70 145 poisson 2.2; -#X text 246 113 lambda - value that is most; -#X text 317 132 likely to appear; -#X connect 0 0 4 0; -#X connect 2 0 4 1; -#X connect 4 0 1 0; diff --git a/help/pulse-help.pd b/help/pulse-help.pd deleted file mode 100644 index 6d1320a..0000000 --- a/help/pulse-help.pd +++ /dev/null @@ -1,35 +0,0 @@ -#N canvas 499 150 464 314 12; -#X obj 23 223 pulse 120 1 4 0; -#X floatatom 23 265 5 0 0; -#X obj 138 265 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -258699 --1; -#X msg 23 23 0; -#X msg 48 80 1; -#X floatatom 51 122 5 0 0; -#X floatatom 138 197 5 0 0; -#X floatatom 109 172 5 0 0; -#X floatatom 80 147 5 0 0; -#X msg 39 53 bang; -#X text 55 23 stop; -#X obj 313 18 metro; -#X text 80 79 start; -#X text 242 44 originally written by; -#X text 240 62 James McCartney for Max; -#X text 74 267 count; -#X text 168 18 pulse :: a better; -#X text 104 123 quarter notes per minute; -#X text 190 199 number of beats to play; -#X text 189 214 before turning off; -#X text 77 54 toggles on/off; -#X text 131 148 interval at which a bang is output; -#X text 160 174 notes to count (default = quarter); -#X text 166 264 pulse turned off automagically; -#X connect 0 0 1 0; -#X connect 0 1 2 0; -#X connect 3 0 0 0; -#X connect 4 0 0 0; -#X connect 5 0 0 1; -#X connect 6 0 0 4; -#X connect 7 0 0 3; -#X connect 8 0 0 2; -#X connect 9 0 0 0; diff --git a/help/remote-help.pd b/help/remote-help.pd deleted file mode 100644 index 6ee5b8f..0000000 --- a/help/remote-help.pd +++ /dev/null @@ -1,20 +0,0 @@ -#N canvas 472 309 567 308 12; -#X text 9 9 remote :: send data to any receive object; -#X obj 32 224 remote; -#X obj 216 222 receive bla; -#X obj 321 222 receive foo; -#X obj 216 250 print bla; -#X obj 321 250 print foo; -#X msg 32 104 bla 17.3 23; -#X msg 76 183 foo 13 \, bla 4; -#X text 148 75 use message: ; -#X text 253 91 with data of any type; -#X text 89 26 written by Olaf Matthes ; -#X msg 61 147 foo five is 2 more than 3; -#X msg 294 146 \; bla 17.3 23; -#X text 296 168 this does the same...; -#X connect 2 0 4 0; -#X connect 3 0 5 0; -#X connect 6 0 1 0; -#X connect 7 0 1 0; -#X connect 11 0 1 0; diff --git a/help/rewrap-help.pd b/help/rewrap-help.pd deleted file mode 100644 index e444c9d..0000000 --- a/help/rewrap-help.pd +++ /dev/null @@ -1,23 +0,0 @@ -#N canvas 328 32 564 467 12; -#X floatatom 27 304 8 0 0 0 - - -; -#X floatatom 27 73 5 0 0 0 - - -; -#X text 202 47 written by ; -#X floatatom 60 133 5 0 0 0 - - -; -#X floatatom 94 158 5 0 0 0 - - -; -#X text 84 71 input value; -#X text 57 102 creation arguments can be changed dynamically:; -#X text 35 341 creation arguments:; -#X text 115 132 lower limit; -#X text 146 157 upper limit; -#X floatatom 110 276 5 0 0 0 - - -; -#X text 36 358 wrap ; -#X obj 27 249 rewrap 6 40; -#X text 200 27 into a range; -#X text 169 275 wrap period; -#X text 107 305 output; -#X text 122 11 rewrap :: wraps floats back and forth; -#X connect 1 0 12 0; -#X connect 3 0 12 1; -#X connect 4 0 12 2; -#X connect 12 0 0 0; -#X connect 12 1 10 0; diff --git a/help/rhythm-help.pd b/help/rhythm-help.pd deleted file mode 100644 index bff970c..0000000 --- a/help/rhythm-help.pd +++ /dev/null @@ -1,35 +0,0 @@ -#N canvas 262 64 579 413 12; -#X obj 25 273 rhythm 0; -#X floatatom 25 356 5 0 0; -#X obj 25 59 notein; -#X obj 348 237 makenote 100 100; -#X msg 348 209 60; -#X floatatom 54 328 5 0 0; -#X text 81 360 beats per minute; -#X text 111 331 beats in milliseconds; -#X msg 79 113 reset; -#X msg 90 146 model 0; -#X msg 96 175 model 1; -#X text 158 147 Large and Kolen adaptation model; -#X text 164 174 Toiviainen adaptation model; -#X text 53 21 rhythm :: detects the beat of rhythmic patterns; -#X text 134 39 written by Olaf Matthes ; -#X text 134 56 based on code written by Rober Rowe and published; -#X text 133 72 in 'Mashine musicianship' \, Massachusetts \, 2001; -#X text 115 275 creation: rhythm ; -#X obj 84 303 bng 20 100 10 0 empty empty empty 0 -6 0 8 -262144 -42246 --1; -#X text 115 304 beat pulse; -#X text 132 114 reset all values \, forget rhythm and stop beat pulse -; -#X connect 0 0 1 0; -#X connect 0 1 5 0; -#X connect 0 2 18 0; -#X connect 2 0 0 0; -#X connect 2 1 0 1; -#X connect 3 0 0 0; -#X connect 3 1 0 1; -#X connect 4 0 3 0; -#X connect 8 0 0 0; -#X connect 9 0 0 0; -#X connect 10 0 0 0; diff --git a/help/scale-help.pd b/help/scale-help.pd deleted file mode 100644 index 816bda5..0000000 --- a/help/scale-help.pd +++ /dev/null @@ -1,31 +0,0 @@ -#N canvas 381 126 552 355 12; -#X floatatom 27 277 8 0 0; -#X floatatom 27 73 5 0 0; -#X text 213 48 written by ; -#X text 37 306 creation:; -#X text 141 11 scale :: scale input from a certain input range; -#X text 212 29 to lie between output boundaries; -#X floatatom 56 131 5 0 0; -#X floatatom 85 152 5 0 0; -#X floatatom 115 173 5 0 0; -#X floatatom 144 194 5 0 0; -#X text 84 71 input value; -#X text 106 278 scaled output value; -#X text 111 130 in low; -#X text 137 151 in high; -#X text 171 172 out low; -#X text 200 194 out high; -#X text 57 104 creation arguments can be changed dynamically:; -#X text 53 323 scale -; -#X obj 27 249 scale 0 9 100 255 0; -#X floatatom 174 220 5 0 0; -#X text 227 219 log coefficient; -#X text 265 237 0 = linear 1 = log; -#X connect 1 0 18 0; -#X connect 6 0 18 1; -#X connect 7 0 18 2; -#X connect 8 0 18 3; -#X connect 9 0 18 4; -#X connect 18 0 0 0; -#X connect 19 0 18 5; diff --git a/help/score-help.pd b/help/score-help.pd deleted file mode 100644 index a049bab..0000000 --- a/help/score-help.pd +++ /dev/null @@ -1,52 +0,0 @@ -#N canvas 246 86 629 516 12; -#X floatatom 30 301 5 0 0; -#X obj 30 12 notein; -#X obj 193 202 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X msg 95 93 start; -#X msg 104 118 stop; -#X text 217 203 reset; -#X text 145 92 start / stop score following; -#X msg 111 146 start 4; -#X text 176 146 start skipping first 4 notes; -#X obj 193 286 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -258699 --1; -#X text 217 287 error; -#X text 148 24 score :: score follower that tries to match incoming -; -#X text 221 41 MIDI data to a score stored in an array; -#X text 219 57 outputs the index number of current position; -#X obj 23 423 loadbang; -#N canvas 0 0 450 300 graph2 0; -#X array sco_array 25 float 1; -#A 0 60 61 62 63 64 65 66 67 68 69 70 71 72 71 70 69 68 67 66 65 64 -63 62 61 60; -#X coords 0 127 24 0 200 140 1; -#X restore 402 361 graph; -#X obj 30 235 score sco_array 2 300; -#X msg 130 173 set sco_array; -#X msg 23 449 \; sco_array resize 25 \; sco_array read examplescore.txt -\;; -#X text 250 174 set to array that contains the score; -#X text 88 303 position on score; -#X text 86 322 (x index of array); -#X obj 30 356 tabread sco_array; -#X floatatom 30 387 5 0 0; -#X text 86 388 note from score; -#X text 291 255 array: name of array containing score; -#X text 235 234 USAGE: score ; -#X text 292 272 skipitems: max. number of notes to skip; -#X text 292 289 skip time: max. time [ms] to rewind; -#X text 378 307 input data; -#X connect 0 0 22 0; -#X connect 1 0 16 0; -#X connect 1 1 16 1; -#X connect 2 0 16 2; -#X connect 3 0 16 0; -#X connect 4 0 16 0; -#X connect 7 0 16 0; -#X connect 14 0 18 0; -#X connect 16 0 0 0; -#X connect 16 1 9 0; -#X connect 17 0 16 0; -#X connect 22 0 23 0; diff --git a/help/speedlim-help.pd b/help/speedlim-help.pd deleted file mode 100644 index 2ef4f82..0000000 --- a/help/speedlim-help.pd +++ /dev/null @@ -1,30 +0,0 @@ -#N canvas 445 253 464 314 12; -#X floatatom 38 54 5 0 0; -#X floatatom 18 264 5 0 0; -#X obj 38 141 speedlim 500; -#X text 126 18 speedlim :: lets information through; -#X text 222 37 only every N milliseconds; -#X text 152 171 creation argument = time in ms; -#X floatatom 129 116 5 0 0; -#X text 184 116 time between outputs in ms; -#X msg 49 82 bang; -#X obj 121 207 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 121 236 timer; -#X floatatom 121 262 5 0 0; -#X text 175 262 this should never be less than; -#X text 175 280 the creation argument of speedlim; -#X obj 18 194 route f; -#X obj 47 236 print; -#X msg 95 82 this is speedlim; -#X connect 0 0 2 0; -#X connect 2 0 9 0; -#X connect 2 0 14 0; -#X connect 6 0 2 1; -#X connect 8 0 2 0; -#X connect 9 0 10 1; -#X connect 9 0 10 0; -#X connect 10 0 11 0; -#X connect 14 0 1 0; -#X connect 14 1 15 0; -#X connect 16 0 2 0; diff --git a/help/split-help.pd b/help/split-help.pd deleted file mode 100644 index c4e8d26..0000000 --- a/help/split-help.pd +++ /dev/null @@ -1,24 +0,0 @@ -#N canvas 328 32 560 463 12; -#X floatatom 27 304 8 0 0 0 - - -; -#X floatatom 27 73 5 0 0 0 - - -; -#X text 196 28 written by ; -#X floatatom 56 131 5 0 0 0 - - -; -#X floatatom 85 152 5 0 0 0 - - -; -#X text 84 71 input value; -#X text 57 104 creation arguments can be changed dynamically:; -#X text 35 341 creation arguments:; -#X obj 27 249 split 6 40; -#X text 111 130 lower limit; -#X text 137 151 upper limit; -#X text 35 378 All floats that fall below the lower limit or above -the upper limit get routed to the 2nd outlet.; -#X text 36 358 split ; -#X floatatom 102 276 5 0 0 0 - - -; -#X text 154 276 floats 'out of range'; -#X text 122 11 split :: split incoming floats according to value; -#X text 106 305 floats 'in range' (including borders!); -#X connect 1 0 8 0; -#X connect 3 0 8 1; -#X connect 4 0 8 2; -#X connect 8 0 0 0; -#X connect 8 1 13 0; diff --git a/help/step-help.pd b/help/step-help.pd deleted file mode 100644 index 9197d01..0000000 --- a/help/step-help.pd +++ /dev/null @@ -1,22 +0,0 @@ -#N canvas 417 206 533 314 12; -#X floatatom 33 229 5 0 0; -#X text 72 7 step :: output sequence of numbers (similar to 'line') -; -#X text 138 25 written by Olaf Matthes (olaf.matthes@gmx.de); -#X text 222 250 stepsize :: step between two numbers; -#X msg 33 76 23 6000 2; -#X msg 62 119 230; -#X obj 101 282 line; -#X text 98 117 send a single number to jump; -#X text 121 77 send a triplet to step to a new value; -#X text 22 282 see also:; -#X msg 80 146 stop; -#X text 127 147 "stop" message to stop output; -#X text 121 92