iem_utils-0.0.20240903/ 0000700 0000000 0000000 00000000000 14665566711 011202 5 ustar 00 iem_utils-0.0.20240903/DEVELOPER.md 0000600 0000000 0000000 00000001477 14665566711 013064 0 ustar 00 Developer information for iem_utils
===================================
"iem_utils" is META-library that aggragates a number of small (dependency-free)
libraries and GUI-plugins for Pd.
All libraries are developped separately, and are included here by means of
git-submodules.
## Checkout
~~~sh
git clone https://git.iem.at/pd/iem_utils
cd iem_utils
git submodule update --init
~~~
## Building
There is a master Makefile that recursively builds all the libraries (that need
building)
~~~sh
make
~~~
## Updating
git-submodules are set to a specific commit (each) - rather than tracking a
remote ("live") branch.
The following brings all submodules up-to-date with their current 'master'
branches.
~~~sh
git submodule foreach git checkout master
git submodule foreach git pull
~~~
## Pushing changes in submodules
TODO
iem_utils-0.0.20240903/Makefile 0000600 0000000 0000000 00000002373 14665566711 012651 0 ustar 00 subprojects = iem_adaptfilt iem_dp iem_roomsim iem_spec2 iem_tab punish
all: $(subprojects)
.PHONY: all archive release submodule update dummy
.PHONY: $(subprojects)
library=iem_utils
version=0.0.$(shell date +%Y%m%d)
archivefile=$(library)-v$(version).tgz
IEM_CFLAGS=-DPD $(CPPFLAGS) -fPIC $(CFLAGS)
IEM_LDFLAGS=-export-dynamic -fPIC -shared $(LDFLAGS)
.PHONY: clean $(subprojects:%=%_clean)
clean: $(subprojects:%=%_clean)
-find . -name "*.o" -delete
-find . -name "*.pd_*" -delete
-find . -name "*.dll" -delete
-find . -name "*.so" -delete
-find . -name "*.tgz" -delete
$(subprojects:%=%_clean):
make -C $(@:%_clean=%) clean
dummy:
@echo -n
archive: $(archivefile)
release: $(archivefile)
git tag -m "released iem_utils $(version)" "v$(version)"
submodule: .gitmodules
git submodule init
git submodule update
update:
git submodule foreach git checkout master
git submodule foreach git pull
%.tgz: dummy
-rm -f $@
tar --transform "s|^|$(@:.tgz=)/|" --exclude-vcs --exclude='.*' --exclude='*.tgz' --exclude $@ -czf $@ *
iem_adaptfilt iem_dp iem_roomsim iem_spec2 iem_tab punish:
$(MAKE) -C $@ \
$(empty)
.PHONY: install $(subprojects:%=%_install)
install: $(subprojects:%=%_install)
$(subprojects:%=%_install):
make -C $(@:%_install=%) install
iem_utils-0.0.20240903/README.md 0000600 0000000 0000000 00000002576 14665566711 012475 0 ustar 00 iem - collection of utility libraries for Pure Data (Pd)
========================================================
This is a collection of (unrelated) external libraries for Pd,
developed at the Institute of Electronic Music and Acoustics (iem) at the
University of Music and Performing Arts Graz, Austria.
# LICENSE
Each library comes with their own license, but all are released under an open
source license (GPL2+, BSD-3).
# CONTENTS
## Pd libraries
### iem_adaptfilt
adaptive filtering
https://git.iem.at/pd/iem_adaptfilt
### iem_dp
double precision
https://git.iem.at/pd/iem_dp
### iem_roomsim
room simulation
https://git.iem.at/pd/iem_roomsim
### iem_spec2
optimized objects for spectral processing
https://git.iem.at/pd/iem_spec2
### iem_tab
table maths
https://git.iem.at/pd/iem_tab
## Pd GUI plugins
### kiosk-plugin
run Pure Data in kiosk mode
https://git.iem.at/pd-gui/kiosk-plugin
### patch2svg-plugin
save patches as SVG
https://git.iem.at/pd-gui/patch2svg-plugin
### tclprompt-plugin
pd-gui plugin that (re)adds a wee tcl-prompt to the Pd-console
https://git.iem.at/pd-gui/tclprompt-plugin
### punish/triggerize-plugin
pd-gui plugin that helps avoiding fan-outs by inserting [trigger] as appropriate.
https://git.iem.at/pd-gui/punish
### punish/patcherize-plugin
pd-gui plugin that helps refactoring code into abstraction/subpatches.
https://git.iem.at/pd-gui/punish
iem_utils-0.0.20240903/iem16/ 0000700 0000000 0000000 00000000000 14665566711 012123 5 ustar 00 iem_utils-0.0.20240903/iem16/GnuGPL.LICENSE 0000600 0000000 0000000 00000035745 14665566711 014243 0 ustar 00 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.
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
iem_utils-0.0.20240903/iem16/Makefile 0000600 0000000 0000000 00000002137 14665566711 013570 0 ustar 00 #!/usr/bin/make -f
# Makefile for pure data externals in lib creb.
# Needs Makefile.pdlibbuilder to work (https://github.com/pure-data/pd-lib-builder)
lib.name = iem16
# special file that does not provide a class
lib.setup.sources = iem16.c
# helper library
shared.sources = \
iem16_delay.c \
iem16_table.c \
$(empty)
# all other C and C++ files in subdirs are source files per class
# (alternatively, enumerate them by hand)
class.sources = $(filter-out $(lib.setup.sources) $(shared.sources),$(wildcard *.c))
datafiles = \
$(wildcard *-help.pd) \
GnuGPL.LICENSE
datadirs = examples
################################################################################
### pdlibbuilder ###############################################################
################################################################################
# Include Makefile.pdlibbuilder from this directory, or else from externals
# root directory in pd-extended configuration.
PDLIBBUILDER_DIR=pd-lib-builder
include $(firstword $(wildcard $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder Makefile.pdlibbuilder ../Makefile.pdlibbuilder))
iem_utils-0.0.20240903/iem16/build/ 0000700 0000000 0000000 00000000000 14665566711 013222 5 ustar 00 iem_utils-0.0.20240903/iem16/build/win-vs2003/ 0000700 0000000 0000000 00000000000 14665566711 014752 5 ustar 00 iem_utils-0.0.20240903/iem16/build/win-vs2003/iem16.sln 0000600 0000000 0000000 00000001344 14665566711 016415 0 ustar 00 Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iem16", "iem16.vcproj", "{C8DAED0C-AB39-4D01-976B-7E4E9E0E10DD}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{C8DAED0C-AB39-4D01-976B-7E4E9E0E10DD}.Release.ActiveCfg = Release|Win32
{C8DAED0C-AB39-4D01-976B-7E4E9E0E10DD}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
iem_utils-0.0.20240903/iem16/build/win-vs2003/iem16.vcproj 0000600 0000000 0000000 00000007373 14665566711 017134 0 ustar 00
iem_utils-0.0.20240903/iem16/build/win-vs6/ 0000700 0000000 0000000 00000000000 14665566711 014533 5 ustar 00 iem_utils-0.0.20240903/iem16/build/win-vs6/iem16.dsp 0000600 0000000 0000000 00000005712 14665566711 016173 0 ustar 00 # Microsoft Developer Studio Project File - Name="iem16" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=IEM16 - WIN32 RELEASE
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "iem16.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "iem16.mak" CFG="IEM16 - WIN32 RELEASE"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "iem16 - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 1
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ""
# PROP Intermediate_Dir "obj\"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IEM16_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /I "..\..\pd\src" /D "WIN32" /D "NT" /D "_WINDOWS" /D "IEM16" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /win32
# SUBTRACT MTL /mktyplib203
# ADD BASE RSC /l 0xc07 /d "NDEBUG"
# ADD RSC /l 0xc07
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib wsock32.lib uuid.lib libc.lib oldnames.lib pd.lib /nologo /dll /machine:I386 /nodefaultlib /out:"..\iem16.dll" /libpath:"../../pd/bin" /export:iem16_setup
# SUBTRACT LINK32 /pdb:none
# Begin Target
# Name "iem16 - Win32 Release"
# Begin Group "Quellcodedateien"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\iem16.c
# End Source File
# Begin Source File
SOURCE=.\iem16_array.c
# End Source File
# Begin Source File
SOURCE=.\iem16_array_tilde.c
# End Source File
# Begin Source File
SOURCE=.\iem16_delay.c
# End Source File
# Begin Source File
SOURCE=.\iem16_table.c
# End Source File
# End Group
# Begin Group "Header-Dateien"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\iem16.h
# End Source File
# Begin Source File
SOURCE=.\iem16_table.h
# End Source File
# Begin Source File
SOURCE=..\..\pd\src\m_pd.h
# End Source File
# End Group
# End Target
# End Project
iem_utils-0.0.20240903/iem16/build/win-vs6/iem16.dsw 0000600 0000000 0000000 00000001061 14665566711 016173 0 ustar 00 Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
###############################################################################
Project: "iem16"=.\iem16.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
iem_utils-0.0.20240903/iem16/del16read~-help.pd 0000600 0000000 0000000 00000002675 14665566711 015357 0 ustar 00 #N canvas 24 20 800 531 12;
#X text 372 274 1st argument: name of delay line;
#X floatatom 116 253 0 0 0 0 - - -;
#X text 151 255 float input (delay time in ms);
#X text 127 310 signal output (delayed signal);
#X floatatom 383 177 0 0 0 0 - - -;
#X obj 116 375 snapshot~;
#X floatatom 116 399 0 0 0 0 - - -;
#X obj 24 246 loadbang;
#X obj 24 313 metro 200;
#X msg 32 273 \; pd dsp 1;
#X text 424 176 input to delay line;
#X obj 383 201 sig~;
#X text 372 290 2nd argument: (initial) delay time in ms;
#X text 36 443 see also:;
#X obj 383 226 del16write~ del_example 1000;
#X obj 24 16 del16read~;
#X obj 126 444 del16write~;
#X obj 239 444 vd16~;
#X text 133 14 - read a 16bit signal from a 16bit-delay line;
#X obj 368 52 delread~;
#X text 21 52 This is very similar to the pd-object;
#X text 49 82 It uses only 16bit to store the samples \, which will
need only half of the memory of pd's floatingpoint-based object.;
#X text 50 120 However \, there are 2 drawbacks: there will be some
additional noise (because floats are more precise than 16bit) \, and
you cannot have values>1 stored in the delay-line;
#X text 38 490 similar pd-objects:;
#X obj 223 489 delread~;
#X obj 307 489 delwrite~;
#X obj 400 489 vd~;
#X text 433 443 updated for iem16 version1.0;
#X obj 116 286 del16read~ del_example 1000;
#X connect 1 0 28 0;
#X connect 4 0 11 0;
#X connect 5 0 6 0;
#X connect 7 0 8 0;
#X connect 7 0 9 0;
#X connect 8 0 5 0;
#X connect 11 0 14 0;
#X connect 28 0 5 0;
iem_utils-0.0.20240903/iem16/del16read~.c 0000600 0000000 0000000 00000006400 14665566711 014236 0 ustar 00 /* copyleft (c) 2003 forum::fÌr::umlÀute -- IOhannes m zmölnig @ IEM
* based on d_delay.c from pd:
* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* del16read~, del16write~, vd16~ */
#include "iem16_delay.h"
/* ----------------------------- del16read~ ----------------------------- */
static t_class *sigdel16read_class;
typedef struct _sigdel16read{
t_object x_obj;
t_symbol *x_sym;
t_float x_deltime; /* delay in msec */
int x_delsamps; /* delay in samples */
t_float x_sr; /* samples per msec */
t_float x_n; /* vector size */
int x_zerodel; /* 0 or vecsize depending on read/write order */
} t_sigdel16read;
static void sigdel16read_16bit(t_sigdel16read *x, t_float f);
static void *sigdel16read_new(t_symbol *s, t_floatarg f){
t_sigdel16read *x = (t_sigdel16read *)pd_new(sigdel16read_class);
x->x_sym = s;
x->x_sr = sys_getsr();
x->x_n = sys_getblksize();
x->x_zerodel = 0;
sigdel16read_16bit(x, f);
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
static void sigdel16read_16bit(t_sigdel16read *x, t_float f){
t_sigdel16write *delwriter =
(t_sigdel16write *)pd_findbyclass(x->x_sym, sigdel16write_class);
x->x_deltime = f;
if (!delwriter)
return;
x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
+ x->x_n - x->x_zerodel;
if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
else if (x->x_delsamps > delwriter->x_cspace.c_n - x->x_n)
x->x_delsamps = delwriter->x_cspace.c_n - x->x_n;
}
static t_int *sigdel16read_perform(t_int *w){
t_float *out = (t_float *)(w[1]);
t_del16writectl *c = (t_del16writectl *)(w[2]);
int delsamps = *(int *)(w[3]);
int n = (int)(w[4]);
int phase = c->c_phase - delsamps, nsamps = c->c_n;
t_iem16_16bit *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
if (phase < 0) phase += nsamps;
bp = vp + phase;
while (n--) {
*out++ = *bp++*IEM16_SCALE_DOWN;
if (bp == ep) bp -= nsamps;
}
return (w+5);
}
static void sigdel16read_dsp(t_sigdel16read *x, t_signal **sp){
t_sigdel16write *delwriter =
(t_sigdel16write *)pd_findbyclass(x->x_sym, sigdel16write_class);
x->x_sr = sp[0]->s_sr * 0.001;
x->x_n = sp[0]->s_n;
if (delwriter) {
sigdel16write_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
sigdel16read_16bit(x, x->x_deltime);
dsp_add(sigdel16read_perform, 4,
sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
}
else if (*x->x_sym->s_name)
pd_error(x, "delread~: %s: no such del16write~",x->x_sym->s_name);
}
static void sigdel16read_setup(void){
sigdel16read_class = class_new(gensym("del16read~"),
(t_newmethod)sigdel16read_new, 0,
sizeof(t_sigdel16read), 0, A_DEFSYM, A_DEFFLOAT, 0);
class_addmethod(sigdel16read_class, (t_method)sigdel16read_dsp,
gensym("dsp"), A_CANT, 0);
class_addfloat(sigdel16read_class, (t_method)sigdel16read_16bit);
}
// G.Holzmann: for PD-extended build system
void del16read_tilde_setup(void)
{
sigdel16read_setup();
}
iem_utils-0.0.20240903/iem16/del16write~-help.pd 0000600 0000000 0000000 00000001742 14665566711 015570 0 ustar 00 #N canvas 83 192 678 431 12;
#X text 88 202 signal input;
#X text 136 16 writes a signal in a delay line;
#X text 281 235 1st argument: name of delay line;
#X obj 24 203 sig~ 0;
#X text 304 265 (= max. delay time);
#X text 281 251 2nd argument: length of delay line in msec;
#X text 24 292 see also:;
#X obj 24 16 del16write~;
#X obj 112 294 del16read~;
#X obj 209 294 vd16~;
#X text 16 353 similar pd-objects:;
#X obj 201 352 delread~;
#X obj 285 352 delwrite~;
#X obj 378 352 vd~;
#X obj 24 237 del16write~ del_line_xxx 500;
#X text 21 51 This is very similar to the pd-object;
#X text 49 81 It uses only 16bit to store the samples \, which will
need only half of the memory of pd's floatingpoint-based object.;
#X text 50 119 However \, there are 2 drawbacks: there will be some
additional noise (because floats are more precise than 16bit) \, and
you cannot have values>1 stored in the delay-line;
#X obj 368 51 delwrite~;
#X text 411 306 updated for iem16 version1.0;
#X connect 3 0 14 0;
iem_utils-0.0.20240903/iem16/del16write~.c 0000600 0000000 0000000 00000005121 14665566711 014454 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_delay.c from pd:
* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* del16read~, del16write~, vd16~ */
#include "iem16_delay.h"
/* ----------------------------- del16write~ ----------------------------- */
static void *sigdel16write_new(t_symbol *s, t_floatarg msec){
int nsamps;
t_sigdel16write *x = (t_sigdel16write *)pd_new(sigdel16write_class);
if (!*s->s_name) s = gensym("del16write~");
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
nsamps = ((float)(0.001f) * msec) * sys_getsr();
if (nsamps < sys_getblksize()) nsamps = sys_getblksize();
nsamps += ((- nsamps) & (SAMPBLK - 1));
nsamps += sys_getblksize();
x->x_cspace.c_n = nsamps;
x->x_cspace.c_vec =
(t_iem16_16bit *)getbytes((nsamps + XTRASAMPS) * sizeof(t_iem16_16bit));
x->x_cspace.c_phase = XTRASAMPS;
x->x_sortno = 0;
x->x_vecsize = 0;
x->x_f = 0;
return (x);
}
static t_int *sigdel16write_perform(t_int *w){
t_float *in = (t_float *)(w[1]);
t_del16writectl *c = (t_del16writectl *)(w[2]);
int n = (int)(w[3]);
int phase = c->c_phase, nsamps = c->c_n;
t_iem16_16bit *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
phase += n;
while (n--) {
*bp++ = (*in++*IEM16_SCALE_UP);
if (bp == ep) {
vp[0] = ep[-4];
vp[1] = ep[-3];
vp[2] = ep[-2];
vp[3] = ep[-1];
bp = vp + XTRASAMPS;
phase -= nsamps;
}
}
c->c_phase = phase;
return (w+4);
}
static void sigdel16write_dsp(t_sigdel16write *x, t_signal **sp){
dsp_add(sigdel16write_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
x->x_sortno = ugen_getsortno();
sigdel16write_checkvecsize(x, sp[0]->s_n);
}
static void sigdel16write_free(t_sigdel16write *x){
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_cspace.c_vec,
(x->x_cspace.c_n + XTRASAMPS) * sizeof(t_iem16_16bit));
}
static void sigdel16write_setup(void){
sigdel16write_class = class_new(gensym("del16write~"),
(t_newmethod)sigdel16write_new, (t_method)sigdel16write_free,
sizeof(t_sigdel16write), 0, A_DEFSYM, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigdel16write_class, t_sigdel16write, x_f);
class_addmethod(sigdel16write_class, (t_method)sigdel16write_dsp,
gensym("dsp"), A_CANT, 0);
}
// G.Holzmann: for PD-extended build system
void del16write_tilde_setup(void)
{
sigdel16write_setup();
}
iem_utils-0.0.20240903/iem16/examples/ 0000700 0000000 0000000 00000000000 14665566711 013741 5 ustar 00 iem_utils-0.0.20240903/iem16/examples/del16read~.pd 0000600 0000000 0000000 00000002675 14665566711 016247 0 ustar 00 #N canvas 24 20 800 531 12;
#X text 372 274 1st argument: name of delay line;
#X floatatom 116 253 0 0 0 0 - - -;
#X text 151 255 float input (delay time in ms);
#X text 127 310 signal output (delayed signal);
#X floatatom 383 177 0 0 0 0 - - -;
#X obj 116 375 snapshot~;
#X floatatom 116 399 0 0 0 0 - - -;
#X obj 24 246 loadbang;
#X obj 24 313 metro 200;
#X msg 32 273 \; pd dsp 1;
#X text 424 176 input to delay line;
#X obj 383 201 sig~;
#X text 372 290 2nd argument: (initial) delay time in ms;
#X text 36 443 see also:;
#X obj 116 286 del16read~ del_example 1000;
#X obj 383 226 del16write~ del_example 1000;
#X obj 24 16 del16read~;
#X obj 126 444 del16write~;
#X obj 239 444 vd16~;
#X text 133 14 - read a 16bit signal from a 16bit-delay line;
#X obj 368 52 delread~;
#X text 21 52 This is very similar to the pd-object;
#X text 49 82 It uses only 16bit to store the samples \, which will
need only half of the memory of pd's floatingpoint-based object.;
#X text 50 120 However \, there are 2 drawbacks: there will be some
additional noise (because floats are more precise than 16bit) \, and
you cannot have values>1 stored in the delay-line;
#X text 38 490 similar pd-objects:;
#X obj 223 489 delread~;
#X obj 307 489 delwrite~;
#X obj 400 489 vd~;
#X text 433 443 updated for iem16 version1.0;
#X connect 1 0 14 0;
#X connect 4 0 11 0;
#X connect 5 0 6 0;
#X connect 7 0 8 0;
#X connect 7 0 9 0;
#X connect 8 0 5 0;
#X connect 11 0 15 0;
#X connect 14 0 5 0;
iem_utils-0.0.20240903/iem16/examples/del16write~.pd 0000600 0000000 0000000 00000001742 14665566711 016460 0 ustar 00 #N canvas 83 192 678 431 12;
#X text 88 202 signal input;
#X text 136 16 writes a signal in a delay line;
#X text 281 235 1st argument: name of delay line;
#X obj 24 203 sig~ 0;
#X text 304 265 (= max. delay time);
#X text 281 251 2nd argument: length of delay line in msec;
#X text 24 292 see also:;
#X obj 24 16 del16write~;
#X obj 112 294 delread16~;
#X obj 209 294 vd16~;
#X text 16 353 similar pd-objects:;
#X obj 201 352 delread~;
#X obj 285 352 delwrite~;
#X obj 378 352 vd~;
#X obj 24 237 del16write~ del_line_xxx 500;
#X text 21 51 This is very similar to the pd-object;
#X text 49 81 It uses only 16bit to store the samples \, which will
need only half of the memory of pd's floatingpoint-based object.;
#X text 50 119 However \, there are 2 drawbacks: there will be some
additional noise (because floats are more precise than 16bit) \, and
you cannot have values>1 stored in the delay-line;
#X obj 368 51 delwrite~;
#X text 411 306 updated for iem16 version1.0;
#X connect 3 0 14 0;
iem_utils-0.0.20240903/iem16/examples/tab16play~.pd 0000600 0000000 0000000 00000003330 14665566711 016270 0 ustar 00 #N canvas 159 54 804 495 10;
#X msg 639 93 \; pd dsp 0;
#X floatatom 11 342 0 0 0 0 - - -;
#X msg 11 109 set array99;
#X text 93 109 "set" message permits you to switch between arrays;
#X text 138 228 creation argument initializes array name;
#X obj 11 316 env~ 16384;
#X obj 87 360 dac~ 1;
#X obj 87 323 *~;
#X obj 100 304 line~;
#X msg 100 263 0.1 100;
#X msg 116 284 0 100;
#X text 162 264 on;
#X text 157 283 off;
#X text 148 301 envelope;
#X text 148 312 generator;
#X text 101 248 amplitude controls:;
#X text 131 362 audio output;
#X obj 87 342 hip~ 5;
#X msg 26 179 0 44100;
#X msg 27 158 44100;
#X msg 26 138 bang;
#X text 80 136 "bang" or 0 plays whole sample;
#X text 82 157 play starting at 44100th sample;
#X text 93 177 play starting at beginning for 44100 samples;
#X msg 25 199 44100 1000;
#X text 103 198 play from 44100 through 45099 (1000 samples);
#X obj 11 228 tab16play~ array99;
#X obj 589 205 table16 array99;
#X text 389 444 updated for iem16 version1.0;
#X obj 5 439 tab16write~;
#X obj 5 458 tab16read4~;
#X obj 89 458 tab16read;
#X obj 89 439 tab16write;
#X obj 166 439 tab16send~;
#X obj 166 458 tab16receive~;
#X obj 32 13 tab16play~;
#X text 29 43 The [tab16play~] object is the same as the [tabplay~]
object \, but it refers to 16bit-arrays stored in [table16] instead
of floating-point arrays (stored in normal pd-tables/arrays);
#X obj 328 444 table16;
#X text 11 417 see also:;
#X text 108 14 play a 16bit-table as a sample (non-transposing);
#X connect 2 0 26 0;
#X connect 5 0 1 0;
#X connect 7 0 17 0;
#X connect 8 0 7 1;
#X connect 9 0 8 0;
#X connect 10 0 8 0;
#X connect 17 0 6 0;
#X connect 18 0 26 0;
#X connect 19 0 26 0;
#X connect 20 0 26 0;
#X connect 24 0 26 0;
#X connect 26 0 5 0;
#X connect 26 0 7 0;
iem_utils-0.0.20240903/iem16/examples/tab16read.pd 0000600 0000000 0000000 00000001542 14665566711 016043 0 ustar 00 #N canvas 245 143 703 316 12;
#X text 62 102 index;
#X floatatom 25 103 0 0 0 0 - - -;
#X floatatom 25 199 0 0 0 0 - - -;
#X text 70 197 output = array99[index];
#X text 189 157 creation argument;
#X text 185 175 gives array name;
#X msg 35 125 set array99;
#X text 147 125 change array name;
#X obj 25 165 tab16read array99;
#X obj 422 131 table16 array99;
#X obj 17 13 tab16read;
#X text 412 257 updated for iem16 version1.0;
#X obj 16 252 tab16write~;
#X obj 16 271 tab16read4~;
#X obj 120 271 tab16read;
#X obj 120 252 tab16write;
#X obj 217 252 tab16send~;
#X obj 217 271 tab16receive~;
#X obj 339 257 table16;
#X text 108 15 - read numbers from a 16bit-table;
#X text 21 42 since [table16] can only hold 16bit values \, the output
of [tab16read] is limited to integer-values between -32768..+32767
;
#X connect 1 0 8 0;
#X connect 6 0 8 0;
#X connect 8 0 2 0;
iem_utils-0.0.20240903/iem16/examples/tab16read4~.pd 0000600 0000000 0000000 00000002536 14665566711 016331 0 ustar 00 #N canvas 59 33 741 466 10;
#X text 21 207 signal input x(n);
#X text 127 21 4-point-interpolating table lookup;
#X obj 11 316 snapshot~;
#X obj 30 290 metro 200;
#X obj 11 124 sig~;
#X floatatom 11 98 0 0 0 0 - - -;
#X obj 30 264 r readout;
#X floatatom 11 342 0 0 0 0 - - -;
#X text 49 94 incoming signal is index. Indices should range from 1
to (size-2) so that the 4-point interpolation is meaningful. You can
shift-drag the number box to see the effect of interpolation.;
#X msg 34 158 set array99;
#X text 116 158 "set" message permits you to switch between arrays
;
#X text 149 228 creation argument initializes array name;
#X obj 10 228 tab16read4~ array99;
#X obj 460 301 table16 array99;
#X text 395 400 updated for iem16 version1.0;
#X obj 11 395 tab16write~;
#X obj 11 414 tab16read4~;
#X obj 95 414 tab16read;
#X obj 95 395 tab16write;
#X obj 172 395 tab16send~;
#X obj 172 414 tab16receive~;
#X obj 334 400 table16;
#X obj 47 21 tab16read4~;
#X text 7 51 tab16read4~ is used to build samplers and other table
lookup algorithms. The interpolation scheme is 4-point polynomial.
;
#X text 185 266 since [table16] can only hold 16bit-values \, the stored
integer values -32768..+32767 are converted to floats -1.0..+1.0;
#X connect 2 0 7 0;
#X connect 3 0 2 0;
#X connect 4 0 12 0;
#X connect 5 0 4 0;
#X connect 6 0 3 0;
#X connect 9 0 12 0;
#X connect 12 0 2 0;
iem_utils-0.0.20240903/iem16/examples/tab16receive~.pd 0000600 0000000 0000000 00000001144 14665566711 016746 0 ustar 00 #N canvas 109 83 646 239 12;
#X text 17 53 creation argument: name of array;
#X text 16 83 By default a block is 64 samples \; this can be reset
using the block~ object.;
#X obj 21 18 tab16receive~;
#X text 376 199 updated for iem16 version1.0;
#X obj 5 176 tab16write~;
#X obj 5 195 tab16read4~;
#X obj 109 195 tab16read;
#X obj 109 176 tab16write;
#X obj 204 176 tab16send~;
#X obj 204 195 tab16receive~;
#X obj 328 181 table16;
#X text 17 155 see also:;
#X text 129 18 - read a block of a 16bit-signal from an array continuously
;
#X text 10 129 16bit-signals are limited to 65536 values between -1.0..+1.0
;
iem_utils-0.0.20240903/iem16/examples/tab16send~.pd 0000600 0000000 0000000 00000001262 14665566711 016256 0 ustar 00 #N canvas 151 91 705 277 12;
#X text 113 26 writes one block of a signal continuously to an array
;
#X text 41 60 creation argument: name of array;
#X text 29 96 By default a block is 64 samples \; this can be reset
using the block~ object.;
#X text 376 239 updated for iem16 version1.0;
#X obj 5 216 tab16write~;
#X obj 5 235 tab16read4~;
#X obj 109 235 tab16read;
#X obj 109 216 tab16write;
#X obj 204 216 tab16send~;
#X obj 204 235 tab16receive~;
#X obj 328 221 table16;
#X text 17 195 see also:;
#X text 14 137 16bit-signals are limited to 65536 values between -1.0..+1.0
;
#X text 16 157 if your signal has absolute values >1.0 \, these are
wrapped around...;
#X obj 11 27 tab16send~;
iem_utils-0.0.20240903/iem16/examples/tab16write.pd 0000600 0000000 0000000 00000001624 14665566711 016263 0 ustar 00 #N canvas 44 17 653 456 12;
#X floatatom 39 96 0 0 0 0 - - -;
#X floatatom 176 170 0 0 0 0 - - -;
#X text 208 192 creation argument;
#X text 210 210 is array name;
#X text 76 87 set y value;
#X text 74 152 right inlet selects x value;
#X msg 55 117 set array99;
#X text 163 116 change array name;
#X obj 39 195 tab16write array99;
#X obj 31 27 tab16write;
#X text 388 378 updated for iem16 version1.0;
#X obj 17 355 tab16write~;
#X obj 17 374 tab16read4~;
#X obj 121 374 tab16read;
#X obj 121 355 tab16write;
#X obj 216 355 tab16send~;
#X obj 216 374 tab16receive~;
#X obj 340 360 table16;
#X text 29 334 see also:;
#X obj 438 156 table16 array99;
#X text 133 28 write numbers to a 16bit-table;
#X text 20 256 since [table16] can only hold 16bit-values \, the stored
numbers have to be integer (ok \, we take care of this!) values between
-32768..+32767.;
#X connect 0 0 8 0;
#X connect 1 0 8 1;
#X connect 6 0 8 0;
iem_utils-0.0.20240903/iem16/examples/tab16write~.pd 0000600 0000000 0000000 00000002001 14665566711 016447 0 ustar 00 #N canvas 119 134 697 433 10;
#X msg 43 131 bang;
#X obj 23 82 sig~ 3000;
#X obj 23 110 phasor~;
#X text 158 213 creation argument initializes array name;
#X msg 40 181 set array99;
#X msg 445 35 \; pd dsp 1;
#X msg 524 37 \; pd dsp 0;
#X text 85 133 bang to start recording;
#X text 126 180 set the destination array;
#X msg 43 153 stop;
#X text 85 154 stop recording;
#X text 385 366 updated for iem16 version1.0;
#X obj 14 343 tab16write~;
#X obj 14 362 tab16read4~;
#X obj 118 362 tab16read;
#X obj 118 343 tab16write;
#X obj 213 343 tab16send~;
#X obj 213 362 tab16receive~;
#X obj 337 348 table16;
#X text 26 322 see also:;
#X obj 22 211 tab16write~ array99;
#X obj 492 160 table16 array99;
#X obj 31 27 tab16write~;
#X text 120 27 object to write a 16bit-signal in an array;
#X text 261 261 since [table16] can only hold 16bit-values \, the incoming
signal (-1.0..+1.0) is stored as integer values -32768..+32767;
#X connect 0 0 20 0;
#X connect 1 0 2 0;
#X connect 2 0 20 0;
#X connect 4 0 20 0;
#X connect 9 0 20 0;
iem_utils-0.0.20240903/iem16/examples/table16.pd 0000600 0000000 0000000 00000004655 14665566711 015540 0 ustar 00 #N canvas 37 0 856 640 10;
#X obj 30 21 table16;
#X text 97 22 16bit-table;
#X text 32 51 [table16] stores 16bit values. The normal pd-tables ([table]
\, array) store the values as floating-points. While floating points
are (often) more precise (this is of course not really true... \, esp.
when comparing integer(4byte) to floating-point.) they use a lot of
memory (4byte).;
#X text 32 121 [table16] uses only 16bit (2bytes) to store the values
\, which is half of the memory.;
#X text 32 155 However there are 2 major drawbacks;
#X text 53 172 a) less precision means less SNR - you can only store
65536 different values \, but this is what CD-quality is (should be
good enough for most musical applications);
#X text 55 221 b) the 65536 values (-32678..+32767) are mapped to -1.0..+1.0!
This means you cannot store signals that exceed this magical limit.
Please make sure \, that the signal has correct values (use [clip~])
or the unclipped values will get wrapped!;
#X text 20 323 There are several objects to access the data of [table16]:
;
#X obj 55 344 tab16write~;
#X obj 55 363 tab16read4~;
#X obj 279 363 tab16read;
#X obj 279 344 tab16write;
#X obj 164 344 tab16send~;
#X obj 164 363 tab16receive~;
#X obj 55 382 tab16read~;
#X text 19 410 The message-objects [tab16read]/[tab16write] store the
values directly (-32767..+32768) \, while the signal-objects convert
the floats -1.0..+1.0 to the correct values or vice-versa.;
#X text 270 21 updated for iem16 version1.0;
#X msg 496 53 resize 100;
#X obj 496 308 table16 array16 99;
#N canvas 0 0 450 300 graph6 0;
#X array array100 10 float 1;
#A 0 1 2 3 4 5 6 7 8 9 0;
#X coords 0 10 9 0 200 140 1;
#X restore 477 452 graph;
#X msg 478 409 \; array100 0 1 2 3 4 5 6 7 8 9;
#X text 481 389 click to init float-array;
#X msg 502 114 from array100;
#X text 21 497 There is no beautiful graphical representation as with
pd's arrays.;
#X msg 508 139 from array100 resize;
#X msg 516 190 from array100 20 30;
#X msg 517 213 from array100 20 30 resize;
#X msg 527 259 from array100 20 30 95;
#X msg 527 279 from array100 20 30 95 resize;
#X text 502 95 copy the data from a float-array;
#X text 603 117 and resize the 16bit-array;
#X text 513 173 copy floats (index20..30);
#X text 653 192 and resize to 30-20;
#X text 526 241 copy indexed values and insert at index95;
#X connect 17 0 18 0;
#X connect 22 0 18 0;
#X connect 24 0 18 0;
#X connect 25 0 18 0;
#X connect 26 0 18 0;
#X connect 27 0 18 0;
#X connect 28 0 18 0;
iem_utils-0.0.20240903/iem16/examples/vd16~.pd 0000600 0000000 0000000 00000002405 14665566711 015247 0 ustar 00 #N canvas 88 40 717 480 12;
#X floatatom 50 254 0 0 0 0 - - -;
#X obj 50 347 outlet~;
#X text 130 346 signal output (delayed signal);
#X obj 50 282 sig~;
#X text 99 279 signal input (delay time in ms);
#X text 218 310 creation argument: name of delay line;
#X text 35 400 see also:;
#X obj 24 16 vd16~;
#X text 77 10 reads a signal from a 16bit delay line at a variable
delay time (4-point-interpolation);
#X text 31 51 vd16~ implements a 4-point interpolating delay tap from
a corresponding delwrite~ object. The delay in milliseconds of the
tap is specified by the incoming signal.;
#X obj 50 314 vd16~ del_example;
#X text 16 433 similar pd-objects:;
#X obj 201 432 delread~;
#X obj 285 432 delwrite~;
#X obj 378 432 vd~;
#X obj 123 403 del16write~;
#X obj 242 403 del16read~;
#X text 411 386 updated for iem16 version1.0;
#X text 28 116 This is very similar to the pd-object;
#X text 56 137 It uses only 16bit to store the samples \, which will
need only half of the memory of pd's floatingpoint-based object.;
#X text 57 175 However \, there are 2 drawbacks: there will be some
additional noise (because floats are more precise than 16bit) \, and
you cannot have values>1 stored in the delay-line;
#X obj 375 112 vd~;
#X connect 0 0 3 0;
#X connect 3 0 10 0;
#X connect 10 0 1 0;
iem_utils-0.0.20240903/iem16/iem16.c 0000600 0000000 0000000 00000003575 14665566711 013224 0 ustar 00 /* ...this is a very IEM16 external ...
it allows for 16bit-constructs where float would eat too much memory
forum::für::umläute@IEM:2003
*/
#include "iem16.h"
/* do a little help thing */
typedef struct iem16 {
t_object x_obj;
} t_iem16;
static t_class *iem16_class;
static void *iem16_new(void){
t_iem16 *x = (t_iem16 *)pd_new(iem16_class);
post("iem16: 16bit objects for low memory usage");
return(x);
}
/* include some externals */
void del16read_tilde_setup();
void del16write_tilde_setup();
void tab16play_tilde_setup();
void tab16read4_setup();
void tab16read4_tilde_setup();
void tab16read_setup();
void tab16read_tilde_setup();
void tab16receive_tilde_setup();
void tab16send_tilde_setup();
void tab16write_setup();
void tab16write_tilde_setup();
void table16_setup();
void vd16_tilde_setup();
void iem16_setup(void) {
static unsigned int setupcount=0;
if(setupcount>0) {
post("iem16:\tsetup called several times, skipping...");
return;
}
setupcount++;
del16read_tilde_setup();
del16write_tilde_setup();
tab16play_tilde_setup();
tab16read4_setup();
tab16read4_tilde_setup();
tab16read_setup();
tab16read_tilde_setup();
tab16receive_tilde_setup();
tab16send_tilde_setup();
tab16write_setup();
tab16write_tilde_setup();
table16_setup();
vd16_tilde_setup();
/* ************************************** */
post("iem16:\t16bit-objects for low memory usage");
post("iem16:\t(l) forum::für::umläute\t\tIOhannes m zmölnig");
post("iem16:\tInstitute of Electronic Music and Acoustics, Graz - iem");
post("iem16:\tcompiled: "__DATE__);
iem16_class = class_new(gensym("iem16"),
iem16_new,
0,
sizeof(t_iem16), CLASS_NOINLET, 0);
class_addcreator((t_newmethod)iem16_new,
gensym("IEM16"), 0);
}
void IEM16_setup(void){
iem16_setup();
}
iem_utils-0.0.20240903/iem16/iem16.h 0000600 0000000 0000000 00000006203 14665566711 013220 0 ustar 00 /* ********************************************** */
/* the IEM16 external */
/* ********************************************** */
/* forum::für::umläute */
/* ********************************************** */
/* the IEM16 external is a runtime-library for miller s. puckette's realtime-computermusic-software "pure data"
* therefore you NEED "pure data" to make any use of the IEM16 external
* (except if you want to use the code for other things)
* download "pure data" at
https://puredata.info
* if you are looking for the latest release of the IEM16-external you should have another look at
https://git.iem.at/pd/iem16
*
* IEM16 is published under the GNU GeneralPublicLicense, that must be shipped with IEM16.
* if you are using Debian GNU/linux, the GNU-GPL can be found under /usr/share/common-licenses/GPL
* if you still haven't found a copy of the GNU-GPL, have a look at http://www.gnu.org
*
* "pure data" has it's own license, that comes shipped with "pure data".
*
* there are ABSOLUTELY NO WARRANTIES for anything
*/
#ifndef INCLUDE_IEM16_H__
#define INCLUDE_IEM16_H__
#include "m_pd.h"
typedef short t_iem16_16bit;
#define IEM16_SCALE_UP (32767)
#define IEM16_SCALE_DOWN (1./32767)
#define VERSION "1.2.1"
#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
/* machine-dependent definitions. These ifdefs really
should have been by CPU type and not by operating system! */
#ifdef __irix__
/* big-endian. Most significant byte is at low address in memory */
# define HIOFFSET 0 /* word offset to find MSB */
# define LOWOFFSET 1 /* word offset to find LSB */
# define int32 long /* a data type that has 32 bits */
#elif defined __WIN32__
/* little-endian; most significant byte is at highest address */
# define HIOFFSET 1
# define LOWOFFSET 0
# define int32 long
#elif defined __FreeBSD__
# include
# if BYTE_ORDER == LITTLE_ENDIAN
# define HIOFFSET 1
# define LOWOFFSET 0
# else
# define HIOFFSET 0 /* word offset to find MSB */
# define LOWOFFSET 1 /* word offset to find LSB */
# endif /* BYTE_ORDER */
# include
# define int32 int32_t
#elif defined __linux__
# include
# if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
# error No byte order defined
# endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define HIOFFSET 1
# define LOWOFFSET 0
# else
# define HIOFFSET 0 /* word offset to find MSB */
# define LOWOFFSET 1 /* word offset to find LSB */
# endif /* __BYTE_ORDER */
# include
# define int32 int32_t
#elif defined __APPLE__
# ifdef __BIG_ENDIAN__
# define HIOFFSET 0 /* word offset to find MSB */
# define LOWOFFSET 1 /* word offset to find LSB */
# else
# define HIOFFSET 1
# define LOWOFFSET 0
# endif
# define int32 int /* a data type that has 32 bits */
#endif /* system */
#ifndef IEM16_EXTERN
#ifdef _WIN32
#ifdef IEM16_INTERNAL
#define IEM16_EXTERN __declspec(dllexport) extern
#else
#define IEM16_EXTERN __declspec(dllimport) extern
#endif /* IEM16_INTERNAL */
#else
#define IEM16_EXTERN extern
#endif /* _WIN32 */
#endif /* IEM16_EXTERN */
#endif
iem_utils-0.0.20240903/iem16/iem16_delay.c 0000600 0000000 0000000 00000001657 14665566711 014401 0 ustar 00 /* copyleft (c) 2003-2021 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_delay.c from pd:
* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#define IEM16_INTERNAL
#include "iem16_delay.h"
#ifdef __m_imp_h_
# define HAVE_CLASS_STRUCT
#endif
t_class *sigdel16write_class;
/* routine to check that all del16writes/del16reads/vds have same vecsize */
void sigdel16write_checkvecsize(t_sigdel16write *x, int vecsize){
if (x->x_rsortno != ugen_getsortno()) {
x->x_vecsize = vecsize;
x->x_rsortno = ugen_getsortno();
}
else if (vecsize != x->x_vecsize) {
const char*objname="del16read/del16write/vd";
#ifdef HAVE_CLASS_STRUCT
t_object*obj=&x->x_obj;
objname = obj->te_g.g_pd->c_name->s_name;
#endif
pd_error(x, "%s vector size mismatch", objname);
}
}
iem_utils-0.0.20240903/iem16/iem16_delay.h 0000600 0000000 0000000 00000002310 14665566711 014371 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#ifndef INCLUDE_IEM16_DELAY_H__
#define INCLUDE_IEM16_DELAY_H__
/* sampling */
#include "iem16.h"
#include
#if defined __WIN32 || defined __WIN32__
//# define NO_UGEN_SORTNO
#endif
#ifdef NO_UGEN_SORTNO
static int ugen_getsortno(void){return 0;}
#else
extern int ugen_getsortno(void);
#endif
IEM16_EXTERN t_class *sigdel16write_class;
typedef struct del16writectl{
int c_n;
t_iem16_16bit *c_vec;
int c_phase;
} t_del16writectl;
typedef struct _sigdel16write{
t_object x_obj;
t_symbol *x_sym;
t_del16writectl x_cspace;
int x_sortno; /* DSP sort number at which this was last put on chain */
int x_rsortno; /* DSP sort # for first del16read or write in chain */
int x_vecsize; /* vector size for del16read~ to use */
float x_f;
} t_sigdel16write;
IEM16_EXTERN void sigdel16write_checkvecsize(t_sigdel16write *x, int vecsize);
# define XTRASAMPS 4
# define SAMPBLK 4
#endif
iem_utils-0.0.20240903/iem16/iem16_table.c 0000600 0000000 0000000 00000001113 14665566711 014355 0 ustar 00 /* copyleft (c) 2003-2021 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1921 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* shared functions */
#define IEM16_INTERNAL
#include "iem16_table.h"
t_class *table16_class;
void table16_usedindsp(t_table16*x){
x->x_usedindsp=1;
}
int table16_getarray16(t_table16*x, int*size,t_iem16_16bit**vec){
*size=x->x_size;
*vec =x->x_table;
return 1;
}
iem_utils-0.0.20240903/iem16/iem16_table.h 0000600 0000000 0000000 00000001701 14665566711 014365 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#ifndef INCLUDE_IEM16_TABLE_H__
#define INCLUDE_IEM16_TABLE_H__
/* sampling */
#include "iem16.h"
#include
/* ------------------------- table16 -------------------------- */
/* a 16bit table */
IEM16_EXTERN t_class *table16_class;
typedef struct _table16 {
t_object x_obj;
t_symbol *x_tablename;
long x_size;
t_iem16_16bit *x_table; /* hold the data */
int x_usedindsp;
t_canvas *x_canvas; /* for file i/o */
} t_table16;
IEM16_EXTERN int table16_getarray16(t_table16*x, int*size,t_iem16_16bit**vec);
IEM16_EXTERN void table16_usedindsp(t_table16*x);
union tabfudge
{
double tf_d;
int32 tf_i[2];
};
#endif
iem_utils-0.0.20240903/iem16/pd-lib-builder/ 0000700 0000000 0000000 00000000000 14665566711 014716 5 ustar 00 iem_utils-0.0.20240903/iem16/pd-lib-builder/CHANGELOG.txt 0000600 0000000 0000000 00000007401 14665566711 016752 0 ustar 00 Changelog for Makefile.pdlibbuilder.
v0.7.0, dated 2023-07-06
- build double-precision externals with the 'floatsize' variable
- allow building multiple flavours of an external side-by-side (#78)
- facilitate multiple platform co-installation of shared lib (#58)
- fix use of shared.ldflags with helper-library (#64)
- fix broken armv6l platform detection (#71)
- improve documentation
v0.6.0, dated 2019-12-21
- detect target platform (OS and architecture) rather than build platform (#55)
- introduce optional user variable 'PLATFORM' for cross compilation
- no longer build OSX/MacOS fat binaries by default (#21, #50)
- do build fat binaries when 'extension=d_fat' is specified for OSX/MacOS
- fix bug where minimum OSX/MacOS version wasn't defined, and set it to 10.6
v0.5.1, dated 2018-03-15
Fixes and improvements for Windows builds:
- properly evaluate variables 'PDDIR' and 'PDBINDIR' to find pd.dll
- define default path of 32 bit Pd on 64 bit Windows
- link C++ externals with standard C libs on Windows, they don't load otherwise
- strip installed Windows binaries by default
(issues #34, #39, #41, #42 respectively)
Warning for all platforms: variable 'PD_PATH' is no longer supported, use the
equivalent 'PDDIR'.
v0.5.0, dated 2018-01-23
Implement target architecture detection for Windows builds,
and set appropriate options for 32 and 64 bit (used to be for 32 bit only).
(feature, issue #37 #38, merge commit 215bf3e)
v0.4.4, dated 2016-11-22
Use variable 'system' when evaluating 'for{Linux,Darwin,Windows}'
(bugfix, issue #31, commit 2c14110)
v0.4.3, dated 2016-11-02
Replace flags '-fpic' by 'fPIC'.
(bugfix, issue #29, commit 426b38b)
v0.4.2, dated 2016-10-30
Fix issue where incorrect message about m_pd.h is given.
(bugfix, commit 2e13d8f)
v0.4.1, dated 2016-10-27
Respect cflag for minimum OSX version when defined by lib makefile.
(bugfix, pull request #22, commit 48c4127)
v0.4.0, dated 2016-10-14
Introduced path variables PDDIR, PDINCLUDEDIR, PDBINDIR, PDLIBDIR which can
also be defined in environment.
(feature, issue #27, commit b0dab72)
v0.3.1, dated 2016-10-13
Fix bug where pd.dll wouldn't be found.
(bugfix, commit a0c87be)
v0.3.0, dated 2016-10-09
Variable 'PD_PATH' introduced for pd-extended / pd-l2ork compatibility.
(feature, issue #26, commit 41e9743)
v0.2.8, dated 2016-10-09
Allow installed files to contain weird characters (notably '$').
(bugfix, pull request #20, commit 5b920b1)
v0.2.7, dated 2016-10-04
Remove all default pd search paths except vanilla's.
(discussion, issue #25, commit a6a89dc)
v0.2.6, dated 2016-09-20
Redefined dependency checking so it won't stall rebuilds on OSX.
(bugfix, issue #16, commit 9fd1795)
v0.2.5, dated 2016-06-26
Fixed dependency checking for object files in other directories.
(bugfix, commit f06e550)
v0.2.4, dated 2016-06-25
Fixed regression bug that disabled all dependency checking.
(bugfix, commit 1d7bb5e)
v0.2.3, dated 2016-03-29
Disabled dependency checking for OSX <= 10.5 because it stalled rebuilds.
(bugfix, issue #16, commit eb614fd)
v0.2.2, dated 2016-03-28
Removed target 'pre' because it forced rebuild of everything in 'all'.
(bugfix, issue #17, commit c989c8e)
v0.2.1, dated 2015-12-27
Implement / respect 'CPPFLAGS','CFLAGS'and 'LDFLAGS'.
(bugfix, issue #5, commit 98f3582)
v0.2.0, dated 2015-12-19
Added per-platform multiline defines 'forLinux', 'forDarwin', 'forWindows'.
(feature, pull request #9, commit 3946ea5)
v0.1.0, dated 2015-12-08
Added targets 'pre' and 'post' to automatically run before and after 'all'.
(feature, pull request #4, commit a5678ac)
v0.0.2, dated 2015-12-06
Improved methods for searching pd paths.
(bugfix, commit ed37e6b)
v0.0.1, dated 2015-10-31
Fixed expansion of variable 'lib.version'.
(bugfix, issue #1, commit 974b617)
v0.0.0, dated 2015-06-24
Initial version.
(commit 16517a2)
iem_utils-0.0.20240903/iem16/pd-lib-builder/Makefile.pdlibbuilder 0000600 0000000 0000000 00000131452 14665566711 021026 0 ustar 00 # Makefile.pdlibbuilder dated 2019-12-21
version = 0.7.0
# Helper makefile for Pure Data external libraries.
# Written by Katja Vetter March-June 2015 for the public domain. No warranties.
# Inspired by Hans Christoph Steiner's Makefile Template and Stephan Beal's
# ShakeNMake.
#
# Grab the newest version of Makefile.pdlibbuilder from
# https://github.com/pure-data/pd-lib-builder/
#
# GNU make version >= 3.81 required.
#
#
#=== characteristics ===========================================================
#
#
# - defines build settings based on autodetected OS and architecture
# - defines rules to build Pd class- or lib executables from C or C++ sources
# - defines rules for libdir installation
# - defines convenience targets for developer and user
# - evaluates implicit dependencies for non-clean builds
#
#
#=== basic usage ===============================================================
#
#
# In your Makefile, define your Pd lib name and class files, and include
# Makefile.pdlibbuilder at the end of the Makefile. Like so:
#
# ________________________________________________________________________
#
# # Makefile for mylib
#
# lib.name = mylib
#
# class.sources = myclass1.c myclass2.c
#
# datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt
#
# include Makefile.pdlibbuilder
# ________________________________________________________________________
#
#
# For files in class.sources it is assumed that class basename == source file
# basename. The default target builds all classes as individual executables
# with Pd's default extension for the platform. For anything more than the
# most basic usage, continue reading.
#
#
#=== list of Makefile.pdlibbuilder API variables ===============================
#
#
# Variables available for definition in your library Makefile:
#
# - lib.name
# - lib.setup.sources
# - class.sources
# - common.sources
# - shared.sources
# - .class.sources
# - .class.ldflags
# - .class.ldlibs
# - cflags
# - ldflags
# - ldlibs
# - datafiles
# - datadirs
# - makefiles
# - makefiledirs
# - externalsdir
#
# Optional multiline defines evaluated per operating system:
#
# - forLinux
# - forDarwin
# - forWindows
#
# Variables available for your makefile or make command line:
#
# - make-lib-executable
# - suppress-wunused
#
# Path variables for make command line or environment:
#
# - PDDIR
# - PDINCLUDEDIR
# - PDBINDIR
# - PDLIBDIR
#
# Standard make variables for make command line or environment:
#
# - CPPFLAGS
# - CFLAGS
# - LDFLAGS
# - CC
# - CXX
# - INSTALL
# - STRIP
# - DESTDIR
#
# Optional user variables for make command line or environment:
#
# - PLATFORM
# - extension
# - floatsize
#
# Deprecated path variables:
#
# - pdincludepath
# - pdbinpath
# - objectsdir
#
#
#=== descriptions of Makefile.pdlibbuilder API variables =======================
#
#
# lib.name:
# Name of the library directory as it will be installed / distributed. Also the
# name of the lib executable in the case where all classes are linked into
# a single binary.
#
# lib.setup.sources:
# Source file(s) (C or C++) which must be compiled only when linking all classes
# into a single lib binary.
#
# class.sources:
# All sources files (C or C++) for which the condition holds that
# class name == source file basename.
#
# .class.sources:
# Source file(s) (C or C++) specific to class . Use this for
# multiple-source classes or when class name != source file basename.
#
# common.sources:
# Source file(s) which must be statically linked to each class in the library.
#
# shared.sources:
# Source file(s) (C or C++) to build a shared dynamic link lib, to be linked
# with all class executables.
#
# cflags, ldflags, ldlibs:
# Define cflags (preprocessor&compiler), ldflags (linker) and ldlibs (dynamic
# link libs) for the whole library. These flags are added to platform-specific
# flags defined by Makefile.pdlibbuilder.
#
# .class.ldflags and .class.ldlibs:
# Define ldflags resp. ldlibs specific to class . These flags are
# added to platform-specific flags defined by Makefile.pdlibbuilder, and flags
# defined in your Makefile for the whole library. Note: cflags can not be
# defined per class in the current implementation.
#
# datafiles and datadirs:
# All extra files you want to include in binary distributions of the
# library: abstractions and help patches, example patches, meta patch, readme
# and license texts, manuals, sound files, etcetera. Use 'datafiles' for all
# files that should go into your lib rootdir and 'datadirs' for complete
# directories you want to copy from source to distribution.
#
# forLinux, forDarwin, forWindows:
# Shorthand for 'variable definitions for Linux only' etc. Use like:
# define forLinux
# cflags += -DLINUX
# class.sources += linuxthing.c
# endef
#
# makefiles and makefiledirs:
# Extra makefiles or directories with makefiles that should be made in sub-make
# processes.
#
# make-lib-executable:
# When this variable is defined 'yes' in your makefile or as command argument,
# Makefile.pdlibbuilder will try to build all classes into a single library
# executable (but it will force exit if lib.setup.sources is undefined).
# If your makefile defines 'make-lib-executable=yes' as the library default,
# this can still be overridden with 'make-lib-executable=no' as command argument
# to build individual class executables (the Makefile.pdlibbuilder default.)
#
# suppress-wunused:
# When this variable is defined ('yes' or any other value), -Wunused-variable,
# -Wunused-parameter, -Wunused-value and -Wunused-function are suppressed,
# but the other warnings from -Wall are retained.
#
# PDDIR:
# Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and
# PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin.
#
# PDINCLUDEDIR:
# Directory where Pd API m_pd.h should be found, and other Pd header files.
# Overrides the default search path.
#
# PDBINDIR:
# Directory where pd.dll should be found for linking (Windows only). Overrides
# the default search path.
#
# PDLIBDIR:
# Root directory for installation of Pd library directories. Overrides the
# default install location.
#
# DESTDIR:
# Prepended path component for staged install.
#
# PLATFORM:
# Target platform for cross compilation in the form of GNU triplet:
# cpu-vendor-os. Example: x86_64-w64-mingw32. This specifies the tool chain that
# pdlibbuilder will use, if installed and locatable. System and architecture
# will then be autodefined accordingly. In most cases no other variables need to
# be overridden.
#
# extension:
# Extension for the external to use. Example: m_amd64
# A sane default is picked, but it is useful if you want to provide
# co-installable externals for multiple platforms (for the same operating
# systems)
#
# floatsize:
# the size of the t_float in bits. Example: 32
# t_float are usually single precision (32bit), which is the default.
# For double precision use floatsize=64
# When building double precision externals, you will want to set the extension
# as well, e.g. extension=windows-amd64-64.dll (--.)
#
# CPPFLAGS:
# Preprocessor flags which are not strictly required for building.
#
# CFLAGS:
# Compiler flags which are not strictly required for building. Compiler flags
# defined by Makefile.pdlibbuilder for warning, optimization and architecture
# specification are overriden by CFLAGS.
#
# LDFLAGS:
# Linker flags which are not strictly required for building. Linker flags
# defined by Makefile.pdlibbuilder for architecture specification are overriden
# by LDFLAGS.
#
# CC and CXX:
# C and C++ compiler programs as defined in your build environment.
#
# INSTALL
# Definition of install program.
#
# STRIP
# Name of strip program. Default 'strip' can be overridden in cross compilation
# environments.
#
# objectsdir:
# Root directory for installation of Pd library directories, like PDLIBDIR but
# not overridable by environment. Supported for compatibility with pd-extended
# central makefile, but deprecated otherwise.
#
# pdincludepath, pdbinpath:
# As PDINCLUDEDIR and PDBINDIR but not overridable by environment. Deprecated
# as user variables.
#
#
#=== paths =====================================================================
#
#
# Source files in directories other than current working directory must be
# prefixed with their relative path. Do not rely on VPATH or vpath.
# Object (.o) files are built in the directory of their source files.
# Executables are built in current working directory.
#
# Default search path for m_pd.h and other API header files is platform
# dependent, and overridable by PDINCLUDEDIR:
#
# Linux: /usr/include/pd
#
# OSX: /Applications/Pd*.app/Contents/Resources/src
#
# Windows: %PROGRAMFILES%/Pd/src
# %PROGRAMFILES(X86)%/Pd/src (32 bit builds on 64 bit Windows)
#
# Default search path for binary pd.dll (Windows), overridable by PDBINDIR
#
# %PROGRAMFILES%/Pd/bin
# %PROGRAMFILES(X86)%/Pd/bin (32 bit builds on 64 bit Windows)
#
# Default location to install pd libraries is platform dependent, and
# overridable by PDLIBDIR:
#
# Linux: /usr/local/lib/pd-externals
# OSX: ~/Library/Pd
# Windows: %APPDATA%/Pd
#
# https://puredata.info/docs/faq/how-do-i-install-externals-and-help-files
# The rationale for not installing to ~/pd-externals by default on Linux
# is that some people share the home dir between 32 and 64 bit installations.
#
#
#=== targets ===================================================================
#
#
# all: build $(executables) plus optional post target
# post: target to build after $(executables)
# alldebug: build all with -g option turned on for debug symbols
# : force clean build of an individual class
# .pre: make preprocessor output file in current working directory
# .lst: make asm/source output file in current working directory
#
# install: install executables and data files
# clean: remove build products from source tree
#
# help: print help text
# vars: print makefile variables
# allvars: print all variables
# depend: print generated prerequisites
# dumpmachine: print compiler output of option '-dumpmachine'
# coffee: dummy target
#
# Variable $(executables) expands to class executables plus optional shared lib,
# or alternatively to single lib executable when make-lib-executable=true.
# Targets pre and post can be defined by library makefile. Make sure to include
# Makefile.pdlibbuilder first so default target all will not be redefined.
#
#
#=== Pd-extended libdir concept ================================================
#
#
# For libdir layout as conceived by Hans-Christoph Steiner, see:
#
# https://puredata.info/docs/developer/Libdir
#
# Files README.txt, LICENSE.txt and -meta.pd are part of the libdir
# convention. Help patches for each class and abstraction are supposed to be
# available. Makefile.pdlibbuilder does not force the presence of these files
# however. It does not automatically include such files in libdir installations.
# Data files you want to include in distributions must be defined explicitly in
# your Makefile.
#
#
#=== Makefile.pdlibbuilder syntax conventions ==================================
#
#
# Makefile.pdlibbuilder variable names are lower case. Default make variables,
# environment variables, and standard user variables (CC, CXX, CFLAGS, DESTDIR)
# are upper case. Use target 'allvars' to print all variables and their values.
#
# 'Fields' in data variables are separated by dots, like in 'foo.class.sources'.
# Words in variables expressing a function or command are separated by dashes,
# like in 'make-lib-executable'.
#
#
#=== useful make options =======================================================
#
#
# Use 'make -d ' to print debug details of the make process.
# Use 'make -p ' to print make's database.
#
#
#=== TODO ======================================================================
#
#
# - decide whether to use -static-libgcc or shared dll in MinGW
# - cygwin support
# - android support
# - figure out how to handle '$' in filenames
# - add makefile template targets dpkg-source dist libdir distclean tags?
#
#
#=== end of documentation sections =============================================
#
#
################################################################################
################################################################################
################################################################################
# GNU make version 3.81 (2006) or higher is required because of the following:
# - function 'info'
# - variable '.DEFAULT_GOAL'
# force exit when make version is < 3.81
ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))), 3.81)
$(error GNU make version 3.81 or higher is required)
endif
# Relative path to externals root dir in multi-lib source tree like
# pd-extended SVN. Default is parent of current working directory. May be
# defined differently in including makefile.
externalsdir ?= ..
# variable you can use to check if Makefile.pdlibbuilder is already included
Makefile.pdlibbuilder = true
################################################################################
### target platform detection ##################################################
################################################################################
#=== target platform ===========================================================
# PLATFORM: optional user variable to define target platform for cross
# compilation. Redefine build tools accordingly. PLATFORM should match
# the exact target prefix of tools present in $PATH, like x86_64-w64-mingw32,
# x86_64-apple-darwin12 etc. Tool definitions are exported to ensure submakes
# will get the same.
ifneq ($(PLATFORM),)
ifneq ($(findstring darwin, $(PLATFORM)),)
export CC = $(PLATFORM)-cc
export CXX = $(PLATFORM)-c++
export CPP = $(PLATFORM)-cc
else
export CC = $(PLATFORM)-gcc
export CXX = $(PLATFORM)-g++
export CPP = $(PLATFORM)-cpp
endif
STRIP = $(PLATFORM)-strip
endif
# Let (native or cross-) compiler report target triplet and isolate individual
# words therein to facilitate later processing.
target.triplet := $(subst -, ,$(shell $(CC) -dumpmachine))
#=== operating system ==========================================================
# The following systems are defined: Linux, Darwin, Windows. GNU and
# GNU/kFreeBSD are treated as Linux to get the same options.
ifneq ($(filter linux gnu% kfreebsd, $(target.triplet)),)
system = Linux
endif
ifneq ($(filter darwin%, $(target.triplet)),)
system = Darwin
endif
ifneq ($(filter mingw% cygwin%, $(target.triplet)),)
system = Windows
endif
# evaluate possible system-specific multiline defines from library makefile
$(eval $(for$(system)))
# TODO: Cygwin, Android
#=== architecture ==============================================================
# The following CPU names can be processed by pdlibbuilder:
# i*86 Intel 32 bit
# x86_64 Intel 64 bit
# arm ARM 32 bit
# aarch64 ARM 64 bit
target.arch := $(firstword $(target.triplet))
################################################################################
### variables per platform #####################################################
################################################################################
#=== flags per floatsize == ====================================================
floatsize = 32
ifneq ($(filter-out 32,$(floatsize)),)
floatsize.flags = -DPD_FLOATSIZE=$(floatsize)
else
floatsize.flags =
endif
#=== flags per architecture ====================================================
# Set architecture-dependent cflags, mainly for Linux. For Mac and Windows,
# arch.c.flags are overriden below. To see gcc's default architecture flags:
# $ gcc -Q --help=target
# ARMv6: Raspberry Pi 1st gen, not detectable from target.arch
ifeq ($(shell uname -m), armv6l)
arch.c.flags = -march=armv6 -mfpu=vfp -mfloat-abi=hard
# ARMv7: Beagle, Udoo, RPi2 etc.
else ifeq ($(target.arch), arm)
arch.c.flags = -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard
# ARMv8 64 bit, not tested yet
else ifeq ($(target.arch), aarch64)
arch.c.flags = -mcpu=cortex-a53
# Intel 32 bit, build with SSE and SSE2 instructions
else ifneq ($(filter i%86, $(target.arch)),)
arch.c.flags = -march=pentium4 -mfpmath=sse -msse -msse2
# Intel/AMD 64 bit, build with SSE, SSE2 and SSE3 instructions
else ifeq ($(target.arch), x86_64)
arch.c.flags = -march=core2 -mfpmath=sse -msse -msse2 -msse3
# if none of the above architectures detected
else
arch.c.flags =
endif
#=== flags and paths for Linux =================================================
ifeq ($(system), Linux)
prefix = /usr/local
libdir := $(prefix)/lib
pkglibdir = $(libdir)/pd-externals
pdincludepath := $(wildcard /usr/include/pd)
extension = pd_linux
cpp.flags := -DUNIX
c.flags := -fPIC
c.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
c.ldlibs := -lc -lm
cxx.flags := -fPIC -fcheck-new
cxx.ldflags := -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
cxx.ldlibs := -lc -lm -lstdc++
shared.extension = so
shared.ldflags = -rdynamic -fPIC -shared -Wl,-soname,$(shared.lib)
endif
#=== flags and paths for Darwin ================================================
# LLVM-clang doesn't support -fcheck-new, therefore this flag is only used when
# compiling with g++.
ifeq ($(system), Darwin)
pkglibdir = $(HOME)/Library/Pd
pdincludepath := $(firstword $(wildcard \
/Applications/Pd*.app/Contents/Resources/src))
extension = pd_darwin
cpp.flags := -DUNIX -DMACOSX -I /sw/include
c.flags :=
c.ldflags := -undefined suppress -flat_namespace -bundle
c.ldlibs := -lc
cxx.ldflags := -undefined suppress -flat_namespace -bundle
cxx.ldlibs := -lc
shared.extension = dylib
shared.ldflags = -dynamiclib -undefined dynamic_lookup \
-install_name @loader_path/$(shared.lib) \
-compatibility_version 1 -current_version 1.0
ifneq ($(filter %g++, $(CXX)),)
cxx.flags := -fcheck-new
endif
ifeq ($(extension), d_fat)
arch := i386 x86_64
else
arch := $(target.arch)
endif
ifneq ($(filter -mmacosx-version-min=%, $(cflags)),)
version.flag := $(filter -mmacosx-version-min=%, $(cflags))
else
version.flag = -mmacosx-version-min=10.6
endif
arch.c.flags := $(addprefix -arch , $(arch)) $(version.flag)
arch.ld.flags := $(arch.c.flags)
endif
#=== flags and paths for Windows ===============================================
# Standard paths on Windows contain spaces, and GNU make functions treat such
# paths as lists, with unintended effects. Therefore we must use shell function
# ls instead of make's wildcard when probing for a path, and use double quotes
# when specifying a path in a command argument.
# Default paths in Mingw / Mingw-w64 environments. 'PROGRAMFILES' is standard
# location for builds with native architecture, 'ProgramFiles(x86)' for i686
# builds on x86_64 Windows (detection method by Lucas Cordiviola). Curly braces
# required because of parentheses in variable name.
ifeq ($(system), Windows)
pkglibdir := $(APPDATA)/Pd
ifeq ($(target.arch), i686)
programfiles := ${ProgramFiles(x86)}
else
programfiles := $(PROGRAMFILES)
endif
pdbinpath := $(programfiles)/Pd/bin
pdincludepath := $(programfiles)/Pd/src
endif
# Store default path to pd.dll in PDBINDIR if the latter is not user-defined.
# For include path this is done in the platform-independent paths section below,
# but for PDBINDIR it is done here so ld flags can be evaluated as immediate
# variables.
ifeq ($(system), Windows)
ifdef PDDIR
PDBINDIR := $(PDDIR)/bin
endif
PDBINDIR ?= $(pdbinpath)
endif
# TODO: decide whether -mms-bitfields should be specified.
ifeq ($(system), Windows)
cpp.flags := -DMSW -DNT
ifeq ($(target.arch), i686)
arch.c.flags := -march=pentium4 -msse -msse2 -mfpmath=sse
else ifeq ($(target.arch), x86_64)
cpp.flags := -DMSW -DNT -DPD_LONGINTTYPE=__int64
arch.c.flags := -march=core2 -msse -msse2 -msse3 -mfpmath=sse
else
arch.c.flags =
endif
extension = dll
c.flags :=
c.ldflags := -static-libgcc -shared \
-Wl,--enable-auto-import "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll"
c.ldlibs :=
cxx.flags := -fcheck-new
cxx.ldflags := -static-libgcc -static-libstdc++ -shared \
-Wl,--enable-auto-import "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll"
cxx.ldlibs :=
shared.extension = dll
shared.ldflags := -static-libgcc -shared "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll"
stripflags = --strip-all
endif
#=== paths =====================================================================
# Platform-dependent default paths are specified above, but overridable.
# Path variables in upper case can be defined as make command argument or in the
# environment. Variable 'objectsdir' is supported for compatibility with
# the build system that pd-l2ork has inherited from pd-extended.
PDINCLUDEDIR ?= $(pdincludepath)
PDLIBDIR ?= $(firstword $(objectsdir) $(pkglibdir))
ifdef PDDIR
PDINCLUDEDIR := $(wildcard $(PDDIR)/src)
endif
# base path where all components of the lib will be installed by default
installpath := $(DESTDIR)$(PDLIBDIR)/$(lib.name)
# check if include path contains spaces (as is often the case on Windows)
# if so, store the path so we can later do checks with it
pdincludepathwithspaces := $(if $(word 2, $(PDINCLUDEDIR)), $(PDINCLUDEDIR))
#=== accumulated build flags ===================================================
# From GNU make docs: 'Users expect to be able to specify CFLAGS freely
# themselves.' So we use CFLAGS to define options which are not strictly
# required for compilation: optimizations, architecture specifications, and
# warnings. CFLAGS can be safely overriden using a make command argument.
# Variables cflags, ldflags and ldlibs may be defined in including makefile.
optimization.flags = -O3 -ffast-math -funroll-loops -fomit-frame-pointer
warn.flags = -Wall -Wextra -Wshadow -Winline -Wstrict-aliasing
# suppress -Wunused-variable & Co if you don't want to clutter a build log
ifdef suppress-wunused
warn.flags += $(addprefix -Wno-unused-, function parameter value variable)
endif
CFLAGS = $(warn.flags) $(optimization.flags) $(arch.c.flags)
# preprocessor flags
cpp.flags := -DPD -I "$(PDINCLUDEDIR)" $(floatsize.flags) $(cpp.flags) $(CPPFLAGS)
# flags for dependency checking (cflags from makefile may define -I options)
depcheck.flags := $(cpp.flags) $(cflags)
# architecture specifications for linker are overridable by LDFLAGS
LDFLAGS := $(arch.ld.flags)
# now add the same ld flags to shared dynamic lib
shared.ldflags += $(LDFLAGS)
# accumulated flags for C compiler / linker
c.flags := $(cpp.flags) $(c.flags) $(cflags) $(CFLAGS)
c.ldflags := $(c.ldflags) $(ldflags) $(LDFLAGS)
c.ldlibs := $(c.ldlibs) $(ldlibs)
# accumulated flags for C++ compiler / linker
cxx.flags := $(cpp.flags) $(cxx.flags) $(cflags) $(CFLAGS)
cxx.ldflags := $(cxx.ldflags) $(ldflags) $(LDFLAGS)
cxx.ldlibs := $(cxx.ldlibs) $(ldlibs)
################################################################################
### variables: library name and version ########################################
################################################################################
# strip possibles spaces from lib.name, they mess up calculated file names
lib.name := $(strip $(lib.name))
# if meta file exists, check library version
metafile := $(wildcard $(lib.name)-meta.pd)
ifdef metafile
lib.version := $(shell sed -n \
's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' \
$(metafile))
endif
################################################################################
### variables: files ###########################################################
################################################################################
object.extension = $(extension).o
#=== sources ===================================================================
# (re)define .class.sources using file names in class.sources
define add-class-source
$(notdir $(basename $v)).class.sources += $v
endef
$(foreach v, $(class.sources), $(eval $(add-class-source)))
# derive class names from .class.sources variables
sourcevariables := $(filter %.class.sources, $(.VARIABLES))
classes := $(basename $(basename $(sourcevariables)))
# accumulate all source files specified in makefile
classes.sources := $(sort $(foreach v, $(sourcevariables), $($v)))
all.sources := $(classes.sources) $(lib.setup.sources) \
$(shared.sources) $(common.sources)
#=== object files ==============================================================
# construct object filenames from all C and C++ source file names
classes.objects := $(addsuffix .$(object.extension), $(basename $(classes.sources)))
common.objects := $(addsuffix .$(object.extension), $(basename $(common.sources)))
shared.objects := $(addsuffix .$(object.extension), $(basename $(shared.sources)))
lib.setup.objects := $(addsuffix .$(object.extension), $(basename $(lib.setup.sources)))
all.objects = $(classes.objects) $(common.objects) $(shared.objects) \
$(lib.setup.objects)
#=== executables ===============================================================
# construct class executable names from class names
classes.executables := $(addsuffix .$(extension), $(classes))
# Construct shared lib executable name if shared sources are defined.
# If extension does not end with shared extension, use both to facilitate co-
# installation for different platforms, like .m_i386.dll and .linux-amd64-32.so
ifdef shared.sources
ifneq ($(filter %.$(shared.extension), .$(extension)), )
# $(extension) already ends with $(shared.extension), no need to duplicate it
shared.lib = lib$(lib.name).$(extension)
else
shared.lib = lib$(lib.name).$(extension).$(shared.extension)
endif
else
shared.lib :=
endif
################################################################################
### variables: tools ###########################################################
################################################################################
# aliases so we can later define 'compile-$1' and set 'c' or 'cxx' as argument
compile-c := $(CC)
compile-cxx := $(CXX)
################################################################################
### checks #####################################################################
################################################################################
# At this point most variables are defined. Now do some checks and info's
# before rules begin.
# print Makefile.pdlibbuilder version before possible termination
$(info ++++ info: using Makefile.pdlibbuilder version $(version))
# Terminate if target triplet remained empty, to avoid all sorts of confusing
# scenarios and spurious bugs.
ifeq ($(target.triplet),)
$(error Command "$(CC) -dumpmachine" did not return a target triplet, \
needed for a build. \
Is compiler "$(CC)" installed in your PATH? ($(PATH)). \
Does compiler "$(CC)" support option "-dumpmachine"?)
endif
# 'forward declaration' of default target, needed to do checks
all:
# To avoid unpredictable results, make sure the default target is not redefined
# by including makefile.
ifneq ($(.DEFAULT_GOAL), all)
$(error Default target must be 'all'.)
endif
# find out which target(s) will be made
ifdef MAKECMDGOALS
goals := $(MAKECMDGOALS)
else
goals := all
endif
# store path to Pd API m_pd.h if it is found
ifdef PDINCLUDEDIR
mpdh := $(shell ls "$(PDINCLUDEDIR)/m_pd.h")
endif
# store path to pd.dll; if not found, ls will give a useful error
ifeq ($(system), Windows)
pddll := $(shell ls "$(PDBINDIR)/pd$(filter-out 32,$(floatsize)).dll")
endif
# when making target all, check if m_pd.h is found and print info about it
ifeq ($(goals), all)
$(if $(mpdh), \
$(info ++++ info: using Pd API $(mpdh)), \
$(warning Where is Pd API m_pd.h? Do 'make help' for info.))
endif
# print target info
$(info ++++ info: making target $(goals) $(if $(lib.name),in lib $(lib.name)))
# when installing, print installpath info
$(if $(filter install install-lib, $(goals)), $(info ++++ info: \
installpath is '$(installpath)'))
#=== define executables ========================================================
# By default we build class executables, and optionally a shared dynamic link
# lib. When make-lib-executable=yes we build all classes into a single lib
# executable, on the condition that variable lib.setup.sources is defined.
ifeq ($(make-lib-executable),yes)
$(if $(lib.setup.sources), ,\
$(error Can not build library blob because lib.setup.sources is undefined))
executables := $(lib.name).$(extension)
else
executables := $(classes.executables) $(shared.lib)
endif
################################################################################
### rules: special targets #####################################################
################################################################################
# Disable built-in rules. If some target can't be built with the specified
# rules, it should not be built at all.
MAKEFLAGS += --no-builtin-rules
.PRECIOUS:
.SUFFIXES:
.PHONY: all post build-lib \
$(classes) $(makefiledirs) $(makefiles) \
install install-executables install-datafiles install-datadirs \
force clean vars allvars depend help
################################################################################
### rules: build targets #######################################################
################################################################################
# Target all forces the build of targets [$(executables) post] in
# deterministic order. Target $(executables) builds class executables plus
# optional shared lib or alternatively a single lib executable when
# make-lib-executable=true. Target post is optionally defined by
# library makefile.
all: post
post: $(executables)
all:
$(info ++++info: target all in lib $(lib.name) completed)
# build all with -g option turned on for debug symbols
alldebug: c.flags += -g
alldebug: cxx.flags += -g
alldebug: all
#=== class executable ==========================================================
# recipe for linking objects in class executable
# argument $1 = compiler type (c or cxx)
# argument $2 = class basename
define link-class
$(compile-$1) \
$($1.ldflags) $($2.class.ldflags) \
-o $2.$(extension) \
$(addsuffix .$(object.extension), $(basename $($2.class.sources))) \
$(addsuffix .$(object.extension), $(basename $(common.sources))) \
$($1.ldlibs) $($2.class.ldlibs) $(shared.lib)
endef
# general rule for linking object files in class executable
%.$(extension): $(shared.lib)
$(info ++++ info: linking objects in $@ for lib $(lib.name))
$(if $(filter %.cc %.cpp, $($*.class.sources)), \
$(call link-class,cxx,$*), \
$(call link-class,c,$*))
#=== library blob ==============================================================
# build all classes into single executable
build-lib: $(lib.name).$(extension)
$(info ++++ info: library blob $(lib.name).$(extension) completed)
# recipe for linking objects in lib executable
# argument $1 = compiler type (c or cxx)
define link-lib
$(compile-$1) \
$($1.ldflags) $(lib.ldflags) \
-o $(lib.name).$(extension) $(all.objects) \
$($1.ldlibs) $(lib.ldlibs)
endef
# rule for linking objects in lib executable
# declared conditionally to avoid name clashes
ifeq ($(make-lib-executable),yes)
$(lib.name).$(extension): $(all.objects)
$(if $(filter %.cc %.cpp, $(all.sources)), \
$(call link-lib,cxx), \
$(call link-lib,c))
endif
#=== shared dynamic lib ========================================================
# recipe for linking objects in shared executable
# argument $1 = compiler type (c or cxx)
define link-shared
$(compile-$1) \
$(shared.ldflags) \
-o $(shared.lib) $(shared.objects) \
$($1.ldlibs) $(shared.ldlibs)
endef
# rule for linking objects in shared executable
# build recipe is in macro 'link-shared'
$(shared.lib): $(shared.objects)
$(info ++++ info: linking objects in shared lib $@)
$(if $(filter %.cc %.cpp, $(shared.sources)), \
$(call link-shared,cxx), \
$(call link-shared,c))
#=== object files ==============================================================
# recipe to make .o file from source
# argument $1 is compiler type (c or cxx)
define make-object-file
$(info ++++ info: making $@ in lib $(lib.name))
$(compile-$1) \
$($1.flags) \
-o $@ -c $<
endef
# Three rules to create .o files. These are double colon 'terminal' rules,
# meaning they are the last in a rules chain.
%.$(object.extension):: %.c
$(call make-object-file,c)
%.$(object.extension):: %.cc
$(call make-object-file,cxx)
%.$(object.extension):: %.cpp
$(call make-object-file,cxx)
#=== explicit prerequisites for class executables ==============================
# For class executables, prerequisite rules are declared in run time. Target
# 'depend' prints these rules for debugging purposes.
# declare explicit prerequisites rule like 'class: class.extension'
# argument $v is class basename
define declare-class-target
$v: $v.$(extension)
endef
# declare explicit prerequisites rule like 'class.extension: object1.o object2.o'
# argument $v is class basename
define declare-class-executable-target
$v.$(extension): $(addsuffix .$(object.extension), $(basename $($v.class.sources))) \
$(addsuffix .$(object.extension), $(basename $(common.sources)))
endef
# evaluate explicit prerequisite rules for all classes
$(foreach v, $(classes), $(eval $(declare-class-target)))
$(foreach v, $(classes), $(eval $(declare-class-executable-target)))
#=== implicit prerequisites for class executables ==============================
# Evaluating implicit prerequisites (header files) with help from the
# preprocessor is 'expensive' so this is done conditionally and selectively.
# Note that it is also possible to trigger a build via install targets, in
# which case implicit prerequisites are not checked.
# When the Pd include path contains spaces it will mess up the implicit
# prerequisites rules.
disable-dependency-tracking := $(strip $(pdincludepathwithspaces))
ifndef disable-dependency-tracking
must-build-everything := $(filter all, $(goals))
must-build-class := $(filter $(classes), $(goals))
must-build-sources := $(foreach v, $(must-build-class), $($v.class.sources))
endif
# declare implicit prerequisites rule like 'object.o: header1.h header2.h ...'
# argument $1 is input source file(s)
# dir is explicitly added because option -MM strips it by default
define declare-object-target
$(dir $1)$(patsubst %.o:,%.$(object.extension):,$(filter %.o: %.h, $(shell $(CPP) $(depcheck.flags) -MM $1))) $(MAKEFILE_LIST)
endef
# evaluate implicit prerequisite rules when rebuilding everything
ifdef must-build-everything
$(if $(wildcard $(all.objects)), \
$(info ++++ info: evaluating implicit prerequisites in lib $(lib.name).....) \
$(foreach v, $(all.sources), $(eval $(call declare-object-target, $v))))
endif
# evaluate implicit prerequisite rules when selectively building classes
ifdef must-build-class
$(foreach v, $(must-build-sources), \
$(eval $(call declare-object-target, $v)))
$(foreach v, $(shared.sources), \
$(eval $(call declare-object-target, $v)))
endif
################################################################################
### rules: preprocessor and assembly files #####################################
################################################################################
# Preprocessor and assembly output files for bug tracing etc. They are not part
# of the build processes for executables. By default these files are created in
# the current working directory. Dependency tracking is not performed, the build
# is forced instead to make sure it's up to date.
force:
#=== preprocessor file =========================================================
# make preprocessor output file with extension .pre
# argument $1 = compiler type (c or cxx)
define make-preprocessor-file
$(info ++++ info: making preprocessor output file $(notdir $*.pre) \
in current working directory)
$(compile-$1) -E $< $(c.flags) $($1.flags) -o $(notdir $*.pre)
endef
%.pre:: %.c force
$(call make-preprocessor-file,c)
%.pre:: %.cc force
$(call make-preprocessor-file,cxx)
%.pre:: %.cpp force
$(call make-preprocessor-file,cxx)
#=== assembly file =============================================================
# make C / assembly interleaved output file with extension .lst
# argument $1 = compiler type (c or cxx)
define make-assembly-file
$(info ++++ info: making assembly output file $(notdir $*.lst) \
in current working directory)
$(compile-$1) \
-c -Wa,-a,-ad -fverbose-asm \
$($1.flags) \
$< > $(notdir $*.lst)
endef
%.lst:: %.c force
$(call make-assembly-file,c)
%.lst:: %.cc force
$(call make-assembly-file,cxx)
%.lst:: %.cpp force
$(call make-assembly-file,cxx)
################################################################################
### rules: installation targets ################################################
################################################################################
#=== strip =====================================================================
# Stripping of installed binaries will only be done when variable 'stripflags'
# is defined non-empty. No default definition is provided except for Windows
# where the unstripped binaries are large, especially in the case of Mingw-w64.
# Note: while stripping all symbols ('-s' or '--strip-all') is possible for
# Linux and Windows, in the case of OSX only non-global symbols can be stripped
# (option '-x' or '--discard-all').
# Make definition of strip command overridable so it can be defined in an
# environment for cross-compilation.
STRIP ?= strip
# Commands in 'strip-executables' will be executed conditionally in the rule for
# target 'install-executables'.
strip-executables = cd "$(installpath)" && \
$(foreach v, $(executables), $(STRIP) $(stripflags) '$v';)
#=== install ===================================================================
# Install targets depend on successful exit status of target all because nothing
# must be installed in case of a build error.
# -p = preserve time stamps
# -m = set permission mode (as in chmod)
# -d = create all components of specified directories
INSTALL = install
INSTALL_PROGRAM := $(INSTALL) -p -m 644
INSTALL_DATA := $(INSTALL) -p -m 644
INSTALL_DIR := $(INSTALL) -m 755 -d
# strip spaces from file names
executables := $(strip $(executables))
datafiles := $(strip $(datafiles))
datadirs := $(strip $(datadirs))
# Do not make any install sub-target with empty variable definition because the
# install program would exit with an error.
install: $(if $(executables), install-executables)
install: $(if $(datafiles), install-datafiles)
install: $(if $(datadirs), install-datadirs)
install-executables: all
$(INSTALL_DIR) -v "$(installpath)"
$(foreach v, $(executables), \
$(INSTALL_PROGRAM) '$v' "$(installpath)";)
$(info ++++ info: executables of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
$(if $(stripflags), $(strip-executables),)
install-datafiles: all
$(INSTALL_DIR) -v "$(installpath)"
$(foreach v, $(datafiles), \
$(INSTALL_DATA) '$(v)' "$(installpath)";)
$(info ++++ info: data files of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
install-datadirs: all
$(foreach v, $(datadirs), $(INSTALL_DIR) "$(installpath)/$v";)
$(foreach v, $(datadirs), \
$(INSTALL_DATA) $(wildcard $v/*) "$(installpath)/$v";)
$(info ++++ info: data directories of lib $(lib.name) installed \
from $(CURDIR) to $(installpath))
################################################################################
### rules: distribution targets ################################################
################################################################################
# TODO
# These targets are implemented in Makefile Template, but I have to figure out
# how to do it under the not-so-strict conditions of Makefile.pdlibbuilder.
# make source package
dist:
@echo "target dist not yet implemented"
# make Debian source package
dpkg-source:
@echo "target dpkg-source not yet implemented"
$(ORIGDIR):
$(DISTDIR):
################################################################################
### rules: clean targets #######################################################
################################################################################
# delete build products from build tree
clean:
rm -f $(all.objects)
rm -f $(classes.executables) $(lib.name).$(extension) $(shared.lib)
rm -f *.pre *.lst
# remove distribution directories and tarballs from build tree
distclean: clean
@echo "target distclean not yet implemented"
################################################################################
### rules: submake targets #####################################################
################################################################################
# Iterate over sub-makefiles or makefiles in other directories.
# When 'continue-make=yes' is set, sub-makes will report 'true' to the parent
# process regardless of their real exit status. This prevents the parent make
# from being aborted by a sub-make error. Useful when you want to quickly find
# out which sub-makes from a large set will succeed.
ifeq ($(continue-make),yes)
continue = || true
endif
# These targets will trigger sub-make processes for entries in 'makefiledirs'
# and 'makefiles'.
all alldebug install clean distclean dist dkpg-source: \
$(makefiledirs) $(makefiles)
# this expands to identical rules for each entry in 'makefiledirs'
$(makefiledirs):
$(MAKE) --directory=$@ $(MAKECMDGOALS) $(continue)
# this expands to identical rules for each entry in 'makefiles'
$(makefiles):
$(MAKE) --directory=$(dir $@) --makefile=$(notdir $@) $(MAKECMDGOALS) $(continue)
################################################################################
### rules: convenience targets #################################################
################################################################################
#=== show variables ============================================================
# Several 'function' macro's cause errors when expanded within a rule or without
# proper arguments. Variables which are set with the define directive are only
# shown by name for that reason.
functions = \
add-class-source \
declare-class-target \
declare-class-executable-target \
declare-object-target \
link-class \
link-lib \
link-shared \
make-object-file \
make-preprocessor-file \
make-assembly-file
# show variables from makefiles
vars:
$(info ++++ info: showing makefile variables:)
$(foreach v,\
$(sort $(filter-out $(functions) functions, $(.VARIABLES))),\
$(if $(filter file, $(origin $v)),\
$(info variable $v = $($v))))
$(foreach v, $(functions), $(info 'function' name: $v))
@echo
# show all variables
allvars:
$(info ++++ info: showing default, automatic and makefile variables:)
$(foreach v, \
$(sort $(filter-out $(functions) functions, $(.VARIABLES))), \
$(info variable ($(origin $v)) $v = $($v)))
$(foreach v, $(functions), $(info 'function' name: $v))
@echo
#=== show dependencies =========================================================
# show generated prerequisites rules
depend:
$(info ++++ info: generated prerequisite rules)
$(foreach v, $(classes), $(info $(declare-class-target)))
$(foreach v, $(classes), $(info $(declare-class-executable-target)))
$(foreach v, $(all.sources), $(info $(call declare-object-target, $v)))
@echo
#=== show help text ============================================================
# brief info about targets and paths
ifdef mpdh
mpdhinfo := $(mpdh)
else
mpdhinfo := m_pd.h was not found. Is Pd installed?
endif
help:
@echo
@echo " Main targets:"
@echo " all: build executables (default target)"
@echo " install: install all components of the library"
@echo " vars: print makefile variables for troubleshooting"
@echo " allvars: print all variables for troubleshooting"
@echo " help: print this help text"
@echo
@echo " Pd API m_pd.h:"
@echo " $(mpdhinfo)"
@echo " You may specify your preferred Pd include directory as argument"
@echo " to the make command, like 'PDINCLUDEDIR=path/to/pd/src'."
@echo
@echo " Path for installation of your libdir(s):"
@echo " $(PDLIBDIR)"
@echo " Alternatively you may specify your path for installation as argument"
@echo " to the make command, like 'PDLIBDIR=path/to/pd-externals'."
@echo
@echo " Default paths are listed in the doc sections in Makefile.pdlibbuilder."
@echo
#=== platform test =============================================================
# This target can be used to test if the compiler for specified PLATFORM is
# correctly defined and available.
dumpmachine:
@$(CC) -dumpmachine
#=== dummy target ==============================================================
coffee:
@echo "Makefile.pdlibbuilder: Can not make coffee. Sorry."
################################################################################
### end of rules sections ######################################################
################################################################################
# for syntax highlighting in vim and github
# vim: set filetype=make:
iem_utils-0.0.20240903/iem16/pd-lib-builder/README.md 0000600 0000000 0000000 00000013146 14665566711 016204 0 ustar 00
### Makefile.pdlibbuilder ###
Helper makefile for Pure Data external libraries. Written by Katja Vetter
March-June 2015 for the public domain and since then developed as a Pd
community project. No warranties. Inspired by Hans Christoph Steiner's Makefile
Template and Stephan Beal's ShakeNMake.
GNU make version >= 3.81 required.
### characteristics ###
* defines build settings based on autodetected target platform
* defines rules to build Pd class- or lib executables from C or C++ sources
* defines rules for libdir installation
* defines convenience targets for developer and user
* evaluates implicit dependencies for non-clean builds
### basic usage ###
In your Makefile, define your Pd lib name and class files, and include
Makefile.pdlibbuilder at the end of the Makefile. Like so:
# Makefile for mylib
lib.name = mylib
class.sources = myclass1.c myclass2.c
datafiles = myclass1-help.pd myclass2-help.pd README.txt LICENSE.txt
PDLIBBUILDER_DIR=.
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
For files in class.sources it is assumed that class name == source file
basename. The default target builds all classes as individual executables
with Pd's default extension for the platform. For anything more than the
most basic usage, read the documentation sections in Makefile.pdlibbuilder.
### paths ###
Makefile.pdlibbuilder >= v0.4.0 supports pd path variables which can be
defined not only as make command argument but also in the environment, to
override platform-dependent defaults:
PDDIR:
Root directory of 'portable' pd package. When defined, PDINCLUDEDIR and
PDBINDIR will be evaluated as $(PDDIR)/src and $(PDDIR)/bin.
PDINCLUDEDIR:
Directory where Pd API m_pd.h should be found, and other Pd header files.
Overrides the default search path.
PDBINDIR:
Directory where pd.dll should be found for linking (Windows only). Overrides
the default search path.
PDLIBDIR:
Root directory for installation of Pd library directories. Overrides the
default install location.
### platform detection and predefined variables ###
Makefile.pdlibbuilder tries to detect architecture and operating system in
order to define platform-specific variables. Since v0.6.0 we let the compiler
report target platform, rather than taking the build machine as reference. This
simplifies cross compilation. The kind of build options that are predefined:
- optimizations useful for realtime DSP processing
- options strictly required for the platform
- options to make the build work accross a range of CPU's and OS versions
The exact choice and definition predefined variables changes over time, as new
platforms arrive and older platforms become obsolete. The easiest way to get an
overview for your platform is by checking the flags categories in the output of
target `vars`. Variables written in capitals (like `CFLAGS`) are intentionally
exposed as user variables, although technically all makefile variables can be
overridden by make command arguments.
### specific language versions ###
Makefile.pdlibbuilder handles C and C++, but can not detect if your code uses
features of a specific version (like C99, C++11, C++14 etc.). In such cases
your makefile should specify that version as compiler option:
cflags = -std=c++11
Also you may need to be explicit about minimum OSX version. For example, C++11
needs OSX 10.9 or higher:
define forDarwin
cflags = -mmacosx-version-min=10.9
endef
### documentation ###
This README.md provides only basic information. A large comment section inside
Makefile.pdlibbuilder lists and explains the available user variables, default
paths, and targets. The internal documentation reflects the exact functionality
of the particular version. For suggestions about project maintenance and
advanced compilation see tips-tricks.md.
### versioning ###
The project is versioned in MAJOR.MINOR.BUGFIX format (see http://semver.org),
and maintained at https://github.com/pure-data/pd-lib-builder. Pd lib developers
are invited to regulary check for updates, and to contribute and discuss
improvements here. If you really need to distribute a personalized version with
your library, rename Makefile.pdlibbuilder to avoid confusion.
### examples ###
The list of projects using pd-lib-builder can be helpful if you are looking for
examples, from the simplest use case to more complex implementations.
- helloworld: traditional illustration of simplest use case
- pd-windowing: straightforward real world use case of a small library
- pd-nilwind / pd-cyclone: more elaborate source tree
- zexy: migrated from autotools to pd-lib-builder
### projects using pd-lib-builder ###
non-exhaustive list
https://github.com/pure-data/helloworld
https://github.com/electrickery/pd-nilwind
https://github.com/electrickery/pd-maxlib
https://github.com/electrickery/pd-sigpack
https://github.com/electrickery/pd-tof
https://github.com/electrickery/pd-windowing
https://github.com/electrickery/pd-smlib
https://github.com/porres/pd-cyclone
https://github.com/porres/pd-else
https://github.com/porres/pd-psycho
https://git.iem.at/pd/comport
https://git.iem.at/pd/hexloader
https://git.iem.at/pd/iemgui
https://git.iem.at/pd/iemguts
https://git.iem.at/pd/iemlib
https://git.iem.at/pd/iemnet
https://git.iem.at/pd/iem_ambi
https://git.iem.at/pd/iem_tab
https://git.iem.at/pd/iem_adaptfilt
https://git.iem.at/pd/iem_roomsim
https://git.iem.at/pd/iem_spec2
https://git.iem.at/pd/mediasettings
https://git.iem.at/pd/zexy
https://git.iem.at/pd-gui/punish
https://github.com/residuum/PuRestJson
https://github.com/libpd/abl_link
https://github.com/wbrent/timbreID
https://github.com/MetaluNet/moonlib
iem_utils-0.0.20240903/iem16/pd-lib-builder/tips-tricks.md 0000600 0000000 0000000 00000021012 14665566711 017512 0 ustar 00 pd-lib-builder cheatsheet
=========================
# Creating special builds
## Building for non-native platform
Using pd-lib-builder >=0.6.0 we can define variable `PLATFORM` to specify a
target triplet for cross-compilation. Assuming a W32 package for Pd is unzipped
into path `${PDWIN32}`, to build for Windows 32 bit:
make PLATFORM=i686-w64-mingw32 PDDIR="${PDWIN32}"
#### Older pd-lib-builder versions
Using pd-lib-builder < 0.6.0, in the absence of variable `PLATFORM`, you would
instead override variables `system`, `target.arch`, `CC` and / or `CXX`,
`STRIP`. Example:
make system=Windows target.arch=i686 CC=i686-w64-mingw32-gcc STRIP=i686-w64-mingw32-strip PDDIR="${PDWIN32}"
#### Toolchains
To build for non-native OS and/or architecture you need a cross toolchain. On
Linux such toolchains are relatively easy to get. For example Debian Buster
amd64 provides them for the following platforms (install g++ with dependencies
for a given platform to get the whole toolchain):
- `arm-linux-gnueabihf`
- `aarch64-linux-gnu`
- `i686-linux-gnu`
- `i686-w64-mingw32` and `x86_64-w64-mingw32` (install `mingw-w64`)
Cross toolchains for OSX/MacOS are not generally distributed. Project
`osxcross` from Thomas Poechtraeger can create them for Linux.
## Universal binaries on macOS
The compiler, by default, builds for the native architecture of the build
machine. To make a "universal" multi-arch build, specify the desired
archtectures on the command line using the "arch" pd-lib-builder Makefile
variable.
For example, to build a "fat" external for both 64-bit Intel and Arm (Apple
Silicon):
make arch="x86_64 arm64"
If the build is successful, the compiled architectures in the built external can
be confirmed via the `file` command:
~~~sh
% file vbap.pd_darwin
vbap.pd_darwin: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64:Mach-O 64-bit bundle arm64]
vbap.pd_darwin (for architecture x86_64): Mach-O 64-bit bundle x86_64
vbap.pd_darwin (for architecture arm64): Mach-O 64-bit bundle arm64
~~~
Note: The available architectures depend on which macOS version & command line
tools/Xcode combination the build system has. For example, any newer macOS
10.15+ will support both x86_64 (Intel 64-bit) and arm64 (Apple Silicon) while
OSX 10.6 - macOS 10.14 can build for x86_64 and i386 (Intel 32-bit).
## Building double-precision externals
At the time of writing (2023-07-06) there is no official Pd that supports
double-precision numbers yet.
However, if you do get hold of an experimental double-precision Pd, you can
easily build your externals for 64-bit numbers, by passing `floatsize=64`
as an argument to `make`.
Starting with Pd>=0.54, double precision externals use different extensions
from traditional (single-precision) externals.
The extension consists of the OS ("linux", "darwin", "windows"), the CPU
architecture ("amd64" (x86_64), "i386" (x86), "arm64",...) and the floatsize
in bits ("64" for double-precision), followed by the system's native extension
for dynamic libraries (".dll" on Windows, ".so" on macOS/Linux/un*xes).
As of pd-lib-builder==0.7.0, you have to manually pass this extension:
make floatsize=64 extension=windows-amd64-64.dll
make floatsize=64 extension=linux-arm64-64.so
make floatsize=64 extension=darwin-fat-64.so arch="x86_64 arm64"
# Project management
In general it is advised to put the `Makefile.pdlibbuilder` into a separate
subdirectory (e.g. `pd-lib-builder/`).
This makes it much easier to update the `Makefile.pdlibbuilder` later
You *should* also use a variable to the actual path of the Makefile.pdlibbuilder
(even if you keep it in the root-directory), as this allows easy experimenting
with newer (or older) (or site-specific) versions of the pd-lib-builder
Makefile.
~~~make
PDLIBBUILDER_DIR=pd-lib-builder/
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
~~~
## Keeping pd-lib-builder up-to-date
### `git subtree`
With git-subtrees, you make the pd-lib-builder repository (or any other
repository for that matter) part of your own repository - with full history and
everything - put nicely into a distinct subdirectory.
Support for *manipulating* subtrees has been added with Git-v1.7.11 (May 2012).
The nice thing however is, that from "outside" the subtree is part of your
repository like any other directory. E.g. older versions of Git can clone your
repository with the full subtree (and all it's history) just fine.
You can also use git-archive to make a complete snapshot of your repository
(including the subtree) - nice, if you e.g. want self-contained downloads of
your project from git hosting platforms (like Github, Gitlab, Bitbucket,...)
In short, `git subtree` is the better `git submodule`.
So here's how to do it:
#### Initial setup/check-out
This will create a `pd-lib-builder/` directory containing the full history of
the pd-lib-builder repository up to its release `v0.5.0`
~~~sh
git subtree add --prefix=pd-lib-builder/ https://github.com/pure-data/pd-lib-builder v0.5.0
~~~
This will automatically merge the `pd-lib-builder/` history into your current
branch, so everything is ready to go.
#### Cloning your repository with the subtree
Nothing special, really.
Just clone your repository as always:
~~~sh
git clone https://git.example.org/pd/superbonk~.git
~~~
#### Updating the subtree
Time passes and sooner or later you will find, that there is a shiny new
pd-lib-builder with plenty of bugfixes and new features.
To update your local copy to pd-lib-builder's current `master`, simply run:
~~~sh
git subtree pull --prefix pd-lib-builder/ https://github.com/pure-data/pd-lib-builder master
~~~
#### Pulling the updated subtree into existing clones
Again, nothing special.
Just pull as always:
~~~sh
git pull
~~~
#### Further reading
More on the power of `git subtree` can be found online
- https://medium.com/@v/git-subtrees-a-tutorial-6ff568381844
- https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree
- ...
### ~~`git submodule`~~ [DISCOURAGED]
#### Initial setup/check-out
To add a new submodule to your repository, just run `git submodule add` and
commit the changes:
~~~sh
git submodule add https://github.com/pure-data/pd-lib-builder
git commit .gitmodules pd-lib-builder/ -m "Added pd-lib-builder as git-submodule"
~~~
#### Cloning your repository with the submodule
When doing a fresh clone of your repository, pass the `--recursive` option to
automatically fetch all submodules:
~~~sh
git clone --recursive https://git.example.org/pd/superbonk~.git
~~~
If you've cloned non-recursively, you can initialize and update the submodules
manually:
~~~sh
git submodule init
git submodule update
~~~
#### Updating the submodule
Submodules are usually fixed to a given commit in their repository.
To update the `pd-lib-builder` submodule to the current `master` do something
like:
~~~sh
cd pd-lib-builder
git checkout master
git pull
cd ..
git status pd-lib-builder
git commit pd-lib-builder -m "Updated pd-lib-builder to current master"
~~~
#### Pulling the updated submodule into existing clones
After you have pushed the submodule updates in your repository, other clones of
the repository can be updated as follows:
~~~sh
git pull
~~~
The above will make your repository aware, that the submodule is out-of-sync.
~~~sh
$ LANG=C git status pd-lib-builder
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: pd-lib-builder (new commits)
$
~~~
In order to sync the submodule to the correct commit, run the following:
~~~sh
git submodule update
~~~
#### Drawbacks
`git submodule` has a number of drawbacks:
- it requires special commands to synchronize the submodules, in addition to
synching your repository.
- you must make sure to use an URL for the submodule that is accessible to your
potential users. e.g. using `git@github.com:pure-data/pd-lib-builder` is bad,
because it requires everybody who wants to checkout your sources to have a
github-account - even if they could checkout *your* repository anonymously.
- submodules will be excluded from `git archive`. This means, that if you use a
mainstream git provider (like Github, GitLab, Bitbucket,...) and make releases
by creating a `git tag`, the automatically generated zipfiles with the sources
will lack the submodule - and your users will not be able to compile your
source code.
In general, I would suggest to **avoid** `git submodule`, and instead use the
better `git subtree` (above).
iem_utils-0.0.20240903/iem16/tab16play~-help.pd 0000600 0000000 0000000 00000003330 14665566711 015400 0 ustar 00 #N canvas 159 54 804 495 10;
#X msg 639 93 \; pd dsp 0;
#X floatatom 11 342 0 0 0 0 - - -;
#X msg 11 109 set array99;
#X text 93 109 "set" message permits you to switch between arrays;
#X text 138 228 creation argument initializes array name;
#X obj 11 316 env~ 16384;
#X obj 87 360 dac~ 1;
#X obj 87 323 *~;
#X obj 100 304 line~;
#X msg 100 263 0.1 100;
#X msg 116 284 0 100;
#X text 162 264 on;
#X text 157 283 off;
#X text 148 301 envelope;
#X text 148 312 generator;
#X text 101 248 amplitude controls:;
#X text 131 362 audio output;
#X obj 87 342 hip~ 5;
#X msg 26 179 0 44100;
#X msg 27 158 44100;
#X msg 26 138 bang;
#X text 80 136 "bang" or 0 plays whole sample;
#X text 82 157 play starting at 44100th sample;
#X text 93 177 play starting at beginning for 44100 samples;
#X msg 25 199 44100 1000;
#X text 103 198 play from 44100 through 45099 (1000 samples);
#X obj 589 205 table16 array99;
#X text 389 444 updated for iem16 version1.0;
#X obj 5 439 tab16write~;
#X obj 5 458 tab16read4~;
#X obj 89 458 tab16read;
#X obj 89 439 tab16write;
#X obj 166 439 tab16send~;
#X obj 166 458 tab16receive~;
#X obj 32 13 tab16play~;
#X text 29 43 The [tab16play~] object is the same as the [tabplay~]
object \, but it refers to 16bit-arrays stored in [table16] instead
of floating-point arrays (stored in normal pd-tables/arrays);
#X obj 328 444 table16;
#X text 11 417 see also:;
#X text 108 14 play a 16bit-table as a sample (non-transposing);
#X obj 11 228 tab16play~ array99;
#X connect 2 0 39 0;
#X connect 5 0 1 0;
#X connect 7 0 17 0;
#X connect 8 0 7 1;
#X connect 9 0 8 0;
#X connect 10 0 8 0;
#X connect 17 0 6 0;
#X connect 18 0 39 0;
#X connect 19 0 39 0;
#X connect 20 0 39 0;
#X connect 24 0 39 0;
#X connect 39 0 5 0;
#X connect 39 0 7 0;
iem_utils-0.0.20240903/iem16/tab16play~.c 0000600 0000000 0000000 00000007004 14665566711 014273 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
#include "iem16_table.h"
/* ------------ tab16play~ - non-transposing sample playback --------------- */
static t_class *tab16play_tilde_class;
typedef struct _tab16play_tilde{
t_object x_obj;
t_outlet *x_bangout;
int x_phase;
int x_nsampsintab;
int x_limit;
t_iem16_16bit *x_vec;
t_symbol *x_arrayname;
} t_tab16play_tilde;
static void *tab16play_tilde_new(t_symbol *s){
t_tab16play_tilde *x = (t_tab16play_tilde *)pd_new(tab16play_tilde_class);
x->x_phase = 0x7fffffff;
x->x_limit = 0;
x->x_arrayname = s;
outlet_new(&x->x_obj, gensym("signal"));
x->x_bangout = outlet_new(&x->x_obj, gensym("bang"));
return (x);
}
static t_int *tab16play_tilde_perform(t_int *w){
t_tab16play_tilde *x = (t_tab16play_tilde *)(w[1]);
t_float *out = (t_float *)(w[2]);
t_iem16_16bit *fp;
int n = (int)(w[3]), phase = x->x_phase,
endphase = (x->x_nsampsintab < x->x_limit ?
x->x_nsampsintab : x->x_limit), nxfer, n3;
if (!x->x_vec || phase >= endphase) goto zero;
nxfer = endphase - phase;
fp = x->x_vec + phase;
if (nxfer > n)
nxfer = n;
n3 = n - nxfer;
phase += nxfer;
while (nxfer--) *out++ = *fp++*IEM16_SCALE_DOWN;
if (phase >= endphase) {
x->x_phase = 0x7fffffff;
while (n3--) *out++ = 0;
}
else x->x_phase = phase;
return (w+4);
zero:
while (n--) *out++ = 0;
return (w+4);
}
void tab16play_tilde_set(t_tab16play_tilde *x, t_symbol *s){
t_table16 *a;
x->x_arrayname = s;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
if (*s->s_name) pd_error(x, "tab16play~: %s: no such table16",
x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!table16_getarray16(a, &x->x_nsampsintab, &x->x_vec)) {
pd_error(x, "%s: bad template for tab16play~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else table16_usedindsp(a);
}
static void tab16play_tilde_dsp(t_tab16play_tilde *x, t_signal **sp){
tab16play_tilde_set(x, x->x_arrayname);
dsp_add(tab16play_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void tab16play_tilde_list(t_tab16play_tilde *x, t_symbol *s,
int argc, t_atom *argv){
(void)s; /* unused */
long start = atom_getfloatarg(0, argc, argv);
long length = atom_getfloatarg(1, argc, argv);
if (start < 0) start = 0;
if (length <= 0)x->x_limit = 0x7fffffff;
else x->x_limit = start + length;
x->x_phase = start;
}
static void tab16play_tilde_stop(t_tab16play_tilde *x){
x->x_phase = 0x7fffffff;
}
void tab16play_tilde_setup(void){
tab16play_tilde_class = class_new(gensym("tab16play~"),
(t_newmethod)tab16play_tilde_new, 0,
sizeof(t_tab16play_tilde), 0, A_DEFSYM, 0);
class_addmethod(tab16play_tilde_class, (t_method)tab16play_tilde_dsp,
gensym("dsp"), A_CANT, 0);
class_addmethod(tab16play_tilde_class, (t_method)tab16play_tilde_stop,
gensym("stop"), 0);
class_addmethod(tab16play_tilde_class, (t_method)tab16play_tilde_set,
gensym("set"), A_DEFSYM, 0);
class_addlist(tab16play_tilde_class, tab16play_tilde_list);
}
iem_utils-0.0.20240903/iem16/tab16read-help.pd 0000600 0000000 0000000 00000001545 14665566711 015156 0 ustar 00 #N canvas 245 143 703 316 12;
#X text 62 102 index;
#X floatatom 25 103 0 0 0 0 - - -;
#X floatatom 25 199 0 0 0 0 - - -;
#X text 70 197 output = array99[index];
#X text 189 157 creation argument;
#X text 185 175 gives array name;
#X msg 35 125 set array99;
#X text 147 125 change array name;
#X obj 422 131 table16 array99;
#X obj 17 13 tab16read;
#X text 412 257 updated for iem16 version1.0;
#X obj 16 252 tab16write~;
#X obj 16 271 tab16read4~;
#X obj 120 271 tab16read;
#X obj 120 252 tab16write;
#X obj 217 252 tab16send~;
#X obj 217 271 tab16receive~;
#X obj 339 257 table16;
#X text 108 15 - read numbers from a 16bit-table;
#X text 21 42 since [table16] can only hold 16bit values \, the output
of [tab16read] is limited to integer-values between -32768..+32767
;
#X obj 25 165 tab16read array99;
#X connect 1 0 20 0;
#X connect 6 0 20 0;
#X connect 20 0 2 0;
iem_utils-0.0.20240903/iem16/tab16read.c 0000600 0000000 0000000 00000003267 14665566711 014052 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16read, tab16read4, tab16write */
#include "iem16_table.h"
/* ---------- tab16read: control, non-interpolating ------------------------ */
static t_class *tab16read_class;
typedef struct _tab16read{
t_object x_obj;
t_symbol *x_arrayname;
} t_tab16read;
static void tab16read_float(t_tab16read *x, t_float f){
t_table16 *a;
int npoints;
t_iem16_16bit *vec;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class)))
pd_error(x, "%s: no such table16", x->x_arrayname->s_name);
else if (!table16_getarray16(a, &npoints, &vec))
pd_error(x, "%s: bad template for tab16read", x->x_arrayname->s_name);
else {
int n = f;
if (n < 0) n = 0;
else if (n >= npoints) n = npoints - 1;
outlet_float(x->x_obj.ob_outlet, (npoints ? vec[n] : 0));
}
}
static void tab16read_set(t_tab16read *x, t_symbol *s){
x->x_arrayname = s;
}
static void *tab16read_new(t_symbol *s){
t_tab16read *x = (t_tab16read *)pd_new(tab16read_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, gensym("float"));
return (x);
}
void tab16read_setup(void){
tab16read_class = class_new(gensym("tab16read"), (t_newmethod)tab16read_new,
0, sizeof(t_tab16read), 0, A_DEFSYM, 0);
class_addfloat(tab16read_class, (t_method)tab16read_float);
class_addmethod(tab16read_class, (t_method)tab16read_set, gensym("set"),
A_SYMBOL, 0);
}
iem_utils-0.0.20240903/iem16/tab16read4.c 0000600 0000000 0000000 00000004332 14665566711 014130 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16read, tab16read4, tab16write */
#include "iem16_table.h"
/* ---------- tab16read4: control, non-interpolating ------------------------ */
static t_class *tab16read4_class;
typedef struct _tab16read4{
t_object x_obj;
t_symbol *x_arrayname;
} t_tab16read4;
static void tab16read4_float(t_tab16read4 *x, t_float f){
t_table16 *array;
int npoints;
t_iem16_16bit *vec;
if (!(array = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class)))
pd_error(x, "%s: no such table16", x->x_arrayname->s_name);
else if (!table16_getarray16(array, &npoints, &vec))
pd_error(x, "%s: bad template for tab16read4", x->x_arrayname->s_name);
else if (npoints < 4)
outlet_float(x->x_obj.ob_outlet, 0);
else if (f <= 1)
outlet_float(x->x_obj.ob_outlet, vec[1]);
else if (f >= npoints - 2)
outlet_float(x->x_obj.ob_outlet, vec[npoints - 2]);
else {
int n = f;
float a, b, c, d, cminusb, frac;
t_iem16_16bit *fp;
if (n >= npoints - 2) n = npoints - 3;
fp = vec + n;
frac = f - n;
a = fp[-1];
b = fp[0];
c = fp[1];
d = fp[2];
cminusb = c-b;
outlet_float(x->x_obj.ob_outlet,
b + frac *
(cminusb - 0.5f * (frac-1.) *
((a - d + 3.0f * cminusb) * frac
+ (b - a - cminusb))));
}
}
static void tab16read4_set(t_tab16read4 *x, t_symbol *s){
x->x_arrayname = s;
}
static void *tab16read4_new(t_symbol *s){
t_tab16read4 *x = (t_tab16read4 *)pd_new(tab16read4_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, gensym("float"));
return (x);
}
void tab16read4_setup(void){
tab16read4_class = class_new(gensym("tab16read4"), (t_newmethod)tab16read4_new,
0, sizeof(t_tab16read4), 0, A_DEFSYM, 0);
class_addfloat(tab16read4_class, (t_method)tab16read4_float);
class_addmethod(tab16read4_class, (t_method)tab16read4_set, gensym("set"),
A_SYMBOL, 0);
}
iem_utils-0.0.20240903/iem16/tab16read4~-help.pd 0000600 0000000 0000000 00000002536 14665566711 015441 0 ustar 00 #N canvas 59 33 741 466 10;
#X text 21 207 signal input x(n);
#X text 127 21 4-point-interpolating table lookup;
#X obj 11 316 snapshot~;
#X obj 30 290 metro 200;
#X obj 11 124 sig~;
#X floatatom 11 98 0 0 0 0 - - -;
#X obj 30 264 r readout;
#X floatatom 11 342 0 0 0 0 - - -;
#X text 49 94 incoming signal is index. Indices should range from 1
to (size-2) so that the 4-point interpolation is meaningful. You can
shift-drag the number box to see the effect of interpolation.;
#X msg 34 158 set array99;
#X text 116 158 "set" message permits you to switch between arrays
;
#X text 149 228 creation argument initializes array name;
#X obj 460 301 table16 array99;
#X text 395 400 updated for iem16 version1.0;
#X obj 11 395 tab16write~;
#X obj 11 414 tab16read4~;
#X obj 95 414 tab16read;
#X obj 95 395 tab16write;
#X obj 172 395 tab16send~;
#X obj 172 414 tab16receive~;
#X obj 334 400 table16;
#X obj 47 21 tab16read4~;
#X text 7 51 tab16read4~ is used to build samplers and other table
lookup algorithms. The interpolation scheme is 4-point polynomial.
;
#X text 185 266 since [table16] can only hold 16bit-values \, the stored
integer values -32768..+32767 are converted to floats -1.0..+1.0;
#X obj 10 228 tab16read4~ array99;
#X connect 2 0 7 0;
#X connect 3 0 2 0;
#X connect 4 0 24 0;
#X connect 5 0 4 0;
#X connect 6 0 3 0;
#X connect 9 0 24 0;
#X connect 24 0 2 0;
iem_utils-0.0.20240903/iem16/tab16read4~.c 0000600 0000000 0000000 00000006112 14665566711 014324 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
#include "iem16_table.h"
/******************** tab16read4~ ***********************/
static t_class *tab16read4_tilde_class;
typedef struct _tab16read4_tilde{
t_object x_obj;
int x_npoints;
t_iem16_16bit *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tab16read4_tilde;
static void *tab16read4_tilde_new(t_symbol *s){
t_tab16read4_tilde *x = (t_tab16read4_tilde *)pd_new(tab16read4_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *tab16read4_tilde_perform(t_int *w){
t_tab16read4_tilde *x = (t_tab16read4_tilde *)(w[1]);
t_float *in = (t_float *)(w[2]);
t_float *out = (t_float *)(w[3]);
int n = (int)(w[4]);
int maxindex;
t_iem16_16bit *buf = x->x_vec;
t_iem16_16bit *fp;
int i;
maxindex = x->x_npoints - 3;
if (!buf) goto zero;
for (i = 0; i < n; i++) {
float findex = *in++;
int index = findex;
float frac, a, b, c, d, cminusb;
if (index < 1) index = 1, frac = 0;
else if (index > maxindex) index = maxindex, frac = 1;
else frac = findex - index;
fp = buf + index;
a = fp[-1]*IEM16_SCALE_DOWN;
b = fp[0]*IEM16_SCALE_DOWN;
c = fp[1]*IEM16_SCALE_DOWN;
d = fp[2]*IEM16_SCALE_DOWN;
cminusb = c-b;
*out++ = b + frac *
(cminusb - 0.5f * (frac-1.) *
((a - d + 3.0f * cminusb) * frac
+ (b - a - cminusb)));
}
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tab16read4_tilde_set(t_tab16read4_tilde *x, t_symbol *s){
t_table16 *a;
x->x_arrayname = s;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
if (*s->s_name)
pd_error(x, "tab16read4~: %s: no such table16", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!table16_getarray16(a, &x->x_npoints, &x->x_vec)) {
pd_error(x, "%s: bad template for tab16read4~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else table16_usedindsp(a);
}
static void tab16read4_tilde_dsp(t_tab16read4_tilde *x, t_signal **sp){
tab16read4_tilde_set(x, x->x_arrayname);
dsp_add(tab16read4_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void tab16read4_tilde_setup(void){
tab16read4_tilde_class = class_new(gensym("tab16read4~"),
(t_newmethod)tab16read4_tilde_new, 0,
sizeof(t_tab16read4_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tab16read4_tilde_class, t_tab16read4_tilde, x_f);
class_addmethod(tab16read4_tilde_class, (t_method)tab16read4_tilde_dsp,
gensym("dsp"), A_CANT, 0);
class_addmethod(tab16read4_tilde_class, (t_method)tab16read4_tilde_set,
gensym("set"), A_SYMBOL, 0);
}
iem_utils-0.0.20240903/iem16/tab16read~.c 0000600 0000000 0000000 00000005227 14665566711 014246 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
#include "iem16_table.h"
/******************** tab16read~ ***********************/
static t_class *tab16read_tilde_class;
typedef struct _tab16read_tilde{
t_object x_obj;
int x_npoints;
t_iem16_16bit *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tab16read_tilde;
static void *tab16read_tilde_new(t_symbol *s){
t_tab16read_tilde *x = (t_tab16read_tilde *)pd_new(tab16read_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *tab16read_tilde_perform(t_int *w){
t_tab16read_tilde *x = (t_tab16read_tilde *)(w[1]);
t_float *in = (t_float *)(w[2]);
t_float *out = (t_float *)(w[3]);
int n = (int)(w[4]);
int maxindex;
t_iem16_16bit *buf = x->x_vec;
int i;
maxindex = x->x_npoints - 1;
if (!buf) goto zero;
for (i = 0; i < n; i++) {
int index = *in++;
if (index < 0) index = 0;
else if (index > maxindex) index = maxindex;
*out++ = buf[index]*IEM16_SCALE_DOWN;
}
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tab16read_tilde_set(t_tab16read_tilde *x, t_symbol *s){
t_table16 *a;
x->x_arrayname = s;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
if (*s->s_name)
pd_error(x, "tab16read~: %s: no such table16", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!table16_getarray16(a, &x->x_npoints, &x->x_vec)) {
pd_error(x, "%s: bad template for tab16read~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else table16_usedindsp(a);
}
static void tab16read_tilde_dsp(t_tab16read_tilde *x, t_signal **sp){
tab16read_tilde_set(x, x->x_arrayname);
dsp_add(tab16read_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void tab16read_tilde_setup(void){
tab16read_tilde_class = class_new(gensym("tab16read~"),
(t_newmethod)tab16read_tilde_new, 0,
sizeof(t_tab16read_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tab16read_tilde_class, t_tab16read_tilde, x_f);
class_addmethod(tab16read_tilde_class, (t_method)tab16read_tilde_dsp,
gensym("dsp"), A_CANT, 0);
class_addmethod(tab16read_tilde_class, (t_method)tab16read_tilde_set,
gensym("set"), A_SYMBOL, 0);
}
iem_utils-0.0.20240903/iem16/tab16receive~-help.pd 0000600 0000000 0000000 00000001144 14665566711 016056 0 ustar 00 #N canvas 109 83 646 239 12;
#X obj 328 181 table16;
#X text 17 53 creation argument: name of array;
#X text 16 83 By default a block is 64 samples \; this can be reset
using the block~ object.;
#X obj 21 18 tab16receive~;
#X text 376 199 updated for iem16 version1.0;
#X obj 5 176 tab16write~;
#X obj 5 195 tab16read4~;
#X obj 109 195 tab16read;
#X obj 109 176 tab16write;
#X obj 204 176 tab16send~;
#X obj 204 195 tab16receive~;
#X text 17 155 see also:;
#X text 129 18 - read a block of a 16bit-signal from an array continuously
;
#X text 10 129 16bit-signals are limited to 65536 values between -1.0..+1.0
;
iem_utils-0.0.20240903/iem16/tab16receive~.c 0000600 0000000 0000000 00000004172 14665566711 014753 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
#include "iem16_table.h"
/* ------------------------ tab16receive~ ------------------------- */
static t_class *tab16receive_class;
typedef struct _tab16receive{
t_object x_obj;
t_iem16_16bit *x_vec;
t_symbol *x_arrayname;
} t_tab16receive;
static t_int *tab16receive_perform(t_int *w){
t_tab16receive *x = (t_tab16receive *)(w[1]);
t_float *out = (t_float *)(w[2]);
int n = w[3];
t_iem16_16bit *from = x->x_vec;
if (from) while (n--) *out++ = *from++*IEM16_SCALE_DOWN;
else while (n--) *out++ = 0;
return (w+4);
}
static void tab16receive_dsp(t_tab16receive *x, t_signal **sp){
t_table16 *a;
int vecsize;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
if (*x->x_arrayname->s_name)
pd_error(x, "tab16send~: %s: no such table16", x->x_arrayname->s_name);
}
else if (!table16_getarray16(a, &vecsize, &x->x_vec))
pd_error(x, "%s: bad template for tab16receive~", x->x_arrayname->s_name);
else {
int n = sp[0]->s_n;
if (n < vecsize) vecsize = n;
table16_usedindsp(a);
dsp_add(tab16receive_perform, 3, x, sp[0]->s_vec, vecsize);
}
}
static void *tab16receive_new(t_symbol *s){
t_tab16receive *x = (t_tab16receive *)pd_new(tab16receive_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
static void tab16receive_setup(void){
tab16receive_class = class_new(gensym("tab16receive~"),
(t_newmethod)tab16receive_new, 0,
sizeof(t_tab16receive), 0, A_DEFSYM, 0);
class_addmethod(tab16receive_class, (t_method)tab16receive_dsp,
gensym("dsp"), A_CANT, 0);
}
// G.Holzmann: for PD-extended build system
void tab16receive_tilde_setup(void)
{
tab16receive_setup();
}
iem_utils-0.0.20240903/iem16/tab16send~-help.pd 0000600 0000000 0000000 00000001262 14665566711 015366 0 ustar 00 #N canvas 151 91 705 277 12;
#X obj 328 221 table16;
#X text 113 26 writes one block of a signal continuously to an array
;
#X text 41 60 creation argument: name of array;
#X text 29 96 By default a block is 64 samples \; this can be reset
using the block~ object.;
#X text 376 239 updated for iem16 version1.0;
#X obj 5 216 tab16write~;
#X obj 5 235 tab16read4~;
#X obj 109 235 tab16read;
#X obj 109 216 tab16write;
#X obj 204 216 tab16send~;
#X obj 204 235 tab16receive~;
#X text 17 195 see also:;
#X text 14 137 16bit-signals are limited to 65536 values between -1.0..+1.0
;
#X text 16 157 if your signal has absolute values >1.0 \, these are
wrapped around...;
#X obj 11 27 tab16send~;
iem_utils-0.0.20240903/iem16/tab16send~.c 0000600 0000000 0000000 00000004414 14665566711 014261 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
#include "iem16_table.h"
/* ------------------------ tab16send~ ------------------------- */
static t_class *tab16send_class;
typedef struct _tab16send{
t_object x_obj;
t_iem16_16bit *x_vec;
int x_graphperiod;
int x_graphcount;
t_symbol *x_arrayname;
float x_f;
} t_tab16send;
static void *tab16send_new(t_symbol *s){
t_tab16send *x = (t_tab16send *)pd_new(tab16send_class);
x->x_graphcount = 0;
x->x_arrayname = s;
x->x_f = 0;
return (x);
}
static t_int *tab16send_perform(t_int *w){
t_tab16send *x = (t_tab16send *)(w[1]);
t_float *in = (t_float *)(w[2]);
int n = w[3];
t_iem16_16bit *dest = x->x_vec;
int i = x->x_graphcount;
if (!x->x_vec) goto bad;
while (n--) *dest = *in++*IEM16_SCALE_UP;
if (!i--)i = x->x_graphperiod;
x->x_graphcount = i;
bad:
return (w+4);
}
static void tab16send_dsp(t_tab16send *x, t_signal **sp){
int vecsize;
t_table16 *a;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
if (*x->x_arrayname->s_name)
pd_error(x, "tab16send~: %s: no such table16", x->x_arrayname->s_name);
}
else if (!table16_getarray16(a, &vecsize, &x->x_vec))
pd_error(x, "%s: bad template for tab16send~", x->x_arrayname->s_name);
else {
int n = sp[0]->s_n;
int ticksper = sp[0]->s_sr/n;
if (ticksper < 1) ticksper = 1;
x->x_graphperiod = ticksper;
if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
if (n < vecsize) vecsize = n;
table16_usedindsp(a);
dsp_add(tab16send_perform, 3, x, sp[0]->s_vec, vecsize);
}
}
void tab16send_tilde_setup(void){
tab16send_class = class_new(gensym("tab16send~"),
(t_newmethod)tab16send_new, 0,
sizeof(t_tab16send), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tab16send_class, t_tab16send, x_f);
class_addmethod(tab16send_class, (t_method)tab16send_dsp, gensym("dsp"), A_CANT, 0);
}
iem_utils-0.0.20240903/iem16/tab16write-help.pd 0000600 0000000 0000000 00000001627 14665566711 015376 0 ustar 00 #N canvas 44 17 653 456 12;
#X floatatom 39 96 0 0 0 0 - - -;
#X floatatom 176 170 0 0 0 0 - - -;
#X text 208 192 creation argument;
#X text 210 210 is array name;
#X text 76 87 set y value;
#X text 74 152 right inlet selects x value;
#X msg 55 117 set array99;
#X text 163 116 change array name;
#X text 388 378 updated for iem16 version1.0;
#X obj 340 360 table16;
#X obj 438 156 table16 array99;
#X text 133 28 write numbers to a 16bit-table;
#X text 20 256 since [table16] can only hold 16bit-values \, the stored
numbers have to be integer (ok \, we take care of this!) values between
-32768..+32767.;
#X obj 39 195 tab16write array99;
#X obj 31 27 tab16write;
#X obj 17 355 tab16write~;
#X obj 17 374 tab16read4~;
#X obj 121 374 tab16read;
#X obj 121 355 tab16write;
#X obj 216 355 tab16send~;
#X obj 216 374 tab16receive~;
#X text 29 334 see also:;
#X connect 0 0 13 0;
#X connect 1 0 13 1;
#X connect 6 0 13 0;
iem_utils-0.0.20240903/iem16/tab16write.c 0000600 0000000 0000000 00000003323 14665566711 014262 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16read, tab16read4, tab16write */
#include "iem16_table.h"
/* ------------------ tab16write: control ------------------------ */
static t_class *tab16write_class;
typedef struct _tab16write {
t_object x_obj;
t_symbol *x_arrayname;
float x_ft1;
int x_set;
} t_tab16write;
static void tab16write_float(t_tab16write *x, t_float f) {
int vecsize;
t_table16 *a;
t_iem16_16bit *vec;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class)))
pd_error(x, "%s: no such table16", x->x_arrayname->s_name);
else if (!table16_getarray16(a, &vecsize, &vec))
pd_error(x, "%s: bad template for tab16write", x->x_arrayname->s_name);
else {
int n = x->x_ft1;
if (n < 0) n = 0;
else if (n >= vecsize) n = vecsize-1;
vec[n] = f;
}
}
static void tab16write_set(t_tab16write *x, t_symbol *s){
x->x_arrayname = s;
}
static void *tab16write_new(t_symbol *s){
t_tab16write *x = (t_tab16write *)pd_new(tab16write_class);
x->x_ft1 = 0;
x->x_arrayname = s;
floatinlet_new(&x->x_obj, &x->x_ft1);
return (x);
}
void tab16write_setup(void){
tab16write_class = class_new(gensym("tab16write"),
(t_newmethod)tab16write_new, 0,
sizeof(t_tab16write), 0, A_DEFSYM, 0);
class_addfloat(tab16write_class, (t_method)tab16write_float);
class_addmethod(tab16write_class, (t_method)tab16write_set, gensym("set"), A_SYMBOL, 0);
}
iem_utils-0.0.20240903/iem16/tab16write~-help.pd 0000600 0000000 0000000 00000002001 14665566711 015557 0 ustar 00 #N canvas 119 134 697 433 10;
#X msg 43 131 bang;
#X obj 23 82 sig~ 3000;
#X obj 23 110 phasor~;
#X text 158 213 creation argument initializes array name;
#X msg 40 181 set array99;
#X msg 445 35 \; pd dsp 1;
#X msg 524 37 \; pd dsp 0;
#X text 85 133 bang to start recording;
#X text 126 180 set the destination array;
#X msg 43 153 stop;
#X text 85 154 stop recording;
#X text 385 366 updated for iem16 version1.0;
#X obj 337 348 table16;
#X text 26 322 see also:;
#X obj 22 211 tab16write~ array99;
#X obj 492 160 table16 array99;
#X obj 31 27 tab16write~;
#X text 120 27 object to write a 16bit-signal in an array;
#X text 261 261 since [table16] can only hold 16bit-values \, the incoming
signal (-1.0..+1.0) is stored as integer values -32768..+32767;
#X obj 14 343 tab16write~;
#X obj 14 362 tab16read4~;
#X obj 118 362 tab16read;
#X obj 118 343 tab16write;
#X obj 213 343 tab16send~;
#X obj 213 362 tab16receive~;
#X connect 0 0 14 0;
#X connect 1 0 2 0;
#X connect 2 0 14 0;
#X connect 4 0 14 0;
#X connect 9 0 14 0;
iem_utils-0.0.20240903/iem16/tab16write~.c 0000600 0000000 0000000 00000005724 14665566711 014467 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
#include "iem16_table.h"
/* ------------------------- tab16write~ -------------------------- */
static t_class *tab16write_tilde_class;
typedef struct _tab16write_tilde {
t_object x_obj;
int x_phase;
int x_nsampsintab;
short *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tab16write_tilde;
static void *tab16write_tilde_new(t_symbol *s) {
t_tab16write_tilde *x = (t_tab16write_tilde *)pd_new(tab16write_tilde_class);
x->x_phase = 0x7fffffff;
x->x_arrayname = s;
x->x_f = 0;
return (x);
}
static t_int *tab16write_tilde_perform(t_int *w) {
t_tab16write_tilde *x = (t_tab16write_tilde *)(w[1]);
t_float *in = (t_float *)(w[2]);
int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
if (!x->x_vec) goto bad;
if (endphase > phase) {
int nxfer = endphase - phase;
t_iem16_16bit *fp = x->x_vec + phase;
if (nxfer > n) nxfer = n;
phase += nxfer;
while (nxfer--)*fp++ = *in++*IEM16_SCALE_UP;
x->x_phase = phase;
}
bad:
return (w+4);
}
void tab16write_tilde_set(t_tab16write_tilde *x, t_symbol *s){
t_table16 *a;
x->x_arrayname = s;
if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
if (*s->s_name) pd_error(x, "tab16write~: %s: no such table16",
x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!table16_getarray16(a, &x->x_nsampsintab, &x->x_vec)) {
pd_error(x, "%s: bad template for tab16write~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else table16_usedindsp(a);
}
static void tab16write_tilde_dsp(t_tab16write_tilde *x, t_signal **sp){
tab16write_tilde_set(x, x->x_arrayname);
dsp_add(tab16write_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void tab16write_tilde_bang(t_tab16write_tilde *x){
x->x_phase = 0;
}
static void tab16write_tilde_stop(t_tab16write_tilde *x){
x->x_phase = x->x_nsampsintab;
}
void tab16write_tilde_setup(void){
tab16write_tilde_class = class_new(gensym("tab16write~"),
(t_newmethod)tab16write_tilde_new, 0,
sizeof(t_tab16write_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tab16write_tilde_class, t_tab16write_tilde, x_f);
class_addmethod(tab16write_tilde_class, (t_method)tab16write_tilde_dsp,
gensym("dsp"), A_CANT, 0);
class_addmethod(tab16write_tilde_class, (t_method)tab16write_tilde_set,
gensym("set"), A_SYMBOL, 0);
class_addmethod(tab16write_tilde_class, (t_method)tab16write_tilde_stop,
gensym("stop"), 0);
class_addbang(tab16write_tilde_class, tab16write_tilde_bang);
}
iem_utils-0.0.20240903/iem16/table16-help.pd 0000600 0000000 0000000 00000004655 14665566711 014650 0 ustar 00 #N canvas 37 0 856 640 10;
#X obj 30 21 table16;
#X text 97 22 16bit-table;
#X text 32 51 [table16] stores 16bit values. The normal pd-tables ([table]
\, array) store the values as floating-points. While floating points
are (often) more precise (this is of course not really true... \, esp.
when comparing integer(4byte) to floating-point.) they use a lot of
memory (4byte).;
#X text 32 121 [table16] uses only 16bit (2bytes) to store the values
\, which is half of the memory.;
#X text 32 155 However there are 2 major drawbacks;
#X text 53 172 a) less precision means less SNR - you can only store
65536 different values \, but this is what CD-quality is (should be
good enough for most musical applications);
#X text 55 221 b) the 65536 values (-32678..+32767) are mapped to -1.0..+1.0!
This means you cannot store signals that exceed this magical limit.
Please make sure \, that the signal has correct values (use [clip~])
or the unclipped values will get wrapped!;
#X text 20 323 There are several objects to access the data of [table16]:
;
#X obj 55 344 tab16write~;
#X obj 55 363 tab16read4~;
#X obj 279 363 tab16read;
#X obj 279 344 tab16write;
#X obj 164 344 tab16send~;
#X obj 164 363 tab16receive~;
#X obj 55 382 tab16read~;
#X text 19 410 The message-objects [tab16read]/[tab16write] store the
values directly (-32767..+32768) \, while the signal-objects convert
the floats -1.0..+1.0 to the correct values or vice-versa.;
#X text 270 21 updated for iem16 version1.0;
#X msg 496 53 resize 100;
#X obj 496 308 table16 array16 99;
#N canvas 0 0 450 300 graph6 0;
#X array array100 10 float 1;
#A 0 1 2 3 4 5 6 7 8 9 0;
#X coords 0 10 9 0 200 140 1;
#X restore 477 452 graph;
#X msg 478 409 \; array100 0 1 2 3 4 5 6 7 8 9;
#X text 481 389 click to init float-array;
#X msg 502 114 from array100;
#X text 21 497 There is no beautiful graphical representation as with
pd's arrays.;
#X msg 508 139 from array100 resize;
#X msg 516 190 from array100 20 30;
#X msg 517 213 from array100 20 30 resize;
#X msg 527 259 from array100 20 30 95;
#X msg 527 279 from array100 20 30 95 resize;
#X text 502 95 copy the data from a float-array;
#X text 603 117 and resize the 16bit-array;
#X text 513 173 copy floats (index20..30);
#X text 653 192 and resize to 30-20;
#X text 526 241 copy indexed values and insert at index95;
#X connect 17 0 18 0;
#X connect 22 0 18 0;
#X connect 24 0 18 0;
#X connect 25 0 18 0;
#X connect 26 0 18 0;
#X connect 27 0 18 0;
#X connect 28 0 18 0;
iem_utils-0.0.20240903/iem16/table16.c 0000600 0000000 0000000 00000013602 14665566711 013531 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_array.c from pd:
* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* sampling */
#include "iem16_table.h"
#include
#include
#include /* for read/write to files */
#if (defined(_MSC_VER) && (_MSC_VER > 600))
# define fdopen(fd,type) _fdopen(fd,type)
#endif
static int am_bigendian(void){
/* actually this should be in m_pd.h */
unsigned short s = 1;
unsigned char c = *(char *)(&s);
return (c==0);
}
static void table16_const(t_table16*x, t_float f);
static void *table16_new(t_symbol *s, t_float f){
t_table16 *x = (t_table16*)pd_new(table16_class);
int i=f;
if(i<1)i=100;
x->x_tablename=s;
x->x_size=i;
x->x_table=getbytes(x->x_size*sizeof(t_iem16_16bit));
x->x_usedindsp=0;
pd_bind(&x->x_obj.ob_pd, x->x_tablename);
x->x_canvas = canvas_getcurrent();
table16_const(x, 0);
return(x);
}
static void table16_free(t_table16 *x){
if(x->x_table)freebytes(x->x_table, x->x_size*sizeof(t_iem16_16bit));
pd_unbind(&x->x_obj.ob_pd, x->x_tablename);
}
static void table16_resize(t_table16*x, t_float f){
int i=f;
int was=x->x_size;
if (i<1){
pd_error(x, "can only resize to sizes >0");
return;
}
x->x_table=resizebytes(x->x_table, was*sizeof(t_iem16_16bit), i*sizeof(t_iem16_16bit));
if(i>was)memset(x->x_table+was, 0, (i-was)*sizeof(t_iem16_16bit));
x->x_size =i;
if (x->x_usedindsp) canvas_update_dsp();
}
static void table16_const(t_table16*x, t_float f){
t_iem16_16bit s = (t_iem16_16bit)f;
int i = x->x_size;
t_iem16_16bit*buf=x->x_table;
while(i--)*buf++=s;
}
static void table16_from(t_table16*x, t_symbol*s, int argc, t_atom*argv){
float scale=IEM16_SCALE_UP;
int resize=0;
int startfrom=0, startto=0, endfrom=0, endto=x->x_size;
t_garray *a=0;
int npoints;
t_word *vec=(0), *src=(0);
t_iem16_16bit *dest;
int i,length=0;
if(argc<1 || argv->a_type!=A_SYMBOL){
pd_error(x, "you have to specify the from-table !");
return;
}
s=atom_getsymbol(argv); argc--;argv++;
if (!(a = (t_garray *)pd_findbyclass(s, garray_class))){
pd_error(x, "%s: no such array", s->s_name);
return;
} else
if (!garray_getfloatwords(a, &npoints, &vec)){
pd_error(x, "%s: bad template for tabread4", s->s_name);
return;
}
if(argc>0 && atom_getsymbol(argv+argc-1)==gensym("resize")){
resize=1;
argc--;
}
endfrom=npoints;
switch(argc){
case 0:break;
case 4:
endto =atom_getfloat(argv+3);
/* fallthrough */
case 3:
startto =atom_getfloat(argv+2);
/* fallthrough */
case 2:
endfrom =atom_getfloat(argv+1);
/* fallthrough */
case 1:
startfrom=atom_getfloat(argv);
break;
default:
pd_error(x, "table16: from [ [ [ []]]] [resize]");
return;
}
if(startfrom<0)startfrom=0;
if (startto<0)startto=0;
if(endfrom<=startfrom)return;
if(endto <=startto) return;
length=endfrom-startfrom;
if(resize){
if(x->x_size < (startto+length))table16_resize(x, startto+length);
} else{
if(x->x_size < (startto+length))length=x->x_size-startto;
}
endfrom=startfrom+length;
endto =startto+length;
dest=x->x_table+startto;
src =vec+startfrom;
i=length;
while(i--)*dest++=(*src++).w_float * scale;
//post("from %s (%d, %d) --> (%d, %d)\tresize=%s", s->s_name, startfrom, endfrom, startto, endto, (resize)?"yes":"no");
}
#define BINREADMODE "rb"
#define BINWRITEMODE "wb"
static void table16_read16(t_table16 *x, t_symbol *filename, t_symbol *endian, t_floatarg fskip)
{
int skip = fskip, filedesc;
int i, nelem;
t_iem16_16bit *vec;
FILE *fd;
char buf[MAXPDSTRING], *bufptr;
short s;
int cpubig = am_bigendian(), swap = 0;
char c = endian->s_name[0];
if (c == 'b')
{
if (!cpubig) swap = 1;
}
else if (c == 'l')
{
if (cpubig) swap = 1;
}
else if (c)
{
pd_error(x, "array_read16: endianness is 'l' (low byte first ala INTEL)");
pd_error(x, "... or 'b' (high byte first ala MIPS,DEC,PPC)");
}
if (!table16_getarray16(x, &nelem, &vec))
{
pd_error(x, "%s: not a 16bit array", x->x_tablename->s_name);
return;
}
if ((filedesc = open_via_path(
canvas_getdir(x->x_canvas)->s_name,
filename->s_name, "", buf, &bufptr, MAXPDSTRING, 1)) < 0
|| !(fd = fdopen(filedesc, BINREADMODE))
)
{
pd_error(x, "%s: can't open", filename->s_name);
return;
}
if (skip)
{
long pos = fseek(fd, (long)skip, SEEK_SET);
if (pos < 0)
{
pd_error(x, "%s: can't seek to byte %d", buf, skip);
fclose(fd);
return;
}
}
for (i = 0; i < nelem; i++)
{
if (fread(&s, sizeof(s), 1, fd) < 1)
{
post("%s: read %d elements into table of size %d",
filename->s_name, i, nelem);
break;
}
if (swap) s = ((s & 0xff) << 8) | ((s & 0xff00) >> 8);
vec[i] = s;
}
while (i < nelem) vec[i++] = 0;
fclose(fd);
}
void table16_setup(void){
table16_class = class_new(gensym("table16"),
(t_newmethod)table16_new, (t_method)table16_free,
sizeof(t_table16), 0, A_DEFSYM, A_DEFFLOAT, 0);
class_addmethod(table16_class, (t_method)table16_resize, gensym("resize"), A_DEFFLOAT, 0);
class_addmethod(table16_class, (t_method)table16_const, gensym("const"), A_DEFFLOAT, 0);
class_addmethod(table16_class, (t_method)table16_from, gensym("from"), A_GIMME, 0);
class_addmethod(table16_class, (t_method)table16_read16, gensym("read16"), A_SYMBOL,
A_DEFFLOAT, A_DEFSYM, 0);
}
void iem16_table_setup(void)
{
table16_setup();
}
iem_utils-0.0.20240903/iem16/vd16~-help.pd 0000600 0000000 0000000 00000002405 14665566711 014357 0 ustar 00 #N canvas 88 40 717 480 12;
#X floatatom 50 254 0 0 0 0 - - -;
#X obj 50 347 outlet~;
#X text 130 346 signal output (delayed signal);
#X obj 50 282 sig~;
#X text 99 279 signal input (delay time in ms);
#X text 218 310 creation argument: name of delay line;
#X text 35 400 see also:;
#X text 77 10 reads a signal from a 16bit delay line at a variable
delay time (4-point-interpolation);
#X text 31 51 vd16~ implements a 4-point interpolating delay tap from
a corresponding delwrite~ object. The delay in milliseconds of the
tap is specified by the incoming signal.;
#X text 16 433 similar pd-objects:;
#X obj 201 432 delread~;
#X obj 285 432 delwrite~;
#X obj 378 432 vd~;
#X obj 123 403 del16write~;
#X obj 242 403 del16read~;
#X text 411 386 updated for iem16 version1.0;
#X text 28 116 This is very similar to the pd-object;
#X text 56 137 It uses only 16bit to store the samples \, which will
need only half of the memory of pd's floatingpoint-based object.;
#X text 57 175 However \, there are 2 drawbacks: there will be some
additional noise (because floats are more precise than 16bit) \, and
you cannot have values>1 stored in the delay-line;
#X obj 375 112 vd~;
#X obj 50 314 vd16~ del_example;
#X obj 24 16 vd16~;
#X connect 0 0 3 0;
#X connect 3 0 20 0;
#X connect 20 0 1 0;
iem_utils-0.0.20240903/iem16/vd16~.c 0000600 0000000 0000000 00000005650 14665566711 013255 0 ustar 00 /* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
* based on d_delay.c from pd:
* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* del16read~, del16write~, vd16~ */
#include "iem16_delay.h"
/* ----------------------------- vd~ ----------------------------- */
static t_class *sig16vd_class;
typedef struct _sig16vd{
t_object x_obj;
t_symbol *x_sym;
t_float x_sr; /* samples per msec */
int x_zerodel; /* 0 or vecsize depending on read/write order */
float x_f;
} t_sig16vd;
static void *sig16vd_new(t_symbol *s){
t_sig16vd *x = (t_sig16vd *)pd_new(sig16vd_class);
if (!*s->s_name) s = gensym("vd~");
x->x_sym = s;
x->x_sr = 1;
x->x_zerodel = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sig16vd_perform(t_int *w){
t_float *in = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
t_del16writectl *ctl = (t_del16writectl *)(w[3]);
t_sig16vd *x = (t_sig16vd *)(w[4]);
int n = (int)(w[5]);
int nsamps = ctl->c_n;
float limit = nsamps - n - 1;
float fn = n-4;
t_iem16_16bit *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
float zerodel = x->x_zerodel;
while (n--) {
float delsamps = x->x_sr * *in++ - zerodel, frac;
int idelsamps;
float a, b, c, d, cminusb;
if (delsamps < 1.00001f) delsamps = 1.00001f;
if (delsamps > limit) delsamps = limit;
delsamps += fn;
fn = fn - 1.0f;
idelsamps = delsamps;
frac = delsamps - (float)idelsamps;
bp = wp - (idelsamps + 3);
if (bp < vp + 4) bp += nsamps;
d = bp[-3]*IEM16_SCALE_DOWN;
c = bp[-2]*IEM16_SCALE_DOWN;
b = bp[-1]*IEM16_SCALE_DOWN;
a = bp[00]*IEM16_SCALE_DOWN;
cminusb = c-b;
*out++ = b + frac *
(cminusb - 0.5f * (frac-1.) *
((a - d + 3.0f * cminusb) * frac
+ (b - a - cminusb)));
}
return (w+6);
}
static void sig16vd_dsp(t_sig16vd *x, t_signal **sp){
t_sigdel16write *delwriter =
(t_sigdel16write *)pd_findbyclass(x->x_sym, sigdel16write_class);
x->x_sr = sp[0]->s_sr * 0.001;
if (delwriter) {
sigdel16write_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
dsp_add(sig16vd_perform, 5,
sp[0]->s_vec, sp[1]->s_vec,
&delwriter->x_cspace, x, sp[0]->s_n);
}
else pd_error(x, "vd~: %s: no such del16write~",x->x_sym->s_name);
}
static void sig16vd_setup(void){
sig16vd_class = class_new(gensym("vd16~"), (t_newmethod)sig16vd_new, 0,
sizeof(t_sig16vd), 0, A_DEFSYM, 0);
class_addmethod(sig16vd_class, (t_method)sig16vd_dsp, gensym("dsp"), A_CANT, 0);
CLASS_MAINSIGNALIN(sig16vd_class, t_sig16vd, x_f);
}
// G.Holzmann: for PD-extended build system
void vd16_tilde_setup(void)
{
sig16vd_setup();
}
iem_utils-0.0.20240903/iem_adaptfilt/ 0000700 0000000 0000000 00000000000 14665566711 014004 5 ustar 00 iem_utils-0.0.20240903/iem_adaptfilt/AUTHORS.txt 0000600 0000000 0000000 00000000121 14665566711 015666 0 ustar 00 markus noisternig
thomas musil
iem_utils-0.0.20240903/iem_adaptfilt/GnuGPL.txt 0000600 0000000 0000000 00000043110 14665566711 015642 0 ustar 00 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)
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) year 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.
iem_utils-0.0.20240903/iem_adaptfilt/LICENSE.txt 0000600 0000000 0000000 00000001672 14665566711 015637 0 ustar 00 iem_adaptfilt - pd-objects for adaptive filtering
Copyright (C) 2004-2006 markus noisternig (noisternig AT iem DOT at)
Copyright (C) 2004-2006 thomas musil (musil AT iem DOT at)
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.
In the official flext distribution, the GNU General Public License is
in the file GnuGPL.txt
iem_utils-0.0.20240903/iem_adaptfilt/Makefile 0000600 0000000 0000000 00000003065 14665566711 015452 0 ustar 00 #!/usr/bin/make -f
# Makefile to the 'iem_adaptfilt' library for Pure Data.
# Needs Makefile.pdlibbuilder as helper makefile for platform-dependent build
# settings and rules (https://github.com/pure-data/pd-lib-builder).
lib.name = iem_adaptfilt
## iemlib.h lives in include/
cflags = -Iinclude
# special file that does not provide a class
lib.setup.sources = src/$(lib.name).c
# all other C and C++ files in subdirs are source files per class
# (alternatively, enumerate them by hand)
# class.sources = $(filter-out $(lib.setup.sources),$(wildcard src/*.c))
class.sources = \
src/NLMS~.c \
src/NLMSerr_in~.c \
src/NLMSCC~.c \
src/n_CNLMS~.c \
src/n_CLNLMS~.c \
src/FXNLMSplus2in~.c \
src/FXNLMSplus3in~.c \
$(empty)
datafiles = \
$(wildcard *.txt) \
$(wildcard *.pdf) \
$(wildcard *.pd) \
$(wildcard *.gif) \
$(wildcard *.bat) \
$(wildcard *.sh) \
$(wildcard *.wav) \
$(empty)
#cflags = -DVERSION=$(shell cat VERSION.txt)
## build a multi-object library
make-lib-executable=yes
## suppress "unused" warnings
#suppress-wunused=yes
################################################################################
### pdlibbuilder ###############################################################
################################################################################
# This Makefile is based on the Makefile from pd-lib-builder written by
# Katja Vetter. You can get it from:
# https://github.com/pure-data/pd-lib-builder
PDLIBBUILDER_DIR=pd-lib-builder/
include $(firstword $(wildcard $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder Makefile.pdlibbuilder))
iem_utils-0.0.20240903/iem_adaptfilt/VERSION.txt 0000600 0000000 0000000 00000000005 14665566711 015667 0 ustar 00 1.02
iem_utils-0.0.20240903/iem_adaptfilt/doc/ 0000700 0000000 0000000 00000000000 14665566711 014551 5 ustar 00 iem_utils-0.0.20240903/iem_adaptfilt/doc/adapt_filt_lib.pdf 0000600 0000000 0000000 00003012310 14665566711 020203 0 ustar 00 %PDF-1.3
%Äåòåë§ó ÐÄÆ
2 0 obj
<< /Length 1 0 R /Filter /FlateDecode >>
stream
xÚÅ]ÛnG’}ϯ¨G
`÷äý2o³ã½6¤Å¾`Pd‹äHìnñâ±üõ[]]Y•‘‡]›+ì£XÝÕ•™q9qâħî×îS§tÿÿ+)¥ê\«ä»¨ÂÊÚîvÝýo·éþú;Õßurø¿»óþ¹Òöðßýÿί¼í¬^ÙØÆùM÷_o;wøëñŸ·7Ý_P+Ù©îíûîU÷—îí¿»ïßö_¿ gôÊyaÒ*Úþ|§ì*Æ¥_?ÞÞYÓ?³TbÁ÷«Ö÷wôýâ©ß'ßøýâ)¿-€XúÊ™þÑ»Ü*éq¬Ú_‡ Ÿú Ã+Ox€þãÇn¸¾ÿG°øex€ò'ÖòÕwÕ%/Ægž\Qi¼çõu})¿ùÕ»ÉÑÿ£¯ÜV÷hïÆ+gÕ#
Ý#æWL~ìÏõ=ÁŽWþV?·Uñð>^ý½¾ÔxÓEuÅ)S=œÈW\¾gWß“ò=÷Õ¯ÂøNëçMïù½¾òO]ϯˆ ó:Ô¿4èüi?ÔWèõO &WR¾ò±º'ª¼@÷ëúR0bºªË6v}²Dcc› Vý¯@»>YâI'«y´Eûdiß[×ã0ž,Ñ8YõK‹32œ“\½Š6;q!Ÿ«»j{h™ï¹ªOœ5í-ÕiÚlÕ¯1*‚ÍVÎâ;‹ý=beS8-Á³^³g‡+Éâ4z6gÃxåÇÊ‚x™?¶ˆžÞõk~®F‹Ê-_Hù®óz¹µ~Q6!Ñå§«ßOL©½ª]«?ítÞD»ßéË7üðvÄ3`<ò"»ó!š Ò•¿Ø™‹“ES>†…ßð"åOŒ7ÇÃ}u%ä½vµ½.);?¿nxßwÔßž¾Òâ± !Å…?T<=hYbÛû b%—¿iñê§ê¥Y;sÊå‚÷3ADÌïÃÃ]½NϬÇä
E&?[½\)¶u{]ݤ¬”®¸$¦qÁäJ˜äÉ•Êè•íaT~ìMý†,Øeý“LL£Iþ׫çÙQ¯ªVƒáX~~6ý»óå³àÕÅyDU.¤0þœúÅ• •8òW“'—è ^þVŸnMÇñ-[#=šäߨJÖ¸ü“n&Wö[̤¼°¿}Wï{ºé¿ë+1ÑÓÍß©#Wû[}Zœàµº˜Ý¿þrêÀÎ¥Uâ–þSv£™÷iµÜËœÐËeã·ôûßÖÛƒ¢ºíM½³i©Ïñ2¢²q
Y?Jjó«)‘bÆTSøÆì"…–+K¦)idÖŠÀÑZM.é+ß°“•{:KŸw]½U«òQ`߆¾£ì·Ú’9ÁÁïwMãàÖOfÿÀ¾§›êƒ¤¯ž.¿Ö`:ø!ZpðCÊáå³~3¾Tö«¼ñÜ;¹²_1º4ýO‡êÊ÷‹/úþüóe\Å8BuC´$ó?Ut¯VÔ¿q³S*Êò"]uí²V”ʇwS_¡„íþ¶¾”ò‘Ú^L.íDû8KAËM†Ò¼óúŠ)g@̯PZv]ßCñÁvS/xÖöèíðŇõé¬ÏËì—öI xÎþ_€ø²ïÃMùûÅ2¿ØÍübeqEˆÀ½P ÅÜ¥²•Ÿ ¤Œ æ|«c0¹Õ¸Û·ïk§¨Qî¡)J½¯\•¦ƒxÅ|lL €6²¼Q9Òü»[–Ðæ×°ýwõN‹'ý›Õó7ÍÚfáæ$²0±tâ®[¯hýV'Ñ‚;ú÷UäïèuoYŒ¢
°Syÿ”?íÚÁzãÀ‹ó.ŒîsQUÐ
ÄbÁ;°UCHUÀUœ¼W¢3tirE£|*ÐÙÕI7½º_ê{}¨wI¢ô¡~)j”&®(IQK%Ù† HW¯:Y YNÅŽg%¹df@
È_óëïÛ–¯–Ìó¼:7½5BÇPÏÇĨ$Pnl<ü@+sI¯ÄD9ÛP§ƒªLR+]{…G ªoO&·/C,x€1[eûÏ¢|8A~„Á„”Œñ9sW°0E·cx¥ÞãMXEÌ€&ozSÙÖ‚°„ÌTæýtጱÄKâ™sæš Âü½ë÷
”jjN~~5ÿaû& àÄÃÓÑáÕ•Küþøõ”×G¯N/Ik~aÇ C ·,³?&ñ˜i„³§oÓ÷ÑÚDjiQÔ¦µ €…6 8CM'þ»z«üã/ ÿh€&&§ðï>³pJ¢÷`u˺ˆYØVG%l»†aÛ»Û:6Rhc;ƒBçri…ý"G•²ú {Š™¶›:àôч2€ß4Ä`¢ ¸
t6qdèëO´ÐÒû4cL}€Z¢÷zË"*P.Éy°´) í•â,˜F#’¬ÙGæ¡È]ò˜LùÔ\³ÀHÂÀ® W7õ“¨ˆ* ý]¹QÕøïÙ%âgðÇ×qŽŒL/fñ‘aFZÆ
`ŒCÞG_zÏã3:XÚï,@°{£Ù.®X!ÒLhî¦~§=pëQ<¢¼_p©¬zû!g$•ÿÙ%ƒ4h]ÞÔϱ}dx‚‰h””ë‚]K´Ô»Úöù‡fO%úÈßyX!󓜺F<ÆvO
\W¼¯½72ãÙ(ëÆmÆŠa ™iÕØ{b°‘èe–¢íå
Ö[:‰Tz$VÎ+C#›ª¡ )Á}óêˆì˜‘¾hŸã,9d>J&yËÊ¢aFù›†.=2%ûÁK°Ç³TÝ=¼ûÈ`¢Þƒ#‹rWG!ôî®dóÇ1,ÈÇŒ=l.Ö°²Ã`‰¼T$ŽãÚA1k¹ð^›ÂbeV'&ÛêCÞ° âYlßÅdÛÑ&»
Í\G<ãû—€!ã÷«£6ñ…x;#Ý<…UðKJzUUV*Pma IÊî¤D|âõú–jz/Ækºrså.M¨ÞýU]õ |âÕÍÝËL—¿Ò—)ŠÚ¨
ý+TE÷á$üòÙ~ª½Å¸;T‡w,Ëvÿuå_”FTEtÙ³<8ê(1U¾o§ä±™›•(—0*ÛvÌj8c.˜…Ùm[
7þ„ž‘Õo\vÛÌÿ!ØÃ’o®¼p¡8ŽhwgH›£ùS©Pò浸ÌôD®;ÛÔûÇF 2•\ÿ
ó½ùžO,P,iQyXÊÍ™ÃNhC&eªhæ/ªY,‰ˆ9Õ&I ²†$¡×;viŸ]‰vÅÅ¡PHI":þÎ’2…ž>#žõ3L/ù¼º<Ö¸RŠÞ-Ë•Tºæ €DɦvùupT’MžQjÂf9»ŠH6¿“%›ƒ-Ý©,í¥ÔžÅ‘™•zWÃŒ‹gö@-‹¬³ûf°¯™°¯š¹Ðaæ‚E@á!?ñ²‚!ÊxtÕý4õnnÖª2M<…_¬DQr§P™ß.]ÛCnùê¦Îî$š¬Féª%úþÝ©éîÞ
AÞÂ
" Ì–A±Yd‚“ApÔ»m5ŽÃÖ‰`u´Ê‘oìT6˜_{ÝÂla‘Žb]˜–‚³àå‰5ßà·Z§×-h(«ü9™ ¤â´Cäkªƒ\1Á ôßEðzjUx_šBa¼…ÕùÆš†fTRJ*ŸO\ä5VíÔádá"¯y1Òš±C³Òôh?Þ€ÌL¢m,ÎÜ=Xø‘ÝÀ??f¹KÈCƒœ7Àö¼:½ê]±X_YôqŠ6û5‡ÔAÍO%Pèš<Ìå-ïËÉçà‚»8^Æ:dÆN”¨‚À²8k¬F[}êZŒ¶®b´]ݰü*¼«sÒïé«/êêj@T(i!ÜŽÜSñv/„¨h³Œå^7"(T3(ó%/÷Ÿ×…%‚‚/Ö-Ú‰hæLTìg5øRR}¨kÜÖ¸µ‡·Q
œ|CN“Ñëaˆwup _„¥q¹a„ˆP Æ*ºŒ.…A\Zg3ùo{ÎŽ#ª{¶ÑH
Ø'Þ¡×ûŒìp–B0(ÒDkÚí>Öv]¡03Ltt…z!xM¡yZÂÂYI¯usÇ8vV‰˜rdw’1yÃYv(*•_n¸"ZÒ{^ˆh®¬BN.{Æq=æ*&óJJk™¶'BŒ‡Dˆ
eÁ6