pax_global_header00006660000000000000000000000064126604515360014522gustar00rootroot0000000000000052 comment=46c8ef0e0b238b613f2cb2c09a7116bd0339e98d pdp-0.14.1+darcs20180201/000077500000000000000000000000001266045153600142765ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/.header.html000066400000000000000000000006071266045153600164750ustar00rootroot00000000000000
This is a darcs archive for the Pure Data Packet project.

To make a local copy of the repositiory do:

  darcs get --partial http://zwizwa.be/darcs/pdp
  cd pdp
  . bootstrap
  ./configure && make

To get updates later, cd to the pdp directory and do:

  darcs pull -a
  cd pdp
  . bootstrap
  ./configure && make

pdp-0.14.1+darcs20180201/CHANGES.LOG000066400000000000000000000154721266045153600157220ustar00rootroot00000000000000last modified: 2003/02/27 ChangeLog: v0.1: 2002/11/23 initial release v0.2: 2002/11/27 added support for BC_YUV422 video and audio playback in pdp_qt / pdp_qt~ (thanks to Yves Degoyon for contrib) some makefile cleanups v0.3: 2002/11/28 pdp_qt / pdp_qt~: fixed some bugs in audio playback and added suport for BC_RGB888 colormodel (loads as greyscale until there is internal support for a rgb image packet) v0.4: 2002/12/03 code style changes added scaf / cellular automata support. added some basic filter abstractions. (blur, phase) v0.5: 2002/12/13 first attempt at a documentation (see doc/) added support for processing in separate lower priority thread with a packet dropping mechanism to avoid audio dropouts. added pdp_control object for controlling pdp's scheduling and detecting packet drops pdp api cleanup (name changes) added some more filter abstractions (motion blur/phase, emboss, sobel, edge) added pdp_route v0.6: 2003/01/03 added pdp_gain, finished pdp_gradient added channel method to pdp_v4l, display method to pdp_xv added some examples in doc/examples fixed gcc3 compilation probs fixed some pdp_qt bugs (shouldn't crash any more) v0.7: 2003/01/12 moved image format conversion routines to pdp_llconv.c added support for rgb->PDP_IMAGE_YV12 in pdp_v4l, pdp_qt added pdp_grey, pdp_chrot, pdp_scope~ moved mmx wrappers to pdp_imageproc_mmx.c added portable c code in pdp_imageproc_portable.c added mmx code for pdp_gain fixed bug in pdp_mix/pdp_mix2 fixed bug in pdp_bq (removed state reset) moved CA stuff to separate lib (see scaf/) (0.7.1) fixed rgb colour conversion bug v0.8: 2003/02/02 added pdp_scale, pdp_zoom, pdp_rotate, pdp_zrot, pdp_scan~, pdp_cheby added support for 1D ca's + shift compensation in pdp_ca thread processing is off by default now added cursor method to pdp_xv, freq method to pdp_v4l (thanks CK) added pdp_sdl (thanks Martin Pi) added some example patches in doc/examples (0.8.1) fixed scaf + gcc<3 compilation problem (0.8.2) fixed compile prob + added documentation (0.8.3) completed documentation v0.9: 2003/02/27 added pdp_scanxy~, pdp_invert now uses autoconf for configuration standard "make install" target optional compililation for external dependencies (xv,qt,v4l,sdl) experimental OSX port (without i/o) fixed crash when closing xv window manually added mouse event output to pdp_xv pdp_ca now automaticly compiles rule files fixed image dimension crashes fixed pdp_xv bang crash added pdp_grey2mask added pdp_slice_cut/pdp_slice_glue (experimental/nondoc) v0.10: 2003/03/06 modules code reorganization removed pdp_affine object and added compatibility object based on pdp_cheby added pdp_mchp and PDP_IMAGE_MCHP packet format (experimental) added pdp_and, pdp_or, pdp_xor, pdp_not, pdp_bitmask, pdp_bitdepth added base class for pdp objects added incremental garbage collector added support for "not so pure" data packets added opengl subproject containing a pdp_glx display object added a PDP_TEX opengl texture packet (opengl lib) added PDP_IMAGE_GREY8, PDP_IMAGE_RGB8, PDP_IMAGE_RGBA8 packets (0.10.1) fixed (fatal) bug in pdp_base, and bug in pdp_noise (non-mmx) (0.10.1) pdp_glx now compiles on mac osx v0.11: 2003/04/08 updated pdp_trigger to behave like pd's trigger object added automatic philips web cam detection removed "zombie" packet passing and made pool manager thread safe (this required an api change: backward compat for pdp thread proc broken) added gem style object rendering & transformation objects (opengl lib) removed pdp_gradient binary module (it is now an abstraction) added pdp_loop (a packet array / loop sampler) added pdp_description added support for libquicktime on osx (thanks Jamie) added support for accumulation packets (dpd) (still experimental) (0.11.1) fixed some packet registering and frame dropping bugs v0.12: 2003/06/21 added support for high level packet conversion (mime-like descriptions) added pdp_convert added "memlimit" message to pdp_control (to limit pdp's mem usage) maximum nb of packets is now only limited by the memlimit added new basic type: bitmap/*/* (PDP_BITMAP) for standard fourcc formats cleaned up pdp_xv/glx (x window glue code reuse) fixed rgb/bgr bug in conversion code added pdp_abs, pdp_zthresh completed dpd framework (for context based processing, i.e. 3dp) rewrote gem like 3d library on top of dpd (it's almost stable) added a matrix type (float/double real/complex) for linear algebra stuff added matrix processors pdp_m_*: mv, mm, +=mm, LU, LU_inverse, LU_solve pdp_cheby now accepts an array with a mapping function added pdp_plasma fixed outlet_pdp bug (this caused all kind of weirdness) added embedded scheme interpreter for testing (see the guile/ dir) added simple forth-style scripting language (pdp's rpn calculator) added png load/save support to pdp_reg (0.12.1) fixed OSX compilation probs (0.12.1) fixed texture coordinate bugs (pdp_opengl) (0.12.1) added multipass rendering support (pdp_opengl) (0.12.1) pdp_cog (Johannes Taelman's gaussian blob estimator) (0.12.1) pdp_sthresh, hthresh, positive, offset, sign (0.12.1) pdp_agc, contrast, flip_lr, flip_tb (0.12.1) added pdp and pdp_opengl examples (0.12.2) pdp_histo, dither, pointcloud (0.12.2) more examples & added some conversion code (0.12.2) fixed c++ compilation issues 0.12.3: 2004/01/13 various bug fixes added pdp_grey2array fixed window event routing problem (3dp) cleaned up source tree (for libpdp) added pdp_netsend / pdp_netreceive to send packets over udp (experimental) more forth scripting stuff added "norm" message and rgb32 colour model to pdp_v4l added keyboard and mouse motion events to pdp_xv and pdp_glx compiles without x support, for use with sdl (i.e. svgalib) more packet forth work started sliceforth library (core signal processing routines) finished pd interface to forth scripting language fixed some crashes with pdp_xv and pdp_glx removed "passing packet" hack added minimal OO support to packet forth moved all the forth stuff to libpdp project (no longer in pdp distro) fixed (worked around) pdp_opengl deadlock bug on startup pdp_opengl still not working properly 0.12.4: 2004/07/09 build fixes 0.12.5: build fixes libquicktime api change help patches renamed xxx.pd -> xxx-help.pd pd-0.40 compatibility sdl delayed window creation 0.12.6: fixes to pdp_imageproc from John Harrison 64-bit support other random fixes build fixes 0.13: Reserved for PF (http://zwizwa.be/packetforth/) PF is a PDP spinoff. 0.14.0: Port ia32 MMX assembly code to GCC extensions (MMX support on amd64) Add V4L2 support to pdp_v4l (merge with pdp_v4l2) Distill system/zl (Zwizwa Lib) from PDP and libprim/PF code. 0.14.1: Port SCAF MMX code to x86_64 ABI Revive pdp_opengl (3dp) Bugfixes pdp-0.14.1+darcs20180201/COPYING000066400000000000000000000431031266045153600153320ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, 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 PDP.LICENSE, 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 Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pdp-0.14.1+darcs20180201/Makefile000066400000000000000000000042411266045153600157370ustar00rootroot00000000000000include Makefile.config # hc ? #ifeq ($(OS_NAME),darwin) #all: darwin #else #all: linux #endif all: $(PDP_TARGET) everything: all make -C opengl make -C scaf pdp_all: make -C system make -C puredata make -C modules darwin: pdp_all rm -f pdp.pd_darwin $(CC) -o pdp.pd_darwin modules/*/*.o system/pdp.o system/*/*.o puredata/*.o $(PDP_LIBS) -bundle -undefined dynamic_lookup -twolevel_namespace -bundle_loader $(PD_EXECUTABLE) linux: pdp_all rm -f pdp.pd_linux $(CC) -rdynamic -shared -o pdp.pd_linux modules/*/*.o system/pdp.o system/*/*.o puredata/*.o $(PDP_LIBS) linux_mmx: linux linux_gcc_mmx: linux buildclean: make -C include clean make -C system clean make -C puredata clean make -C modules clean backupclean: rm -f *~ */*~ */*/*~ clean: buildclean backupclean rm -f pdp.pd_linux distroclean: buildclean make -C scaf clean make -C opengl clean mrproper: clean distroclean make -C scaf mrproper rm -rf configure rm -rf config.log rm -rf config.status rm -rf autom4te.cache #this needs to stay in to keep the makefiles working #rm -rf Makefile.config tags: etags --language=auto include/*.h system/*.c system/mmx/*.s system/*/*.c puredata/*.c \ modules/*/*.c scaf/*/*.c scaf/*/*.s opengl/*/*.c tagsclean: rm -f TAGS install: all #check if pd is installed. if this fails make install will stop here. test -d $(prefix)/lib/pd install -d $(prefix)/lib/pd/extra install -m 755 $(PDP_LIBRARY_NAME) $(prefix)/lib/pd/extra install -m 755 -d $(prefix)/include/pdp install -m 644 include/*.h $(prefix)/include/pdp install -m 644 abstractions/*.pd $(prefix)/lib/pd/extra install -m 644 doc/objects/*.pd $(prefix)/lib/pd/doc/5.reference install -m 755 -d $(prefix)/lib/pd/doc/pdp install -m 755 -d $(prefix)/lib/pd/doc/pdp/introduction install -m 755 -d $(prefix)/lib/pd/doc/pdp/examples install -m 644 doc/reference.txt $(prefix)/lib/pd/doc/pdp install -m 644 doc/introduction/*.pd $(prefix)/lib/pd/doc/pdp/introduction install -m 644 doc/examples/*.pd $(prefix)/lib/pd/doc/pdp/examples install -m 755 bin/pdp-config $(prefix)/bin snapshot: bin/snapshot -d darcs release: bin/snapshot `bin/release-version` @echo bump PDP_VERSION in configure.ac! pdp-0.14.1+darcs20180201/Makefile.config.in000066400000000000000000000030421266045153600176060ustar00rootroot00000000000000# if configure can't find the m_pd.h header # specify pd's include path here and ignore the warning # #PD_CPPFLAGS=-I/path_to_pd_dir/src #PD_EXECUTABLE=/path_to_pd_dir/bin/pd PD_CPPFLAGS=@PD_CPPFLAGS@ PD_EXECUTABLE=@PD_EXECUTABLE@ PDP_CFLAGS=@PDP_CFLAGS@ # these are reused in opengl module prefix=@prefix@ PDP_VERSION=@PDP_VERSION@ PDP_TARGET=@PDP_TARGET@ PDP_LIBRARY_NAME = @PDP_LIBRARY_NAME@ PDP_EXTRA_CPPFLAGS = @PDP_EXTRA_CPPFLAGS@ PDP_EXTRA_CFLAGS = @PDP_EXTRA_CFLAGS@ SDL_FLAGS = -D_REENTRANT # optional objects PDP_OPTMOD = @PDP_OPTMOD@ PDP_X11MOD = @PDP_X11MOD@ PDP_PDMOD = @PDP_PDMOD@ PDP_OPTTYPES = @PDP_OPTTYPES@ PDP_MATRIX_BASIC = @PDP_MATRIX_BASIC@ PDP_IMAGE_BASIC = @PDP_IMAGE_BASIC@ PDP_IMAGE_SPECIAL = @PDP_IMAGE_SPECIAL@ ZL_OPTMOD = @ZL_OPTMOD@ PDP_CPPFLAGS = -I. -I../../system -I/usr/X11R6/include -I../include -I../../include $(PD_CPPFLAGS) $(PDP_EXTRA_CPPFLAGS) -DPDP_TARGET=$(PDP_TARGET) PDP_LIBS = @LIBS@ PDP_AFLAGS = #--gstabs PDP_CFLAGS += $(SDL_CFLAGS) $(PDP_EXTRA_CFLAGS) -DPDP_VERSION=\"$(PDP_VERSION)\" ifeq ($(shell uname -s),Darwin) PDP_CFLAGS += -fnested-functions endif #PDP_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ # -Wall -W -Wstrict-prototypes \ # -Wno-unused -Wno-parentheses -Wno-switch -DPDP_VERSION=\"$(PDP_VERSION)\" \ # -g $(SDL_CFLAGS) $(PDP_EXTRA_CFLAGS) # -Werror # -Wshadow # compiler and assembler #CC = gcc-3.2 #CC = gcc #AS = as CC = @CC@ # build rules .c.o: $(CC) $(PDP_CFLAGS) $(PDP_CPPFLAGS) -o $*.o -c $*.c .s.o: $(AS) -o $*.o $*.s $(PDP_AFLAGS) pdp-0.14.1+darcs20180201/Makefile.creb000066400000000000000000000033421266045153600166520ustar00rootroot00000000000000# Makefile for pure data externals in lib creb. # Needs Makefile.pdlibbuilder to work. lib.name = creb # all C and C++ files in subdirs are source files per class class.sources = $(wildcard modules/*.c modules++/*.cc) datafiles = \ $(wildcard doc/*-help.pd abs/*.pd) \ creb-meta.pd \ CHANGES.LOG \ COPYING \ README \ TODO ################################################################################ ### pdlibbuilder ############################################################### ################################################################################ # Include Makefile.pdlibbuilder from this directory, or else from externals # root directory in pd-extended configuration. include $(firstword $(wildcard Makefile.pdlibbuilder ../Makefile.pdlibbuilder)) ################################################################################ ### creb extra targets ######################################################### ################################################################################ # if creb still doesn't have a meta.pd file, create it on the fly define meta #N canvas 48 350 450 300 10;\ \n#X text 9 18 AUTHOR Tom Schouten ;\ \n#X text 9 42 DESCRIPTION This is a collection of pd externals. My bag of tricks.;\ \n#X text 9 79 LICENSE GNU GPL 2;\ \n#X text 9 105 VERSION 0.9.2; endef all: creb-meta.pd creb-meta.pd: @echo "$(meta)" > creb-meta.pd # install files with idiosyncratic source/destination paths install-data: install-creb-extras install-creb-extras: all $(INSTALL_DIR) $(installpath)/manual && \ $(INSTALL_DATA) doc/reference.txt $(installpath)/manual $(INSTALL_DIR) $(installpath)/examples && \ $(INSTALL_DATA) $(wildcard doc/examples/*.pd) $(installpath)/examples pdp-0.14.1+darcs20180201/README000066400000000000000000000237711266045153600151700ustar00rootroot00000000000000PDP - Pure Data Packet v0.12.7 a packet processing library for pure data Copyright (c) by Tom Schouten 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., 675 Mass Ave, Cambridge, MA 02139, USA. The GNU Public Licence can be found in the file COPYING ------------------------------------------------------------------ This external pd library is a framework for image/video processing (and other raw data packets) that is fast, simple and flexible and as much as possible compatible with the pd messaging system. This distro contains the main pdp library and 3 extension libs: * pdp_scaf (in directory scaf/) * pdp_opengl (in directory opengl/) Features: * packet formats: greyscale and YCrCb encoded images, binary cellular automata (CA), textures, render buffers, matrices. * sources: noise, video4linux and quicktime (with audio), CA, plasma * sinks: xvideo display, sdl, glx display * filters: convolution, biquad time, biquad space, CA * warping: rotate, zoom, stretch * transforms: colour translation/scaling, grey->palette * add, mul, mix, random pixel mix * utility objs: packet register, snapshot, trigger * packet delay line, loop, .. * and more.. (see doc/reference.txt) Optional features * cellular automata simulator and effects processor with built in forth extension language (only for mmx) * opengl 3d processing (gem like, but built around packets) See the README files in the scaf/ and opengl/ dirs for more info on the extension libraries. Requirements: * pd * linux * libgsl * a video4linux device for video input. special support for philips webcam included. * libquicktime (not quicktime4linux!) for quicktime playback. * libpng for png image loading/saving * an X display with XVideo extension, glx or SDL for video display. Documentation: When you use "make install" to install pd, all docs will be in the pd doc directory. Right click on an object and select help for a help patch. The pdp directory in pd's doc contains a reference.txt file which lists all objects and abstractions and an introduction and example section. NOTE: all help patches use a pdp_help_input and pdp_help_output abstraction. you can edit these to choose which input or output object you want for the help patches. Building: ./configure make Options for configure: --enable-mmx compile with mmx support --enable-pwc force pdp_v4l to use philips web cam If pd is not installed in /usr/local you'll have to specify the prefix on the configure command line with ./configure --prefix=/prefix type make install To install pdp in $prefix/lib/pd: the library in externs/ the abstractions in extra/ and the documentation in doc/5.reference and doc/pdp You can also try the "buildall" script. This will configure, build and install the whole distribution. It works for intel/mmx. NOTE: If you're not using the standard pd install location, and have everything in a single tree, just untar pdp next to the pd source tree, or set the prefix dir to the location of the pd source. Bugs: See the TODO file. Apart from the few items listed on top of this file, pdp is fairly stable: i am unaware of crash bugs. If you encounter a crash please consider sending a bug report. PiDiP Is Definitely In Pieces Have a look at Yves Degoyon's PiDiP library, the must have addition to the basic pdp library. It contains a lot of extra effects (from EffecTV and FreeJ), a quicktime recording object, streaming modules, ascii art objects ... (the list is growing rapidly ;) Yves also did a gem2pd and a pdp2gem object to connect pdp and gem together. http://ydegoyon.free.fr/ Acknowledgements PDP is no longer a one man show. Many thanks to the people who directly or indirectly contributed to this project. Either by writing a giant extension lib (thanks Yves) or by contributing code snippets (Thanks Martin, CK), or by giving mental support, feedback, bug reports and ideas. I also wish to thank the GEM crew. This project borrows a lot of ideas and some code from the GEM project. And while i'm at it, i wish to thank everyone who contributed code to the PD project as a whole and the people that are very helpful at answering questions on the mailing list. Last but not least i wish to thank Miller for making the PD project open source. If that didn't happen i wouldn't know what i'd be doing now :) Some Remarks: * New versions of this package can be found at http://zwizwa.be/pd/pdp Experimental relases are in the subdirectory test/ But best to track the darcs archive at http://zwizwa.be/darcs/pdp-12 * If you have libquicktime and quicktime4linux installed, this can give problems with the configure script. Consider removing quicktime4linux. (libquicktime is a drop-in replacement). * The modules that depend on system libraries only get compiled when the configure script can locate them. If compilation or linking fails please let me know. * Packets can be processed in a low priority thread with a dropping mechanism to prevent overload or audio drops, or they can be processed in the main pd thread. This can be set/unset by sending a "thread x" message to pdp_control. Processing in pdp thread is off by default. Use the pd thread for rock solid video timing. Increase the audio latency to avoid dropouts. If you want low audio latency, and don't care about a dropped video frame here and there, switch on the pdp thread. Note that when using the pdp thread, the control flow is no longer depth first. Additinal delays will be introduced. * Pdp runs on osx, using an x server (apple or fink) and libquickime (fink). pdp_xv does not work yet. Once apple includes xv support in their x server, it should. Until then, use pdp_glx for output. * Some quicktime remarks: pdp_qt~ is still a bit experimental, you might try pdp_yqt in yves' lib to see if it works better for you. Also, it seems that libquicktime does not work with compressed headers. The suggested codec is jpeg (photo) and uncompressed audio with the same samplerate as the one pd is using. You can use other codecs, but i've found this one to perform the best. (hint: compile libquicktime with mmx jpeg support) Try to avoid the mpga codec. It is haunted. * The reason i use YV12 and not RGB is simple: it's faster, and for linear operations it doesn't make much difference. Most camera's and codecs use a luma/chroma system, and most video cards support hardware accellerated display. Note that in YUV, the u (Cb) and v (Cr) components can be negative, so saturation after multiplication with a positive (or negative) value produces not only black and white, but also red, green, blue and their complements. In short, in YUV, nonlinear operations have a different effect than in RGB. Another thing: all the spatial operations are not implemented "correctly" because of the subsampling involved.The image packets are 16bit/component planar. This is to simplify the mmx code and to have a little more headroom and precision for processing. * Since version 0.11 there is a type system used for identifying a packet type and performing type conversion. A type is represented by a symbol, with subtypes separated by the "/" character. I.e. "image/grey/320x240" is a grey 16 bit/component image with dimensions 320 by 240. For conversions a wildcard can be specified. I.e. "image/*/*" which matches image type packets with all encodings and dimensions. * Since version 0.12 there are 2 different image data types: "image/*/*" and "bitmap/*/*". The image type is the native 16 bit/component pdp type. It supports the subtypes "image/grey/*": one channel grey scale images, "image/YCrCb/*": luma/chroma packets with subsampled chroma planes and "image/multi/*": a multi channel planar format (i.e. to store 3 or 4 channel rgb or rgba data). Almost all processors use this data type. The bitmap type is an intermediate type which can contain standard fourcc encoded 8 bit/component images i.e. "bitmap/rgb/*", "bitmap/yv12/*", "bitmap/grey/*". Currently no processors support this type natively, so you have to use pdp_convert to convert them to "image/*/*". * Writing new objects is not much different than normal pd externs. Pdp just adds some functions to the pd kernel for package allocation, manipulation and communication. The api is very raw to keep it as simple as possible. Since 0.10 there is a pdp_base object you can derive your objects from. Have a look at pdp_add, pdp_gain and pdp_noise to see how it works. There is not much documentation, but i do my best to keep things clean so the code and the header files should get you started. You can always just send me an email for info, or ask on the pd-dev list. Since version 0.12 there is a simple forth scripting language in pdp. This is far from finished, but it should make pdp programming a lot easier. * Philips webcam detection is now automatic. However this requires a fairly recent kernel (one which includes the pwc driver version 8.6 or higher). If you have a pwc and pdp_v4l does not display a "pwc detected" message, you can conifigure with --enable-pwc. This forces pdp_v4l to use the pwc api extensions. Directory structure: abstractions/ some abstractions that use the pdp objects doc/introduction/ getting started with pdp doc/examples/ some example patches doc/objects/ pd style reference documentation include/ header files modules/ pd object code opengl/ opengl extension lib (experimental) scaf/ CA extension lib system/ core pdp system Bugreports, feature suggestions, code, documentation, example patches and general comments and questions are welcome. Have Fun, Tom last modified: 2003/07/20 pdp-0.14.1+darcs20180201/README-12000066400000000000000000000012261266045153600153770ustar00rootroot00000000000000This is `old' pdp. Adapted from the version 0.12.4 released on 09-Jul-2004. As you might know, i started working on Packet Forth about two years ago. This has shifted my opinion as to what PDP should be quite a bit. In order not to annoy people using the old PDP with my new and exciting insights about forth, I declare this version to be the `stable' PDP 12. The DEC PDP 13 never existed, so this might have been a sign... For people interested in packet forth, check http://zwizwa.be/packetforth for more information. Stable PDP might include some additions from PF later on, but main focus right now is stability. Groet, Tom Mon Oct 31 16:53:49 EST 2005 pdp-0.14.1+darcs20180201/TODO000066400000000000000000000054771266045153600150030ustar00rootroot00000000000000known bugs: * running out of memory (using delay lines or loops) will likely crash pd. short story: don't, use pdp_control's memlimit for limiting pdp's memory usage. todo 0.14.1: * finalize MMX port (crot, randmix + low level conversion routines) * switch to new build system in project.mk * remove procqueue todo 0.14.0: * final tests todo 0.12.5: * find nasty 3dp bug * fix pdp_glx BadMatch bug (crashes on OSX) : fixed in pf * platform independent [pdp_vdac] [pdp_vadc] * fix pdp_help_input/output so they are actually usable * incorporate jamie's osx changes / guenter's windows port todo later: * field based bttv capture (might be possible without driver hacks using v4l2) * pdp_crop/pad * where to solve autoconvert? per type, or central in pdp_base? 2 cases: - template based autoconvert: in pdp_base - compatibility based autoconvert: i.e. pdp_add (solve in base: move_passive) * finish high level packet conversion: - move 8bit images to packet level (iow: cleanup pdp_qt, pdp_v4l, pdp_xv) (solve with forth) - get rid of pdp_type* methods * fix mac/linux name differences (use pdp_video, pdp_movie, pdp_window) * pdp_xv framerate doc + pwc addons * enable audio output on bttv cards in pdp_v4l * fix cache slicer objects + thread problems (fixed in sliceforth) * derive as much classes as possible from pdp_base class (obsolete: use forth instead) * displacement warp, substitution warp, refraction warp, timespace warp, wormhole warp * check the use of varargs for image processing dispatching routine (obsolete: forth) * more scopes * 2D affine transforms parametrized by vectors (center, x-axis, y-axis) (np1 + matrix processing objects) * some abstractions around pdp_cheby (colour shape, ...) * efficient rescalers: pdp_double pdp_halve (+ efficient arbitrary scaler in sliceforth) * move float color conversion and float<->fixed point conv code to system * crop, shift (pad+scroll) * solve biquad (blur) mmx boundary init prob (bands at edges: solve with proper init?) (sliceforth) * optimize blur effect (1 pole ? / dependency stalls) (sliceforth) * jpeg/png packet and streaming support (pdp_netsend / pdp_netreceive : binary compat issues!!) * find out why resampling code (warping) is so slow (reg->mem->reg->mem stalls?) (solve in sliceforth) * mmx profiling (done: sliceforth) * add audio resampling in pdp_qt~ * use pd_error instead of post for errors * ascii art packet processors * 3D time space interpolation * colour keying * motion tracking * moebius transforms * type multiplexing: find a way to use the same name for packet processors. (solved in forth: polymorhpy) i.e. pdp_add should add images, but also vectors, ascii packets, textures,... * modify 2D rotation to be used as arbitrary rotation (givens) * add 3D rotation * frame rate limited delay line (burst delay?) * optimize resampling code (mipmapped packed 16bit format?) pdp-0.14.1+darcs20180201/abstractions/000077500000000000000000000000001266045153600167725ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/abstractions/pdp_affine.pd000066400000000000000000000005701266045153600214140ustar00rootroot00000000000000#N canvas 600 556 450 300 10; #X obj 47 39 inlet; #X obj 111 39 inlet; #X obj 170 38 inlet; #X obj 98 151 pdp_cheby; #X obj 63 205 outlet; #X text 26 7 for patch compatibility with older versions of pdp; #X msg 119 98 coef 1 \$1; #X msg 197 97 coef 0 \$1; #X connect 0 0 3 0; #X connect 1 0 6 0; #X connect 2 0 7 0; #X connect 3 0 4 0; #X connect 6 0 3 0; #X connect 7 0 3 0; pdp-0.14.1+darcs20180201/abstractions/pdp_agc.pd000066400000000000000000000013111266045153600207100ustar00rootroot00000000000000#N canvas 572 396 450 300 10; #X obj 174 115 pdp_cog; #X obj 174 222 /; #X obj 174 147 t b f; #X obj 116 89 pdp_t p p; #X obj 116 252 pdp_gain; #X text 22 13 an automatic gain control using the pdp_cog object; #X obj 23 40 inlet; #X obj 238 146 inlet; #X obj 174 183 f \$1; #X obj 116 279 outlet; #X text 158 36 creation argument or right inlet; #X text 157 51 is desired average intensity; #X obj 23 62 route chanmask; #X msg 23 102 chanmask \$1; #X connect 0 0 2 0; #X connect 1 0 4 1; #X connect 2 0 8 0; #X connect 2 1 1 1; #X connect 3 0 4 0; #X connect 3 1 0 0; #X connect 4 0 9 0; #X connect 6 0 12 0; #X connect 7 0 8 1; #X connect 8 0 1 0; #X connect 12 0 13 0; #X connect 12 1 3 0; #X connect 13 0 4 0; pdp-0.14.1+darcs20180201/abstractions/pdp_blur.pd000066400000000000000000000012231266045153600211240ustar00rootroot00000000000000#N canvas 344 526 521 227 10; #X obj 26 33 inlet; #X obj 26 174 outlet; #X obj 26 134 pdp_bq; #X obj 70 66 pdp_ut_addscaleclip -1 -0.5 0.05 0.48; #X obj 70 33 inlet; #X msg 181 34 2; #X msg 70 98 lpf \$1 0.25; #X msg 136 34 0; #X obj 136 10 loadbang; #X msg 163 98 hor 1; #X msg 209 98 ver 1; #X text 100 138 this uses pdp_bq as a 2 pass lowpass filter to produce a blur effect in all directions; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 5 0 2 1; #X connect 6 0 2 0; #X connect 7 0 3 0; #X connect 8 0 7 0; #X connect 8 0 5 0; #X connect 8 0 9 0; #X connect 8 0 10 0; #X connect 9 0 2 0; #X connect 10 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_blur_hor.pd000066400000000000000000000012131266045153600217730ustar00rootroot00000000000000#N canvas 344 526 521 227 10; #X obj 26 33 inlet; #X obj 26 174 outlet; #X obj 26 134 pdp_bq; #X obj 70 66 pdp_ut_addscaleclip -1 -0.5 0.05 0.48; #X obj 70 33 inlet; #X msg 181 34 2; #X msg 70 98 lpf \$1 0.25; #X msg 136 34 0; #X obj 136 10 loadbang; #X msg 163 98 hor 1; #X msg 209 98 ver 0; #X text 100 138 this uses pdp_bq as a 2 pass lowpass filter to produce a horzontal blur effect; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 5 0 2 1; #X connect 6 0 2 0; #X connect 7 0 3 0; #X connect 8 0 7 0; #X connect 8 0 5 0; #X connect 8 0 9 0; #X connect 8 0 10 0; #X connect 9 0 2 0; #X connect 10 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_blur_ver.pd000066400000000000000000000012141266045153600220000ustar00rootroot00000000000000#N canvas 368 520 521 227 10; #X obj 26 33 inlet; #X obj 26 174 outlet; #X obj 26 134 pdp_bq; #X obj 70 66 pdp_ut_addscaleclip -1 -0.5 0.05 0.48; #X obj 70 33 inlet; #X msg 181 34 2; #X msg 70 98 lpf \$1 0.25; #X msg 136 34 0; #X obj 136 10 loadbang; #X text 100 138 this uses pdp_bq as a 2 pass lowpass filter to produce a vertical blur effect; #X msg 209 98 ver 1; #X msg 163 98 hor 0; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 5 0 2 1; #X connect 6 0 2 0; #X connect 7 0 3 0; #X connect 8 0 7 0; #X connect 8 0 5 0; #X connect 8 0 11 0; #X connect 8 0 10 0; #X connect 10 0 2 0; #X connect 11 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_cheby3o.pd000066400000000000000000000007511266045153600215210ustar00rootroot00000000000000#N canvas 29 385 450 300 10; #X obj 42 87 inlet; #X obj 194 189 outlet; #X obj 194 159 pdp_cheby 3; #X msg 115 87 coef 0 \$1; #X msg 194 86 coef 1 \$1; #X msg 278 85 coef 2 \$1; #X msg 358 84 coef 3 \$1; #X obj 115 62 inlet; #X obj 194 62 inlet; #X obj 278 61 inlet; #X obj 358 60 inlet; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 6 0 2 0; #X connect 7 0 3 0; #X connect 8 0 4 0; #X connect 9 0 5 0; #X connect 10 0 6 0; pdp-0.14.1+darcs20180201/abstractions/pdp_contrast.pd000066400000000000000000000016771266045153600220320ustar00rootroot00000000000000#N canvas 700 349 450 324 10; #X obj 42 159 pdp_sthresh; #X obj 42 261 pdp_gain; #X msg 100 211 -1; #X obj 100 235 /; #X obj 189 196 - 1; #X obj 189 168 * 2; #X text 10 -1 contrast enhancement (works on YCrCb and greyscale); #X obj 170 117 moses 0.49; #X msg 235 141 0.49; #X obj 170 94 / 2; #X msg 87 101 chanmask 1; #X obj 170 46 loadbang; #X obj 170 69 f \$1; #X obj 42 47 inlet; #X obj 238 47 inlet; #X obj 42 285 outlet; #X text 11 13 i.e. to process the output of pdp_agc; #X obj 170 142 f; #X obj 42 185 pdp_t p b; #X connect 0 0 18 0; #X connect 1 0 15 0; #X connect 2 0 3 0; #X connect 3 0 1 1; #X connect 4 0 3 1; #X connect 5 0 4 0; #X connect 7 0 17 0; #X connect 7 1 8 0; #X connect 8 0 17 0; #X connect 9 0 7 0; #X connect 10 0 1 0; #X connect 10 0 0 0; #X connect 11 0 10 0; #X connect 11 0 12 0; #X connect 12 0 9 0; #X connect 13 0 0 0; #X connect 14 0 9 0; #X connect 17 0 0 1; #X connect 17 0 5 0; #X connect 18 0 1 0; #X connect 18 1 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_conv_alledge.pd000066400000000000000000000014531266045153600226070ustar00rootroot00000000000000#N canvas 245 202 522 199 10; #X obj 29 17 inlet; #X obj 29 156 outlet; #X obj 29 97 pdp_conv; #X msg 95 36 hmask 0.33 0.33 0.33; #X msg 95 59 vmask -0.33 -0.33 -0.33; #X obj 29 126 pdp_add; #X obj 95 13 loadbang; #X obj 292 34 int; #X obj 292 56 * 2; #X obj 292 79 - 1; #X obj 292 12 inlet; #X text 101 115 pdp_alledge is an all edge sensitive convolution filter using pdp_add and pdp_conv to compose a non separable edge detection convolution mask (pdp_conv can only compute separable convolution masks). the right inlet sets number of times the filter is run (2n-1); #X connect 0 0 2 0; #X connect 0 0 5 1; #X connect 2 0 5 0; #X connect 3 0 2 0; #X connect 3 0 4 0; #X connect 4 0 2 0; #X connect 5 0 1 0; #X connect 6 0 3 0; #X connect 7 0 8 0; #X connect 8 0 9 0; #X connect 9 0 2 1; #X connect 10 0 7 0; pdp-0.14.1+darcs20180201/abstractions/pdp_conv_emboss.pd000066400000000000000000000016601266045153600225020ustar00rootroot00000000000000#N canvas 172 505 641 290 10; #X obj 30 55 inlet; #X obj 29 206 outlet; #X obj 29 93 pdp_conv; #X obj 29 126 pdp_add; #X obj 108 9 loadbang; #X obj 218 86 pdp_conv; #X obj 29 176 pdp_affine 1; #X msg 108 151 0.5; #X msg 108 37 hmask 1 0 0; #X msg 218 35 hmask 0 0 1; #X obj 145 151 inlet; #X text 142 178 this uses pdp_conv \, pdp_add and pdp_affine to produce an emboss effect using the convolution mask (-1 0 0 \; 0 0 0 \; 0 0 1) the right inlet sets the chroma offset.; #X msg 218 60 vmask 0 0 1; #X msg 108 60 vmask -1 0 0; #X msg 108 128 chanmask 1; #X connect 0 0 2 0; #X connect 0 0 5 0; #X connect 2 0 3 0; #X connect 3 0 6 0; #X connect 4 0 8 0; #X connect 4 0 9 0; #X connect 5 0 3 1; #X connect 6 0 1 0; #X connect 7 0 6 2; #X connect 8 0 2 0; #X connect 8 0 13 0; #X connect 9 0 5 0; #X connect 9 0 12 0; #X connect 10 0 6 2; #X connect 12 0 5 0; #X connect 13 0 2 0; #X connect 13 0 14 0; #X connect 14 0 6 0; #X connect 14 0 7 0; pdp-0.14.1+darcs20180201/abstractions/pdp_conv_smooth.pd000066400000000000000000000005721266045153600225240ustar00rootroot00000000000000#N canvas 490 446 522 199 10; #X obj 29 17 inlet; #X obj 29 156 outlet; #X obj 29 97 pdp_conv; #X obj 95 13 loadbang; #X obj 292 12 inlet; #X msg 95 36 mask 0.33 0.33 0.33; #X text 107 108 pdp_conv_smooth is an averaging convolution filter. second inlet sets number of passes.; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 5 0; #X connect 4 0 2 1; #X connect 5 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_conv_sobel_edge.pd000066400000000000000000000010411266045153600232730ustar00rootroot00000000000000#N canvas 222 642 607 202 10; #X obj 15 35 pdp_conv_sobel_hor; #X obj 149 34 pdp_conv_sobel_ver; #X obj 15 114 pdp_add; #X obj 15 74 pdp_mul; #X obj 149 71 pdp_mul; #X text 123 105 this uses the horizontal and vertical sobel directional masks squared as an edge detector.; #X obj 14 -6 inlet; #X obj 15 151 outlet; #X obj 15 15 pdp_trigger p p; #X connect 0 0 3 0; #X connect 0 0 3 1; #X connect 1 0 4 0; #X connect 1 0 4 1; #X connect 2 0 7 0; #X connect 3 0 2 0; #X connect 4 0 2 1; #X connect 6 0 8 0; #X connect 8 0 0 0; #X connect 8 1 1 0; pdp-0.14.1+darcs20180201/abstractions/pdp_conv_sobel_hor.pd000066400000000000000000000006621266045153600231670ustar00rootroot00000000000000#N canvas 222 642 591 202 10; #X obj 29 55 inlet; #X obj 29 132 outlet; #X obj 29 93 pdp_conv; #X obj 108 9 loadbang; #X msg 108 37 vmask 0.5 1 0.5; #X msg 108 60 hmask -1 0 1; #X text 108 101 this uses pdp_conv to produce the vertical sobel edge detector with convolution mask (-.5 0 0.5 \; -1 0 1 \; -0.5 0 .5); #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 4 0; #X connect 4 0 2 0; #X connect 4 0 5 0; #X connect 5 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_conv_sobel_ver.pd000066400000000000000000000006641266045153600231750ustar00rootroot00000000000000#N canvas 222 642 591 202 10; #X obj 29 55 inlet; #X obj 29 131 outlet; #X obj 29 93 pdp_conv; #X obj 108 9 loadbang; #X msg 108 37 hmask 0.5 1 0.5; #X msg 108 60 vmask 1 0 -1; #X text 108 101 this uses pdp_conv to produce the horizontal sobel edge detector with convolution mask (-.5 -1 -0.5 \; 0 0 0 \; 0.5 1 .5); #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 4 0; #X connect 4 0 2 0; #X connect 4 0 5 0; #X connect 5 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_diff.pd000066400000000000000000000005531266045153600210750ustar00rootroot00000000000000#N canvas 550 527 517 215 10; #X obj 62 132 pdp_sub; #X obj 62 104 pdp_reg; #X obj 62 72 pdp_trigger bang pdp; #X obj 62 38 inlet; #X obj 62 163 outlet; #X text 161 17 compute the difference between current; #X text 161 33 and previous frame; #X connect 0 0 4 0; #X connect 1 0 0 1; #X connect 2 0 1 0; #X connect 2 1 1 1; #X connect 2 1 0 0; #X connect 3 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_dither.pd000066400000000000000000000013321266045153600214400ustar00rootroot00000000000000#N canvas 563 412 450 378 10; #X obj 209 213 pdp_abs; #X obj 209 144 pdp_noise; #X obj 57 249 pdp_sub; #X obj 209 172 pdp_grey; #X obj 57 148 pdp_grey; #X obj 57 88 inlet; #X msg 209 114 type grey; #X obj 57 204 pdp_contrast \$1; #X obj 57 308 outlet; #X obj 57 117 pdp_t p b; #X obj 157 87 inlet; #X obj 209 86 loadbang; #X text 25 8 a dither effect; #X text 26 45 returns a grey image (image/grey/*); #X obj 57 277 pdp_sign; #X text 26 23 right inlet is contrast; #X connect 0 0 2 1; #X connect 1 0 3 0; #X connect 2 0 14 0; #X connect 3 0 0 0; #X connect 4 0 7 0; #X connect 5 0 9 0; #X connect 6 0 1 0; #X connect 7 0 2 0; #X connect 9 0 4 0; #X connect 9 1 1 0; #X connect 10 0 7 1; #X connect 11 0 6 0; #X connect 14 0 8 0; pdp-0.14.1+darcs20180201/abstractions/pdp_gain3.pd000066400000000000000000000011651266045153600211660ustar00rootroot00000000000000#N canvas 576 356 409 204 10; #X obj 107 82 pdp_gain; #X obj 107 115 pdp_gain; #X obj 107 146 pdp_gain; #X obj 107 50 inlet; #X obj 184 49 inlet; #X obj 250 49 inlet; #X obj 309 48 inlet; #X obj 107 178 outlet; #X obj 19 22 loadbang; #X msg 19 50 chanmask 1; #X msg 19 84 chanmask 2; #X msg 19 117 chanmask 4; #X text 113 14 set gain independently for 3 channels; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 7 0; #X connect 3 0 0 0; #X connect 4 0 0 1; #X connect 5 0 1 1; #X connect 6 0 2 1; #X connect 8 0 9 0; #X connect 9 0 0 0; #X connect 9 0 10 0; #X connect 10 0 1 0; #X connect 10 0 11 0; #X connect 11 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_gradient.pd000066400000000000000000000027741266045153600217710ustar00rootroot00000000000000#N canvas 465 0 719 454 10; #X obj 49 19 inlet; #X obj 216 399 outlet; #X obj 216 235 pdp_gain; #X obj 216 286 pdp_gain; #X obj 216 340 pdp_gain; #X msg 361 217 chanmask 1; #X msg 361 268 chanmask 2; #X obj 361 178 loadbang; #X obj 99 267 unpack 0 0 0; #X msg 361 322 chanmask 4; #X obj 216 146 pdp_grey2mask; #X obj 5 198 unpack 0 0 0; #X obj 267 207 r \$0-ch1; #X obj 267 260 r \$0-ch2; #X obj 267 312 r \$0-ch3; #X obj 5 328 s \$0-ch1; #X obj 127 328 s \$0-ch3; #X obj 66 328 s \$0-ch2; #X obj 5 229 pdp_ut_rgb2ycrcb; #X msg 111 46 rgb 1 0.5 0; #X msg 111 74 ycrcb 1 0.5 0; #X text 230 46 set a red/green/blue gradient; #X text 140 16 a gradient abstraction based on gain and grey2mask; #X obj 49 118 route rgb ycrcb; #X text 308 391 hint: replace pdp_gain by pdp_cheby to get nonlinear gradients.; #X text 229 76 set a luma/chroma_red/chroma_blue gradient; #X text 322 146 this copies luma channel to chroma channels; #X connect 0 0 23 0; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 1 0; #X connect 5 0 2 0; #X connect 5 0 6 0; #X connect 6 0 3 0; #X connect 6 0 9 0; #X connect 7 0 5 0; #X connect 7 0 19 0; #X connect 8 0 15 0; #X connect 8 1 17 0; #X connect 8 2 16 0; #X connect 9 0 4 0; #X connect 10 0 2 0; #X connect 11 0 18 0; #X connect 11 1 18 1; #X connect 11 2 18 2; #X connect 12 0 2 1; #X connect 13 0 3 1; #X connect 14 0 4 1; #X connect 18 0 15 0; #X connect 18 1 17 0; #X connect 18 2 16 0; #X connect 19 0 23 0; #X connect 20 0 23 0; #X connect 23 0 11 0; #X connect 23 1 8 0; #X connect 23 2 10 0; pdp-0.14.1+darcs20180201/abstractions/pdp_grey.pd000066400000000000000000000003121266045153600211240ustar00rootroot00000000000000#N canvas 608 510 395 122 10; #X obj 39 23 inlet; #X obj 39 51 pdp_convert image/grey/*; #X obj 39 79 outlet; #X text 101 21 backwards compatibility abstraction; #X connect 0 0 1 0; #X connect 1 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_invert.pd000066400000000000000000000006501266045153600214720ustar00rootroot00000000000000#N canvas 487 324 440 275 10; #X obj 34 51 inlet; #X obj 34 236 outlet; #X obj 34 173 pdp_gain; #X obj 34 100 pdp_cheby 1; #X obj 153 24 loadbang; #X msg 141 146 chanmask 6; #X msg 153 58 chanmask 1 \, coef 0 1 \, coef 1 -1; #X msg 141 120 -1; #X connect 0 0 3 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 6 0; #X connect 5 0 2 0; #X connect 6 0 3 0; #X connect 6 0 7 0; #X connect 7 0 2 1; #X connect 7 0 5 0; pdp-0.14.1+darcs20180201/abstractions/pdp_m_inverse.pd000066400000000000000000000005141266045153600221510ustar00rootroot00000000000000#N canvas 805 557 415 150 10; #X obj 21 49 pdp_m_LU; #X obj 21 24 inlet; #X obj 21 103 outlet; #X text 150 31 computes a matrix inverse using the; #X text 149 48 LU decomposition (PA = LU); #X text 148 84 (uses double precision processing); #X obj 21 77 pdp_m_LU_inverse; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 6 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_motion_blur.pd000066400000000000000000000006361266045153600225200ustar00rootroot00000000000000#N canvas 119 483 508 168 10; #X obj 29 17 inlet; #X obj 29 124 outlet; #X obj 29 99 pdp_bqt; #X obj 87 18 inlet; #X obj 87 42 pdp_ut_logmap_comp 0.005 0.4; #X msg 87 68 lpf \$1 0.25; #X text 97 108 pdp_motion_blur uses pdp_bqt (time biquad filter) configured as a lowpass filter to produce a motion blur effect.; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 4 0; #X connect 4 0 5 0; #X connect 5 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_motion_fade.pd000066400000000000000000000010001266045153600224350ustar00rootroot00000000000000#N canvas 58 0 508 168 10; #X obj 29 17 inlet; #X obj 29 124 outlet; #X obj 29 99 pdp_bqt; #X obj 87 18 inlet; #X text 94 102 pdp_motion_fade uses pdp_bqt (time biquad filter) configured as an highpass filter to produce a motion triggered fade-out effect. ; #X obj 340 -1 loadbang; #X obj 340 24 f \$1; #X obj 87 42 pdp_ut_logmap_comp 0.01 0.4; #X msg 87 68 hpf \$1 0.25; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 7 0; #X connect 5 0 6 0; #X connect 6 0 7 0; #X connect 7 0 8 0; #X connect 8 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_motion_phase.pd000066400000000000000000000006421266045153600226510ustar00rootroot00000000000000#N canvas 58 0 508 168 10; #X obj 29 17 inlet; #X obj 29 124 outlet; #X obj 29 99 pdp_bqt; #X obj 87 18 inlet; #X text 94 102 pdp_motion_blur uses pdp_bqt (time biquad filter) configured as an allpass filter to produce a motion phase shift effect.; #X obj 87 42 pdp_ut_logmap_comp 0.01 0.4; #X msg 87 68 apf \$1 0.25; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 5 0; #X connect 5 0 6 0; #X connect 6 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_offset.pd000066400000000000000000000006471266045153600214570ustar00rootroot00000000000000#N canvas 515 434 450 300 10; #X obj 48 69 inlet; #X obj 48 243 outlet; #X obj 48 191 pdp_cheby; #X msg 173 93 coef 0 \$1; #X obj 103 69 loadbang; #X obj 173 68 inlet; #X obj 103 111 float \$1; #X text 45 21 add an offset to an image; #X msg 103 138 reset \, coef 1 1 \, coef 0 \$1; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 6 0; #X connect 5 0 3 0; #X connect 6 0 8 0; #X connect 8 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_phase.pd000066400000000000000000000031161266045153600212630ustar00rootroot00000000000000#N canvas 304 524 746 291 10; #X obj 25 21 inlet; #X obj 25 249 outlet; #X obj 25 209 pdp_bq; #X obj 42 144 pdp_ut_addscaleclip -1 -0.5 0.05 0.48; #X obj 42 44 inlet; #X msg 118 109 0; #X obj 178 22 loadbang; #X msg 304 191 lr 1; #X msg 344 191 rl 0; #X msg 42 176 apf \$1 0.15; #X obj 287 22 inlet; #X msg 384 191 lr 0; #X msg 422 191 rl 1; #X msg 539 191 bt 1; #X msg 579 191 tb 0; #X msg 619 191 bt 0; #X msg 672 191 tb 1; #X obj 287 86 select 0; #X msg 227 191 lr 0; #X msg 265 191 rl 0; #X obj 522 19 inlet; #X obj 522 84 select 0; #X obj 338 114 moses 0; #X obj 573 114 moses 0; #X msg 241 53 1; #X msg 463 191 tb 0; #X msg 501 191 bt 0; #X text 99 235 this uses pdp_bq as an allpass filter to produce a phase shift effect. 2nd inlet sets amount. 3rd and 4th inlets set directions. ; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 9 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 5 0; #X connect 6 0 7 0; #X connect 6 0 8 0; #X connect 6 0 24 0; #X connect 7 0 2 0; #X connect 8 0 2 0; #X connect 9 0 2 0; #X connect 10 0 17 0; #X connect 11 0 2 0; #X connect 12 0 2 0; #X connect 13 0 2 0; #X connect 14 0 2 0; #X connect 16 0 2 0; #X connect 17 0 18 0; #X connect 17 0 19 0; #X connect 17 1 22 0; #X connect 18 0 2 0; #X connect 19 0 2 0; #X connect 20 0 21 0; #X connect 21 0 25 0; #X connect 21 0 26 0; #X connect 21 1 23 0; #X connect 22 0 8 0; #X connect 22 0 7 0; #X connect 22 1 12 0; #X connect 22 1 11 0; #X connect 23 0 14 0; #X connect 23 0 13 0; #X connect 23 1 16 0; #X connect 23 1 15 0; #X connect 24 0 17 0; #X connect 24 0 21 0; #X connect 25 0 2 0; #X connect 26 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_phase_hor.pd000066400000000000000000000017611266045153600221370ustar00rootroot00000000000000#N canvas 304 524 534 291 10; #X obj 25 21 inlet; #X obj 25 249 outlet; #X obj 25 209 pdp_bq; #X obj 42 144 pdp_ut_addscaleclip -1 -0.5 0.05 0.48; #X obj 42 44 inlet; #X msg 89 44 0; #X obj 89 18 loadbang; #X msg 42 176 apf \$1 0.15; #X obj 338 114 moses 0; #X text 99 235 this uses pdp_bq as an allpass filter to produce a phase shift effect in the horizontal direction. 2nd inlet sets direction and amount. range is from -1 to 1; #X obj 42 93 abs; #X msg 304 191 lr 0; #X msg 344 191 rl 1; #X msg 384 191 lr 1; #X msg 422 191 rl 0; #X msg 89 93 ver 0; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 7 0; #X connect 4 0 10 0; #X connect 4 0 8 0; #X connect 5 0 10 0; #X connect 5 0 8 0; #X connect 5 0 15 0; #X connect 6 0 5 0; #X connect 6 0 11 0; #X connect 6 0 12 0; #X connect 7 0 2 0; #X connect 8 0 12 0; #X connect 8 0 11 0; #X connect 8 1 14 0; #X connect 8 1 13 0; #X connect 10 0 3 0; #X connect 11 0 2 0; #X connect 12 0 2 0; #X connect 13 0 2 0; #X connect 14 0 2 0; #X connect 15 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_phase_ver.pd000066400000000000000000000017541266045153600221450ustar00rootroot00000000000000#N canvas 304 524 518 291 10; #X obj 25 21 inlet; #X obj 25 249 outlet; #X obj 25 209 pdp_bq; #X obj 42 144 pdp_ut_addscaleclip -1 -0.5 0.05 0.48; #X obj 42 44 inlet; #X msg 89 44 0; #X obj 89 18 loadbang; #X obj 338 114 moses 0; #X obj 42 93 abs; #X msg 42 176 apf \$1 0.15; #X msg 89 93 hor 0; #X msg 304 191 tb 1; #X msg 344 191 bt 0; #X msg 384 191 tb 0; #X msg 422 191 bt 1; #X text 99 235 this uses pdp_bq as an allpass filter to produce a phase shift effect in the vertical direction. 2nd inlet sets direction and amount. range is from -1 to 1; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 9 0; #X connect 4 0 8 0; #X connect 4 0 7 0; #X connect 5 0 8 0; #X connect 5 0 7 0; #X connect 5 0 10 0; #X connect 6 0 5 0; #X connect 6 0 11 0; #X connect 6 0 12 0; #X connect 7 0 12 0; #X connect 7 0 11 0; #X connect 7 1 14 0; #X connect 7 1 13 0; #X connect 8 0 3 0; #X connect 9 0 2 0; #X connect 10 0 2 0; #X connect 11 0 2 0; #X connect 12 0 2 0; #X connect 13 0 2 0; #X connect 14 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_png_to.pd000066400000000000000000000010471266045153600214520ustar00rootroot00000000000000#N canvas 0 0 450 300 10; #X obj 37 50 inlet; #X obj 102 262 outlet; #X obj 102 209 pdp_convert \$1; #X obj 102 180 pdp_reg; #X text 34 15 load a png file and convert to a packet type specified by the creation argument. default = bitmap/*/*; #X obj 102 121 symbol; #X msg 102 149 load_png \$1 \, bang; #X obj 37 81 route bang; #X msg 37 208 bang; #X obj 102 236 pdp_reg; #X connect 0 0 7 0; #X connect 2 0 9 0; #X connect 3 0 2 0; #X connect 5 0 6 0; #X connect 6 0 3 0; #X connect 7 0 8 0; #X connect 7 1 5 0; #X connect 8 0 9 0; #X connect 9 0 1 0; pdp-0.14.1+darcs20180201/abstractions/pdp_pps.pd000066400000000000000000000007261266045153600207710ustar00rootroot00000000000000#N canvas 115 450 614 279 10; #X obj 41 53 pdp_trigger; #X obj 113 90 timer; #X obj 113 187 /; #X obj 113 125 t b f; #X msg 113 155 1000; #X obj 41 21 inlet; #X obj 113 219 outlet; #X text 151 36 pdp_pps uses pdp_trigger to measure the number of packets per second. you can use this as a performance monitor.; #X connect 0 1 1 1; #X connect 0 1 1 0; #X connect 1 0 3 0; #X connect 2 0 6 0; #X connect 3 0 4 0; #X connect 3 1 2 1; #X connect 4 0 2 0; #X connect 5 0 0 0; pdp-0.14.1+darcs20180201/abstractions/pdp_qt_control.pd000066400000000000000000000067551266045153600223630ustar00rootroot00000000000000#N canvas 287 151 577 553 10; #X obj 390 48 inlet; #X text 315 10 nb of frames; #X text 313 23 connect pdp_qt's 3rd outlet here; #X obj 390 99 s \$0-frames; #X obj 8 9 inlet; #X msg 150 186 pp; #X msg 53 85 set l; #X msg 104 87 set pp; #X msg 160 87 set r; #N canvas 821 623 335 233 randplay 0; #X obj 82 122 random; #X obj 111 96 r \$0-frames; #X msg 73 81 bang; #X obj 69 39 inlet; #X obj 82 153 outlet; #X text 154 24 random frame playback; #X connect 0 0 4 0; #X connect 1 0 0 1; #X connect 2 0 0 0; #X connect 3 0 2 0; #X restore 377 288 pd randplay; #N canvas 418 263 365 227 loopplay 0; #X obj 63 79 f 0; #X obj 63 101 + 1; #X obj 63 147 mod; #X obj 70 121 r \$0-frames; #X msg 62 59 bang; #X obj 62 30 inlet; #X obj 63 182 outlet; #X text 166 33 normal looped playback; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 0 1; #X connect 2 0 6 0; #X connect 3 0 2 1; #X connect 4 0 0 0; #X connect 5 0 4 0; #X restore 59 284 pd loopplay; #X obj 4 35 route bang; #N canvas 253 244 365 227 rloopplay 0; #X obj 63 79 f 0; #X obj 63 147 mod; #X obj 96 129 r \$0-frames; #X msg 62 59 bang; #X obj 62 30 inlet; #X obj 63 182 outlet; #X obj 63 101 + 1; #X obj 133 79 r \$0-frames; #X obj 132 102 - 1; #X text 166 33 reverse looped playback; #X connect 0 0 6 0; #X connect 1 0 0 1; #X connect 1 0 5 0; #X connect 2 0 1 1; #X connect 3 0 0 0; #X connect 4 0 3 0; #X connect 6 0 1 0; #X connect 7 0 8 0; #X connect 8 0 6 1; #X restore 152 284 pd rloopplay; #X msg 215 87 set rl; #N canvas 0 0 450 300 addjitter 0; #X obj 150 65 inlet; #X obj 177 244 outlet; #X obj 259 66 inlet; #X obj 259 90 abs; #X obj 225 173 r \$0-frames; #X obj 186 201 mod; #X obj 259 113 + 1; #X obj 211 139 random 1; #X text 32 26 add jitter. sort of. something like the nervous effect. ; #X obj 160 115 t f b; #X obj 185 169 +; #X connect 0 0 9 0; #X connect 2 0 3 0; #X connect 3 0 6 0; #X connect 4 0 5 1; #X connect 5 0 1 0; #X connect 6 0 7 1; #X connect 7 0 10 1; #X connect 9 0 10 0; #X connect 9 1 7 0; #X connect 10 0 5 0; #X restore 148 395 pd addjitter; #X obj 150 426 outlet; #X obj 53 60 route loop pingpong random rloop nervous; #X obj 95 419 print; #N canvas 751 514 434 327 pingpongplay 1; #X obj 117 73 r \$0-frames; #X msg 62 59 bang; #X obj 62 30 inlet; #X obj 56 243 outlet; #X text 120 13 pingpong (palindrome) looped playback; #X obj 118 121 * 2; #X obj 55 191 -; #X obj 55 213 abs; #X obj 63 79 f 0; #X floatatom 113 203 5 0 0 0 - - -; #X obj 58 108 + 1; #X obj 62 141 mod; #X obj 117 98 - 1; #X connect 0 0 12 0; #X connect 1 0 8 0; #X connect 2 0 1 0; #X connect 5 0 11 1; #X connect 6 0 7 0; #X connect 7 0 3 0; #X connect 7 0 9 0; #X connect 8 0 10 0; #X connect 10 0 11 0; #X connect 11 0 6 0; #X connect 11 0 8 1; #X connect 12 0 5 0; #X connect 12 0 6 1; #X restore 249 284 pd pingpongplay; #X obj 150 217 route l rl pp r; #X text 60 12 left input: metro and control; #X text 49 465 loop modes: loop (normal) \, rloop (reverse loop) \, pingpong (palindrome) \, random. send a nervous message to add some random jitter.; #X obj 390 75 abs; #X connect 0 0 22 0; #X connect 4 0 11 0; #X connect 5 0 19 0; #X connect 6 0 5 0; #X connect 7 0 5 0; #X connect 8 0 5 0; #X connect 9 0 14 0; #X connect 10 0 14 0; #X connect 11 0 5 0; #X connect 11 1 16 0; #X connect 12 0 14 0; #X connect 13 0 5 0; #X connect 14 0 15 0; #X connect 16 0 6 0; #X connect 16 1 7 0; #X connect 16 2 8 0; #X connect 16 3 13 0; #X connect 16 4 14 1; #X connect 18 0 14 0; #X connect 19 0 10 0; #X connect 19 1 12 0; #X connect 19 2 18 0; #X connect 19 3 9 0; #X connect 22 0 3 0; pdp-0.14.1+darcs20180201/abstractions/pdp_qtloop2~.pd000066400000000000000000000112011266045153600217530ustar00rootroot00000000000000#N canvas 526 20 677 778 10; #X obj 82 83 inlet; #X obj 255 82 inlet; #X obj 103 506 pdp_loop; #X obj 154 702 outlet; #X obj 18 473 r \$0-loopin; #X obj 24 145 s \$0-filename; #X text 60 59 bang or hot frame; #X text 142 727 packet outlet; #X msg 132 137 bang; #X obj 82 111 route open bang; #X obj 103 554 pdp_convert image/YCrCb/*; #X obj 294 214 s \$0-playaudioframe; #X obj 294 237 outlet; #X obj 132 375 mod; #X obj 178 345 r \$0-nbframes; #X obj 418 363 outlet; #X obj 495 137 outlet~; #X obj 581 133 outlet~; #N canvas 98 558 711 881 more_logic 0; #X obj 215 518 pdp_qt; #X obj 246 772 symbol \$0-L; #X obj 340 773 symbol \$0-R; #X msg 246 797 dump \$1 0; #X msg 340 797 dump \$1 1; #X msg 140 473 open \$1; #X obj 21 367 symbol; #X obj 216 729 t f b; #X obj 232 490 r \$0-qtin; #X obj 340 833 s \$0-qtin; #X obj 245 318 s \$0-loopin; #X obj 21 338 r \$0-filename; #X obj 215 692 s \$0-loopin; #X text 337 227 new movie loaded \, nb of frames received here; #X text 268 730 dump audio; #X text 374 288 set loop size; #X obj 215 463 until; #X text 262 465 dump frames; #X obj 215 258 t f f; #X msg 245 289 size \$1 \, record; #X text 374 303 start recording; #X obj 199 435 f 0; #X obj 252 551 s \$0-nbframes; #X obj 215 227 r \$0-nbframes; #X msg 21 494 DONE; #X obj 21 671 print pdp_qtloop~; #X obj 215 661 pdp_convert bitmap/yv12/*; #X obj 215 348 t f f; #X obj 233 601 pack 0 0; #X obj 21 393 t b b b s; #X msg 233 627 decoding frame \$1 of \$2; #X obj 233 576 + 1; #X text 407 661 images are stored in 12bpp; #X obj 217 173 outlet~; #X obj 340 172 outlet~; #X obj 217 106 * 1920; #X obj 217 41 r \$0-playaudioframe; #X text 215 18 restart audio playback from frame #; #X text 277 106 samplerate / framerate; #X obj 32 32 table \$0-L; #X obj 32 56 table \$0-R; #N canvas 367 318 450 300 fracframemodulo 0; #X obj 93 43 inlet; #X obj 93 274 outlet; #X obj 93 97 /; #X obj 109 67 r \$0-nbframes; #X obj 123 147 int; #X obj 93 122 t f f; #X obj 93 179 -; #X obj 109 220 r \$0-nbframes; #X obj 93 248 *; #X connect 0 0 2 0; #X connect 2 0 5 0; #X connect 3 0 2 1; #X connect 4 0 6 1; #X connect 5 0 6 0; #X connect 5 1 4 0; #X connect 6 0 8 0; #X connect 7 0 8 1; #X connect 8 0 1 0; #X restore 217 68 pd fracframemodulo; #X obj 216 144 tabreadmix~ \$0-L; #X obj 340 143 tabreadmix~ \$0-R; #X obj 518 73 inlet; #X connect 0 0 26 0; #X connect 0 1 31 0; #X connect 0 2 22 0; #X connect 1 0 3 0; #X connect 2 0 4 0; #X connect 3 0 9 0; #X connect 4 0 9 0; #X connect 5 0 0 0; #X connect 6 0 29 0; #X connect 7 1 1 0; #X connect 7 1 2 0; #X connect 8 0 0 0; #X connect 11 0 6 0; #X connect 16 0 0 0; #X connect 18 0 27 0; #X connect 18 1 19 0; #X connect 19 0 10 0; #X connect 21 0 16 0; #X connect 23 0 18 0; #X connect 24 0 25 0; #X connect 26 0 12 0; #X connect 27 0 21 1; #X connect 27 0 28 1; #X connect 28 0 30 0; #X connect 29 0 24 0; #X connect 29 1 7 0; #X connect 29 2 21 0; #X connect 29 3 5 0; #X connect 30 0 25 0; #X connect 31 0 28 0; #X connect 35 0 42 0; #X connect 35 0 43 0; #X connect 36 0 41 0; #X connect 41 0 35 0; #X connect 42 0 33 0; #X connect 43 0 34 0; #X connect 44 0 43 1; #X connect 44 0 42 1; #X restore 495 104 pd more_logic; #X obj 132 170 f; #X obj 132 287 t f f; #X text 240 61 cold frame; #X obj 162 375 mod; #X obj 162 319 + 1; #X obj 118 613 pdp_route; #X obj 154 661 pdp_mix; #X text 273 257 frame nb outlet; #X msg 176 461 0; #X msg 208 461 1; #X obj 176 488 f; #X text 215 408 get current and next frame from pdp_loop; #X obj 132 219 int; #X obj 206 267 -; #X obj 132 196 t f f f; #X obj 132 249 t f f; #X text 277 317 crossfade fraction; #X obj 206 317 s \$0-frac; #X obj 198 631 r \$0-frac; #X obj 206 292 * -1; #X obj 103 408 t f b; #X obj 162 408 t f b; #X text 397 385 nb frames outlet; #X text 249 19 like pdp_qtloop~ but uses tabreadmix~ from creb; #X obj 497 77 inlet; #X text 479 57 grain size; #X connect 0 0 9 0; #X connect 1 0 19 1; #X connect 2 0 10 0; #X connect 4 0 2 0; #X connect 8 0 19 0; #X connect 9 0 5 0; #X connect 9 1 8 0; #X connect 9 2 19 0; #X connect 10 0 24 0; #X connect 13 0 39 0; #X connect 14 0 13 1; #X connect 14 0 22 1; #X connect 14 0 15 0; #X connect 18 0 16 0; #X connect 18 1 17 0; #X connect 19 0 33 0; #X connect 20 0 13 0; #X connect 20 1 23 0; #X connect 22 0 40 0; #X connect 23 0 22 0; #X connect 24 0 25 0; #X connect 24 1 25 1; #X connect 25 0 3 0; #X connect 27 0 29 0; #X connect 28 0 29 0; #X connect 29 0 24 1; #X connect 31 0 34 0; #X connect 32 0 38 0; #X connect 33 0 31 0; #X connect 33 1 32 1; #X connect 33 2 12 0; #X connect 33 2 11 0; #X connect 34 0 20 0; #X connect 34 1 32 0; #X connect 37 0 25 2; #X connect 38 0 36 0; #X connect 39 0 2 0; #X connect 39 1 27 0; #X connect 40 0 2 0; #X connect 40 1 28 0; #X connect 43 0 18 0; pdp-0.14.1+darcs20180201/abstractions/pdp_qtloop~.pd000066400000000000000000000106641266045153600217050ustar00rootroot00000000000000#N canvas 526 20 677 778 10; #X obj 82 83 inlet; #X obj 255 82 inlet; #X obj 103 506 pdp_loop; #X obj 154 702 outlet; #X obj 18 473 r \$0-loopin; #X obj 24 145 s \$0-filename; #X text 60 59 bang or hot frame; #X text 142 727 packet outlet; #X msg 132 137 bang; #X obj 82 111 route open bang; #X obj 103 554 pdp_convert image/YCrCb/*; #X obj 294 214 s \$0-playaudioframe; #X obj 294 237 outlet; #X obj 132 375 mod; #X obj 178 345 r \$0-nbframes; #X obj 418 363 outlet; #X obj 495 137 outlet~; #X obj 581 133 outlet~; #N canvas 98 558 711 881 more_logic 0; #X obj 215 518 pdp_qt; #X obj 246 772 symbol \$0-L; #X obj 340 773 symbol \$0-R; #X msg 246 797 dump \$1 0; #X msg 340 797 dump \$1 1; #X msg 140 473 open \$1; #X obj 21 367 symbol; #X obj 216 729 t f b; #X obj 232 490 r \$0-qtin; #X obj 340 833 s \$0-qtin; #X obj 245 318 s \$0-loopin; #X obj 21 338 r \$0-filename; #X obj 215 692 s \$0-loopin; #X text 337 227 new movie loaded \, nb of frames received here; #X text 268 730 dump audio; #X text 374 288 set loop size; #X obj 215 463 until; #X text 262 465 dump frames; #X obj 215 258 t f f; #X msg 245 289 size \$1 \, record; #X text 374 303 start recording; #X obj 199 435 f 0; #X obj 252 551 s \$0-nbframes; #X obj 215 227 r \$0-nbframes; #X msg 21 494 DONE; #X obj 21 671 print pdp_qtloop~; #X obj 215 661 pdp_convert bitmap/yv12/*; #X obj 215 348 t f f; #X obj 233 601 pack 0 0; #X obj 21 393 t b b b s; #X msg 233 627 decoding frame \$1 of \$2; #X obj 233 576 + 1; #X text 407 661 images are stored in 12bpp; #X obj 217 173 outlet~; #X obj 340 172 outlet~; #X obj 217 106 * 1920; #X obj 217 41 r \$0-playaudioframe; #X text 215 18 restart audio playback from frame #; #X text 277 106 samplerate / framerate; #X obj 32 32 table \$0-L; #X obj 32 56 table \$0-R; #N canvas 367 318 450 300 fracframemodulo 0; #X obj 93 43 inlet; #X obj 93 274 outlet; #X obj 93 97 /; #X obj 109 67 r \$0-nbframes; #X obj 123 147 int; #X obj 93 122 t f f; #X obj 93 179 -; #X obj 109 220 r \$0-nbframes; #X obj 93 248 *; #X connect 0 0 2 0; #X connect 2 0 5 0; #X connect 3 0 2 1; #X connect 4 0 6 1; #X connect 5 0 6 0; #X connect 5 1 4 0; #X connect 6 0 8 0; #X connect 7 0 8 1; #X connect 8 0 1 0; #X restore 217 68 pd fracframemodulo; #X obj 216 144 tabplay~ \$0-L; #X obj 340 143 tabplay~ \$0-R; #X connect 0 0 26 0; #X connect 0 1 31 0; #X connect 0 2 22 0; #X connect 1 0 3 0; #X connect 2 0 4 0; #X connect 3 0 9 0; #X connect 4 0 9 0; #X connect 5 0 0 0; #X connect 6 0 29 0; #X connect 7 1 1 0; #X connect 7 1 2 0; #X connect 8 0 0 0; #X connect 11 0 6 0; #X connect 16 0 0 0; #X connect 18 0 27 0; #X connect 18 1 19 0; #X connect 19 0 10 0; #X connect 21 0 16 0; #X connect 23 0 18 0; #X connect 24 0 25 0; #X connect 26 0 12 0; #X connect 27 0 21 1; #X connect 27 0 28 1; #X connect 28 0 30 0; #X connect 29 0 24 0; #X connect 29 1 7 0; #X connect 29 2 21 0; #X connect 29 3 5 0; #X connect 30 0 25 0; #X connect 31 0 28 0; #X connect 35 0 42 0; #X connect 35 0 43 0; #X connect 36 0 41 0; #X connect 41 0 35 0; #X connect 42 0 33 0; #X connect 43 0 34 0; #X restore 495 104 pd more_logic; #X obj 132 170 f; #X obj 132 287 t f f; #X text 240 61 cold frame; #X obj 162 375 mod; #X obj 162 319 + 1; #X obj 118 613 pdp_route; #X obj 154 661 pdp_mix; #X text 273 257 frame nb outlet; #X msg 176 461 0; #X msg 208 461 1; #X obj 176 488 f; #X text 215 408 get current and next frame from pdp_loop; #X obj 132 219 int; #X obj 206 267 -; #X obj 132 196 t f f f; #X obj 132 249 t f f; #X text 277 317 crossfade fraction; #X obj 206 317 s \$0-frac; #X obj 198 631 r \$0-frac; #X obj 206 292 * -1; #X obj 103 408 t f b; #X obj 162 408 t f b; #X text 397 385 nb frames outlet; #X connect 0 0 9 0; #X connect 1 0 19 1; #X connect 2 0 10 0; #X connect 4 0 2 0; #X connect 8 0 19 0; #X connect 9 0 5 0; #X connect 9 1 8 0; #X connect 9 2 19 0; #X connect 10 0 24 0; #X connect 13 0 39 0; #X connect 14 0 13 1; #X connect 14 0 22 1; #X connect 14 0 15 0; #X connect 18 0 16 0; #X connect 18 1 17 0; #X connect 19 0 33 0; #X connect 20 0 13 0; #X connect 20 1 23 0; #X connect 22 0 40 0; #X connect 23 0 22 0; #X connect 24 0 25 0; #X connect 24 1 25 1; #X connect 25 0 3 0; #X connect 27 0 29 0; #X connect 28 0 29 0; #X connect 29 0 24 1; #X connect 31 0 34 0; #X connect 32 0 38 0; #X connect 33 0 31 0; #X connect 33 1 32 1; #X connect 33 2 12 0; #X connect 33 2 11 0; #X connect 34 0 20 0; #X connect 34 1 32 0; #X connect 37 0 25 2; #X connect 38 0 36 0; #X connect 39 0 2 0; #X connect 39 1 27 0; #X connect 40 0 2 0; #X connect 40 1 28 0; pdp-0.14.1+darcs20180201/abstractions/pdp_saturation.pd000066400000000000000000000010271266045153600223530ustar00rootroot00000000000000#N canvas 322 388 509 326 10; #X obj 39 105 inlet; #X obj 270 103 inlet; #X obj 39 255 outlet; #X obj 85 105 loadbang; #X text 32 14 adjust colour saturation by applying a gain to the chroma channels.; #X text 31 47 this only works for image/YCrCb/* packets and 3 channel image/multi/* packets containing luma and chroma channels.; #X obj 39 192 pdp_gain; #X msg 85 155 chanmask 6 \, gain \$1; #X obj 85 131 f \$1; #X connect 0 0 6 0; #X connect 1 0 6 1; #X connect 3 0 8 0; #X connect 6 0 2 0; #X connect 7 0 6 0; #X connect 8 0 7 0; pdp-0.14.1+darcs20180201/abstractions/pdp_save_png_sequence.pd000066400000000000000000000013341266045153600236550ustar00rootroot00000000000000#N canvas 654 482 490 382 10; #X obj 54 65 inlet; #X obj 119 362 pdp_reg; #X obj 119 130 pdp_t b p; #X obj 119 186 + 1; #X obj 54 93 route bang; #X obj 119 251 makefilename /tmp/frame%d.png; #X obj 119 215 moses \$1; #X obj 140 279 print; #X msg 119 305 save_png \$1; #X msg 54 126 0; #X text 146 10 save a png sequence in the /tmp directory; #X text 146 25 creation argument is the number of frames; #X obj 119 160 f \$1; #X text 146 40 send a bang to start writing; #X connect 0 0 4 0; #X connect 2 0 12 0; #X connect 2 1 1 0; #X connect 3 0 6 0; #X connect 3 0 12 1; #X connect 4 0 9 0; #X connect 4 1 2 0; #X connect 5 0 7 0; #X connect 5 0 8 0; #X connect 6 0 5 0; #X connect 8 0 1 0; #X connect 9 0 12 1; #X connect 12 0 3 0; pdp-0.14.1+darcs20180201/abstractions/pdp_sub.pd000066400000000000000000000002661266045153600207570ustar00rootroot00000000000000#N canvas 577 543 450 300 10; #X obj 48 49 inlet; #X obj 118 47 inlet; #X obj 47 161 outlet; #X obj 48 104 pdp_mix2 1 -1; #X connect 0 0 3 0; #X connect 1 0 3 1; #X connect 3 0 2 0; pdp-0.14.1+darcs20180201/abstractions/pdp_tag.pd000066400000000000000000000007121266045153600207350ustar00rootroot00000000000000#N canvas 700 231 450 300 10; #X obj 56 25 inlet; #X obj 55 191 outlet; #X msg 162 174 \$1 \$2 \$3 \$4; #X text 148 31 tag a pdp message (for routing); #X obj 0 110 symbol \$1; #X obj 56 68 unpack s s 0; #X obj 55 139 pack s s s 0; #X obj 39 91 t b s; #X obj 55 165 route list; #X connect 0 0 5 0; #X connect 4 0 6 0; #X connect 5 0 7 0; #X connect 5 1 6 2; #X connect 5 2 6 3; #X connect 6 0 8 0; #X connect 7 0 4 0; #X connect 7 1 6 1; #X connect 8 0 1 0; pdp-0.14.1+darcs20180201/abstractions/pdp_v4l_hack.pd000066400000000000000000000030311266045153600216520ustar00rootroot00000000000000#N canvas 0 29 958 1049 10; #X obj 83 95 pdp_v4l; #X obj 83 35 inlet; #X obj 91 182 outlet; #X obj 154 179 outlet; #X obj 244 122 route card; #X obj 244 174 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 162 55 info; #X obj 44 54 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 244 204 control EXPOSURE_AUTO 1 \, control EXPOSURE_ABSOLUTE 350; #X msg 28 239 open /dev/video0; #X msg 26 264 open /dev/video1; #X obj 529 173 print unknown_camera; #X obj 244 147 route USB_2_0_Camera Microsoft___LifeCam_HD_5000; #X obj 386 173 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 254 17 The idea here is to automatically set some properties based on camera ID \, but it seems easier to just do this manually. My Microsoft HD-5000 needs: control EXPOSURE_AUTO 1 \, control EXPOSURE_ABSOLUTE 156 It seems that most cameras only work on their highest frequency when exposure is off. If exposure control is not available \, just adding more ambient light can be enough to raise the effective framerate. ; #X msg 243 236 control EXPOSURE_AUTO 1 \, control EXPOSURE_ABSOLUTE 156 \, fps 30; #X msg 202 335 dim 320 340; #X msg 197 362 dim 640 480; #X connect 0 0 2 0; #X connect 0 1 3 0; #X connect 0 1 4 0; #X connect 1 0 0 0; #X connect 4 0 12 0; #X connect 5 0 8 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 12 0 5 0; #X connect 12 1 13 0; #X connect 12 2 11 0; #X connect 13 0 15 0; #X connect 15 0 0 0; #X connect 16 0 0 0; #X connect 17 0 0 0; pdp-0.14.1+darcs20180201/abstractions/pdp_xv_keycursor.pd000066400000000000000000000036331266045153600227320ustar00rootroot00000000000000#N canvas 135 108 708 682 10; #X obj 19 103 print; #X obj 19 67 pdp_xv; #X obj 111 168 route keypress; #X obj 367 215 table \$0-x; #X obj 87 394 tabwrite \$0-x; #X obj 396 335 tabread \$0-x; #X obj 486 335 tabread \$0-y; #X obj 409 383 pack s 0 0; #X obj 183 392 tabwrite \$0-y; #X obj 77 260 route motion; #X obj 88 367 unpack 0 0; #X obj 444 215 table \$0-y; #X obj 87 339 spigot; #X msg 157 311 0; #X msg 125 312 1; #X obj 157 288 route keyrelease; #X msg 385 360 movecursor; #X msg 409 412 \$1 \$2 \$3; #X obj 18 468 outlet; #X obj 17 128 t a a; #X obj 403 277 t b f f; #X obj 88 426 outlet; #X obj 152 423 outlet; #X obj 267 428 outlet; #X obj 239 231 t f f; #X obj 409 438 s \$0-control; #X obj 19 40 r \$0-control; #X obj 20 16 inlet; #X text 182 53 a keyboard/mouse controller using pdp_xv; #X text 180 76 hold a key while moving the mouse to update the x/y controller value. hint: turn off keyboard autoropeat using "xset r off" in a terminal window.; #X text 252 454 scan code; #X text 82 450 x coord; #X text 151 449 y coord; #X text 9 494 plain events; #X obj 450 119 inlet; #X obj 450 143 unpack 0 0 0; #X obj 382 175 tabwrite \$0-x; #X obj 480 175 tabwrite \$0-y; #X connect 1 0 0 0; #X connect 1 0 19 0; #X connect 2 0 24 0; #X connect 2 1 9 0; #X connect 5 0 7 1; #X connect 6 0 7 2; #X connect 7 0 17 0; #X connect 9 0 12 0; #X connect 9 1 15 0; #X connect 10 0 4 0; #X connect 10 0 21 0; #X connect 10 1 8 0; #X connect 10 1 22 0; #X connect 12 0 10 0; #X connect 13 0 12 1; #X connect 14 0 12 1; #X connect 15 0 13 0; #X connect 16 0 7 0; #X connect 17 0 25 0; #X connect 19 0 18 0; #X connect 19 1 2 0; #X connect 20 0 16 0; #X connect 20 1 5 0; #X connect 20 2 6 0; #X connect 24 0 4 1; #X connect 24 0 8 1; #X connect 24 0 23 0; #X connect 24 0 14 0; #X connect 24 1 20 0; #X connect 26 0 1 0; #X connect 27 0 1 0; #X connect 34 0 35 0; #X connect 35 0 36 0; #X connect 35 1 37 0; #X connect 35 2 37 1; #X connect 35 2 36 1; pdp-0.14.1+darcs20180201/abstractions/rgb2ycrcb.pd000066400000000000000000000002321266045153600211730ustar00rootroot00000000000000#N canvas 318 162 450 300 10; #X obj 94 76 inlet; #X obj 144 76 inlet; #X obj 195 76 inlet; #X text 94 53 red; #X text 143 52 green; #X text 197 53 blue; pdp-0.14.1+darcs20180201/bin/000077500000000000000000000000001266045153600150465ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/bin/patchversion000077500000000000000000000001521266045153600174770ustar00rootroot00000000000000#!/bin/bash # cat <&2 exit 1 fi while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case $1 in -n) NEWLINE="-n" ;; --libdir) echo $NEWLINE $prefix/lib/scaf ;; --version) echo $NEWLINE $version ;; --cflags) echo $NEWLINE -I$prefix/include/pdp ;; *) echo "${usage}" 1>&2 exit 1 ;; esac shift done pdp-0.14.1+darcs20180201/bin/predist000066400000000000000000000002531266045153600164430ustar00rootroot00000000000000 # patch version if environment variable is set [ -z $PDP_DIST_VERSION ] || sh bin/patchversion $PDP_DIST_VERSION # run autoconf with (patched) configure.ac sh bootstrap pdp-0.14.1+darcs20180201/bin/release-version000066400000000000000000000001141266045153600200700ustar00rootroot00000000000000cat configure.ac |grep PDP_VERSION= | sed s/PDP_VERSION=// | sed s/-darcs// pdp-0.14.1+darcs20180201/bin/snapshot000077500000000000000000000006361266045153600166400ustar00rootroot00000000000000#!/bin/bash [ "$1" == "-d" ] && shift && APPEND="-`date +%Y%m%d_%H%M%S`" [ -z "$1" ] && echo "usage $0 [-d] " && exit 1 VER="$1$APPEND" # for autoconf patch in bin/predist export PDP_DIST_VERSION=$VER # create archive darcs dist -d "pdp-$VER" ARCHIVE="pdp-$VER.tar.gz" # echo $ARCHIVE PUBDIR="$HOME/www/zwizwa.be/pd/pdp" echo "PUBDIR=$PUBDIR" if [ -d "$PUBDIR" ]; then cp -av $ARCHIVE $PUBDIR fi pdp-0.14.1+darcs20180201/bootstrap000066400000000000000000000002171266045153600162360ustar00rootroot00000000000000chmod +x buildall bin/* autoconf (cd scaf ; chmod +x compiler/scafc ; chmod +x compiler/scafc.pl ; autoconf) (cd opengl ; chmod +x configure) pdp-0.14.1+darcs20180201/buildall000077500000000000000000000004651266045153600160210ustar00rootroot00000000000000#!/bin/sh # a build script to build and configure the entire pdp distro # might need some editing to work for you # PREFIX=--prefix=/home/tom/pd # build the stable stuff ./configure --enable-mmx && make install cd scaf ./configure && make install cd .. # build the experimental stuff make -C opengl pdp-0.14.1+darcs20180201/configure.ac000066400000000000000000000212741266045153600165720ustar00rootroot00000000000000AC_INIT(system/pdp.c) AC_CONFIG_HEADER(include/pdp_config.h) AC_PROG_CC AC_HEADER_STDC dnl TAG REPO WHEN RELEASE VERSION CHANGES !!! dnl After changing version, do "make mrproper ; sh bootstrap" PDP_VERSION=0.14.2 AC_SUBST(PDP_VERSION) AC_ARG_ENABLE(mmx, [ --enable-mmx enable MMX support (no)], , enable_mmx=no) AC_ARG_ENABLE(asm-mmx, [ --enable-asm-mmx enable MMX support, assembly code (32bit only) (no)], , enable_asm_mmx=no) AC_ARG_ENABLE(quicktime, [ --enable-quicktime enable libquicktime support (yes)], , enable_quicktime=yes) AC_ARG_ENABLE(v4l, [ --enable-v4l enable Video4Linux support (yes)], , enable_v4l=yes) AC_ARG_ENABLE(pwc, [ --enable-pwc force additional Philips WebCam support (auto)],,enable_pwc=auto) AC_ARG_ENABLE(x, [ --enable-x enable X11 support (required by XVideo and GLX) (yes)], , enable_x=yes) AC_ARG_ENABLE(xv, [ --enable-xv enable XVideo display support (yes)], , enable_xv=yes) AC_ARG_ENABLE(sdl, [ --enable-sdl enable SDL display support (yes)], , enable_sdl=yes) AC_ARG_ENABLE(glx, [ --enable-glx enable GLX display support (yes)], , enable_glx=yes) AC_ARG_ENABLE(gsl, [ --enable-gsl enable gsl support (for matrix packets) (yes)], , enable_gsl=yes) AC_ARG_ENABLE(png, [ --enable-png enable png image load/save support (yes)], , enable_png=yes) AC_ARG_ENABLE(debug, [ --enable-debug enable debugging support (no)], , enable_debug=no) AC_ARG_WITH([pd], [ --with-pd= where to look for pd-headers and and -libs]) # long double? -Wno-long-double PDP_CFLAGS="-DPD -Wall -W -Wstrict-prototypes -Wno-unused -Wno-parentheses -Wno-switch -fPIC" dnl -Werror -Wshadow dnl the -Wshadow option is way too strict.. gl headers won't compile dnl setup debugging if test $enable_debug == yes then AC_DEFINE(PDP_DEBUG, 1, "enable debugging support") PDP_CFLAGS="$PDP_CFLAGS -g -Werror -DDEBUG" else AC_DEFINE(PDP_DEBUG, 0, "disable debugging support") PDP_CFLAGS="$PDP_CFLAGS -O2 -funroll-loops -fomit-frame-pointer -ffast-math" fi if test $prefix == NONE; then prefix=/usr/local fi dnl setup forced pwc support if test $enable_pwc == yes; then AC_DEFINE(HAVE_PWCV4L, 1,enable forced pwc v4l support) fi dnl try to locate the pd header in case the setup is nonstandard dnl check in $prefix/pd/src then ../pd/src dnl if this fails we trust it is in the standard include path PWD=`pwd` if test "x$with_pd" != "x"; then if test -d "${with_pd}"; then PDPATH=${with_pd} fi if test -d "${PDPATH}/src"; then AC_MSG_RESULT([adding ${PDPATH}/src to INCLUDES]) PD_CPPFLAGS="-I${PDPATH}/src" AC_MSG_RESULT([adding ${PDPATH}/src to LDFLAGS]) LDFLAGS="-L${PDPATH}/src ${LDFLAGS}" else if test -d "${PDPATH}"; then AC_MSG_RESULT([adding ${PDPATH} to INCLUDES]) PD_CPPFLAGS="-I${PDPATH}" fi fi else dnl try some defaults if test -f $prefix/pd/src/m_pd.h; then PD_CPPFLAGS="-I$prefix/pd/src" elif test -f $prefix/src/pd/src/m_pd.h; then PD_CPPFLAGS="-I$prefix/src/pd/src" elif test -f $PWD/../pd/src/m_pd.h; then PD_CPPFLAGS="-I$PWD/../pd/src" elif test -f $PWD/../src/m_pd.h; then PD_CPPFLAGS="-I$PWD/../src" elif test -f /usr/local/include/pd/m_pd.h; then PD_CPPFLAGS="-I/usr/local/include/pd" elif test -f /usr/include/pd/m_pd.h; then PD_CPPFLAGS="-I/usr/include/pd" fi fi CPPFLAGS="$CPPFLAGS $PD_CPPFLAGS" AC_CHECK_HEADER(m_pd.h,, echo "WARNING: m_pd.h not found. Is PD installed?" echo "WARNING: if you have changed PD_CPPFLAGS in Makefile.config.in you can ignore this warning." ) AC_CHECK_LIB(m,sin) ARCH=`uname -s` if test $ARCH == Linux; then PDP_LIBRARY_NAME=pdp.pd_linux if test $enable_mmx == yes; then PDP_TARGET=linux_gcc_mmx PDP_CFLAGS="$PDP_CFLAGS -mmmx" elif test $enable_asm_mmx == yes; then PDP_TARGET=linux_mmx PDP_CFLAGS="$PDP_CFLAGS -mmmx" else PDP_TARGET=linux fi elif test $ARCH == Darwin; then PDP_LIBRARY_NAME=pdp.pd_darwin PDP_TARGET=darwin else echo WARNING: Architecture `uname -s` not supported. exit fi dnl Darwin specific stuff: this is still pretty experimental dnl How to test if frameworks are present ???? if test $ARCH == Darwin then PD_EXECUTABLE=$prefix/bin/pd LIBS="$LIBS -L/sw/lib" CPPFLAGS="$CPPFLAGS -I/sw/include" PDP_EXTRA_CPPFLAGS="-I/sw/include" dnl if not darwin, assume target is linux else have_v4l="no" have_libv4l="no" AC_CHECK_HEADERS([libv4l1-videodev.h], have_libv4l="yes") AC_CHECK_HEADERS([linux/videodev.h], have_v4l="yes") if test "x$have_libv4l" = "xyes" then have_v4l="yes" fi if test "x$enable_v4l" = "xno" then have_v4l="no" fi if test "x$have_v4l" = "xyes" then ZL_OPTMOD="$ZL_OPTMOD v4l.o" PDP_OPTMOD="$PDP_OPTMOD pdp_v4l.o" AC_DEFINE(HAVE_PDP_V4L, 1, [build pdp_v4l]) if test "x$have_libv4l" = "xyes" then AC_DEFINE(HAVE_PDP_LIBV4L, 1, [build pdp_v4l with libv4l]) PDP_V4L_CFLAGS="`pkg-config --cflags libv4l 2>/dev/null || pkg-config --cflags libv4l2`" PDP_V4L_LIBS="`pkg-config --libs libv4l 2>/dev/null || pkg-config --libs libv4l2`" else PDP_V4L_CFLAGS="" PDP_V4L_LIBS="" fi PDP_CFLAGS="$PDP_CFLAGS $PDP_V4L_CFLAGS" LIBS="$LIBS $PDP_V4L_LIBS" else AC_MSG_RESULT([not building pdp_v4l]) fi fi dnl optional gsl support if test $enable_gsl == yes; then AC_CHECK_LIB(gslcblas,main) AC_CHECK_LIB(gsl,main, PDP_OPTTYPES="$PDP_OPTTYPES pdp_matrix.o" PDP_MATRIX_BASIC="$PDP_MATRIX_BASIC pdp_mat_mul.o pdp_mat_lu.o pdp_mat_vec.o" PDP_IMAGE_BASIC="$PDP_IMAGE_BASIC pdp_cheby.o" PDP_IMAGE_SPECIAL="$PDP_IMAGE_SPECIAL pdp_histo.o" AC_DEFINE(HAVE_PDP_GSL, 1, gsl support) PDP_GSL_FOUND=1, echo " libgsl not found: not building matrix type support") if test -n "$PDP_GSL_FOUND"; then if test $ARCH == Darwin then LIBS="$LIBS -lgslcblas -lgsl" else dnl if not darwin, assume target is linux LIBS="$LIBS `pkg-config --libs gsl`" fi fi fi dnl optional png support if test $enable_png == yes then AC_CHECK_LIB(png, png_read_image, LIBS="$LIBS -lz -lpng" AC_DEFINE(HAVE_PDP_PNG, 1, build png support), echo " libpng not found: not building png support") fi dnl optional xwindow support if test $enable_x == yes; then AC_CHECK_LIB(X11, XOpenDisplay, ZL_OPTMOD="$ZL_OPTMOD xwindow.o" AC_DEFINE(HAVE_PDP_X, 1, build X11 support) LIBS="$LIBS -L/usr/X11R6/lib -lX11", echo " libX11 not found: not building X11 support", -L/usr/X11R6/lib) else dnl no x support -> no xv and glx support enable_xv=no enable_glx=no fi dnl optional xvideo support if test $enable_xv == yes; then AC_CHECK_LIB(Xv, XvPutImage, ZL_OPTMOD="$ZL_OPTMOD xv.o" PDP_OPTMOD="$PDP_OPTMOD pdp_xv.o" LIBS="$LIBS -lXv -lXext" AC_DEFINE(HAVE_PDP_XV, 1, build pdp_xv), echo " libXv not found: not building pdp_xv", -L/usr/X11R6/lib -lX11 -lXext) fi dnl optional libquicktime support if test $enable_quicktime == yes; then AC_CHECK_LIB(quicktime, lqt_decode_video, PDP_OPTMOD="$PDP_OPTMOD pdp_qt.o" LIBS="$LIBS -lquicktime" AC_DEFINE(HAVE_PDP_QT, 1, build pdp_qt), echo " libquicktime not found: not building pdp_qt") fi dnl optional glx support if test $enable_glx == yes then AC_CHECK_LIB(GL, glXSwapBuffers, ZL_OPTMOD="$ZL_OPTMOD glx.o 3Dcontext_common.o 3Dcontext_glx.o" PDP_OPTMOD="$PDP_OPTMOD pdp_glx.o" LIBS="$LIBS -lGL -lGLU" AC_DEFINE(HAVE_PDP_GLX, 1, build pdp_glx), echo " libGL not found: not building pdp_glx", -L/usr/X11R6/lib -lGLU) fi dnl optional sdl support if test $enable_sdl == yes then AC_CHECK_LIB(SDL, SDL_Init, PDP_OPTMOD="$PDP_OPTMOD pdp_sdl.o" LIBS="$LIBS -lSDL" AC_DEFINE(HAVE_PDP_SDL, 1, build pdp_sdl), echo " libSDL not found: not building pdp_sdl") fi echo target is $PDP_TARGET echo "used configure options:" echo " --enable-mmx=$enable_mmx" echo " --enable-quicktime=$enable_quicktime" echo " --enable-v4l=$enable_v4l" echo " --enable-pwc=$enable_pwc" echo " --enable-sdl=$enable_sdl" echo " --enable-x=$enable_x" echo " --enable-xv=$enable_xv" echo " --enable-glx=$enable_glx" echo " --enable-gsl=$enable_gsl" echo " --enable-png=$enable_png" echo " --enable-debug=$enable_debug" AC_SUBST(PD_CPPFLAGS) AC_SUBST(PD_EXECUTABLE) AC_SUBST(PDP_EXTRA_CPPFLAGS) AC_SUBST(PDP_CFLAGS) AC_SUBST(PDP_EXTRA_CFLAGS) AC_SUBST(PDP_LIBRARY_NAME) AC_SUBST(PDP_TARGET) AC_SUBST(PDP_OPTMOD) AC_SUBST(ZL_OPTMOD) AC_SUBST(PDP_PDMOD) AC_SUBST(PDP_OPTTYPES) AC_SUBST(PDP_IMAGE_BASIC) AC_SUBST(PDP_IMAGE_SPECIAL) AC_SUBST(PDP_MATRIX_BASIC) AC_CONFIG_FILES(Makefile.config) AC_CONFIG_FILES(bin/pdp-config) AC_OUTPUT pdp-0.14.1+darcs20180201/debug/000077500000000000000000000000001266045153600153645ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/debug/c++test.cc000066400000000000000000000000441266045153600171410ustar00rootroot00000000000000#include "pdp.h" int main(void) { } pdp-0.14.1+darcs20180201/debug/gdb_pdp_load000066400000000000000000000020371266045153600177070ustar00rootroot00000000000000cd ~/pd/packet file ~/pd/distro/pd/bin/pd.debug # file ~/pd/distro/pd/bin/pd #set args -noadc -nodac -lib pdp -lib opengl/pdp_opengl:scaf/pdp_scaf -nodac -noadc -path abstractions:opengl/abstractions opengl/doc/examples/example06.pd set args -nodac -noadc -nomidi -lib pdp -path abstractions ../deadlocktest.pd #set args -nodac -noadc -nomidi -lib pdp -path abstractions -nogui #set args -nodac -noadc -nomidi -lib pdp -path abstractions ../xvdualtest.pd #opengl/test/pdp_ogl_draw_limb.pd # set args -lib pdp -nodac -noadc -path abstractions test/test_pdp_thread.pd # set args -lib pdp -nodac -noadc test/test_pdp_ca.pd # set args -r 44100 -alsa -frags 64 -lib pdp -nodac -noadc test/test_pdp_qt_read.pd # dir ~/pd/distro/pd/src dir include dir modules dir system dir system/mmx dir scaf/include dir scaf/pdp # until i figure out how to stop pd without hanging it # or set a breakpoint before a library is loaded # i'll use the bng_new routine (alt-b) to stop break bng_new # uncomment this to break in the library loader # break sys_load_lib pdp-0.14.1+darcs20180201/debug/gdb_pdp_load_rt000066400000000000000000000004031266045153600204070ustar00rootroot00000000000000cd /home/tom/pd/packet file /home/tom/pd/distro/pd/bin/pd.debug # file ~/pd/distro/pd/bin/pd set args -rt -r 44100 -alsa -frags 64 -lib pdp -nodac -noadc -nogui test/test_pdp_qt_read.pd dir modules dir system dir mmx dir scaf dir scaf/modules dir scaf/system pdp-0.14.1+darcs20180201/debug/quicktime_crashtest.pd000066400000000000000000000100431266045153600217620ustar00rootroot00000000000000#N canvas 190 294 862 660 10; #X obj 122 506 pdp_xv; #X msg 135 81 bang; #X floatatom 54 78 5 0 0; #X msg 222 90 open /home/ben/MOV/test1.mov; #X msg 418 369 open /home/ben/MOV/eye.mov; #X obj 126 26 i 0; #X obj 182 37 + 1; #X obj 217 47 metro 40; #X obj 262 17 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X msg 25 47 0; #X msg 64 49 9999; #X msg 25 149 loop \$1; #X obj 21 123 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 264 231 5 0 0; #X floatatom 538 184 5 0 0; #X msg 370 44 open \$1; #X obj 369 20 openpanel; #X obj 354 3 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X floatatom 192 459 5 0 0; #X floatatom 309 9 5 0 0; #X msg 298 135 open /home/ben/MOV/nogeseenfilmke.mov; #X obj 346 406 table tab1; #X msg 56 23 close; #X obj 250 542 dac~; #X msg 315 390 0; #X obj 316 427 tabplay~ tab1; #X msg 332 325 importaudio tab1; #X obj 26 185 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X floatatom 180 83 5 0 0; #X msg 215 7 stop; #X obj 478 213 i; #X obj 490 276 mod; #X obj 494 244 + 1; #X floatatom 558 226 5 0 0; #X msg 30 211 autoplay \$1; #X floatatom 501 321 5 0 0; #X obj 119 331 pdp_del 10; #X floatatom 194 289 5 0 0; #X obj 384 221 *; #X obj 288 159 hsl 300 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X obj 305 44 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X msg 329 254 loop \$1; #X obj 325 228 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1; #X obj 236 258 pdp_trigger; #X obj 117 421 pdp_mix; #X floatatom 182 390 5 0 0; #X obj 278 349 hsl 300 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X msg 434 394 open /home/ben/MOV/nogeseenfilmke.mov; #X obj 241 175 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1; #X msg 245 201 autoplay \$1; #X obj 408 254 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 65 281 close; #X obj 352 484 vol~; #X obj 221 497 vol~; #X floatatom 252 470 5 0 0; #X floatatom 382 460 5 0 0; #X msg 418 281 close; #X msg 121 145 play; #X msg 347 229 play; #X msg 447 13 bang; #X msg 564 13 stop; #X msg 540 97 \; pd dsp 1; #X msg 616 98 \; pd dsp 0; #X floatatom 608 13 5 0 0; #X msg 732 104 close; #X msg 778 105 close; #X obj 470 66 route 0 1 2 3 4 5 6 7; #X msg 675 13 140; #X obj 489 42 random 6; #X obj 483 12 metro 140; #X obj 715 46 loadbang; #X msg 750 76 \; pd dsp 1; #X obj 133 205 pdp_qt~; #X obj 322 283 pdp_qt~; #X obj 207 71 random 250; #X connect 1 0 72 0; #X connect 2 0 72 0; #X connect 3 0 72 0; #X connect 4 0 73 0; #X connect 5 0 6 0; #X connect 5 0 1 0; #X connect 6 0 5 1; #X connect 7 0 74 0; #X connect 8 0 7 0; #X connect 9 0 2 0; #X connect 10 0 2 0; #X connect 11 0 72 0; #X connect 12 0 11 0; #X connect 14 0 31 1; #X connect 14 0 38 1; #X connect 15 0 72 0; #X connect 16 0 15 0; #X connect 17 0 16 0; #X connect 18 0 0 1; #X connect 19 0 7 1; #X connect 20 0 72 0; #X connect 22 0 72 0; #X connect 24 0 25 0; #X connect 26 0 72 0; #X connect 27 0 34 0; #X connect 28 0 72 1; #X connect 29 0 7 0; #X connect 30 0 32 0; #X connect 31 0 35 0; #X connect 32 0 31 0; #X connect 33 0 32 1; #X connect 34 0 72 0; #X connect 36 0 44 0; #X connect 37 0 36 1; #X connect 38 0 28 0; #X connect 39 0 38 0; #X connect 40 0 19 0; #X connect 41 0 73 0; #X connect 42 0 41 0; #X connect 44 0 0 0; #X connect 45 0 44 2; #X connect 46 0 45 0; #X connect 47 0 73 0; #X connect 48 0 49 0; #X connect 49 0 73 0; #X connect 50 0 73 0; #X connect 51 0 72 0; #X connect 56 0 73 0; #X connect 57 0 72 0; #X connect 58 0 73 0; #X connect 59 0 69 0; #X connect 59 0 58 0; #X connect 59 0 57 0; #X connect 60 0 69 0; #X connect 63 0 69 1; #X connect 64 0 72 0; #X connect 65 0 73 0; #X connect 66 0 3 0; #X connect 66 1 20 0; #X connect 66 2 4 0; #X connect 66 3 47 0; #X connect 66 6 64 0; #X connect 66 7 65 0; #X connect 67 0 63 0; #X connect 68 0 66 0; #X connect 69 0 68 0; #X connect 70 0 59 0; #X connect 70 0 71 0; #X connect 72 0 43 0; #X connect 72 0 36 0; #X connect 72 1 13 0; #X connect 72 2 14 0; #X connect 72 3 23 1; #X connect 72 4 23 0; #X connect 73 0 44 1; #X connect 73 3 23 0; #X connect 73 4 23 1; #X connect 74 0 28 0; pdp-0.14.1+darcs20180201/debug/teststuff.c000066400000000000000000000011351266045153600175570ustar00rootroot00000000000000/* some test stuff */ #if 0 { t_pdp_list *l = pdp_list_from_cstring("(een 2 3. (1 1 1 1 1))", 0); t_pdp_list *s = pdp_list_from_cstring("(symbol int float (int int ...))", 0); //PDP_ASSERT(0); pdp_list_print(l); pdp_list_print(s);` post("%d", pdp_tree_check_syntax(l, s)); exit(1); } #endif #if 0 { char *c = "(test 1 2 (23 4)) ( 1 [asdflkj; las;dlfkj;a sdf]) (een (zes (ze)ven ())) ["; while (*c){ t_pdp_list *l = pdp_list_from_cstring(c, &c); if (l) pdp_list_print(l); else{ post("parse error: remaining input: %s", c); break; } } exit(1); } #endif pdp-0.14.1+darcs20180201/doc/000077500000000000000000000000001266045153600150435ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/doc/debian-builddep000066400000000000000000000001611266045153600177740ustar00rootroot00000000000000libv4l-dev libgsl0-dev libz-dev libpng12-dev libx11-dev libxv-dev libquicktime-dev libgl1-mesa-dev libsdl1.2-dev pdp-0.14.1+darcs20180201/doc/examples/000077500000000000000000000000001266045153600166615ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/doc/examples/example01.pd000066400000000000000000000022121266045153600207770ustar00rootroot00000000000000#N canvas 657 0 518 446 10; #X obj 133 414 pdp_glx; #X obj 177 76 pdp_v4l; #X obj 177 33 metro 40; #X obj 176 8 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 35 149 pdp_conv; #X obj 35 173 pdp_conv_sobel_edge; #X obj 412 60 pdp_control; #X msg 412 32 thread \$1; #X obj 412 8 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 133 352 pdp_gradient; #X obj 133 288 pdp_motion_phase; #X msg 254 30 type grey; #X obj 35 125 pdp_del 8; #X obj 35 198 pdp_gain 6; #X msg 240 252 0.45; #X text 223 125 8 frames delay; #X text 223 149 smooth; #X text 223 174 edge detect; #X text 222 200 amplify; #X text 232 6 process in greyscale; #X text 322 287 motion phase shifter; #X text 320 354 grey -> colour palette; #X msg 36 323 rgb 1 0.5 0; #X obj 133 252 pdp_add; #X msg 133 216 debug; #X connect 1 0 12 0; #X connect 1 0 23 1; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 5 0; #X connect 5 0 13 0; #X connect 7 0 6 0; #X connect 8 0 7 0; #X connect 9 0 0 0; #X connect 10 0 9 0; #X connect 11 0 1 0; #X connect 12 0 4 0; #X connect 13 0 23 0; #X connect 14 0 10 1; #X connect 22 0 9 0; #X connect 23 0 10 0; #X connect 24 0 23 0; pdp-0.14.1+darcs20180201/doc/examples/example02.pd000066400000000000000000000023551266045153600210100ustar00rootroot00000000000000#N canvas 85 437 473 316 10; #X obj 91 268 pdp_glx; #X obj 91 73 pdp_v4l; #X obj 91 30 metro 40; #X obj 90 5 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1 ; #X obj 326 57 pdp_control; #X msg 326 29 thread \$1; #X obj 326 5 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 146 3 process in greyscale; #X obj 135 195 pdp_gain; #X obj 135 222 pdp_gain; #X msg 168 27 type yv12; #X obj 91 129 pdp_mix; #X msg 169 51 type grey; #X obj 216 194 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 -262144 -1 -1 0.62 256; #X obj 139 103 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 -262144 -1 -1 0.82 256; #X obj 215 133 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 -262144 -1 -1 8 256; #X obj 135 162 pdp_del 25; #X obj 216 173 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 -262144 -1 -1 1.5 256; #X text 289 177 gains clip at -1 \, 1; #X msg 159 129 reset; #X connect 1 0 11 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 5 0 4 0; #X connect 6 0 5 0; #X connect 8 0 9 0; #X connect 9 0 11 1; #X connect 10 0 1 0; #X connect 11 0 0 0; #X connect 11 0 16 0; #X connect 12 0 1 0; #X connect 13 0 9 1; #X connect 14 0 11 2; #X connect 15 0 16 1; #X connect 16 0 8 0; #X connect 17 0 8 1; #X connect 19 0 16 0; pdp-0.14.1+darcs20180201/doc/examples/example03.pd000066400000000000000000000057571266045153600210220ustar00rootroot00000000000000#N canvas 141 84 841 685 10; #X obj 68 318 pdp_noise; #X obj 68 85 metro 40; #X obj 68 58 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 68 484 pdp_del 50; #X obj 112 424 pdp_gain; #X floatatom 240 518 5 0 0; #X obj 68 514 pdp_blur; #X obj 243 499 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 10100 1; #X floatatom 240 367 5 0 0; #X obj 243 342 hsl 128 15 0 5 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X floatatom 240 587 5 0 0; #X obj 243 567 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 4100 1; #X floatatom 239 428 5 0 0; #X obj 242 409 hsl 128 15 -5 5 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 11900 1; #X msg 15 460 reset; #X obj 68 459 pdp_add; #X obj 68 357 pdp_gain; #X text 203 7 this example shows how to use a delay line with a loop gain > 1 and some processing inside the loop to produce a plasma like effect. (WARNING: this can produce a very intense strobe effect \, so if you're sensitive to flashing lights please be careful...); #X text 391 407 a |gain| > 1 ensures regeneration; #X floatatom 119 56 5 0 0; #X obj 68 582 pdp_motion_phase; #X floatatom 133 459 5 0 0; #X text 392 495 blur ensures spatial coupling (determines the speed at which "blobs" move around the screen); #X text 392 565 a motion phase effect to spice it up (this causes local negative feedback around suddon changes); #X msg 109 13 40; #X msg 144 13 1000; #X msg 109 250 type grey; #X msg 109 135 type yv12; #X obj 68 619 pdp_glx; #X text 201 247 it also works for black and white \, but all negative colours will be clipped to 0 (black) on output.; #X text 393 340 mix in some noise to get it going (set blur to minimal when starting so the added noise won't be blurred to black); #X text 202 96 it illustrates one of the advantages of working in an additive/subtractive colour space. (here yuv or YCrCb). since legal colours can be both positive and negative \, the analogy with audio signals is easily drawn. this network can be seen as a nonlinear feedback delay network. (nonlinear because of the saturating gain). the image delay line can be seen as a parallel delay line \, one for each pixel. coupling between the delays is done using a spatial blur effect. the additional temporal filtering isn't necessary \, but it produces a nice additional effect.; #X obj 534 661 pdp_control; #X obj 534 684 print; #X msg 534 637 thread \$1; #X obj 534 614 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X connect 0 0 16 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 15 1; #X connect 6 0 20 0; #X connect 7 0 5 0; #X connect 7 0 6 1; #X connect 9 0 8 0; #X connect 9 0 16 1; #X connect 11 0 10 0; #X connect 11 0 20 1; #X connect 13 0 12 0; #X connect 13 0 4 1; #X connect 14 0 3 0; #X connect 15 0 3 0; #X connect 16 0 15 0; #X connect 19 0 1 1; #X connect 20 0 4 0; #X connect 20 0 28 0; #X connect 21 0 3 1; #X connect 24 0 19 0; #X connect 25 0 19 0; #X connect 26 0 0 0; #X connect 27 0 0 0; #X connect 32 0 33 0; #X connect 34 0 32 0; #X connect 35 0 34 0; pdp-0.14.1+darcs20180201/doc/examples/example04.pd000066400000000000000000000046701266045153600210140ustar00rootroot00000000000000#N canvas 89 39 931 736 10; #X obj 68 204 pdp_noise; #X obj 68 85 metro 40; #X obj 68 58 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 112 303 pdp_gain; #X floatatom 240 518 5 0 0; #X obj 68 514 pdp_blur; #X obj 243 499 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 6500 1; #X floatatom 240 233 5 0 0; #X obj 243 208 hsl 128 15 0 5 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X floatatom 240 587 5 0 0; #X obj 243 567 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 5000 1; #X floatatom 239 307 5 0 0; #X obj 242 288 hsl 128 15 -5 5 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 8920 1; #X msg 15 339 reset; #X obj 68 338 pdp_add; #X obj 68 243 pdp_gain; #X text 393 286 a |gain| > 1 ensures regeneration; #X floatatom 119 56 5 0 0; #X obj 68 582 pdp_motion_phase; #X floatatom 133 338 5 0 0; #X text 392 495 blur ensures spatial coupling (determines the speed at which "blobs" move around the screen); #X text 392 565 a motion phase effect to spice it up (this causes local negative feedback around suddon changes); #X msg 109 13 40; #X msg 144 13 1000; #X msg 146 119 type grey; #X msg 147 90 type yv12; #X obj 68 619 pdp_glx; #X text 393 206 mix in some noise to get it going (set blur to minimal when starting so the added noise won't be blurred to black); #X obj 68 363 pdp_del 50; #X text 242 14 this example is like example03 with a zoom / rotation object thrown in; #X obj 68 480 pdp_zrot; #X floatatom 239 377 5 0 0; #X obj 242 358 hsl 128 15 0.1 10 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 8567 1; #X floatatom 239 446 5 0 0; #X obj 242 426 hsl 128 15 0 360 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 300 1; #X text 393 357 zoom; #X msg 239 334 1; #X msg 239 403 0; #X msg 239 261 1; #X text 392 420 rotation; #X connect 0 0 15 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 14 1; #X connect 5 0 18 0; #X connect 6 0 4 0; #X connect 6 0 5 1; #X connect 8 0 7 0; #X connect 8 0 15 1; #X connect 10 0 9 0; #X connect 10 0 18 1; #X connect 12 0 11 0; #X connect 12 0 3 1; #X connect 13 0 28 0; #X connect 14 0 28 0; #X connect 15 0 14 0; #X connect 17 0 1 1; #X connect 18 0 3 0; #X connect 18 0 26 0; #X connect 19 0 28 1; #X connect 22 0 17 0; #X connect 23 0 17 0; #X connect 24 0 0 0; #X connect 25 0 0 0; #X connect 28 0 30 0; #X connect 30 0 5 0; #X connect 31 0 30 1; #X connect 32 0 31 0; #X connect 33 0 30 2; #X connect 34 0 33 0; #X connect 36 0 32 0; #X connect 37 0 34 0; #X connect 38 0 12 0; pdp-0.14.1+darcs20180201/doc/examples/example05.pd000066400000000000000000000066631266045153600210210ustar00rootroot00000000000000#N canvas 584 220 538 637 10; #X obj 10 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 120 117 pdp_grey; #X obj 435 194 pdp_control; #X msg 435 167 thread 0; #X obj 121 224 pdp_reg; #X floatatom 81 7 5 0 0; #X msg 35 10 stop; #X floatatom 187 341 5 0 0; #X obj 120 410 pdp_zrot; #X floatatom 188 389 5 0 0; #X obj 120 453 pdp_blur; #X floatatom 188 435 5 0 0; #X obj 120 92 pdp_noise; #X obj 120 70 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #N canvas 623 175 567 478 nlmap 0; #X obj 89 138 pdp_affine; #X msg 123 108 -1; #X msg 156 108 1; #X obj 92 161 pdp_mul; #X obj 95 189 pdp_gain; #X floatatom 234 159 5 0 0; #X msg 259 119 3.73; #X obj 100 272 pdp_affine; #X msg 134 242 -1; #X msg 167 242 1; #X obj 103 295 pdp_mul; #X obj 106 323 pdp_gain; #X floatatom 168 299 5 0 0; #X msg 185 271 3.73; #X obj 254 54 inlet; #X obj 79 55 inlet; #X obj 98 405 outlet; #X obj 164 60 loadbang; #X obj 190 84 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 260 220 this computes f(f(image)); #X text 261 236 with f(x) = k*x*(1-x); #X text 286 160 k; #X text 260 253 the logistic map; #X text 173 353 2 iterations are used to eliminate most of the high frequency flickering; #X connect 0 0 3 0; #X connect 1 0 0 1; #X connect 2 0 0 2; #X connect 3 0 4 0; #X connect 4 0 10 1; #X connect 4 0 7 0; #X connect 5 0 4 1; #X connect 5 0 12 0; #X connect 6 0 5 0; #X connect 7 0 10 0; #X connect 8 0 7 1; #X connect 9 0 7 2; #X connect 10 0 11 0; #X connect 11 0 16 0; #X connect 12 0 11 1; #X connect 13 0 12 0; #X connect 14 0 5 0; #X connect 15 0 3 1; #X connect 15 0 0 0; #X connect 17 0 18 0; #X connect 18 0 2 0; #X connect 18 0 1 0; #X connect 18 0 6 0; #X connect 18 0 8 0; #X connect 18 0 9 0; #X restore 121 274 pd nlmap; #X obj 73 576 pdp_glx; #X floatatom 180 232 5 0 0; #X text 196 275 2 iterations of the logistic map function; #X obj 121 143 pdp_mul; #X obj 297 94 pdp_noise; #X obj 297 72 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 297 121 pdp_mul; #X obj 73 521 pdp_saturation; #X floatatom 166 490 5 0 0; #X obj 30 36 metro 70; #X msg 181 206 3.8; #X msg 186 318 1.17; #X msg 188 368 -2.33; #X text 242 341 zoom; #X text 241 391 rotate; #X msg 188 414 0.33; #X text 139 12 feedback with nonlinear mapping + zoom + rotate + blur ; #X msg 82 -15 40; #X msg 116 -15 500; #X text 111 47 grey1; #X obj 212 119 pdp_grey; #X obj 212 94 pdp_noise; #X obj 212 72 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 203 49 grey2; #X text 287 50 colour1; #X obj 388 95 pdp_noise; #X obj 388 73 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 378 51 colour2; #X msg 238 463 -0.5; #X msg 282 463 0.5; #X connect 0 0 24 0; #X connect 1 0 18 1; #X connect 1 0 18 0; #X connect 3 0 2 0; #X connect 4 0 14 0; #X connect 5 0 24 1; #X connect 6 0 24 0; #X connect 7 0 8 1; #X connect 8 0 10 0; #X connect 9 0 8 2; #X connect 10 0 4 1; #X connect 11 0 10 1; #X connect 12 0 1 0; #X connect 13 0 12 0; #X connect 14 0 8 0; #X connect 14 0 22 0; #X connect 16 0 14 1; #X connect 18 0 4 0; #X connect 19 0 21 1; #X connect 19 0 21 0; #X connect 20 0 19 0; #X connect 21 0 4 0; #X connect 22 0 15 0; #X connect 23 0 22 1; #X connect 24 0 4 0; #X connect 25 0 16 0; #X connect 26 0 7 0; #X connect 27 0 9 0; #X connect 30 0 11 0; #X connect 32 0 5 0; #X connect 33 0 5 0; #X connect 35 0 4 0; #X connect 36 0 35 0; #X connect 37 0 36 0; #X connect 40 0 4 0; #X connect 41 0 40 0; #X connect 43 0 23 0; #X connect 44 0 23 0; pdp-0.14.1+darcs20180201/doc/examples/example06.pd000066400000000000000000000035761266045153600210220ustar00rootroot00000000000000#N canvas 92 197 605 585 10; #X obj 24 85 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 42 25 stop; #X msg 80 24 bang; #X floatatom 122 25 5 0 0; #X obj 60 485 pdp_glx; #X obj 60 439 pdp_bq; #X obj 111 334 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 169 332 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 97 278 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 154 277 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X msg 95 303 lr \$1; #X msg 150 304 rl \$1; #X msg 99 350 tb \$1; #X msg 154 351 bt \$1; #X obj 392 240 hsl 128 15 0.05 0.5 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 3000 1; #X obj 450 280 hsl 128 15 0.1 10 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 1900 1; #X obj 391 307 t b f; #X obj 394 345 pack s 0 0; #X msg 391 378 \$1 \$2 \$3; #X obj 447 310 t b f; #X msg 301 199 lpf; #X msg 333 200 apf; #X obj 130 198 random 2; #X obj 195 198 random 2; #X obj 60 147 pdp_trigger; #X obj 128 235 random 2; #X obj 193 235 random 2; #X obj 60 111 pdp_v4l; #X obj 301 121 loadbang; #X obj 60 53 metro 40; #X text 388 219 frequency; #X text 447 261 Q; #X text 312 175 filter type; #X connect 0 0 27 0; #X connect 1 0 29 0; #X connect 2 0 29 0; #X connect 3 0 29 1; #X connect 5 0 4 0; #X connect 6 0 12 0; #X connect 7 0 13 0; #X connect 8 0 10 0; #X connect 9 0 11 0; #X connect 10 0 5 0; #X connect 11 0 5 0; #X connect 12 0 5 0; #X connect 13 0 5 0; #X connect 14 0 16 0; #X connect 15 0 19 0; #X connect 16 0 17 0; #X connect 16 1 17 1; #X connect 17 0 18 0; #X connect 18 0 5 0; #X connect 19 0 17 0; #X connect 19 1 17 2; #X connect 20 0 17 0; #X connect 21 0 17 0; #X connect 22 0 8 0; #X connect 23 0 9 0; #X connect 24 0 5 0; #X connect 24 1 23 0; #X connect 24 1 22 0; #X connect 24 1 26 0; #X connect 24 1 25 0; #X connect 25 0 6 0; #X connect 26 0 7 0; #X connect 27 0 24 0; #X connect 28 0 20 0; #X connect 29 0 27 0; pdp-0.14.1+darcs20180201/doc/examples/example07.pd000066400000000000000000000034031266045153600210100ustar00rootroot00000000000000#N canvas 466 98 659 764 10; #X obj 18 649 pdp_glx; #X obj 17 58 pdp_noise; #X obj 16 14 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 17 325 pdp_add; #X obj 17 277 pdp_gain; #X obj 87 277 pdp_gain; #X floatatom 127 238 5 0 0; #X floatatom 174 238 5 0 0; #X obj 17 120 pdp_mix; #X floatatom 96 92 5 0 0; #X obj 16 35 metro 40; #X obj 17 87 pdp_grey; #X msg 96 70 0.8; #X floatatom 76 212 5 0 0; #X obj 105 375 pdp_del 1; #X msg 163 349 1; #X obj 17 440 pdp_add; #X obj 105 400 pdp_gain; #X floatatom 208 382 5 0 0; #X obj 17 243 pdp_blur; #X msg 133 69 1; #X floatatom 76 560 5 0 0; #X obj 17 591 pdp_blur; #X obj 18 619 pdp_gain; #X floatatom 101 594 5 0 0; #X msg 73 535 0.22; #X msg 208 358 -0.61; #X msg 132 214 4.3; #X msg 178 215 -6.69; #X msg 76 183 0.32; #X msg 130 566 4; #X text 287 386 subtract previous frame (time derivative); #X text 97 47 some noise to get started; #X text 235 216 construct a laplace like operator by blurring the image and subtractiong the original from it; #X text 371 12 a surface wave patch; #X floatatom 67 8 5 0 0; #X connect 1 0 11 0; #X connect 2 0 10 0; #X connect 3 0 16 0; #X connect 4 0 3 0; #X connect 5 0 3 1; #X connect 6 0 4 1; #X connect 7 0 5 1; #X connect 8 0 5 0; #X connect 8 0 14 0; #X connect 8 0 19 0; #X connect 9 0 8 2; #X connect 10 0 1 0; #X connect 11 0 8 0; #X connect 12 0 9 0; #X connect 13 0 19 1; #X connect 14 0 17 0; #X connect 15 0 14 1; #X connect 16 0 22 0; #X connect 16 0 8 1; #X connect 17 0 16 1; #X connect 18 0 17 1; #X connect 19 0 4 0; #X connect 20 0 9 0; #X connect 21 0 22 1; #X connect 22 0 23 0; #X connect 23 0 0 0; #X connect 24 0 23 1; #X connect 25 0 21 0; #X connect 26 0 18 0; #X connect 27 0 6 0; #X connect 28 0 7 0; #X connect 29 0 13 0; #X connect 30 0 24 0; #X connect 35 0 10 1; pdp-0.14.1+darcs20180201/doc/examples/example08.pd000066400000000000000000000027061266045153600210160ustar00rootroot00000000000000#N canvas 508 53 640 487 10; #X obj 17 376 pdp_glx; #X obj 17 11 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 17 32 metro 40; #X floatatom 67 8 5 0 0 0 - - -; #X obj 17 58 pdp_v4l; #X obj 17 279 pdp_zrot; #X obj 175 144 unpack 0 0; #X obj 280 263 * 360; #X obj 281 240 * 3; #X msg 140 303 cursor; #X obj 140 280 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X floatatom 325 226 5 0 0 0 - - -; #X floatatom 325 249 5 0 0 0 - - -; #X obj 175 108 route drag; #X obj 17 231 pdp_mix; #X floatatom 61 205 5 0 0 0 - - -; #X obj 17 453 print; #X obj 17 422 spigot; #X obj 54 397 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 83 396 print the mouse event messages; #X floatatom 175 180 5 0 0 0 - - -; #X floatatom 240 182 5 0 0 0 - - -; #X text 109 41 using the mouse pointer in an xv window to control a patch; #X text 262 108 drag event coordinates mapped to zoom and rotation ; #X msg 86 178 0.98; #X msg 47 177 0; #X connect 0 0 13 0; #X connect 0 0 17 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 3 0 2 1; #X connect 4 0 14 0; #X connect 5 0 0 0; #X connect 5 0 14 1; #X connect 6 0 8 0; #X connect 6 0 20 0; #X connect 6 1 7 0; #X connect 6 1 21 0; #X connect 7 0 5 2; #X connect 8 0 5 1; #X connect 9 0 0 0; #X connect 10 0 9 0; #X connect 11 0 8 1; #X connect 12 0 7 1; #X connect 13 0 6 0; #X connect 14 0 5 0; #X connect 15 0 14 2; #X connect 17 0 16 0; #X connect 18 0 17 1; #X connect 24 0 15 0; #X connect 25 0 15 0; pdp-0.14.1+darcs20180201/doc/examples/example09.pd000066400000000000000000000016051266045153600210140ustar00rootroot00000000000000#N canvas 43 348 497 337 10; #X obj 88 104 pdp_grey2mask; #X obj 88 148 pdp_gain; #X obj 88 174 pdp_gain; #X obj 88 198 pdp_gain; #X msg 6 130 chanmask 1; #X msg 6 180 chanmask 4; #X msg 6 156 chanmask 2; #X obj 6 103 loadbang; #X floatatom 208 130 5 0 0; #X floatatom 208 156 5 0 0; #X floatatom 208 180 5 0 0; #X obj 88 234 pdp_glx; #X obj 88 40 metro 30; #X obj 88 13 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 88 75 pdp_v4l; #X text 26 267 a simple colour gradient patch using grey2mask and individual channel gains (set with the binary chanmask); #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 11 0; #X connect 4 0 1 0; #X connect 4 0 6 0; #X connect 5 0 3 0; #X connect 6 0 2 0; #X connect 6 0 5 0; #X connect 7 0 4 0; #X connect 8 0 1 1; #X connect 9 0 2 1; #X connect 10 0 3 1; #X connect 12 0 14 0; #X connect 13 0 12 0; #X connect 14 0 0 0; pdp-0.14.1+darcs20180201/doc/examples/example10.pd000066400000000000000000000026071266045153600210070ustar00rootroot00000000000000#N canvas 147 266 497 337 10; #X obj 88 104 pdp_grey2mask; #X msg 6 130 chanmask 1; #X msg 6 186 chanmask 4; #X msg 6 158 chanmask 2; #X obj 6 103 loadbang; #X floatatom 207 130 5 0 0; #X floatatom 253 130 5 0 0; #X floatatom 299 130 5 0 0; #X obj 88 234 pdp_glx; #X obj 88 40 metro 30; #X obj 88 13 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 88 75 pdp_v4l; #X obj 88 148 pdp_cheby3o; #X floatatom 345 130 5 0 0; #X floatatom 207 158 5 0 0; #X floatatom 253 158 5 0 0; #X floatatom 299 158 5 0 0; #X obj 88 176 pdp_cheby3o; #X floatatom 345 158 5 0 0; #X floatatom 207 186 5 0 0; #X floatatom 253 186 5 0 0; #X floatatom 299 186 5 0 0; #X obj 88 204 pdp_cheby3o; #X floatatom 345 186 5 0 0; #X text 26 267 a more complex colour gradient patch using grey2mask and individual channel chebychev colour shapers (set with the binary chanmask); #X connect 0 0 12 0; #X connect 1 0 3 0; #X connect 1 0 12 0; #X connect 1 0 12 0; #X connect 2 0 22 0; #X connect 3 0 2 0; #X connect 3 0 17 0; #X connect 4 0 1 0; #X connect 5 0 12 1; #X connect 6 0 12 2; #X connect 7 0 12 3; #X connect 9 0 11 0; #X connect 10 0 9 0; #X connect 11 0 0 0; #X connect 12 0 17 0; #X connect 13 0 12 4; #X connect 14 0 17 1; #X connect 15 0 17 2; #X connect 16 0 17 3; #X connect 17 0 22 0; #X connect 18 0 17 4; #X connect 19 0 22 1; #X connect 20 0 22 2; #X connect 21 0 22 3; #X connect 22 0 8 0; #X connect 23 0 22 4; pdp-0.14.1+darcs20180201/doc/examples/example11.pd000066400000000000000000000047241266045153600210120ustar00rootroot00000000000000#N canvas 210 529 680 275 10; #N canvas 0 0 450 300 graph1 0; #X array mapping 64 float 1; #A 0 0.0916017 -0.201423 -0.477099 -0.711681 -0.884964 -0.982024 -0.9945 -0.921318 -0.76878 -0.550026 -0.283897 0.00668462 0.296691 0.561142 0.777261 0.926433 0.995809 0.979413 0.878658 0.702222 0.465302 0.188305 -0.104911 -0.389091 -0.639758 -0.835322 -0.958937 -0.999957 -0.954848 -0.827497 -0.628871 -0.37608 -0.0908956 0.202118 0.477722 0.712179 0.885295 0.982158 0.994426 0.92104 0.768324 0.54943 0.283212 -0.00739881 -0.297373 -0.561733 -0.777711 -0.926702 -0.995875 -0.979271 -0.87832 -0.701718 -0.464675 -0.187609 0.105617 0.389745 0.640304 0.835712 0.959139 0.999952 0.954637 0.827096 0.628316 0.375418; #X coords 0 1 63 -1 200 140 1; #X restore 242 21 graph; #X msg 50 142 approx mapping; #X obj 20 86 pdp_t; #X text 235 165 -1 ----------- 0 ----------- 1; #X obj 50 115 spigot; #X obj 87 92 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 20 225 pdp_cheby 10; #X obj 515 138 tabsend~ mapping; #X obj 515 112 osc~; #X floatatom 515 65 5 0 0; #X floatatom 573 64 5 0 0; #N canvas 0 0 450 300 fblock 0; #X obj 36 36 inlet; #X obj 101 35 inlet; #X obj 42 196 outlet; #X obj 104 83 samplerate~; #X obj 59 158 +; #X obj 103 144 *; #X obj 103 59 t b b f; #X text 200 35 fblock: compute block relative frequencies; #X text 200 79 right inlet is also "active"; #X text 201 119 main usage is to compute block synchronous frequencies ; #X text 200 134 for spectral domain processing; #X text 201 49 out = left + right * (sys samplerate / blocksize); #X obj 101 115 / 64; #X connect 0 0 4 0; #X connect 1 0 6 0; #X connect 3 0 12 0; #X connect 4 0 2 0; #X connect 5 0 4 1; #X connect 6 0 4 0; #X connect 6 1 3 0; #X connect 6 2 5 1; #X connect 12 0 5 0; #X restore 515 89 pd fblock; #X obj 20 40 metro 40; #X obj 20 62 pdp_v4l; #X msg 515 37 0.17; #X text 236 208 send a signal to a table and use this as an intensity mapping function in pdp_cheby; #X obj 20 250 pdp_glx; #X obj 20 15 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X msg 573 36 3; #X msg 133 207 chanmask \$1; #X floatatom 133 185 5 0 0; #X msg 133 165 1; #X connect 1 0 6 0; #X connect 2 0 6 0; #X connect 2 1 4 0; #X connect 4 0 1 0; #X connect 5 0 4 1; #X connect 6 0 16 0; #X connect 8 0 7 0; #X connect 9 0 11 0; #X connect 10 0 11 1; #X connect 11 0 8 0; #X connect 12 0 13 0; #X connect 13 0 2 0; #X connect 14 0 9 0; #X connect 17 0 12 0; #X connect 18 0 10 0; #X connect 19 0 6 0; #X connect 20 0 19 0; #X connect 21 0 20 0; pdp-0.14.1+darcs20180201/doc/examples/example12.pd000066400000000000000000000022201266045153600210000ustar00rootroot00000000000000#N canvas 578 52 639 493 10; #X obj 83 183 metro 40; #X obj 83 154 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 83 361 pdp_glx; #X obj 165 299 pdp_loop 50; #X obj 218 167 f 0; #X obj 218 198 + 1; #X obj 218 107 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 247 140 0; #X obj 165 361 pdp_glx; #X msg 165 259 store \$1; #X obj 83 225 pdp_v4l; #X msg 41 117 open /dev/video1; #X floatatom 218 230 5 0 0 0 - - -; #X obj 312 385 pdp_save_png_sequence 50; #X obj 312 351 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 21 97 open /dev/video0; #X text 337 349 <- click to save sequence in /tmp dir; #X text 247 106 <- click to make a snapshot; #X text 288 139 <- click to reset recording to loop; #X text 273 229 <- recorded frame; #X text 28 27 make loop of snapshots; #X connect 0 0 10 0; #X connect 0 0 3 0; #X connect 1 0 0 0; #X connect 3 0 8 0; #X connect 3 0 13 0; #X connect 4 0 5 0; #X connect 5 0 4 1; #X connect 5 0 9 0; #X connect 5 0 12 0; #X connect 6 0 4 0; #X connect 7 0 4 1; #X connect 9 0 3 0; #X connect 10 0 2 0; #X connect 10 0 3 0; #X connect 11 0 10 0; #X connect 14 0 13 0; #X connect 15 0 10 0; pdp-0.14.1+darcs20180201/doc/examples/example13.pd000066400000000000000000000053231266045153600210100ustar00rootroot00000000000000#N canvas 419 114 799 646 10; #X obj 450 429 pdp_glx; #X obj 545 76 pdp_control; #X msg 545 48 thread \$1; #X obj 545 24 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 134 40 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 471 397 size 640 480; #X obj 239 393 +; #X obj 190 432 vsl 15 128 1 0 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X obj 190 393 -; #X obj 59 386 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X obj 59 401 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X obj 59 416 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X obj 205 432 vsl 15 128 1 0 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X obj 220 432 vsl 15 128 1 0 0 0 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X obj 190 366 unpack f f; #X obj 62 317 unpack f f; #X obj 68 360 +; #X obj 45 360 -; #X obj 151 264 pack f f; #X obj 215 265 pack f f; #X msg 295 77 dim 320 240; #X obj 134 72 metro 40; #X msg 294 54 dim 640 480; #X obj 134 100 pdp_v4l; #X obj 450 366 pdp_zoom; #X floatatom 450 308 5 0 0; #X msg 553 311 centerx \$1; #X floatatom 553 289 5 0 0; #X floatatom 636 292 5 0 0; #X msg 635 310 centery \$1; #X obj 511 197 unpack f f f f; #X obj 450 287 min; #X obj 446 252 expr .5/($f1+.02); #X obj 572 252 expr .5/($f1+.02); #X msg 450 339 zoomx \$1 \, zoomy \$1; #X msg 295 8 open /dev/video0; #X msg 295 30 open /dev/video1; #X obj 309 244 pack f f f f; #X obj 134 156 pdp_diff; #X text 208 156 <- compute difference between current and previous frame; #X obj 134 226 pdp_cog_abs_thresh 0.15; #X text 331 492 using the blob tracker on a difference signal to detect motion; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 21 0; #X connect 5 0 0 0; #X connect 6 0 13 0; #X connect 8 0 7 0; #X connect 14 0 12 0; #X connect 14 0 8 0; #X connect 14 0 6 0; #X connect 14 1 8 1; #X connect 14 1 6 1; #X connect 15 0 17 0; #X connect 15 0 16 0; #X connect 15 0 10 0; #X connect 15 1 16 1; #X connect 15 1 17 1; #X connect 16 0 11 0; #X connect 17 0 9 0; #X connect 18 0 15 0; #X connect 19 0 14 0; #X connect 20 0 23 0; #X connect 21 0 23 0; #X connect 22 0 23 0; #X connect 23 0 38 0; #X connect 24 0 0 0; #X connect 25 0 34 0; #X connect 26 0 24 0; #X connect 27 0 26 0; #X connect 28 0 29 0; #X connect 29 0 24 0; #X connect 30 0 27 0; #X connect 30 1 32 0; #X connect 30 2 28 0; #X connect 30 3 33 0; #X connect 31 0 25 0; #X connect 32 0 31 0; #X connect 33 0 31 1; #X connect 34 0 24 0; #X connect 35 0 23 0; #X connect 36 0 23 0; #X connect 37 0 30 0; #X connect 38 0 24 0; #X connect 38 0 40 0; #X connect 40 1 18 0; #X connect 40 1 37 0; #X connect 40 2 19 0; #X connect 40 2 37 2; #X connect 40 3 18 1; #X connect 40 3 37 1; #X connect 40 4 19 1; #X connect 40 4 37 3; pdp-0.14.1+darcs20180201/doc/examples/example14.pd000066400000000000000000000026011266045153600210050ustar00rootroot00000000000000#N canvas 621 348 611 467 10; #X obj 168 329 pdp_glx; #X obj 168 78 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 168 142 pdp_v4l; #X obj 168 108 metro 40; #X msg 265 83 open /dev/video1; #X floatatom 311 151 5 0 0; #X obj 168 194 pdp_agc 0.5; #X floatatom 310 211 5 0 0; #X obj 168 245 pdp_contrast 0.5; #X msg 4 157 chanmask \$1; #X floatatom 4 133 5 0 0; #X msg 4 104 1; #X msg 35 104 3; #X msg 67 104 5; #X msg 99 104 7; #X obj 314 192 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 12300 1; #X obj 314 132 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 7900 1; #X msg 265 58 open /dev/video0; #X floatatom 310 272 5 0 0; #X obj 314 253 hsl 128 15 0 3 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X obj 168 298 pdp_saturation 0.5; #X text 7 79 Y; #X text 36 78 YCr; #X text 68 79 YCb; #X text 98 78 YCrCb; #X text 25 15 some basic image enhancements; #X text 13 60 agc color channels; #X obj 183 166 pdp_flip_lr; #X connect 1 0 3 0; #X connect 2 0 27 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 6 1; #X connect 6 0 8 0; #X connect 7 0 8 1; #X connect 8 0 20 0; #X connect 9 0 6 0; #X connect 10 0 9 0; #X connect 11 0 10 0; #X connect 12 0 10 0; #X connect 13 0 10 0; #X connect 14 0 10 0; #X connect 15 0 7 0; #X connect 16 0 5 0; #X connect 17 0 2 0; #X connect 18 0 20 1; #X connect 19 0 18 0; #X connect 20 0 0 0; #X connect 27 0 6 0; pdp-0.14.1+darcs20180201/doc/examples/example15.pd000066400000000000000000000013451266045153600210120ustar00rootroot00000000000000#N canvas 632 359 559 496 10; #X obj 127 57 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 127 81 metro 40; #X obj 148 57 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 126 110 pdp_v4l; #X msg 229 56 open /dev/video0; #X msg 228 80 open /dev/video1; #X obj 126 151 pdp_motion_fade 1; #X obj 126 174 pdp_contrast 0.16; #X obj 126 199 pdp_mul; #X obj 126 224 pdp_gain 22; #X text 7 2 using motion_fade \, contrast \, mul and gain to get a motion triggered effect; #X obj 126 258 pdp_glx; #X connect 0 0 1 0; #X connect 1 0 3 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 7 0; #X connect 7 0 8 1; #X connect 7 0 8 0; #X connect 8 0 9 0; #X connect 9 0 11 0; pdp-0.14.1+darcs20180201/doc/introduction/000077500000000000000000000000001266045153600175645ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/doc/introduction/control.pd000066400000000000000000000007541266045153600215770ustar00rootroot00000000000000#N canvas 372 355 668 154 10; #X obj 33 107 pdp_glx; #X obj 33 57 pdp_v4l; #X msg 33 12 bang; #X obj 33 81 pdp_trigger; #X obj 33 35 metro 1000; #X obj 105 108 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 140 20 pdp_trigger sends out a bang message on the right outlet before it passes the incoming pdp message on the left outlet.; #X msg 73 12 stop; #X connect 1 0 3 0; #X connect 2 0 4 0; #X connect 3 0 0 0; #X connect 3 1 5 0; #X connect 4 0 1 0; #X connect 7 0 4 0; pdp-0.14.1+darcs20180201/doc/introduction/input_output.pd000066400000000000000000000053411266045153600226730ustar00rootroot00000000000000#N canvas 250 34 894 848 10; #X obj 107 427 pdp_v4l; #X obj 107 53 metro 40; #X msg 159 14 stop; #X msg 107 14 bang; #X msg 51 14 bang; #X obj 107 695 pdp_glx; #X msg 209 93 open /dev/video0; #X msg 209 117 open /dev/video1; #X text 347 95 you can choose the input device using the 'open' message. the default is /dev/video0; #X msg 209 142 close; #X text 348 143 closes the video port; #X msg 209 168 type yv12; #X msg 209 192 type grey; #X text 348 171 type sets the ouput image package type. currently only yv12 (luma/chroma color) and greyscale are supported.; #X msg 210 221 dim 320 240; #X msg 210 244 dim 640 480; #X text 348 215 dim sets the dimensions of the captured frame. please note that in all objects dimensions and packet type (color/greyscale) have to be the same to be combined (i.e. mixed); #X msg 210 556 dim 320 240; #X msg 210 579 dim 640 480; #X text 349 559 dim sets the window dimensions; #X msg 210 510 create; #X msg 210 531 destroy; #X text 208 447 pdp_glx ouputs video in a window using the GLX extension. if your graphics card/driver supports it you can have multiple output windows. if a pdp message is received and a window is not open \, one is created automaticly.; #X text 349 513 use these messages to explicitly create/destroy the window; #X text 207 18 pdp_v4l grabs video from the video4linux device. it grabs a frame whenever a bang message is received. the output rate is limited by the maximum framerate of the video device. if there is no device opened \, it will attempt to open /dev/video0; #X msg 212 627 cursor \$1; #X obj 212 607 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 348 627 enables/disables cursor in xv window; #X msg 210 319 channel \$1; #X floatatom 210 295 5 0 0 0 - - -; #X text 347 320 sets the v4l channel (like tuner \, composite \, svideo \, ...); #X floatatom 210 359 5 0 0 0 - - -; #X msg 210 383 freq \$1; #X floatatom 271 359 5 0 0 0 - - -; #X msg 271 383 freqMHz \$1; #X text 346 359 sets the v4l tuner frequency (in v4l units and MHz) ; #X text 347 655 specify the x window display; #X msg 212 653 display :0; #X obj 107 748 print; #X text 211 745 the output channel sends mouse event messages (press/release/drag and individual p/r/d for each button); #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 4 0 0 0; #X connect 5 0 38 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X connect 9 0 0 0; #X connect 11 0 0 0; #X connect 12 0 0 0; #X connect 14 0 0 0; #X connect 15 0 0 0; #X connect 17 0 5 0; #X connect 18 0 5 0; #X connect 20 0 5 0; #X connect 21 0 5 0; #X connect 25 0 5 0; #X connect 26 0 25 0; #X connect 28 0 0 0; #X connect 29 0 28 0; #X connect 31 0 32 0; #X connect 32 0 0 0; #X connect 33 0 34 0; #X connect 34 0 0 0; #X connect 37 0 5 0; pdp-0.14.1+darcs20180201/doc/introduction/quicktime.pd000066400000000000000000000061251266045153600221100ustar00rootroot00000000000000#N canvas 400 126 715 814 10; #X obj 59 391 pdp_qt; #X obj 59 462 pdp_glx; #X floatatom 77 429 5 0 0; #X floatatom 127 430 5 0 0; #X obj 56 41 metro 40; #X msg 56 13 bang; #X msg 97 13 stop; #X msg 15 13 bang; #X obj 140 41 openpanel; #X msg 140 66 open \$1; #X msg 140 13 bang; #X msg 140 92 close; #X text 249 66 open/close for file access; #X floatatom 140 120 5 0 0; #X floatatom 140 146 5 0 0; #X text 248 117 float on left inlet selects a frame for output; #X msg 140 197 loop \$1; #X obj 203 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 250 198 automatic looping can be enabled/disabled; #X text 251 9 pdp_qt plays a quicktime movie.; #X text 250 221 this enables automatic playback at the frame rate specified in the movie file. in pdp_qt~ playback is synchronized to the audio stream.; #X obj 335 535 table array; #X msg 142 341 dump array 0; #X text 252 330 if the movie contains audio \, this command dumps the audio data into an array specified by the first argument. the second argument is the audio channel (default = 0 = left); #X msg 142 291 stop; #X text 251 289 stops automatic playback (same as autoplay 0); #X msg 141 222 autoplay 1; #X msg 142 267 play; #X text 252 432 the second outlet outputs the current frame number. the third outlet outputs the total number of frames in a movie when it is opened.; #X obj 56 786 pdp_glx; #X obj 56 715 pdp_qt~; #X obj 84 757 dac~; #X msg 33 644 play; #X obj 127 635 openpanel; #X msg 127 660 open \$1; #X msg 127 607 bang; #X msg 9 760 close; #X text 251 660 pdp_qt~ is the same as pdp_qt exept that it also outputs the audio data corresponding to the current frame on its 2 rightmost outlets. if there is a lag between audio and video a pdp_del object can be inserted to delay the image. note that in order to get acceptable audio quality with relatively few dropouts you might need to increase the pd audio latency.; #X msg 7 429 close; #X msg 142 315 cont; #X text 251 269 starts automatic playback (same as 0 \, autplay 1 \, bang); #X text 251 310 resumes automatic playback (same as autplay 1 \, bang) ; #X msg 9 617 loop 1; #X floatatom 78 645 5 0 0; #X obj 448 535 tabplay~ array; #X obj 448 576 dac~; #X obj 448 506 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 126 685 dump array 0; #X text 249 137 float on right inlet selects the frame to be read on the next sync event (bang message / internal sync).; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 0 2 3 0; #X connect 4 0 0 0; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 7 0 0 0; #X connect 8 0 9 0; #X connect 9 0 0 0; #X connect 10 0 8 0; #X connect 11 0 0 0; #X connect 13 0 0 0; #X connect 14 0 0 1; #X connect 16 0 0 0; #X connect 17 0 16 0; #X connect 22 0 0 0; #X connect 24 0 0 0; #X connect 26 0 0 0; #X connect 27 0 0 0; #X connect 30 0 29 0; #X connect 30 3 31 0; #X connect 30 4 31 1; #X connect 32 0 30 0; #X connect 33 0 34 0; #X connect 34 0 30 0; #X connect 35 0 33 0; #X connect 36 0 29 0; #X connect 38 0 1 0; #X connect 39 0 0 0; #X connect 42 0 30 0; #X connect 43 0 30 1; #X connect 44 0 45 0; #X connect 44 0 45 1; #X connect 46 0 44 0; #X connect 47 0 30 0; pdp-0.14.1+darcs20180201/doc/introduction/traffic.pd000066400000000000000000000060421266045153600215310ustar00rootroot00000000000000#N canvas 155 92 978 574 10; #X msg 362 2 stop; #X obj 362 27 metro 40; #X obj 362 53 pdp_v4l; #X obj 32 524 pdp_glx; #X obj 847 336 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 847 388 pdp_control; #X msg 847 361 thread \$1; #X obj 434 56 hdl 15 1 1 4 empty empty empty 0 -6 0 8 -262144 -1 -1 2; #X obj 432 278 pdp_del 25; #X obj 410 332 pdp_mix; #X obj 457 305 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 6500 1; #X floatatom 497 249 5 0 0; #X text 457 83 packet router. second inlet sets destination outlet. creation argument sets number of outlets.; #X obj 240 333 pdp_snap; #X obj 240 302 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 249 357 packet snapshot; #X msg 262 301 snap; #X obj 410 456 pdp_trigger; #X text 508 463 before it passes the packet; #X text 507 450 trigger sends a bang on right outlet; #X obj 482 487 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 248 389 bang sends out packet; #X obj 434 146 send packet; #X text 524 138 pdp packets can be sent over send/receive pairs; #X text 523 152 (not over netsend/netreceive pairs!); #X obj 451 382 pdp_pps; #X floatatom 451 412 5 0 0; #X text 513 381 packet rate calculator; #X obj 32 21 receive packet; #X obj 203 254 pdp_reg; #X text 68 222 a packet register; #X text 58 235 (like int and float); #X obj 32 81 pdp_mix; #X obj 79 51 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 10500 1; #X obj 32 136 pdp_conv; #X obj 203 227 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 115 70 feedback; #X obj 362 87 pdp_route 4; #X text 107 82 is allowed; #X obj 335 3 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 754 292 enable or disable processing; #X text 754 307 in separate thread; #X text 471 342 second inlet 0->1; #X text 472 328 mix (crossfade) 2 packets.; #X floatatom 83 111 5 0 0; #X text 58 253 left: hot packet; #X text 58 267 right: cold packet; #X floatatom 847 449 5 0 0; #X obj 847 420 route pdp_drop; #X text 801 473 dropped packet counter; #X text 43 159 convolution: default is blur; #X text 135 110 number of passes; #X text 248 373 snap takes snapshot; #X text 134 118 comment; #X text 431 185 packet delay line. second inlet sets delay. creation argument sets total delay line length. WARNING: this uses a lot of memory. keep the size small to prevent the system to start swapping to disk.; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 37 0; #X connect 4 0 6 0; #X connect 5 0 48 0; #X connect 6 0 5 0; #X connect 7 0 37 1; #X connect 8 0 9 1; #X connect 9 0 17 0; #X connect 9 0 25 0; #X connect 10 0 9 2; #X connect 11 0 8 1; #X connect 13 0 3 0; #X connect 14 0 13 0; #X connect 16 0 13 0; #X connect 17 0 3 0; #X connect 17 1 20 0; #X connect 25 0 26 0; #X connect 28 0 32 0; #X connect 29 0 3 0; #X connect 32 0 34 0; #X connect 33 0 32 2; #X connect 34 0 32 1; #X connect 34 0 3 0; #X connect 35 0 29 0; #X connect 37 0 29 1; #X connect 37 1 13 1; #X connect 37 2 8 0; #X connect 37 2 9 0; #X connect 37 3 22 0; #X connect 39 0 1 0; #X connect 44 0 34 1; #X connect 48 0 47 0; pdp-0.14.1+darcs20180201/doc/misc/000077500000000000000000000000001266045153600157765ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/doc/misc/devdoc.html000066400000000000000000000224111266045153600201300ustar00rootroot00000000000000 PDP Developer Documentation

FIXME: This is probably a bit out of date.

PDP Developer Documentation

Introduction

There is not yet much developer information, partly because pdp is not that big and since the goals are not completely clear yet, a lot will probably change on the inside in the future. I believe it is not too hard to figure out how it works, once you get started somewhere. This document is a minimalistic attempt to provide that starting point. For full prototypes see the header files. I suggest you have a look at the pdp_base base class, and some simple modules: pdp_add, pdp_noise and pdp_gain for examples.

PDP architecture

Architecture is a big word, but pdp is organized as modules. A packet pool module (a reuse pool memory manager), a packet class, a processing queue module, a high level type conversion module, an image packet class, and some low level modules for image type conversion, image resampling and all sorts of other image processing. Besides that there are 2 extension libraries: pdp_scaf, a cellular automata extension and pdp_opengl, a 3d rendering extension. These are separate because of portability issues. The different pdp_* externs in the main pdp library use the core modules' functionality to minimize code duplication. I'm relatively happy with how it fits together, but some things need to change for future plans. Most objects are written in the object oriented c style of pd. To prevent namespace conflicts, (almost) all routines start with the pdp_ prefix. The second name is the name of the object or module they belong to. The first argument is always a pointer to an object or an integer (for packets).

PD ties

PDP is written as an extension for PD. One of the goals of pdp is to evolve to a separate library that can be reused in other software. The architecture will be split into two parts. A pd-independent part (the packet classes, the packet pool, the type conversion system and the forth system) and a part with pd specific stuff (the process queue and interfaces to the pd system like the base classes and the pd communication protocol). In order to do this the packet class will probably evolve to a proper object model, supporting run time attribute binding (inspired by the python object model).

There are some things that put a stamp on the current pdp design. Most importantly pd's processor object model and communication protocol. (i.e. the fact that pd only supports unidirectional messaging creates the awkward concept of a "passing packet" to eliminate excessive data copying.)

In pd, the pdp messaging protocol is implemented as pd messages. The protocol is however 3 phase. With a read only register phase, a read/write register phase and a process phase. This functionality is part of the base class or the forth processor object. The dpd protocol is entirely different, and is used in the opengl library. It is not based on parallel dataflow but serial context passing.

Packets

PDP introduces a new atom: the data packet. This can contain all kinds of data. Images (16bit/8bit), cellular automata (1bit), matrices (real/complex float/double), opengl textures and 3d rendering contexts. Packets are stored in a pool to ensure fast reuse, and to enable sharing. The paradigm is centered around a combination of an object oriented approach and a dataflow approach.

The methods operating on packets (pdp_packet_*) are mainly for administrative purposes: memory management (construction, registering, copying) and getting or setting info.

All processing is done in the pd modules. Processors can be defined using the forth scripting language, but this is still experimental. The forth system can be accessed from the guile library.

There is a central mechanism for packet type conversion. This is to facilitate the combination of different media types. Whenever a packet class is constructed (i.e. in an extension library), a number of conversion routines should be defined to convert the added type to one or some of the main pdp types.

PDP API Overview

The pdp public api contains only a single class: the packet. (The internal api has more classes, that can be used too if necessary, but i won't document them.) A packet is a class in pdp. The table below lists the supported methods. The first argument of a call is a packet id.
pdp_packet_*
new construct a raw packet (depreciated)
new_* construct packet of specific type/subtype/...
mark_unused release
mark_passing conditional release (release on first copy ro/rw)
copy_ro readonly (shared) copy
copy_rw private copy
clone_rw private copy (copies only meta data, not the content)
header get the raw header (t_pdp *)
data get the raw data (void *)
pass_if_valid send a packet to pd outlet, if it is valid, and mark unused
replace_if_valid delete packet and replace with new one, if new is valid
copy_ro_or_drop copy readonly, or don't copy if dest slot is full + send drop notify
copy_rw_or_drop same, but private copy
get_description retrieve type info
convert_ro same as copy_ro, but with an automatic conversion matching a type template
convert_rw same as convert_ro, but producing a private copy

The pool object methods. All the packets are stored in a central packet pool.
pdp_pool_*
collect_garbage manually free all unused resources in packet pool

The process queue object methods. PDP supports a separate processing thread.
pdp_queue_*
add add a process method + callback
finish wait until a specific task is done
wait wait until processing queue is done

The control methods. General pdp control messages.
pdp_control_*
notify_drop notify that a packet has been dropped

The type mediator methods.
pdp_type_*
description_match check if two type templates match
register_conversion register a type conversion program

NOTE: it is advised to derive your module from the pdp base class defined in pdp_base.h instead of communicating directly with the pdp core

pdp_base class

If you want to write a pdp extern, you can derive it from the pdp_base class, instead of t_object. This class abstracts a lot of the hassle of writing ordinary (inplace) packet processors. The base allows you to register process callbacks. There are 3 kinds of callbacks: preproc, process and postproc. The preproc method is called inside the pd thread. This can be used to setup some things that can only be done inside the pd thread. The process method should do most of the work, and is called from the pdp processing thread if it is enabled, after the preproc method is finished. You can't use most of pd's calls in this method. The postproc method is called from the pd thread after the process method is finished, and can be used to send data to pd outlets. Simple packet processors only need the process method (packet input/output is handled by the pdp_base class).

pdp_imageproc_* modules

Most of the image processing code is organized as planar 16 bit signed processors. This is crude and oversimplified, but it helps to keep the code size small and fast at the same time (platform dependent assembly code is reduced to a bare minimum). These routines can be used to build higher level image processing objects that are more (cache) efficient than an abstraction using separate pdp modules. If you plan to write your own image processing routines, you can use the pdp_imageproc_dispatch_ routine to support all 16bit image types at once (greyscale, subsampled YCrCb, multichannel planar). This requires you write the image processing routine as a planar (greyscale) processor using the pdp_imageproc_ interface. (see pdp_imageproc.h)

pdp_llconv call

Low level image conversion routines. (operating on raw data buffers). You probably won't need this, since the high level type conversion (pdp_packet_convert_ro/rw) covers most of its functionality.
Tom Schouten
Last modified: Fri Sep 19 04:52:12 CEST 2003 pdp-0.14.1+darcs20180201/doc/misc/old-overview.html000066400000000000000000000106571266045153600213170ustar00rootroot00000000000000

Pure Data Packet

Introduction

PDP is an extension library for Pure Data, aimed at providing video and other media processing fuctionality. That's still it's main purpose, but as of version 0.13, there is more. PDP turned into a tool for writing PDP. See the section on Packet Forth.

PDP runs on Linux and OSX. The OSX version depends on Fink.

PDP's focus is on images and video, but there is no reason it should stay like that. There is support for matrix processing, 1D and 2D binary cellular automata, opengl rendering (like Gem), scheme scripting (guile), ascii packets, bit grids, ...

For more image processing objects, streaming objects and a collection of very useful additions to the bare bones PDP functionality, have a look at Yves Degoyon's PiDiP library.

Since version 0.13.x, which is a merger between stable (0.12.x) and packet forth, PDP has been split up into 3 parts:

  • libtile - A lowlevel library for platform specific (integer, mmx, altivec) image processing operations and cache optimizations.
  • libpdp - The packet managing library + pf scripting language.
  • pdp - This is the stable pdp 0.12.x with support for packet forth.

    PDP for Pure Data

    This is considered to be the stable part of pdp. It has been stable since 0.12.x It has it's bugs & drawbacks & oversimplifications but will mostly stay like it is. It is optimized for intel/mmx and uses a 16bit signed yuv format ideal for real time video processing, mixing, blending and feedback. The pf layer is accessible from pd/pdp. The result of this is that you can write pdp objects in pf, or directly map pf operations to pdp objects. A 'getting started' documentation for pd/pdp/pidip is being worked on. Until then you can have a look at the 'pdp' subdirectory in pd's 'Pure Documentation'. Most objects are documented with pd style help patches accessible by right clicking on an object. The place to send questions is the pd mailing list. Bugreports can be sent to the pd list or me: pdp TA zzz TOD kotnet TOD org .

    Packet Forth

    The libpdp library is a C support library for media processing. It implements a mime-like media type system (packets), type conversion and packet operations, interface logic to connect pf to other applications, and other things you might need to write small 'scratch' media applications. All operations are implemented as extensions to a forth-like glue language called Packet Forth. For more information on this see the documentation in the libpdp distribution, or the mailing list archives.

    CVS

    The latest stable pdp release is 0.12.4. Because 0.13.x is still in a flux, the preferred way of accessing the code is CVS. You can access the modules in this way:

    export CVSROOT=:pserver:anonymous@zwizwa.fartit.com:/usr/local/cvsroot
    cvs login
    cvs co libtile
    cvs co libpdp
    cvs co pdp

    To update, simply cd to each of the 3 directories, and type cvs update -d.

    When extracting from cvs, you need to run the ./bootstrap script to create the configure scripts and build and install the packages in the order above. In order to compile pdp with libpdp (pf) support, you need to add a --enable-pf option when invoking pdp's configure script.

    Links

  • Pure Data at IEM
  • PiDiP Is Definitely In Pieces
  • al-Jwarizmi
  • PidipVJ
  • Videoflow / Cruzados BGN
  • Eth0
  • RRADical
  • Veejay / SendVIMS
  • FreeJ
  • EffecTV pdp-0.14.1+darcs20180201/doc/misc/rawout.txt000066400000000000000000000121501266045153600200570ustar00rootroot00000000000000How to use [pdp_rawout] to record video --------------------------------------- Some observations * pdp is a real time performance tool * ffmpeg and mencoder are very nice pieces of software that solve the video encoding problem * encoding video is cpu intensive * large harddisks are cheap For these reason, I decide to not implement container/codec recording in pdp. Using [pdp_rawout] and [pdp_rawout~] it is possible to dump video and audio streams directly to harddisk using the minimal amount of cpu time. There they can be picked up later by tools like mencoder and ffmpeg. ( For playback, pdp supports only libquicktime, which is, next to mjpegtools, a good solution for frame-based seekable video files. Since version 0.9.4 libquicktime supposedly supports AVI playback and record. Streaming playback and more efficient block codecs can be supported externally using [pdp_rawin] ) FFMPEG ------ FFMPEG is the 'industry standard' for open source video encoding. Its core components are libavcodec and libavformat, which implement the coder/decoder and container format handling. The latter two are used in a lot of other projects, like MPlayer and libquicktime. Send a video stream through [pdp_convert bitmap/i420/*] then stream it to disk using [pdp_rawout /tmp/video.i420] while you are performing. You can convert it to divx avi using ffmpeg -an -r 25 -s 320x240 -f rawvideo -i video.i420 video.avi To include audio, use [pdp_rawout~ 2 /tmp/audio.s16] to stream audio to disk. You can convert it with ffmpeg using ffmpeg -ar 44100 -ac 2 -f s16le -i audio.s16 audio.mp3 Doing both at the same time: ffmpeg -r 25 -s 320x240 -f rawvideo -i video.i420 -ar 44100 -ac 2 -f s16le -i audio.s16 -vcodec mjpeg -b 3000 clip.avi Note: i didn't figure out how to make ffmpeg read yv12 encoded files. However, pdp supports the bitmap/i420/* format. The latter is also the data format used in the yuv4mpeg protocol from the mjpeg tools. Codecs and Bitrates ------------------- The preferred codec to use during the editing stage is motion JPEG. If you have the space, use raw files, but i haven't figured out how to make them portable. The most portable mjpeg format seems to be wrapped in a mov. This is the format used in cinelerra. Uncompressed 320x240x25 yv12/i420 is 2.88 mbyte/sec A decent mjpeg compresion rate is 4:1, giving 720 kbyte/sec = 5760 kbit/sec with practically no loss of quality. 3000 and 2000 kbps are still acceptable. Sometimes it might be interesting to create DV files. These have a tighter binding to TV norms PAL and NTSC, and seem to be a standard at this moment. DV gives about 13gig/hour or 3 mbyte/sec. The actual rate is 5:1 compression at 25 Mbps (video only). Adding audio, timecode, etc.. comes to about 29 Mbps. (TODO: how to create DV files) The preferred distribution codec is either DIVX or H.264 (don't confuse with H.263 which is aimed at low bitrate video conferencing) A/V sync -------- The key to A/V sync is the observation that the ratio between audio and video frequency (samplerate and framerate), is a _rational_ one. This enables to have perfect sync: there are no roundoff errors since the relation between audio and video sample times can be computed exactly. The object [pdp_metro~] can be used to produce a locked video clock, given a rational framerate. It can produce a video clock that is compatible with standard A/V rates. For example the awkward 29.97Hz video rate is exactly supported as 29970/1000. Note that the 44.1kHz audio rate does not yield simple fractions for standard NTSC and PAL/SECAM framerates. I.e. in DV you have to use 48kHz. Enabling arbitrary long buffering (bufsize -1) in [pdp_rawout] and using [pdp_metro~] with the correct sample rate and video frame rate should produce perfect A/V sync without dropouts if your harddisk can keep up on the average. MJPEGTOOLS ---------- I mainly use lavtrans for converting the avi/mjpeg file made with ffmpeg to quicktime format. This should be readable by most video editing software. I had some problems with sharing th avi/mjpeg files themselves. To convert the avi file to mov use: lavtrans -o clip.mov -f q clip.avi Mplayer/Mencoder ---------------- The MPlayer project uses libavcodec, and even distributes a copy with the MPlayer source. You'll need mencoder mainly if you want to use an encoder that's not in the ffmpeg package (lavcodec), or what to do some format conversion that's not supported by ffmpeg directly. Of course mplayer is handy for inspecting raw files. To play a raw video stream try: mplayer -rawvideo on:w=320:h=240:fps=25 video.i420 To encode video only using the ffmpeg (lavc) mjpeg codec (it is possible to use yv12 here, using the format=yv12 option) mencoder -rawvideo on:w=320:h=240:fps=25 video.i420 -ovc lavc \ -lavcopts vcodec=mjpeg -o clip.avi links ----- http://mjpeg.sourceforge.net/ http://ffmpeg.sourceforge.net/index.php http://libquicktime.sourceforge.net/ http://www.mplayerhq.hu http://libdv.sourceforge.net/ http://solarmuri.ssl.berkeley.edu/~fisher/public/manuscripts/scientific-movie-HOWTO.txt http://mpeg4ip.sourceforge.net/ http://heroinewarrior.com/cinelerra.php3 http://www.adamwilt.com/DV-tech.html pdp-0.14.1+darcs20180201/doc/objects/000077500000000000000000000000001266045153600164745ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/doc/objects/README000066400000000000000000000003031266045153600173500ustar00rootroot00000000000000This directory contains help patches for the individual pdp modules and abstractions. Use the pdp_help_input.pd and pdp_help_output.pd patches to setup your desired in/out for the help patches. pdp-0.14.1+darcs20180201/doc/objects/pdp_abs-help.pd000066400000000000000000000007411266045153600213610ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 296 pdp_gain; #X msg 128 268 1; #X text 229 235 absolute value; #X obj 77 231 pdp_abs; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 10 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 3 0; #X connect 8 0 7 1; #X connect 10 0 7 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_add-help.pd000066400000000000000000000015631266045153600213470ustar00rootroot00000000000000#N canvas 180 63 511 383 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 322 pdp_help_output; #X obj 77 279 pdp_add; #X obj 121 246 pdp_reg; #X obj 196 183 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 229 181 click here; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0 0 - - -; #X msg 128 109 0.5; #X text 229 283 adds (and saturates) 2 packets; #X msg 230 246 chanmask \$1; #X floatatom 230 221 5 0 0 0 - - -; #X msg 374 131 thread \$1; #X obj 373 107 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 377 164 pdp_control; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 8 0; #X connect 4 0 3 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 8 0 4 0; #X connect 8 0 5 1; #X connect 9 0 8 1; #X connect 10 0 9 0; #X connect 12 0 4 0; #X connect 13 0 12 0; #X connect 14 0 16 0; #X connect 15 0 14 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_and-help.pd000066400000000000000000000011061266045153600213520ustar00rootroot00000000000000#N canvas 552 356 511 383 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 322 pdp_help_output; #X obj 121 246 pdp_reg; #X obj 196 183 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 229 181 click here; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 279 pdp_and; #X text 229 283 bitwise and; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 7 0; #X connect 4 0 10 1; #X connect 5 0 4 0; #X connect 7 0 10 0; #X connect 7 0 4 1; #X connect 8 0 7 1; #X connect 9 0 8 0; #X connect 10 0 3 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_bitdepth-help.pd000066400000000000000000000014371266045153600224220ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 140 61 start; #X msg 187 61 stop; #X obj 140 93 pdp_help_input; #X obj 140 352 pdp_help_output; #X obj 140 308 pdp_gain; #X msg 191 280 1; #X floatatom 219 209 8 0 0; #X obj 222 185 hsl 128 15 0 8 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 2500 1; #X floatatom 238 278 5 0 0; #X obj 140 243 pdp_bitdepth; #X text 292 247 set bit depth (0->16); #X obj 140 158 pdp_gain; #X msg 191 130 1; #X floatatom 227 130 5 0 0; #X msg 32 192 chanmask \$1; #X floatatom 32 164 5 0 0; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 11 0; #X connect 4 0 3 0; #X connect 5 0 4 1; #X connect 6 0 9 1; #X connect 7 0 6 0; #X connect 8 0 4 1; #X connect 9 0 4 0; #X connect 11 0 9 0; #X connect 12 0 11 1; #X connect 13 0 11 1; #X connect 14 0 9 0; #X connect 15 0 14 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_bitmask-help.pd000066400000000000000000000010721266045153600222440ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 287 pdp_help_output; #X obj 77 243 pdp_gain; #X msg 128 215 1; #X text 229 182 apply a bitwise mask (16 bit); #X floatatom 149 144 8 0 0; #X obj 152 120 hsl 128 15 0 65535 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X floatatom 175 213 5 0 0; #X obj 77 178 pdp_bitmask; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 10 0; #X connect 4 0 3 0; #X connect 5 0 4 1; #X connect 7 0 10 1; #X connect 8 0 7 0; #X connect 9 0 4 1; #X connect 10 0 4 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_bq-help.pd000066400000000000000000000076501266045153600212240ustar00rootroot00000000000000#N canvas 364 134 765 779 10; #X floatatom 100 598 5 0 0; #X msg 28 361 ver \$1; #X msg 28 393 hor \$1; #X obj 96 362 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 95 389 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 28 629 pdp_bq; #X floatatom 89 495 5 0 0; #X msg 28 495 onep \$1; #X floatatom 89 526 5 0 0; #X msg 28 530 twop \$1; #X obj 85 272 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 87 304 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 79 209 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 82 244 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 28 209 lr \$1; #X msg 28 244 rl \$1; #X msg 28 277 tb \$1; #X msg 28 305 bt \$1; #X obj 454 406 t b f; #X floatatom 489 369 5 0 0; #X floatatom 488 317 5 0 0; #X obj 454 436 pack s 0 0; #X msg 454 469 \$1 \$2 \$3; #X obj 489 405 t b f; #X msg 410 370 lpf; #X msg 409 344 hpf; #X msg 409 398 apf; #X msg 409 425 bsf; #X obj 461 38 pdp_help_input; #X msg 461 13 start; #X msg 507 13 stop; #X obj 28 746 pdp_help_output; #X text 159 598 right inlet sets number of passes; #X text 37 16 pdp_bq: a spatial biquad filter; #X obj 495 196 pdp_blur; #X obj 598 194 pdp_phase; #X obj 461 93 pdp_route 3; #X obj 533 65 hdl 15 1 0 3 empty empty empty 0 -6 0 8 -262144 -1 -1 0; #X obj 41 670 r \$0-out; #X obj 495 246 s \$0-out; #X floatatom 544 119 5 0 0; #X floatatom 617 117 5 0 0; #X text 312 358 high pass; #X text 313 382 low pass; #X text 314 410 all pass; #X text 313 439 band stop; #X text 541 367 pole Q; #X text 94 31 it is a bit awkward to use directly; #X text 94 45 try one of the abstractions (pdp_blur and; #X text 95 61 pdp_phase); #X text 122 208 left->right; #X text 124 242 right->left; #X text 126 272 top->bottom; #X text 126 300 bottom->top; #X text 133 359 bt and tb; #X text 132 383 lr and rl; #X text 147 494 one pole filter; #X text 146 524 double one pole filter; #X msg 89 464 0.1; #X msg 556 95 0.5; #X msg 616 94 0.5; #X text 588 62 choose example here; #X msg 672 118 1; #X msg 673 140 0; #X msg 673 163 -1; #X msg 712 116 1; #X msg 713 138 0; #X msg 713 161 -1; #X text 93 91 "unstable" behaviour is possible; #X msg 490 347 0.1; #X msg 488 293 0.3; #X obj 28 720 pdp_gain; #X floatatom 112 693 5 0 0; #X msg 112 671 1; #X text 95 107 when frequency and Q are outside their; #X text 96 122 sensible ranges; #X text 122 180 set filter direction:; #X text 264 342 set the filter type:; #X text 137 476 set the filter type:; #X text 538 319 (between 0 and 1 \, 0.5 = nyquist); #X text 540 333 comment; #X text 540 305 pole frequency; #X msg 100 572 1; #X msg 457 611 chanmask \$1; #X floatatom 457 585 5 0 0; #X text 456 633 binary channel mask; #X connect 0 0 5 1; #X connect 1 0 5 0; #X connect 2 0 5 0; #X connect 3 0 1 0; #X connect 4 0 2 0; #X connect 5 0 71 0; #X connect 6 0 7 0; #X connect 7 0 5 0; #X connect 8 0 9 0; #X connect 8 0 9 0; #X connect 9 0 5 0; #X connect 10 0 16 0; #X connect 11 0 17 0; #X connect 12 0 14 0; #X connect 13 0 15 0; #X connect 14 0 5 0; #X connect 15 0 5 0; #X connect 16 0 5 0; #X connect 17 0 5 0; #X connect 18 0 21 0; #X connect 18 1 21 1; #X connect 19 0 23 0; #X connect 20 0 18 0; #X connect 21 0 22 0; #X connect 22 0 5 0; #X connect 23 0 21 0; #X connect 23 1 21 2; #X connect 24 0 21 0; #X connect 25 0 21 0; #X connect 26 0 21 0; #X connect 27 0 21 0; #X connect 28 0 36 0; #X connect 29 0 28 0; #X connect 30 0 28 0; #X connect 34 0 39 0; #X connect 35 0 39 0; #X connect 36 0 5 0; #X connect 36 1 34 0; #X connect 36 2 35 0; #X connect 37 0 36 1; #X connect 38 0 71 0; #X connect 40 0 34 1; #X connect 41 0 35 1; #X connect 58 0 6 0; #X connect 59 0 40 0; #X connect 60 0 41 0; #X connect 62 0 35 2; #X connect 63 0 35 2; #X connect 64 0 35 2; #X connect 65 0 35 3; #X connect 66 0 35 3; #X connect 67 0 35 3; #X connect 69 0 19 0; #X connect 70 0 20 0; #X connect 71 0 31 0; #X connect 72 0 71 1; #X connect 73 0 72 0; #X connect 82 0 0 0; #X connect 83 0 5 0; #X connect 84 0 83 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_bqt-help.pd000066400000000000000000000050041266045153600213770ustar00rootroot00000000000000#N canvas 384 88 785 659 10; #X floatatom 88 211 5 0 0; #X msg 27 211 onep \$1; #X floatatom 88 242 5 0 0; #X msg 27 246 twop \$1; #X obj 454 406 t b f; #X floatatom 489 369 5 0 0; #X floatatom 488 317 5 0 0; #X obj 454 436 pack s 0 0; #X msg 454 469 \$1 \$2 \$3; #X obj 489 405 t b f; #X msg 410 370 lpf; #X msg 409 344 hpf; #X msg 409 398 apf; #X msg 409 425 bsf; #X obj 461 38 pdp_help_input; #X msg 461 13 start; #X msg 507 13 stop; #X obj 27 616 pdp_help_output; #X obj 461 93 pdp_route 3; #X obj 533 65 hdl 15 1 0 3 empty empty empty 0 -6 0 8 -262144 -1 -1 0; #X obj 40 540 r \$0-out; #X obj 558 231 s \$0-out; #X floatatom 490 157 5 0 0; #X floatatom 601 156 5 0 0; #X text 312 358 high pass; #X text 313 382 low pass; #X text 314 410 all pass; #X text 313 439 band stop; #X text 541 367 pole Q; #X text 99 31 it is a bit awkward to use directly; #X text 146 210 one pole filter; #X text 145 240 double one pole filter; #X msg 88 180 0.1; #X msg 502 133 0.5; #X msg 600 133 0.5; #X text 588 62 choose example here; #X text 93 91 "unstable" behaviour is possible; #X msg 490 347 0.1; #X msg 488 293 0.3; #X obj 27 590 pdp_gain; #X floatatom 118 564 5 0 0; #X msg 118 542 1; #X text 95 107 when frequency and Q are outside their; #X text 96 122 sensible ranges; #X text 264 342 set the filter type:; #X text 136 192 set the filter type:; #X text 538 319 (between 0 and 1 \, 0.5 = nyquist); #X text 540 333 comment; #X text 540 305 pole frequency; #X text 37 16 pdp_bqt: a temporal biquad filter; #X text 99 45 try one of the abstractions (pdp_motion_blur and; #X text 100 61 pdp_motion_phase); #X obj 434 190 pdp_motion_blur; #X obj 558 190 pdp_motion_phase; #X obj 27 499 pdp_bqt; #X msg 48 312 reset; #X text 95 313 reset state; #X connect 0 0 1 0; #X connect 1 0 54 0; #X connect 2 0 3 0; #X connect 2 0 3 0; #X connect 3 0 54 0; #X connect 4 0 7 0; #X connect 4 1 7 1; #X connect 5 0 9 0; #X connect 6 0 4 0; #X connect 7 0 8 0; #X connect 8 0 54 0; #X connect 9 0 7 0; #X connect 9 1 7 2; #X connect 10 0 7 0; #X connect 11 0 7 0; #X connect 12 0 7 0; #X connect 13 0 7 0; #X connect 14 0 18 0; #X connect 15 0 14 0; #X connect 16 0 14 0; #X connect 18 0 54 0; #X connect 18 1 52 0; #X connect 18 2 53 0; #X connect 19 0 18 1; #X connect 20 0 39 0; #X connect 22 0 52 1; #X connect 23 0 53 1; #X connect 32 0 0 0; #X connect 33 0 22 0; #X connect 34 0 23 0; #X connect 37 0 5 0; #X connect 38 0 6 0; #X connect 39 0 17 0; #X connect 40 0 39 1; #X connect 41 0 40 0; #X connect 52 0 21 0; #X connect 53 0 21 0; #X connect 54 0 39 0; #X connect 55 0 54 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_cheby-help.pd000066400000000000000000000041641266045153600217110ustar00rootroot00000000000000#N canvas 117 219 672 516 10; #X msg 67 108 coef 0 \$1; #X floatatom 67 84 5 0 0; #X floatatom 137 84 5 0 0; #X msg 137 108 coef 1 \$1; #X floatatom 206 83 5 0 0; #X msg 206 108 coef 2 \$1; #X floatatom 275 84 5 0 0; #X msg 275 108 coef 3 \$1; #X floatatom 243 359 5 0 0; #X text 122 394 creation arg: order (nb coefs = order + 1); #X text 123 410 (default = minimal order = 2); #X msg 243 309 reset; #X obj 21 46 pdp_help_input; #X msg 21 16 start; #X msg 70 16 stop; #X obj 21 445 pdp_help_output; #X text 296 359 right inlet: number of iterations; #X text 295 308 set all coefs to 0; #X msg 243 338 1; #X msg 243 267 chanmask \$1; #X floatatom 243 244 5 0 0; #X text 157 63 set individual coefficients; #N canvas 0 0 450 300 graph1 0; #X array mapping 64 float 1; #A 0 -0.908307 -0.86545 -0.794021 -0.76545 -0.694021 -0.622593 -0.451164 -0.0511646 0.234549 0.377406 0.427406 0.477406 0.520263 0.534549 0.548835 0.534549 0.505978 0.477406 0.448835 0.420264 0.348835 0.298835 0.148835 0.0845496 -0.0511645 -0.151164 -0.236879 -0.322593 -0.436878 -0.436878 -0.436878 -0.436878 -0.422593 -0.394021 -0.36545 -0.308307 -0.26545 -0.136879 0.120264 0.291692 0.434549 0.534549 0.591692 0.648835 0.677406 0.677406 0.663121 0.648835 0.648835 0.634549 0.605978 0.605978 0.605978 0.605978 0.605978 0.605978 0.634549 0.648835 0.677406 0.705978 0.76312 0.848835 0.934549 0.977406; #X coords 0 1 63 -1 200 140 1; #X restore 427 20 graph; #X msg 242 217 approx mapping; #X obj 21 158 pdp_t; #X text 418 165 -1 ----------- 0 ----------- 1; #X obj 242 190 spigot; #X obj 279 167 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 361 216 approximate a mapping function; #X obj 21 403 pdp_cheby 10; #X connect 0 0 29 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 3 0 29 0; #X connect 4 0 5 0; #X connect 5 0 29 0; #X connect 6 0 7 0; #X connect 7 0 29 0; #X connect 8 0 29 1; #X connect 11 0 29 0; #X connect 12 0 24 0; #X connect 13 0 12 0; #X connect 14 0 12 0; #X connect 18 0 8 0; #X connect 19 0 29 0; #X connect 20 0 19 0; #X connect 23 0 29 0; #X connect 24 0 29 0; #X connect 24 1 26 0; #X connect 26 0 23 0; #X connect 27 0 26 1; #X connect 29 0 15 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_chrot-help.pd000066400000000000000000000005251266045153600217330ustar00rootroot00000000000000#N canvas 355 66 554 208 10; #X obj 74 64 pdp_help_input; #X msg 74 31 start; #X msg 124 31 stop; #X obj 74 121 pdp_chrot; #X obj 74 157 pdp_help_output; #X floatatom 151 99 5 0 0; #X text 204 100 rotate the chroma components by this angle; #X connect 0 0 3 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 4 0; #X connect 5 0 3 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_cog-help.pd000066400000000000000000000020131266045153600213560ustar00rootroot00000000000000#N canvas 683 169 505 377 10; #X floatatom 146 142 5 0 0; #X floatatom 146 166 5 0 0; #X floatatom 146 190 5 0 0; #X floatatom 146 214 5 0 0; #X floatatom 146 239 5 0 0; #X text 32 12 pdp_cog: compute intensity \, center of gravity and standard deviation. (interpret an image as a gaussian blob).; #X text 201 215 standard deviation x; #X text 200 239 standard deviation y; #X obj 78 50 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 21 236 pdp_help_output; #X obj 78 73 pdp_help_input; #X text 200 141 average intensity; #X text 200 168 center of gravity x; #X text 200 190 center of gravity y; #X text 203 47 creation argument is threshold; #X obj 78 124 pdp_cog; #X floatatom 375 291 5 0 0; #X obj 226 317 pdp_cog_abs_thresh 0.1; #X text 87 342 the same \, but takes the absolute value and performs a thresholding operation; #X connect 8 0 10 0; #X connect 10 0 9 0; #X connect 10 0 15 0; #X connect 15 0 0 0; #X connect 15 1 1 0; #X connect 15 2 2 0; #X connect 15 3 3 0; #X connect 15 4 4 0; #X connect 16 0 17 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_constant-help.pd000066400000000000000000000012001266045153600224340ustar00rootroot00000000000000#N canvas 306 280 575 277 10; #X obj 46 231 pdp_help_output; #X obj 46 149 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 125 76 dim 320 240; #X text 221 76 set packet dimensions; #X msg 125 103 type grey; #X msg 125 126 type yv12; #X obj 46 198 pdp_constant; #X floatatom 125 172 5 0 0; #X text 221 105 generate greyscale image; #X text 221 124 generate colour image (default); #X text 221 174 set constant; #X text 118 26 pdp_constant creates an image filled with a constant when a bang is received; #X connect 1 0 6 0; #X connect 2 0 6 0; #X connect 4 0 6 0; #X connect 5 0 6 0; #X connect 6 0 0 0; #X connect 7 0 6 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_control-help.pd000066400000000000000000000035201266045153600222720ustar00rootroot00000000000000#N canvas 259 276 910 567 10; #X obj 143 325 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 143 415 pdp_control; #X msg 143 366 thread \$1; #X obj 48 54 pdp_help_input; #X msg 48 24 start; #X msg 105 24 stop; #X obj 48 205 pdp_help_output; #X obj 48 154 pdp_conv; #X floatatom 117 86 5 0 0; #X obj 46 361 osc~; #X floatatom 46 326 5 0 0; #X obj 46 430 osc~; #X floatatom 79 402 5 0 0; #X obj 46 460 dac~; #X obj 143 454 print; #X text 182 323 switch thread processing on or of; #X text 197 455 a pdp_drop message will be sent out; #X text 197 471 when a package is dropped; #X text 119 155 a convolution object to burn cycles; #X obj 666 254 pdp_control; #X msg 666 226 collectgarbage; #X obj 646 478 pdp_control; #X text 175 82 increase this with thread processing enabled \, no audio should be dropped. if you do it with thread processing disabled \, increasing it too much can lock up the machine when real time scheduling is enabled.; #X msg 646 452 memlimit \$1; #X msg 688 422 5e+07; #X msg 615 421 0; #X text 687 402 50M; #X text 613 401 off; #X text 472 178 free all unused packets. pdp's garbage collection is "lazy" meaning packets will only be freed when the maximum usage limit is reached.; #X text 179 25 pdp_control: fine tune the pdp system. (threads & memory). ; #X text 470 357 set the max memory usage limit for the packet pool. the default is off (value <= 0).; #X text 475 511 (this is a safety measure: in pdp it is easy to use too much memory \, i.e. with delay lines \, which will likely crash pd); #X connect 0 0 2 0; #X connect 1 0 14 0; #X connect 2 0 1 0; #X connect 3 0 7 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 7 0 6 0; #X connect 8 0 7 1; #X connect 9 0 11 0; #X connect 10 0 9 0; #X connect 11 0 13 0; #X connect 12 0 11 1; #X connect 20 0 19 0; #X connect 23 0 21 0; #X connect 24 0 23 0; #X connect 25 0 23 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_conv-help.pd000066400000000000000000000025211266045153600215570ustar00rootroot00000000000000#N canvas 450 114 702 535 10; #X obj 39 353 pdp_conv; #X floatatom 90 326 5 0 0; #X msg 87 195 hor \$1; #X msg 86 137 ver \$1; #X obj 87 170 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 1 ; #X obj 86 112 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 1 ; #X msg 89 264 vmask 0.25 0.5 0.25; #X msg 89 291 hmask 0.25 0.5 0.25; #X msg 88 239 vmask 0.25 -0.5 0.25; #X obj 39 63 pdp_help_input; #X msg 39 24 start; #X msg 86 24 stop; #X obj 39 480 pdp_help_output; #X obj 39 436 pdp_gain; #X floatatom 90 409 5 0 0; #X msg 90 386 1; #X text 162 327 right inlet sets number of iterations; #X text 263 239 these messages set the horizontal and vertical convolution masks. note that there is no support for 2 dimensional masks. if you want that you'll need to factor things out. (see the pdp_conv_* abstractions for examples); #X text 264 157 enable/disable horizontal and vertical masks; #X text 162 428 note: mask coefficents are between -1 and 1; #X text 162 441 use a gain object to compensate for this; #X msg 128 385 9; #X connect 0 0 13 0; #X connect 1 0 0 1; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 2 0; #X connect 5 0 3 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 13 0 12 0; #X connect 14 0 13 1; #X connect 15 0 14 0; #X connect 21 0 14 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_convert-help.pd000066400000000000000000000006711266045153600222760ustar00rootroot00000000000000#N canvas 556 468 575 277 10; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 225 pdp_help_output; #X obj 118 69 hdl 15 1 0 2 empty empty empty 0 -6 0 8 -262144 -1 -1 0; #X obj 46 90 pdp_route 2; #X obj 118 154 pdp_convert image/grey/*; #X text 307 153 convert a packet; #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 4 0 5 1; #X connect 5 0 3 0; #X connect 5 1 6 0; #X connect 6 0 3 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_del-help.pd000066400000000000000000000015401266045153600213560ustar00rootroot00000000000000#N canvas 414 20 609 368 10; #X floatatom 107 116 5 0 0 0 - - -; #X floatatom 64 207 5 0 0 0 - - -; #X obj 20 60 pdp_help_input; #X msg 20 31 start; #X msg 72 30 stop; #X obj 20 236 pdp_mix; #X obj 20 268 pdp_help_output; #X msg 64 183 0.5; #X text 164 116 right inlet sets current delay length; #X text 164 149 a packet delay line.; #X text 164 180 (dont make this too large \, packets are not compressed!) ; #X obj 42 147 pdp_del 50; #X text 164 165 first creation arg = max delay length; #X text 165 213 second creation arg: initial delay (default = max) ; #X obj 176 259 pdp_description; #X obj 176 285 print; #X msg 339 259 _debug; #X connect 0 0 11 1; #X connect 1 0 5 2; #X connect 2 0 5 0; #X connect 2 0 11 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 6 0; #X connect 7 0 1 0; #X connect 11 0 5 1; #X connect 11 0 14 0; #X connect 16 0 11 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_description-help.pd000066400000000000000000000013741266045153600231420ustar00rootroot00000000000000#N canvas 338 375 593 300 10; #X symbolatom 78 197 40 0 0; #X obj 78 46 pdp_noise; #X obj 78 23 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 183 44 pdp_noise; #X obj 183 21 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 183 71 pdp_grey; #X text 263 139 output packet description as a symbol; #X obj 288 44 pdp_noise; #X obj 288 21 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 -1; #X obj 288 71 pdp_mchp; #X floatatom 178 171 5 0 0; #X obj 78 118 pdp_reg; #X obj 78 142 pdp_description; #X connect 1 0 11 0; #X connect 2 0 1 0; #X connect 3 0 5 0; #X connect 4 0 3 0; #X connect 5 0 11 0; #X connect 7 0 9 0; #X connect 8 0 7 0; #X connect 9 0 11 0; #X connect 11 0 12 0; #X connect 12 0 0 0; #X connect 12 1 10 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_flip_lr-help.pd000066400000000000000000000004221266045153600222370ustar00rootroot00000000000000#N canvas 504 211 449 178 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 136 pdp_help_output; #X obj 77 101 pdp_flip_lr; #X text 222 101 flip left <-> right; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 3 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_flip_tb-help.pd000066400000000000000000000004221266045153600222270ustar00rootroot00000000000000#N canvas 504 211 449 178 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 136 pdp_help_output; #X obj 77 101 pdp_flip_tb; #X text 222 101 flip top <-> bottom; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 3 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_gain-help.pd000066400000000000000000000013121266045153600215250ustar00rootroot00000000000000#N canvas 444 413 538 379 10; #X msg 91 25 start; #X msg 139 25 stop; #X obj 91 56 pdp_help_input; #X obj 91 312 pdp_help_output; #X obj 91 236 pdp_gain; #X floatatom 142 207 5 0 0; #X text 201 205 right inlet sets overal gain; #X text 201 252 creation argument sets initial gain; #X text 200 270 (default = 1); #X text 202 236 pdp_gain clips when overdriven; #X msg 109 124 chanmask \$1; #X floatatom 109 100 5 0 0; #X text 203 124 set which channels are processed; #X text 203 140 using a binary mask. LSB = chan 0; #X text 203 157 default (any negative number) = all; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 3 0; #X connect 5 0 4 1; #X connect 10 0 4 0; #X connect 11 0 10 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_glx-help.pd000066400000000000000000000040131266045153600214020ustar00rootroot00000000000000#N canvas 251 11 708 682 10; #X msg 132 223 dim 320 240; #X msg 132 246 dim 640 480; #X text 300 227 dim sets the window dimensions; #X msg 131 151 create; #X msg 131 172 destroy; #X text 229 159 use these messages to explicitly create/destroy the window; #X msg 133 463 cursor \$1; #X obj 133 443 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 298 464 enables/disables cursor in xv window; #X obj 29 61 pdp_help_input; #X msg 29 25 start; #X msg 78 24 stop; #X text 295 200 specify the x window display; #X msg 131 197 display :0; #X obj 29 609 print; #X text 133 584 the output channel sends mouse event messages (press/release/drag and individual p/r/d for each button); #X msg 132 273 pos 100 100; #X text 300 273 set window position; #X msg 132 336 fullscreen; #X text 298 340 resize to entire screen; #X text 299 305 set both at once; #X msg 132 303 posdim 100 300 320 240; #X msg 131 417 tile 5 5 \$1 \$2; #X text 297 418 take a part of the screen (for tiling multiple pdp_xv's) ; #X obj 131 396 pack 0 0; #X obj 190 396 t b f; #X floatatom 131 377 5 0 0 0 - - -; #X floatatom 190 376 5 0 0 0 - - -; #X msg 134 489 movecursor 0.5 0.5; #X text 299 486 move the cursor inside the window; #X obj 29 573 pdp_glx; #X obj 134 512 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 134 532 interpol \$1; #X text 129 88 pdp_glx ouputs video in a window using the openGL extension on an X11 window system. if a pdp message is received and a window is not open \, one is created automaticly.; #X text 300 534 enable/disable interpolation; #X connect 0 0 30 0; #X connect 1 0 30 0; #X connect 3 0 30 0; #X connect 4 0 30 0; #X connect 6 0 30 0; #X connect 7 0 6 0; #X connect 9 0 30 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 13 0 30 0; #X connect 16 0 30 0; #X connect 18 0 30 0; #X connect 21 0 30 0; #X connect 22 0 30 0; #X connect 24 0 22 0; #X connect 25 0 24 0; #X connect 25 1 24 1; #X connect 26 0 24 0; #X connect 27 0 25 0; #X connect 28 0 30 0; #X connect 30 0 14 0; #X connect 31 0 32 0; #X connect 32 0 30 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_grey2mask-help.pd000066400000000000000000000013071266045153600225170ustar00rootroot00000000000000#N canvas 369 257 656 300 10; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 275 pdp_help_output; #X obj 90 146 pdp_grey2mask; #X obj 46 183 pdp_mul; #X obj 46 247 pdp_gain; #X floatatom 97 220 5 0 0; #X text 194 136 convert a grey scale image or the luma channel of a colour image to an image mask. (to be used for multiplication); #X obj 90 119 pdp_reg; #X obj 172 73 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 197 70 click here to propagate a new mask; #X connect 0 0 5 0; #X connect 0 0 9 1; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 4 0 5 1; #X connect 5 0 6 0; #X connect 6 0 3 0; #X connect 7 0 6 1; #X connect 9 0 4 0; #X connect 10 0 9 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_help_input.pd000066400000000000000000000044731266045153600220430ustar00rootroot00000000000000#N canvas 683 29 681 161 10; #X obj 23 524 pdp_v4l; #X text 17 11 this abstraction is used as an input module in most of the documentation patches. change it to reflect your preferred input object.; #X obj 262 234 inlet; #X msg 315 324 stop; #X obj 258 672 outlet; #X obj 262 385 metro; #X obj 292 360 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 -262144 -1 -1 100 256; #X msg 23 287 open /dev/video0; #X obj 260 88 loadbang; #X obj 199 169 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 315 167 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 171 189 connect here; #X text 291 187 connect here; #X obj 187 470 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 334 468 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 45 329 v4l device; #X text 18 312 change this to your; #X obj 260 137 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 262 426 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 520 308 change this to the movie; #X text 519 323 you want to use; #X msg 520 379 loop 1; #X msg 262 325 bang; #X text 163 203 for video4linux; #X text 294 201 for quicktime; #X text 156 497 connect here; #X text 148 511 for video4linux; #X text 302 497 connect here; #X text 305 511 for quicktime; #X text 308 377 set framerate here; #X obj 262 258 route start stop; #X obj 329 292 select 0; #X obj 262 292 select 1; #X msg 40 357 open /dev/video1; #X obj 247 601 pdp_noise; #X obj 268 523 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 236 552 connect here; #X text 239 566 for noise input; #X text 293 137 disconnect for noise input; #X obj 492 255 ggee/getdir; #X msg 492 288 open \$1/../../doc/media/midr-mjpeg.mov; #X obj 492 515 pdp_qt; #X connect 0 0 4 0; #X connect 2 0 30 0; #X connect 3 0 5 0; #X connect 5 0 18 0; #X connect 6 0 5 1; #X connect 7 0 0 0; #X connect 8 0 17 0; #X connect 9 0 7 0; #X connect 10 0 39 0; #X connect 13 0 0 0; #X connect 14 0 41 0; #X connect 17 0 10 0; #X connect 18 0 13 0; #X connect 21 0 41 0; #X connect 22 0 5 0; #X connect 30 0 22 0; #X connect 30 1 3 0; #X connect 30 2 32 0; #X connect 31 0 3 0; #X connect 32 0 22 0; #X connect 32 1 31 0; #X connect 33 0 0 0; #X connect 34 0 4 0; #X connect 35 0 34 0; #X connect 39 0 40 0; #X connect 40 0 21 0; #X connect 40 0 41 0; #X connect 41 0 4 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_help_output.pd000066400000000000000000000013001266045153600222260ustar00rootroot00000000000000#N canvas 116 376 510 304 10; #X obj 192 70 inlet; #X obj 59 178 pdp_xv; #X text 18 9 this abstraction is used as an output module in most of the documentation patches. change it to reflect your preferred output object.; #X obj 232 179 pdp_glx; #X text 31 201 X11 XVideo output; #X text 198 199 X11 openGL output; #X text 60 217 (linux); #X text 199 214 (linux \, mesa \, osx); #X obj 192 98 pdp_route 3; #X msg 34 128 display :0; #X obj 264 69 hradio 15 1 1 3 empty empty empty 0 -6 0 8 -262144 -1 -1 1; #X obj 388 180 pdp_sdl; #X text 378 199 SDL output; #X text 386 216 (linux); #X connect 0 0 8 0; #X connect 8 0 1 0; #X connect 8 1 3 0; #X connect 8 2 11 0; #X connect 9 0 1 0; #X connect 10 0 8 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_histo-help.pd000066400000000000000000000017671266045153600217530ustar00rootroot00000000000000#N canvas 594 324 616 432 10; #X msg 87 208 size \$1; #X floatatom 87 184 5 0 0; #N canvas 0 0 450 300 graph2 0; #X array array1 64 float 0; #X coords 0 1 63 -1 200 140 1; #X restore 390 32 graph; #X obj 127 47 pdp_help_input; #X obj 127 113 pdp_help_output; #X obj 127 77 pdp_gain; #X floatatom 251 50 5 0 0; #X obj 127 23 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X msg 86 271 array array1; #X floatatom 155 183 5 0 0; #X msg 155 207 scale \$1; #X text 37 355 the size is rounded to the next power of 2; #X text 36 373 first argument is size \, second is optional scaling factor.; #X text 37 338 create a histogram from an image and send to a table ; #X floatatom 229 183 5 0 0; #X msg 229 207 samplesize \$1; #X obj 19 299 pdp_histo array1 64 10; #X connect 0 0 16 0; #X connect 1 0 0 0; #X connect 3 0 5 0; #X connect 5 0 4 0; #X connect 5 0 16 0; #X connect 6 0 5 1; #X connect 7 0 3 0; #X connect 8 0 16 0; #X connect 9 0 10 0; #X connect 10 0 16 0; #X connect 14 0 15 0; #X connect 15 0 16 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_hthresh-help.pd000066400000000000000000000011671266045153600222640ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 296 pdp_gain; #X msg 128 268 1; #X floatatom 160 199 5 0 0; #X text 234 283 (-t > x > t) -> 0; #X text 234 248 ( x > t) -> x; #X text 234 266 (-t > x) -> x; #X text 233 230 hard threshold; #X obj 77 231 pdp_hthresh; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 14 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 3 0; #X connect 8 0 7 1; #X connect 9 0 14 1; #X connect 14 0 7 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_loop-help.pd000066400000000000000000000032251266045153600215650ustar00rootroot00000000000000#N canvas 427 312 733 458 10; #X obj 32 85 metro 40; #X obj 17 59 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 152 393 pdp_loop 25; #X msg 275 109 record; #X floatatom 83 58 5 0 0; #X msg 39 58 stop; #X floatatom 274 363 5 0 0; #X floatatom 274 338 5 0 0; #X msg 275 82 store \$1; #X floatatom 275 57 5 0 0; #X msg 274 158 stop; #X obj 152 428 pdp_help_output; #X obj 152 87 pdp_help_input; #X msg 152 59 start; #X msg 199 59 stop; #X text 365 325 set playback position; #X text 372 345 hot; #X text 369 362 cold; #X text 365 159 stop recording; #X text 366 107 start recording at position 0; #X text 365 82 store a single packet at an arbitrary position; #X text 154 33 source playback; #X text 16 34 loop playback; #X text 272 393 creation arg: loop size; #X msg 275 132 record 10 2; #X text 365 133 start recording at position 10 \, recording 2 packets ; #X msg 274 209 loop \$1; #X obj 274 188 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 365 210 looping on/off; #X msg 274 310 0; #X msg 274 273 size \$1; #X floatatom 274 249 5 0 0; #X text 366 270 set a new loop size. (don't make this too large); #X msg 561 356 collectgarbage; #X obj 561 387 pdp_control; #X msg 546 329 thread 1; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 2 0 11 0; #X connect 3 0 2 0; #X connect 4 0 0 1; #X connect 5 0 0 0; #X connect 6 0 2 1; #X connect 7 0 2 0; #X connect 8 0 2 0; #X connect 9 0 8 0; #X connect 10 0 2 0; #X connect 12 0 2 0; #X connect 13 0 12 0; #X connect 14 0 12 0; #X connect 24 0 2 0; #X connect 26 0 2 0; #X connect 27 0 26 0; #X connect 29 0 7 0; #X connect 30 0 2 0; #X connect 31 0 30 0; #X connect 33 0 34 0; #X connect 35 0 34 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_metro~-help.pd000066400000000000000000000012531266045153600221370ustar00rootroot00000000000000#N canvas 0 0 450 300 10; #X obj 133 102 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 133 210 pdp_help_output; #X msg 210 66 fps 25; #X text 322 60 PAL; #X msg 211 94 fps 2997 100; #X text 322 94 NTSC; #X text 18 13 Audio/Video sync object. Will output bangs at desired frequency (fps) \, synced to the audio sampling rate. The fps message accepts either an integer or a fractional number.; #X msg 316 204 \; pd dsp \$1; #X obj 316 170 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 133 175 pdp_v4l; #X obj 133 139 pdp_metro~; #X connect 0 0 10 0; #X connect 2 0 10 0; #X connect 4 0 10 0; #X connect 8 0 7 0; #X connect 9 0 1 0; #X connect 10 0 9 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_mix-help.pd000066400000000000000000000010611266045153600214050ustar00rootroot00000000000000#N canvas 314 353 576 288 10; #X obj 103 132 pdp_reg; #X obj 201 86 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 200 155 5 0 0; #X obj 81 48 pdp_help_input; #X msg 81 18 start; #X msg 130 18 stop; #X obj 81 238 pdp_help_output; #X text 268 80 click here; #X obj 81 184 pdp_mix; #X text 268 159 crossfade between 2 packets; #X text 268 175 0 = left inlet \, 1 = middle inlet; #X connect 0 0 8 1; #X connect 1 0 0 0; #X connect 2 0 8 2; #X connect 3 0 0 1; #X connect 3 0 8 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 8 0 6 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_mix2-help.pd000066400000000000000000000012321266045153600214670ustar00rootroot00000000000000#N canvas 314 353 576 288 10; #X obj 98 132 pdp_reg; #X obj 201 86 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 205 138 5 0 0; #X obj 81 48 pdp_help_input; #X msg 81 18 start; #X msg 130 18 stop; #X obj 81 238 pdp_help_output; #X text 268 80 click here; #X obj 81 201 pdp_mix2; #X floatatom 205 161 5 0 0; #X text 158 199 pdp_mix2 adds two packets after applying attenuation ; #X text 268 136 left packet attenuation; #X text 268 159 right packet attenuation; #X connect 0 0 8 1; #X connect 1 0 0 0; #X connect 2 0 8 2; #X connect 3 0 0 1; #X connect 3 0 8 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 8 0 6 0; #X connect 9 0 8 3; pdp-0.14.1+darcs20180201/doc/objects/pdp_mul-help.pd000066400000000000000000000012661266045153600214140ustar00rootroot00000000000000#N canvas 224 229 462 390 10; #X msg 130 53 start; #X msg 177 53 stop; #X obj 130 85 pdp_help_input; #X obj 130 345 pdp_help_output; #X obj 174 179 pdp_reg; #X obj 248 142 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 281 140 click here; #X obj 130 310 pdp_gain; #X floatatom 181 282 5 0 0; #X text 282 216 multiplies 2 packets; #X obj 130 212 pdp_mul; #X msg 181 256 2; #X floatatom 40 150 5 0 0; #X msg 40 177 chanmask \$1; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 10 0; #X connect 2 0 4 1; #X connect 4 0 10 1; #X connect 5 0 4 0; #X connect 7 0 3 0; #X connect 8 0 7 1; #X connect 10 0 7 0; #X connect 11 0 8 0; #X connect 12 0 13 0; #X connect 13 0 10 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_netsend-help.pd000066400000000000000000000033011266045153600222470ustar00rootroot00000000000000#N canvas 236 47 523 395 10; #X obj 174 74 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 155 43 metro 40; #X obj 155 18 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 167 171 pdp_convert bitmap/yv12/*; #X floatatom 238 20 5 0 0 0 - - -; #X msg 263 132 sleepgrain \$1; #X floatatom 263 112 5 0 0 0 - - -; #X floatatom 308 74 5 0 0 0 - - -; #X msg 308 94 udpsize \$1; #X obj 295 44 hsl 128 15 1024 60000 1 0 empty empty empty -2 -6 0 8 -262144 -1 -1 4000 1; #X msg 339 161 sleep \$1; #X obj 379 136 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X floatatom 327 200 5 0 0 0 - - -; #X msg 327 220 sleepperiod \$1; #X msg 16 13 connect acer 7777; #X obj 124 212 pdp_netsend; #X msg 324 15 1472; #X msg 211 81 dim 160 120; #X msg 212 62 dim 320 240; #X msg 18 44 connect localhost 7777; #X obj 65 247 pdp_netreceive 7777; #X obj 78 275 pdp_glx; #X obj 123 136 pdp_route; #X obj 203 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X floatatom 281 248 5 0 0 0 - - -; #X msg 281 268 timeout \$1; #X obj 154 103 pdp_v4l; #X obj 132 275 pdp_glx; #X text 97 334 this is still experimental (SIGSEGVs ahead); #X connect 0 0 26 0; #X connect 1 0 26 0; #X connect 2 0 1 0; #X connect 3 0 15 0; #X connect 4 0 1 1; #X connect 5 0 15 0; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 15 0; #X connect 9 0 7 0; #X connect 10 0 15 0; #X connect 11 0 10 0; #X connect 12 0 13 0; #X connect 13 0 15 0; #X connect 14 0 15 0; #X connect 16 0 8 0; #X connect 17 0 26 0; #X connect 18 0 26 0; #X connect 19 0 15 0; #X connect 20 0 21 0; #X connect 22 0 15 0; #X connect 22 1 3 0; #X connect 23 0 22 1; #X connect 24 0 25 0; #X connect 25 0 15 0; #X connect 26 0 22 0; #X connect 26 0 27 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_noise-help.pd000066400000000000000000000014161266045153600217310ustar00rootroot00000000000000#N canvas 0 33 718 415 10; #X obj 46 231 pdp_help_output; #X obj 46 198 pdp_noise; #X obj 46 149 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 174 71 dim 320 240; #X text 270 71 set packet dimensions; #X msg 174 98 type grey; #X msg 174 121 type yv12; #X text 270 100 generate greyscale; #X text 270 119 generate colour (default); #X msg 174 152 seed 123; #X text 270 152 set seed value; #X text 167 21 pdp_noise creates a random image (with uniform distribution between -1 and 1) when a bang is received; #X obj 46 110 metro 40; #X obj 46 79 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1 ; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 5 0 1 0; #X connect 6 0 1 0; #X connect 9 0 1 0; #X connect 12 0 2 0; #X connect 13 0 12 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_not-help.pd000066400000000000000000000007351266045153600214170ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 231 pdp_not; #X text 229 235 bitwise not; #X obj 77 296 pdp_gain; #X msg 128 268 1; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 7 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 9 0; #X connect 9 0 3 0; #X connect 10 0 9 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_or-help.pd000066400000000000000000000011041266045153600212260ustar00rootroot00000000000000#N canvas 552 356 511 383 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 322 pdp_help_output; #X obj 114 246 pdp_reg; #X obj 196 183 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 229 181 click here; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 279 pdp_or; #X text 229 283 bitwise or; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 7 0; #X connect 4 0 10 1; #X connect 5 0 4 0; #X connect 7 0 4 1; #X connect 7 0 10 0; #X connect 8 0 7 1; #X connect 9 0 8 0; #X connect 10 0 3 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_plasma-help.pd000066400000000000000000000015571266045153600220770ustar00rootroot00000000000000#N canvas 655 0 575 333 10; #X obj 46 262 pdp_help_output; #X obj 46 149 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 174 71 dim 320 240; #X text 270 71 set packet dimensions; #X msg 174 98 type grey; #X msg 174 121 type yv12; #X text 270 100 generate greyscale; #X text 270 119 generate colour (default); #X msg 174 152 seed 123; #X text 270 152 set seed value; #X text 167 21 pdp_noise creates a random image (with uniform distribution between -1 and 1) when a bang is received; #X obj 46 198 pdp_plasma; #X floatatom 174 176 5 0 0 0 - - -; #X text 270 176 turbulence; #X obj 46 241 pdp_reg; #X obj 113 221 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X connect 1 0 11 0; #X connect 2 0 11 0; #X connect 4 0 11 0; #X connect 5 0 11 0; #X connect 8 0 11 0; #X connect 11 0 14 0; #X connect 12 0 11 1; #X connect 14 0 0 0; #X connect 15 0 14 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_pointcloud-help.pd000066400000000000000000000016331266045153600227750ustar00rootroot00000000000000#N canvas 462 571 450 371 10; #X obj 40 94 pdp_help_input; #X obj 40 36 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 40 174 pdp_help_output; #X text 111 11 convert an image to a point cloud; #X text 111 43 creation argument is number of points; #X text 111 26 (containing the points with highest intesity); #X floatatom 168 114 5 0 0; #X text 219 114 <- nb points; #X obj 40 140 pdp_pointcloud 10; #X floatatom 265 151 5 0 0; #X msg 267 174 nbclusters \$1; #X obj 180 216 pdp_description; #X obj 180 243 print; #X obj 35 296 pdp_glx; #X obj 39 221 pdp_m_mm A A^T; #X obj 34 273 pdp_scale 64 64; #X obj 34 252 pdp_convert image/*/*; #X connect 0 0 8 0; #X connect 1 0 0 0; #X connect 6 0 8 1; #X connect 8 0 2 0; #X connect 8 1 11 0; #X connect 8 1 14 1; #X connect 8 1 14 0; #X connect 9 0 10 0; #X connect 10 0 8 0; #X connect 11 0 12 0; #X connect 14 0 16 0; #X connect 15 0 13 0; #X connect 16 0 15 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_positive-help.pd000066400000000000000000000013041266045153600224520ustar00rootroot00000000000000#N canvas 479 219 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X floatatom 128 135 5 0 0; #X obj 77 296 pdp_gain; #X msg 145 271 1; #X obj 77 231 pdp_positive; #X text 224 230 test positive and return a bitmask; #X text 225 245 >= 0 -> all one / < 0 -> all zero; #X text 223 264 to use in conjunction with logic ops; #X obj 77 268 pdp_xor; #X obj 277 146 pdp_cheby; #X obj 77 163 pdp_offset; #X msg 128 109 -0.5; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 11 1; #X connect 2 0 13 0; #X connect 4 0 13 1; #X connect 5 0 3 0; #X connect 6 0 5 1; #X connect 7 0 11 0; #X connect 11 0 5 0; #X connect 13 0 7 0; #X connect 14 0 4 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_qt-help.pd000066400000000000000000000043131266045153600212370ustar00rootroot00000000000000#N canvas 400 126 740 623 10; #X obj 59 391 pdp_qt; #X floatatom 77 429 5 0 0; #X floatatom 127 430 5 0 0; #X obj 56 41 metro 40; #X msg 56 13 bang; #X msg 97 13 stop; #X msg 15 13 bang; #X obj 140 41 openpanel; #X msg 140 66 open \$1; #X msg 140 13 bang; #X msg 140 92 close; #X text 249 66 open/close for file access; #X floatatom 140 120 5 0 0; #X floatatom 140 146 5 0 0; #X text 248 117 float on left inlet selects a frame for output; #X msg 140 197 loop \$1; #X obj 203 182 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 250 198 automatic looping can be enabled/disabled; #X text 251 9 pdp_qt plays a quicktime movie.; #X text 250 221 this enables automatic playback at the frame rate specified in the movie file. in pdp_qt~ playback is synchronized to the audio stream.; #X msg 142 341 dump array 0; #X text 252 330 if the movie contains audio \, this command dumps the audio data into an array specified by the first argument. the second argument is the audio channel (default = 0 = left); #X msg 142 291 stop; #X text 251 289 stops automatic playback (same as autoplay 0); #X msg 141 222 autoplay 1; #X msg 142 267 play; #X text 252 432 the second outlet outputs the current frame number. the third outlet outputs the total number of frames in a movie when it is opened.; #X msg 142 315 cont; #X text 251 269 starts automatic playback (same as 0 \, autplay 1 \, bang); #X text 251 310 resumes automatic playback (same as autplay 1 \, bang) ; #X text 249 137 float on right inlet selects the frame to be read on the next sync event (bang message / internal sync).; #X obj 59 462 pdp_help_output; #X obj 335 535 table array; #X obj 448 535 tabplay~ array; #X obj 448 576 dac~; #X obj 448 506 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X connect 0 0 31 0; #X connect 0 1 1 0; #X connect 0 2 2 0; #X connect 3 0 0 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 0 0; #X connect 7 0 8 0; #X connect 8 0 0 0; #X connect 9 0 7 0; #X connect 10 0 0 0; #X connect 12 0 0 0; #X connect 13 0 0 1; #X connect 15 0 0 0; #X connect 16 0 15 0; #X connect 20 0 0 0; #X connect 22 0 0 0; #X connect 24 0 0 0; #X connect 25 0 0 0; #X connect 27 0 0 0; #X connect 33 0 34 0; #X connect 33 0 34 1; #X connect 35 0 33 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_qt~-help.pd000066400000000000000000000014321266045153600214340ustar00rootroot00000000000000#N canvas 400 126 692 254 10; #X obj 62 122 pdp_qt~; #X obj 90 164 dac~; #X msg 39 51 play; #X obj 133 42 openpanel; #X msg 133 67 open \$1; #X msg 133 14 bang; #X text 257 67 pdp_qt~ is the same as pdp_qt exept that it also outputs the audio data corresponding to the current frame on its 2 rightmost outlets. if there is a lag between audio and video a pdp_del object can be inserted to delay the image. note that in order to get acceptable audio quality with relatively few dropouts you might need to increase the pd audio latency.; #X msg 15 24 loop 1; #X floatatom 84 52 5 0 0; #X obj 62 214 pdp_help_output; #X connect 0 0 9 0; #X connect 0 3 1 0; #X connect 0 4 1 1; #X connect 2 0 0 0; #X connect 3 0 4 0; #X connect 4 0 0 0; #X connect 5 0 3 0; #X connect 7 0 0 0; #X connect 8 0 0 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_randmix-help.pd000066400000000000000000000012301266045153600222500ustar00rootroot00000000000000#N canvas 314 353 584 288 10; #X obj 81 184 pdp_randmix; #X obj 117 132 pdp_reg; #X obj 200 87 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 200 155 5 0 0; #X obj 81 48 pdp_help_input; #X msg 81 18 start; #X msg 130 18 stop; #X obj 81 238 pdp_help_output; #X text 268 80 click here; #X text 268 159 random crossfade between 2 packets; #X text 268 175 0 = left \, 1 = right; #X obj 203 125 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 6100 1; #X connect 0 0 7 0; #X connect 1 0 0 1; #X connect 2 0 1 0; #X connect 3 0 0 2; #X connect 4 0 0 0; #X connect 4 0 1 1; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 11 0 3 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_rawin-help.pd000066400000000000000000000024031266045153600217310ustar00rootroot00000000000000#N canvas 504 520 841 405 10; #X msg 103 130 open /tmp/otherpipe; #X msg 403 219 open; #X text 135 173 set type (how to interpret raw data); #X obj 75 307 pdp_help_output; #X text 442 219 open default pipe; #X text 143 258 creation args: ; #X obj 371 280 print done; #X text 236 306 2nd outlet: bang if pipe is closed; #X text 249 131 open any pipe for reading; #X msg 118 152 close; #X text 164 152 close pipe; #X obj 403 199 spigot; #X obj 439 178 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 137 191 type bitmap/rgb/320x240; #X obj 103 236 pdp_rawin /tmp/pipe image/grey/320x240; #X text 102 19 pdp_rawin: read raw data from a pipe (or file); #X obj 64 73 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 64 96 sync \$1; #X obj 10 194 metro 40; #X obj 10 173 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X text 237 322 connect to [open< to ensure pipe stays open \, or file loops.; #X text 130 96 synchronize to pipe (1) or bang (0 = default); #X connect 0 0 14 0; #X connect 1 0 14 0; #X connect 9 0 14 0; #X connect 11 0 1 0; #X connect 12 0 11 1; #X connect 13 0 14 0; #X connect 14 0 3 0; #X connect 14 1 6 0; #X connect 14 1 11 0; #X connect 16 0 17 0; #X connect 17 0 14 0; #X connect 18 0 14 0; #X connect 19 0 18 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_rawout-help.pd000066400000000000000000000015431266045153600221360ustar00rootroot00000000000000#N canvas 254 556 687 380 10; #X msg 132 63 open /tmp/otherpipe; #X msg 177 145 open; #X text 216 145 open default pipe; #X obj 132 219 print done; #X text 117 266 connect to [open< to ensure pipe stays open; #X text 278 64 open any pipe for reading; #X msg 147 85 close; #X text 193 85 close pipe; #X obj 177 125 spigot; #X obj 230 124 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X text 134 15 pdp_rawout: write raw data to a pipe (or file); #X text 293 169 creation args: ; #X obj 132 169 pdp_rawout /tmp/pipe; #X obj 15 124 pdp_help_input; #X obj 15 98 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X text 116 250 outlet: bang if pipe is closed; #X connect 0 0 12 0; #X connect 1 0 12 0; #X connect 6 0 12 0; #X connect 8 0 1 0; #X connect 9 0 8 1; #X connect 12 0 3 0; #X connect 12 0 8 0; #X connect 13 0 12 0; #X connect 14 0 13 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_reg-help.pd000066400000000000000000000022221266045153600213650ustar00rootroot00000000000000#N canvas 327 276 676 444 10; #X obj 41 318 pdp_reg; #X obj 41 287 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X msg 85 15 start; #X msg 135 15 stop; #X obj 85 53 pdp_help_input; #X obj 41 359 pdp_help_output; #X text 121 90 pdp_reg works in the same way as the pd float or int objects; #X text 271 124 bang: sends stored packet to output; #X text 271 109 pdp: stores packet and sends to output; #X text 271 145 pdp: stores a new packet; #X text 121 111 left intlet (hot):; #X text 120 145 right intlet (cold):; #X msg 122 236 load_png \$1; #X obj 122 212 openpanel; #X obj 122 190 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 219 189 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 219 235 save_png \$1; #X text 331 226 as a png image file.; #X text 332 211 you can save the contents of the register; #X obj 219 211 savepanel; #X msg 219 266 save_png /tmp/snap.png; #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 4 0; #X connect 3 0 4 0; #X connect 4 0 0 1; #X connect 12 0 0 0; #X connect 13 0 12 0; #X connect 14 0 13 0; #X connect 15 0 19 0; #X connect 16 0 0 0; #X connect 19 0 16 0; #X connect 20 0 0 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_rotate-help.pd000066400000000000000000000014231266045153600221100ustar00rootroot00000000000000#N canvas 467 414 562 448 10; #X msg 195 174 centerx \$1; #X floatatom 195 145 5 0 0; #X floatatom 279 145 5 0 0; #X msg 279 174 centery \$1; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 401 pdp_help_output; #X text 194 70 (0 \, 0) = top left; #X text 194 84 (1 \, 1) = bottom right; #X msg 247 113 0.5; #X floatatom 187 318 5 0 0; #X msg 187 288 0; #X text 192 6 pdp_zrot: zoom and rotation; #X obj 46 363 pdp_rotate; #X text 239 319 right inlet sets rotation angle; #X text 194 54 set rotation center; #X connect 0 0 14 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 3 0 14 0; #X connect 4 0 14 0; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 10 0 1 0; #X connect 10 0 2 0; #X connect 11 0 14 1; #X connect 12 0 11 0; #X connect 14 0 7 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_route-help.pd000066400000000000000000000011241266045153600217460ustar00rootroot00000000000000#N canvas 614 448 575 277 10; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 225 pdp_help_output; #X obj 46 172 pdp_gain 1; #X obj 130 172 pdp_gain 2; #X obj 118 69 hdl 15 1 0 2 empty empty empty 0 -6 0 8 -262144 -1 -1 0; #X text 155 88 routes a packet to a specified outlet \, determined by the right inlet; #X text 155 124 creation argument = number of outlets (default = 2) ; #X obj 46 90 pdp_route 2; #X connect 0 0 9 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 9 1; #X connect 9 0 4 0; #X connect 9 1 5 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_scale-help.pd000066400000000000000000000017061266045153600217050ustar00rootroot00000000000000#N canvas 475 141 635 386 10; #X msg 76 207 dim 256 256; #X msg 76 235 dim 320 240; #X obj 28 275 pdp_scale 320 240; #X msg 75 181 dim 32 32; #X msg 259 234 quality \$1; #X obj 28 65 pdp_help_input; #X msg 28 36 start; #X msg 80 35 stop; #X obj 28 317 pdp_help_output; #X text 347 225 0 = nearest neighbour; #X text 347 240 1 = bilinear; #X text 74 154 set new packet dimensions; #X text 161 28 pdp_scale rescales the packet format.; #X text 161 56 use this if you want to combine different packet sizes. or have movies that don't have a legal size (not a multiple of 8x8) ; #X msg 259 204 0; #X msg 294 204 1; #X text 159 103 (try to avoid rescaling by using movies with equal (legal) dimensions \, it is not a cheap operation and can easily be done in advance); #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 8 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 6 0 5 0; #X connect 7 0 5 0; #X connect 14 0 4 0; #X connect 15 0 4 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_scanxy~-help.pd000066400000000000000000000040321266045153600223140ustar00rootroot00000000000000#N canvas 362 152 806 785 10; #X floatatom 73 226 5 0 0; #X obj 73 602 dac~; #X obj 13 48 pdp_help_input; #X msg 13 19 start; #X obj 13 632 pdp_help_output; #X obj 73 546 *~; #X floatatom 89 517 5 0 0; #X obj 73 486 hip~ 20; #X floatatom 117 459 5 0 0; #X floatatom 131 406 5 0 0; #X obj 73 433 lop~ 1000; #X msg 222 342 interpolate \$1; #X obj 222 316 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X text 251 313 set interpolation between consecutive packets on/off ; #X text 216 377 (the audio crossfade size is determined by the pd blocksize. so you can use a block~ object to set this); #X obj 73 375 pdp_scanxy~; #X floatatom 145 228 5 0 0; #X floatatom 73 146 5 0 0; #X msg 224 225 0; #X msg 255 225 0.25; #X obj 224 197 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 61 20 stop; #X obj 13 96 pdp_blur; #X floatatom 58 72 5 0 0; #X floatatom 161 167 5 0 0; #X obj 145 198 * 1; #X text 220 46 pdp_scanxy~: scanned synthesis with coordinate input. (0 \, 0) = top left \, (1 \, 1) = bottom right; #X obj 73 267 osc~; #X obj 145 266 osc~; #X text 223 164 set frequency ratio for lissajous path; #X text 250 196 resync phase; #X obj 73 293 *~ 0.5; #X obj 145 293 *~ 0.5; #X obj 73 318 +~ 0.5; #X obj 145 318 +~ 0.5; #X text 220 87 the waveform is scanned from the luma plane of an image. the path is determined by the left(x) and right(y) coordinate inlets. ; #X connect 0 0 27 0; #X connect 2 0 22 0; #X connect 3 0 2 0; #X connect 5 0 1 0; #X connect 5 0 1 1; #X connect 6 0 5 1; #X connect 7 0 5 0; #X connect 8 0 7 1; #X connect 9 0 10 1; #X connect 10 0 7 0; #X connect 11 0 15 0; #X connect 12 0 11 0; #X connect 15 0 10 0; #X connect 16 0 28 0; #X connect 17 0 0 0; #X connect 17 0 25 0; #X connect 18 0 27 1; #X connect 19 0 28 1; #X connect 20 0 18 0; #X connect 20 0 19 0; #X connect 21 0 2 0; #X connect 22 0 4 0; #X connect 22 0 15 0; #X connect 23 0 22 1; #X connect 24 0 25 1; #X connect 25 0 16 0; #X connect 27 0 31 0; #X connect 28 0 32 0; #X connect 31 0 33 0; #X connect 32 0 34 0; #X connect 33 0 15 0; #X connect 34 0 15 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_scan~-help.pd000066400000000000000000000022661266045153600217420ustar00rootroot00000000000000#N canvas 387 370 666 499 10; #X obj 73 140 pdp_scan~; #X obj 73 113 phasor~; #X floatatom 73 86 5 0 0; #X obj 73 353 dac~; #X obj 13 48 pdp_help_input; #X msg 13 19 start; #X obj 13 397 pdp_help_output; #X obj 73 311 *~; #X floatatom 89 282 5 0 0; #X obj 73 251 hip~ 20; #X floatatom 117 224 5 0 0; #X floatatom 131 171 5 0 0; #X obj 73 198 lop~ 1000; #X msg 217 102 interpolate \$1; #X obj 217 76 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 216 124 set interpolation between consecutive packets on/off ; #X text 216 142 (the audio crossfade size is determined by the pd blocksize. so you can use a block~ object to set this); #X text 218 236 the waveform is scanned from the luma plane of an image. the path is an oval centered at the middle of the image with axes equal to 60% of the image width/height.; #X text 214 43 pdp_scan~: oval scanned synthesis with a phase input ; #X connect 0 0 12 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 4 0 0 0; #X connect 4 0 6 0; #X connect 5 0 4 0; #X connect 7 0 3 0; #X connect 7 0 3 1; #X connect 8 0 7 1; #X connect 9 0 7 0; #X connect 10 0 9 1; #X connect 11 0 12 1; #X connect 12 0 9 0; #X connect 13 0 0 0; #X connect 14 0 13 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_scope~-help.pd000066400000000000000000000011411266045153600221160ustar00rootroot00000000000000#N canvas 526 43 567 300 10; #X obj 37 200 pdp_scope~; #X obj 37 44 metro 40; #X obj 37 19 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 94 18 5 0 0; #X msg 131 131 type grey; #X msg 131 109 type yv12; #X obj 37 256 pdp_help_output; #X msg 131 157 dim 320 240; #X obj 59 121 osc~; #X floatatom 59 88 5 0 0; #X text 131 66 a very simple oscilloscope; #X text 227 132 set output image type and dimensions; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 1 1; #X connect 4 0 0 0; #X connect 5 0 0 0; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 8 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_sign-help.pd000066400000000000000000000011061266045153600215500ustar00rootroot00000000000000#N canvas 479 219 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X floatatom 128 135 5 0 0; #X obj 77 296 pdp_gain; #X msg 145 271 1; #X msg 128 109 -0.5; #X obj 77 231 pdp_sign; #X text 239 231 get the sign (-1 \, 1); #X obj 77 268 pdp_mul; #X obj 77 163 pdp_gain; #X obj 173 207 pdp_abs; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 10 1; #X connect 2 0 11 0; #X connect 4 0 11 1; #X connect 5 0 3 0; #X connect 6 0 5 1; #X connect 7 0 4 0; #X connect 8 0 10 0; #X connect 10 0 5 0; #X connect 11 0 8 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_snap-help.pd000066400000000000000000000011351266045153600215530ustar00rootroot00000000000000#N canvas 623 480 596 300 10; #X msg 92 15 start; #X msg 142 15 stop; #X obj 92 53 pdp_help_input; #X obj 41 240 pdp_help_output; #X text 140 172 bang: sends stored packet to output; #X text 113 143 left intlet (hot):; #X text 112 202 right intlet (cold):; #X obj 41 171 pdp_snap; #X text 115 103 pdp_reg takes a snapshot from a pdp stream.; #X text 263 201 pdp inlet; #X text 139 157 snap: stores the next packet that arrives on second inlet; #X msg 8 130 bang; #X msg 49 130 snap; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 7 1; #X connect 7 0 3 0; #X connect 11 0 7 0; #X connect 12 0 7 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_sthresh-help.pd000066400000000000000000000012011266045153600222640ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 296 pdp_gain; #X msg 128 268 1; #X obj 77 231 pdp_sthresh; #X floatatom 160 199 5 0 0; #X text 233 230 soft threshold; #X text 234 283 (-t > x > t) -> 0; #X text 234 266 (-t > x) -> (x + t); #X text 234 248 ( x > t) -> (x - t); #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 9 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 3 0; #X connect 8 0 7 1; #X connect 9 0 7 0; #X connect 10 0 9 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_trigger-help.pd000066400000000000000000000045661266045153600222700ustar00rootroot00000000000000#N canvas 218 0 631 489 10; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 179 pdp_help_output; #X obj 46 102 pdp_trigger; #X text 163 98 default behaviour is to outputs bang on the right output before sending packet to the left output; #X obj 118 146 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 45 269 pdp_noise; #X obj 45 245 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 45 294 pdp_trigger bang pdp bang bang pdp; #X obj 45 460 print o1; #X obj 278 326 print o5; #X obj 161 388 print o3; #X obj 103 429 print o2; #X obj 219 354 print o4; #X text 163 57 pdp_trigger behaves very much like the pd trigger object ; #X text 162 243 you can give it pdp (p) or bang (b) arguments to send out packets or bangs from right to left; #X obj 365 406 pdp_t b p b b p; #X text 325 386 there is also a short version:; #X text 142 565 confusing note:; #X obj 46 575 pdp_noise; #X obj 46 551 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 46 604 pdp_add; #X obj 61 746 pdp_noise; #X obj 61 722 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 61 806 pdp_add; #X obj 105 776 pdp_gain; #X text 142 584 you don't need a trigger object if you connect a pdp object's outlet to only one active inlet.; #X text 139 657 if an outlet is connected to more than one active inlet \, you need a trigger object like you would do with standard pd message objects; #X obj 285 725 pdp_noise; #X obj 285 701 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 285 806 pdp_add; #X obj 343 778 pdp_gain; #X obj 285 751 pdp_t p p; #X floatatom 156 750 5 0 0; #X floatatom 394 750 5 0 0; #X text 287 829 correct; #X text 139 852 (even more confusing note: this is because pdp uses a 3 phase communication protocol.); #X text 452 459 (scroll down for more); #X text 48 829 unpredictable; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 4 0 3 0; #X connect 4 1 6 0; #X connect 7 0 9 0; #X connect 8 0 7 0; #X connect 9 0 10 0; #X connect 9 1 13 0; #X connect 9 2 12 0; #X connect 9 3 14 0; #X connect 9 4 11 0; #X connect 20 0 22 0; #X connect 20 0 22 1; #X connect 21 0 20 0; #X connect 23 0 25 0; #X connect 23 0 26 0; #X connect 24 0 23 0; #X connect 26 0 25 1; #X connect 29 0 33 0; #X connect 30 0 29 0; #X connect 32 0 31 1; #X connect 33 0 31 0; #X connect 33 1 32 0; #X connect 34 0 26 1; #X connect 35 0 32 1; pdp-0.14.1+darcs20180201/doc/objects/pdp_v4l-help.pd000066400000000000000000000047171266045153600213300ustar00rootroot00000000000000#N canvas 0 33 1438 415 10; #X obj 107 53 metro 40; #X msg 159 14 stop; #X msg 107 14 bang; #X msg 51 14 bang; #X msg 210 132 open /dev/video0; #X msg 210 156 open /dev/video1; #X text 348 128 you can choose the input device using the 'open' message. the default is /dev/video0; #X msg 210 181 close; #X text 349 182 closes the video port; #X msg 210 207 type yv12; #X msg 210 231 type grey; #X text 349 210 type sets the ouput image package type. currently only yv12 (luma/chroma color) and greyscale are supported.; #X msg 211 260 dim 320 240; #X msg 211 283 dim 640 480; #X msg 212 336 channel \$1; #X floatatom 212 312 5 0 0 0 - - -; #X floatatom 210 459 5 0 0 0 - - -; #X msg 210 483 freq \$1; #X floatatom 271 459 5 0 0 0 - - -; #X msg 271 483 freqMHz \$1; #X text 346 459 sets the v4l tuner frequency (in v4l units and MHz) ; #X obj 107 656 pdp_help_output; #X text 348 567 creation arguments: ; #X text 347 661 i.e. if you get weird colours \, try; #X obj 601 661 pdp_v4l /dev/video RGB24; #X text 206 14 pdp_v4l grabs video from the video4linux device. it sends out the most recently grabbed frame whenever a bang message is received \, and will then discard that frame (it will be sent out on time at most). the output framerate is limited by the device only. ; #X text 206 89 (to make sure you receive every frame with little jitter \, poll pdp_v4l with a high rate metronome); #X text 348 595 capture format can be one of "auto" \, "YUV420P" \, "YUV422" \, "RGB24" or "RGB32". for most cards autodetect (default) should work. if not \, add the desired capture format argument when you create a pdp_v4l object.; #X obj 107 568 pdp_v4l; #X text 349 338 sets the v4l channel (like tuner \, composite \, svideo \, ...); #X msg 212 366 norm PAL; #X msg 211 410 norm SECAM; #X msg 211 388 norm NTSC; #X msg 211 431 norm AUTO; #X text 349 377 sets the video norm; #X obj 146 592 route card; #X msg 209 529 info; #X obj 146 615 print; #X connect 0 0 28 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 28 0; #X connect 4 0 28 0; #X connect 5 0 28 0; #X connect 7 0 28 0; #X connect 9 0 28 0; #X connect 10 0 28 0; #X connect 12 0 28 0; #X connect 13 0 28 0; #X connect 14 0 28 0; #X connect 15 0 14 0; #X connect 16 0 17 0; #X connect 17 0 28 0; #X connect 18 0 19 0; #X connect 19 0 28 0; #X connect 28 0 21 0; #X connect 28 1 35 0; #X connect 30 0 28 0; #X connect 31 0 28 0; #X connect 32 0 28 0; #X connect 33 0 28 0; #X connect 35 0 37 0; #X connect 36 0 28 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_xor-help.pd000066400000000000000000000012561266045153600214260ustar00rootroot00000000000000#N canvas 552 356 511 383 10; #X msg 100 45 start; #X msg 147 45 stop; #X obj 100 77 pdp_help_input; #X obj 100 329 pdp_help_output; #X obj 144 252 pdp_reg; #X obj 213 204 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 246 202 click here; #X obj 100 170 pdp_gain; #X floatatom 151 142 5 0 0; #X msg 151 116 0.5; #X obj 100 286 pdp_xor; #X text 252 290 bitwise xor; #X msg 11 205 chanmask \$1; #X floatatom 11 180 5 0 0; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 7 0; #X connect 4 0 10 1; #X connect 5 0 4 0; #X connect 7 0 4 1; #X connect 7 0 10 0; #X connect 8 0 7 1; #X connect 9 0 8 0; #X connect 10 0 3 0; #X connect 12 0 10 0; #X connect 13 0 12 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_xv-help.pd000066400000000000000000000036061266045153600212540ustar00rootroot00000000000000#N canvas 251 11 708 682 10; #X msg 132 223 dim 320 240; #X msg 132 246 dim 640 480; #X text 300 227 dim sets the window dimensions; #X msg 131 151 create; #X msg 131 172 destroy; #X text 129 88 pdp_xv ouputs video in a window using the xVideo extension. if your graphics card/driver supports it you can have multiple output windows. if a pdp message is received and a window is not open \, one is created automaticly.; #X text 229 159 use these messages to explicitly create/destroy the window; #X msg 133 463 cursor \$1; #X obj 133 443 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 298 464 enables/disables cursor in xv window; #X obj 29 61 pdp_help_input; #X msg 29 25 start; #X msg 78 24 stop; #X text 295 200 specify the x window display; #X msg 131 197 display :0; #X obj 29 587 print; #X text 133 584 the output channel sends mouse event messages (press/release/drag and individual p/r/d for each button); #X obj 29 551 pdp_xv; #X msg 132 273 pos 100 100; #X text 300 273 set window position; #X msg 132 336 fullscreen; #X text 298 340 resize to entire screen; #X text 299 305 set both at once; #X msg 132 303 posdim 100 300 320 240; #X msg 131 417 tile 5 5 \$1 \$2; #X text 297 418 take a part of the screen (for tiling multiple pdp_xv's) ; #X obj 131 396 pack 0 0; #X obj 190 396 t b f; #X floatatom 131 377 5 0 0 0 - - -; #X floatatom 190 376 5 0 0 0 - - -; #X msg 134 489 movecursor 0.5 0.5; #X text 299 486 move the cursor inside the window; #X connect 0 0 17 0; #X connect 1 0 17 0; #X connect 3 0 17 0; #X connect 4 0 17 0; #X connect 7 0 17 0; #X connect 8 0 7 0; #X connect 10 0 17 0; #X connect 11 0 10 0; #X connect 12 0 10 0; #X connect 14 0 17 0; #X connect 17 0 15 0; #X connect 18 0 17 0; #X connect 20 0 17 0; #X connect 23 0 17 0; #X connect 24 0 17 0; #X connect 26 0 24 0; #X connect 27 0 26 0; #X connect 27 1 26 1; #X connect 28 0 26 0; #X connect 29 0 27 0; #X connect 30 0 17 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_zoom-help.pd000066400000000000000000000017741266045153600216070ustar00rootroot00000000000000#N canvas 467 414 562 448 10; #X obj 46 288 pdp_zoom; #X floatatom 121 264 5 0 0; #X floatatom 174 130 5 0 0; #X msg 87 160 zoomx \$1; #X msg 174 160 zoomy \$1; #X floatatom 87 129 5 0 0; #X msg 282 162 centerx \$1; #X floatatom 282 133 5 0 0; #X floatatom 366 133 5 0 0; #X msg 366 162 centery \$1; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 341 pdp_help_output; #X text 173 265 right inlet sets zoom amount; #X text 281 42 set zoom center; #X text 281 58 (0 \, 0) = top left; #X text 281 72 (1 \, 1) = bottom right; #X text 71 79 set individual axis zoom; #X msg 142 102 1; #X msg 334 101 0.5; #X msg 121 234 1; #X connect 0 0 13 0; #X connect 1 0 0 1; #X connect 2 0 4 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 3 0; #X connect 6 0 0 0; #X connect 7 0 6 0; #X connect 8 0 9 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 10 0; #X connect 12 0 10 0; #X connect 19 0 2 0; #X connect 19 0 5 0; #X connect 20 0 7 0; #X connect 20 0 8 0; #X connect 21 0 1 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_zrot-help.pd000066400000000000000000000023001266045153600216030ustar00rootroot00000000000000#N canvas 467 414 562 448 10; #X floatatom 257 275 5 0 0; #X floatatom 174 130 5 0 0; #X msg 87 160 zoomx \$1; #X msg 174 160 zoomy \$1; #X floatatom 87 129 5 0 0; #X msg 282 162 centerx \$1; #X floatatom 282 133 5 0 0; #X floatatom 366 133 5 0 0; #X msg 366 162 centery \$1; #X obj 46 40 pdp_help_input; #X msg 46 10 start; #X msg 95 10 stop; #X obj 46 401 pdp_help_output; #X text 281 58 (0 \, 0) = top left; #X text 281 72 (1 \, 1) = bottom right; #X text 71 79 set individual axis zoom; #X msg 142 102 1; #X msg 334 101 0.5; #X msg 257 245 1; #X obj 46 363 pdp_zrot; #X text 309 276 second inlet sets zoom amount; #X floatatom 257 333 5 0 0; #X msg 257 303 0; #X text 309 334 third inlet sets rotation angle; #X text 281 42 set zoom/rotation center; #X text 192 6 pdp_zrot: zoom and rotation; #X connect 0 0 19 1; #X connect 1 0 3 0; #X connect 2 0 19 0; #X connect 3 0 19 0; #X connect 4 0 2 0; #X connect 5 0 19 0; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 19 0; #X connect 9 0 19 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 16 0 1 0; #X connect 16 0 4 0; #X connect 17 0 6 0; #X connect 17 0 7 0; #X connect 18 0 0 0; #X connect 19 0 12 0; #X connect 21 0 19 2; #X connect 22 0 21 0; pdp-0.14.1+darcs20180201/doc/objects/pdp_zthresh-help.pd000066400000000000000000000007621266045153600223060ustar00rootroot00000000000000#N canvas 504 211 500 438 10; #X msg 77 38 start; #X msg 124 38 stop; #X obj 77 70 pdp_help_input; #X obj 77 340 pdp_help_output; #X obj 77 163 pdp_gain; #X floatatom 128 135 5 0 0; #X msg 128 109 0.5; #X obj 77 296 pdp_gain; #X msg 128 268 1; #X text 233 230 zero threshold ( < 0 -> 0 ); #X obj 77 231 pdp_zthresh; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 4 0 10 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 3 0; #X connect 8 0 7 1; #X connect 10 0 7 0; pdp-0.14.1+darcs20180201/doc/pdp-dev.txt000066400000000000000000001023741266045153600171520ustar00rootroot00000000000000PDP dev notes Entry: Syncing with pd SVN Date: Tue Aug 31 18:55:21 CEST 2010 # full repo: svn co https://pure-data.svn.sourceforge.net/svnroot/pure-data pure-data # only pdp: svn co https://pure-data.svn.sourceforge.net/svnroot/pure-data/trunk/externals/pdp/ pdp-pde Entry: Picking up PDP? Date: Mon Nov 28 16:42:54 EST 2011 After I forked PF from PDP I've been working on many things that might deserve some re-integration into the PDP framework. I'm not too happy with the design of PDP. Every time I pick up PDP again I think the problems might be fixable, but then give up shortly after that, seeing that they are not.. A better approach might be to start a new system and make interfaces with Pd / PDP. List of problems: * Memory allocation / reference counting. This is fixed in PF but backporting would break PiDiP etc. * Interfaces. This includes Pd, PDP's packet interface, raw buffer processing, interfaces of ad-hoc modules (video i/o ...). * Composability on the instruction level, i.e. automate inlining and unrolling. Most algorithms are simple, but a lot of effort is spent in manually writing unrolled loops with simple formulas. Entry: Upgrading V4L Date: Tue Nov 29 13:19:49 EST 2011 According to IOhannes v4l1 is no longer supported in recent kernels (zoo: 2.6.33.7-rt29 still works). The preferred way is now to use libv4l. He had changed PDP accordingly. To install on Debian: apt-get install libv4l-dev In configure.ac I had to change "pkg-config libv4l" to "pkg-config libv4l2" to make it compile on debian. That was probably the reason why I couldn't get my old webcams to work on zoo. Running naked xawtv also no longer works[1]: tom@zoo:~$ xawtv This is xawtv-3.95.dfsg.1, running on Linux/x86_64 (2.6.33.7-rt29) xinerama 0: 1440x900+0+0 X Error of failed request: XF86DGANoDirectVideoMode Major opcode of failed request: 130 (XFree86-DGA) Minor opcode of failed request: 1 (XF86DGAGetVideoLL) Serial number of failed request: 69 Current serial number in output stream: 69 I have to use : xawtv -nodga Mplayer just works mplayer tv:// It still gets messed up when plugging it in a USB hub, which seems to be a problem with the camera. [1221785.408222] usb 7-4: new full speed USB device using ohci_hcd and address 28 [1221785.639110] usb 7-4: New USB device found, idVendor=046d, idProduct=08b2 [1221785.639113] usb 7-4: New USB device strings: Mfr=0, Product=0, SerialNumber=0 [1221785.641365] pwc: Logitech QuickCam 4000 Pro USB webcam detected. [1221785.641396] pwc: Registered as video0. [1221785.923306] input: PWC snapshot button as /class/input/input10 After plugging it back into a host port it doesn't recover. I tried to unload pwc, videodev and the v4l compat modules but nothing but v4l select errors. [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=513818 Entry: V4L2 Date: Mon Oct 29 20:08:59 EDT 2012 Merging some code from pdp_v4l2 (pidip) into pdp_v4l. I've had some hard kernel crashes working with the PWC cams. Last happened when unplugging: BUG: ... NULL pointer ... pwc_cleanup_queued_bufs() trace: usb_pwc_disconnect tom@zoo:~$ cat /proc/version Linux version 3.2.0-3-rt-amd64 (Debian 3.2.21-3) (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-8) ) #1 SMP PREEMPT RT Thu Jun 28 10:46:01 UTC 2012 tom@zoo:~$ linux-image-3.2.0-3-rt-amd64 EDIT: Looks like there are later versions. tom@zoo:~$ sudo apt-get install linux-image-rt-amd64 Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: linux-image-3.2.0-4-rt-amd64 Suggested packages: linux-doc-3.2 debian-kernel-handbook grub-pc extlinux lilo The following NEW packages will be installed: linux-image-3.2.0-4-rt-amd64 linux-image-rt-amd64 0 upgraded, 2 newly installed, 0 to remove and 2061 not upgraded. Need to get 23.6 MB of archives. Entry: Alternative implementation Date: Mon Oct 29 21:55:28 EDT 2012 More like the "dsp" approach: fixed frame rate video engine. Maybe this can be done generically: use Pd to create an "external" dataflow network implemented by another app. Entry: Picking a webcam Date: Tue Oct 30 18:57:57 EDT 2012 Always a gamble going just by model number, but it seems best to go for either spca5xx or uvc: http://mxhaard.free.fr/spca5xx.html http://www.ideasonboard.org/uvc/ These are on the UVC list: HD-3000 and HD-5000 http://www.amazon.com/Microsoft-T3H-00011-LifeCam-HD-3000/dp/B008ZVRAQS http://www.amazon.com/Microsoft-LifeCam-HD-5000-720p-Webcam/dp/B002XN7C6W Entry: Microsoft LifeCam HD-5000 Date: Thu Nov 1 18:38:11 EDT 2012 045e:076d Microsoft Corp. LifeCam HD-5000 This needs to be massaged a little bit before it gives proper 30fps display. See here[1]. This worked for me: - manual exposure set to 153 - auto focus off Valid exposure values are: > But the camera does not respond to exposure adjustment linearly. There > are some valid values between 5-20000. They are from darkest to brightest > 5, 9 & 10 (same brightness), 19 & 20, 39, 78, 156, 312, 625, 1250, 2500, > 5000 and 10000. Every other value gives the maximum brightness. 156 is the > maximum value to get 30 fps. Maybe I can send a patch to the uvcvideo list? [1] http://comments.gmane.org/gmane.linux.drivers.uvc.devel/5717 Entry: Sharable C modules Date: Thu Nov 1 20:16:48 EDT 2012 Thinking about libprim etc... Basic idea is that you want a compile-time insertion of a project-specific struct header. Entry: V4L2 controls Date: Thu Nov 1 23:01:40 EDT 2012 Everything is in /usr/include/linux/videodev2.h The thing to find out is how guvcview maps controls to defines from videodev2.h [1] http://v4l.videotechnology.com/dwg/v4l2.html#CONTROL Entry: MMX on 64 bit? Date: Sun Nov 4 09:39:25 EST 2012 as --32 -o pixel_pack_s16u8.o pixel_pack_s16u8.s it's not actually the MMX, but using 32bit registers, i.e.: as -o pixel_unpack_u8s16.o pixel_unpack_u8s16.s pixel_unpack_u8s16.s: Assembler messages: pixel_unpack_u8s16.s:25: Error: invalid instruction suffix for `push' pixel_unpack_u8s16.s:27: Error: operand type mismatch for `push' pixel_unpack_u8s16.s:28: Error: operand type mismatch for `push' 25 pushl %ebp 26 movl %esp, %ebp 27 push %esi 28 push %edi Entry: Leaf objects Date: Sun Nov 4 10:30:55 EST 2012 So, the goal is to merge the "leaf object" library of PDP and libprim, starting with V4L. Entry: MMX stuff Date: Sun Nov 4 15:03:52 EST 2012 Got to fix ABI problems in the MMX code. Maybe it's best to go for SSE2 on the longer term, as it seems to have most of the saturated integer math that's necessary for PDP's feel. It would be nice to do some auto-vector code also. Or GCC extensions[4]. The good thing here is that ABI stuff gets taken care of by GCC. [1] http://en.wikipedia.org/wiki/SSE2 [2] http://gcc.gnu.org/projects/tree-ssa/vectorization.html [3] http://softpixel.com/~cwright/programming/simd/sse2.php [4] http://stackoverflow.com/questions/7919304/gcc-sse-code-optimization Entry: 64 bit processors Date: Sun Nov 4 17:07:53 EST 2012 Yeah I missed that revolution ;) I have two. zoo is an Acer desktop, tx is an Acer TimeLine X laptop. # 4 cores, only first one shown tom@tx:~$ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 42 model name : Intel(R) Core(TM) i5-2430M CPU @ 2.40GHz stepping : 7 microcode : 0x17 cpu MHz : 800.000 cache size : 3072 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid bogomips : 4788.54 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management: # 4 cores, only first one shown tom@zoo:~$ cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 16 model : 4 model name : AMD Phenom(tm) II X4 820 Processor stepping : 2 microcode : 0x1000086 cpu MHz : 800.000 cache size : 512 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 4 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 5 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt hw_pstate npt lbrv svm_lock nrip_save bogomips : 5600.14 TLB size : 1024 4K pages clflush size : 64 cache_alignment : 64 address sizes : 48 bits physical, 48 bits virtual power management: ts ttp tm stc 100mhzsteps hwpstate What's interesting is the CPUflags. Making the intersection gives: SHARED: apic cx8 lahf_lm monitor nx popcnt sep vme clflush de lm msr pae pse sse cmov fpu mca mtrr pat pse36 sse2 constant_tsc fxsr mce nonstop_tsc pge rdtscp syscall cx16 ht mmx nopl pni rep_good tsc AMD: 3dnow cmp_legacy extd_apicid lbrv nrip_save sse4a 3dnowext cpu fxsr_opt misalignsse osvw svm 3dnowprefetch cr8_legacy hw_pstate mmxext pdpe1gb svm_lock abm extapic ibs npt skinit wdt INTEL: acpi ds_cpl flexpriority pln tm2 xsave aes dtes64 ida pts tpr_shadow xsaveopt aperfmperf dtherm pbe ss tsc_deadline_timer xtopology arat dts pcid sse4_1 vmx xtpr arch_perfmon epb pclmulqdq sse4_2 vnmi avx ept pdcm ssse3 vpid bts est pebs tm x2apic So both implement some SSE4 instructions, but they are named separately. What is the subset that can be used? [1] says they share 4 instructions. Maybe it's best just to use SSE2. Actually, SSE3 is called PNI[2] and supported by both. According to [2] it's also supported on Atom. [1] http://en.wikipedia.org/wiki/SSE4#SSE4_subsets [2] http://en.wikipedia.org/wiki/SSE3 Entry: TODO Date: Sun Nov 4 17:39:37 EST 2012 - cleanup v4l / x11 code to allow objects to be used outside PDP. there is already significant code in libprim that can be merged. - fix x64 ABI problems in MMX code. maybe best to let GCC handle it and use inline asm instead? Entry: MMX through GCC extensions Date: Mon Nov 5 14:11:24 EST 2012 #include Which I find in /usr/lib/gcc/x86_64-linux-gnu/4.6/include/mmintrin.h EDIT: Seems to make it quite a bit faster indeed. logistics patch is now running at 30fps with 65% CPU with only gain, add, mul, mix, biquad converted. Using __attribute__((always_inline)) for the inner biquad functions takes off another 5-7% for the whole patch. With cheby it's at 45%. TODO: - more MMX objects: resample, pack/unpack, crot, rand, randmix, - check asm for inline / alignment -> seems ok - xv / glx: find out where the tearing comes from Entry: leaf_v4l separated Date: Tue Nov 6 19:57:44 EST 2012 Next is to find out how to put libprim and PDP on the same codebase. Entry: Higher frame rate on built-in camera TimeLineX Date: Tue Nov 6 21:40:20 EST 2012 In guvcview when I change powerline frequency setting, temporarily the picture displays a higher frame rate. What's going on here? 058f:b002 Alcor Micro Corp. Entry: zl_ Date: Wed Nov 7 21:32:28 EST 2012 Instead of mixing with libprim it seems best to just make a simple C library of utility objects. A basic reusable old-tech approach. librpim is too tied to the scripting idea, and is probably best tied to zl_ directly Oh, and zl_ stands for Zwizwa Library ;) I think I'm going to keep the language-foo out of PDP. PDP is good as it is: simple, straightforward. The only place I see for languages is at compile time, to generate code. Entry: Next Date: Thu Nov 8 21:45:59 EST 2012 - integrate xwindow.c object into PDP, replacing most of the pdp_xwindow stuff. maybe this needs a gl object first? - MMX resample: better fetch strategy Entry: Resampling Date: Fri Nov 9 11:05:50 EST 2012 I'm not sure any more if it is useful to do many pixels in parallel. It seems that at least some operations need to be done serially. -> What does need to happen is that 4 pixels are computed and stored together. So it makes sense to do part of the ops in parallel since result storage is in parallel. What about restructuring? What can be done in parallell is to compute the offsets of the 4 vectors to be fetched from memory, that would work out nice. The coordinates would still be stored in 2 vectors, but the 4 components are used to compute the 4 vector locations: (x,y), (x+1,y), (x,y+1), (x+1,y+1) The challenge in doing this is to encode that +1 somehow. Currently this can't be done exactly since the coordinates are in 0.32 image-relative coordinates to allow for easy wrap-around. I.e. need to guarantee that x * scale and (x+offset_1) * scale always point to neighboring pixel indices. is there any mathematical property that can guarantee this? It might really be simpler to just perform a compare + correction. I.e. a modulo that works only for a the vectors that are just outside the range. Do this in parallel: x_inc = x_inc > right_edge ? 0 : x_inc y_inc = y_inc > bottom_edge ? 0 : y_inc In MMX that is PCMPGTW followed by PAND _mm_cmpgt_pi16() _mm_and_si64() Entry: Pd as a dataflow compiler Date: Fri Nov 9 12:40:13 EST 2012 Time to make this work ey ;) New project: PDC : Pure Data Compiler. Arrange a network. The result is a DFG that can be given any kind of interpretation. Any time the DFG changes, it gets recompiled and re-loaded. Essentially, abstract evaluation. Entry: Resample Date: Sat Nov 10 15:17:55 EST 2012 I'm giving up for doing this in straight mmx: there doesn't seem to be a good way: most of the code is shuffling that can just as well be replaced by integer operations and possibly straight s16 memory accesses. I'm going to commit now and remove all the shuffling code. It was an interesting trip though :) Another thing: if all pixel increments are made such that they are always positive, and always smaller than the with/height of the image, a simple compare -> conditional subtract is actually enough to compute the integer/fractional addresses directly: no multiplication is necessary. However, it is nearly free. Entry: Bug Date: Sat Nov 10 20:37:49 EST 2012 So I thought I had a bug as my scanned synthetis patch was running so slow. Turns out this was because it was running at 640x480 instead of 320x240! Entry: Camera 0c45:62c0 Microdia Sonix USB 2.0 Camera Date: Sun Nov 11 01:29:31 EST 2012 Very nice surprise, the cam works at high framerate. However, after upgrading: linux-image-3.0.0-1-686-pa linux-image-3.2.0-4-rt-686-pae the cam only does 1, 5 fps and won't accept anything else. [ 0.000000] Linux version 3.0.0-1-686-pae (Debian 3.0.0-3) (ben@decadent.org.uk) (gcc version 4.5.3 (Debian 4.5.3-8) ) #1 SMP Sat Aug 27 16:41:03 UTC 2011 ... [ 7.622315] uvcvideo: Found UVC 1.00 device USB 2.0 Camera (0c45:62c0) [ 7.639655] input: USB 2.0 Camera as /devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/input/input7 [ 7.640637] usbcore: registered new interface driver uvcvideo [ 7.640646] USB Video Class driver (v1.1.0) Framerates go up to 30. [ 0.000000] Linux version 3.2.0-4-rt-686-pae (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-12) ) #1 SMP PREEMPT RT Debian 3.2.32-1 ... [ 95.380809] uvcvideo: Found UVC 1.00 device USB 2.0 Camera (0c45:62c0) [ 95.407087] input: USB 2.0 Camera as /devices/pci0000:00/0000:00:1d.2/usb4/4-1/4-1:1.0/input/input12 [ 95.409414] usbcore: registered new interface driver uvcvideo [ 95.409426] USB Video Class driver (1.1.1) framerates 1, 5 Entry: 2.6.32 Date: Mon Nov 12 11:04:14 EST 2012 This kernel is still running on an old pentium MMX computer, which is probably a good for testing if it still works. Entry: Building pd-extended Date: Tue Nov 13 16:23:38 EST 2012 I need to be careful not to break the pure-data externals repository build. Seems that core has moved to git, but all externals are still in SVN. I'm putting it under ~/pd/svn/pure-data from: svn checkout https://pure-data.svn.sourceforge.net/svnroot/pure-data/trunk pure-data To build a part: cd pure-data/externals make pdp make creb Entry: Converting to darcs-2 Date: Sat Dec 8 10:44:13 EST 2012 Entry: Running in gdb Date: Sat Dec 8 18:47:16 EST 2012 Next probably good to run it in gdb. It's simple enough with "gdb --args" Entry: X stuff Date: Sat Dec 8 19:41:56 EST 2012 Might just be my X since it's a bit unstable.. X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 132 (XVideo) Minor opcode of failed request: 19 () Value in failed request: 0x3f Serial number of failed request: 460 Current serial number in output stream: 461 How to debug this? -> I don't know where it comes from. Maybe the window manager? I added a limit to the window size of 4000x4000. Entry: List parser Date: Sun Dec 9 11:57:09 EST 2012 Problem with interfacing OO C code with pd is just the control messages. What I want is some kind of straightforward way to map a pd list, i.e. |coef 123< to a function call x_coef(x, 123). This needs a dispatcher, or a "de-dynamicifier". The trouble here is type stuff: somehow the static C type need a run-time representation. Instead of parsing header files, it seems best to tackle this at the source, encoding the syntax in some CPP constructs that are easily evaluated to different parts (declaration, implementation, parser, ...) Using explicit markers: #define API \ FUN_BEGIN(float, set_coef1) ARG(float, c) FUN_END \ FUN_BEGIN(float, set_coef1) ARG(float, c) FUN_END \ Using macro varargs FUN(ID(float, set_amp, "Set amplitude"), ID(float, amp, "amplitude")) FUN(ID(float, set_coord, "Set 2D coordinates"), ID(float, x, "X coordinate"), ID(float, y, "Y coordinate")) Declaration is then: #define FUN(n, ...) n (__VA_LIST__); #define ID(t,n,doc) t n Let's try this out for the xv wrapper. Entry: Release? Date: Tue May 14 13:24:25 EDT 2013 I got interrupted in December.. What's next? - new build system? - make V4L2 build properly - more tests? Entry: Prerelease Date: Tue May 14 14:32:13 EDT 2013 Hello, There's a PDP release in the pipeline: 0.14.0: Port ia32 MMX assembly code to GCC extensions (MMX support on amd64) Add V4L2 support to pdp_v4l (merge with pdp_v4l2) Distill zl (Zwizwa Lib) from PDP and libprim/PF code. This is quite a big change internally and is not 100% stable yet. It should be functionally equivalent with previous version. I'm going to put out what I have now for people that like to try it out. If you run into a bug, post here or send it to pdp@zwizwa.be http://zwizwa.be/pd/pdp/test/pdp-darcs-20130514_145023.tar.gz Some known issues are GLX crashes when texture size changes and V4L1 support being broken. ( See pdp_v4l_hack for a new camera-specific setup hack that was necessary to get high FPS on a Microsoft cam. It might be useful for other cams too. ) Cheers Tom Entry: Todo from pd-list Date: Wed May 15 20:19:40 EDT 2013 - find m_pd.h in different path WONTFIX? - fix default target DONE - weird images sizes sometimes crash (not in debug build?) Entry: 3dp Date: Fri Oct 11 10:08:33 EDT 2013 TODO: - Move the 3D context object to zl. - Cleanup zl such that pdp contains standalone lib to avoid merge issues The core object that's passed around in 3dp is a 3Dcontext. It seems simplest to move the implementation of this into zl. However... it might be best to take this code from PF, and just make 3dp work with recent api changes. It's not a small change to do this merge properly... Entry: procqueue Date: Sat Oct 12 19:21:57 EDT 2013 I thought I took that out... Apparently not. Means 3dp needs to support it? Entry: 3DP bug when opening 2 separate windows Date: Tue Oct 15 19:48:23 EDT 2013 tom@zoo:~/pdp/opengl/doc/examples$ pd.local example05.pd X Error of failed request: BadMatch (invalid parameter attributes) Major opcode of failed request: 154 (GLX) Minor opcode of failed request: 11 (X_GLXSwapBuffers) Serial number of failed request: 66 Current serial number in output stream: 67 Entry: SCAF also broken (32bit asm) Date: Tue Oct 15 20:07:52 EDT 2013 example 6 Entry: TODO 3dp Date: Tue Oct 15 20:14:54 EDT 2013 example 5,6,8,11,12,13,15 Entry: 3dp bug when changing window size in ex 8 with lots of squares Date: Tue Oct 15 20:17:14 EDT 2013 tom@zoo:~/pdp/opengl/doc/examples$ pd.local example08.pd MULTI_AUDIODEV 3 PDP_AUDIODEV 1 29157 using JACK priority 6 scheduling enabled. priority 8 scheduling enabled. Fontconfig warning: "/etc/fonts/conf.d/50-user.conf", line 9: reading configurations from ~/.fonts.conf is deprecated. Fontconfig warning: "/etc/fonts/conf.d/53-monospace-lcd-filter.conf", line 10: Having multiple values in isn't supported and may not work as expected Fontconfig warning: "/etc/fonts/conf.d/65-droid-sans-fonts.conf", line 103: Having multiple values in isn't supported and may not work as expected Fontconfig warning: "/etc/fonts/conf.d/65-droid-sans-fonts.conf", line 138: Having multiple values in isn't supported and may not work as expected Fontconfig warning: "/etc/fonts/conf.d/90-fonts-unfonts-core.conf", line 11: Having multiple values in isn't supported and may not work as expected Fontconfig warning: "/etc/fonts/conf.d/90-fonts-unfonts-extra.conf", line 16: Having multiple values in isn't supported and may not work as expected ev: 22 ev: 22 ev: 19 X Error of failed request: BadDrawable (invalid Pixmap or Window parameter) Major opcode of failed request: 137 (DRI2) Minor opcode of failed request: 8 (DRI2SwapBuffers ) Resource id in failed request: 0x1800003 Serial number of failed request: 1765 Current serial number in output stream: 1765 Entry: 3dp window events don't seem to work after libprim/zl update Date: Wed Oct 16 09:47:09 EDT 2013 check mouserotate Entry: torus is gone! Date: Sun Oct 27 10:51:48 EDT 2013 static void draw_wtorus(t_drawcommand *x) { float ri = x->x_p0; float ro = x->x_p1; int n = (int)x->x_p2; int m = (int)x->x_p3; if (n < 1) n = 20; if (m < 1) m = n; // glutWireTorus(ri, ro, n, m); } In PF? Ok, this is because the GLUT dependency was removed. Added it back to pdp_opengl Entry: 3Dcontext events fixed Date: Sun Oct 27 12:33:21 EDT 2013 using the new "for" approach. Entry: TODO 3dp Date: Sun Oct 27 12:34:23 EDT 2013 example 5,6,8,11,12,13,15 Entry: example08.pd: gl method called outside of context? Date: Sun Oct 27 12:48:36 EDT 2013 Not sure how to fix this, since "current context" doesn't really mean anything in the packet conversion code.. bt #0 0x02f5b290 in pdp_packet_texture_isvalid () from /home/tom/darcs/pdp/opengl/pdp_opengl.pd_linux #1 0x02f5b361 in _pdp_packet_texture_old_or_dummy () from /home/tom/darcs/pdp/opengl/pdp_opengl.pd_linux #2 0x02f5b524 in _pdp_packet_texture_convert_bitmap_to_texture () from /home/tom/darcs/pdp/opengl/pdp_opengl.pd_linux #3 0x009ac85b in _pdp_type_run_conversion_program () from /home/tom/darcs/pdp/pdp.pd_linux #4 0x009acdac in _pdp_packet_convert () from /home/tom/darcs/pdp/pdp.pd_linux #5 0x009acec6 in pdp_packet_convert_rw () from /home/tom/darcs/pdp/pdp.pd_linux #6 0x02f5af7e in _pdp_packet_texture_convert_image_to_texture () from /home/tom/darcs/pdp/opengl/pdp_opengl.pd_linux #7 0x009ac85b in _pdp_type_run_conversion_program () from /home/tom/darcs/pdp/pdp.pd_linux #8 0x009acdac in _pdp_packet_convert () from /home/tom/darcs/pdp/pdp.pd_linux #9 0x009acf36 in pdp_packet_convert_ro () from /home/tom/darcs/pdp/pdp.pd_linux #10 0x00987d6d in pdp_convert_input_0 () from /home/tom/darcs/pdp/pdp.pd_linux #11 0x080af90b in pd_typedmess () #12 0x080b16cf in outlet_anything () #13 0x009b7316 in outlet_pdp_register () from /home/tom/darcs/pdp/pdp.pd_linux #14 0x009b752e in pdp_packet_pass_if_valid () from /home/tom/darcs/pdp/pdp.pd_linux #15 0x009b7ac3 in pdp_pass_if_valid () from /home/tom/darcs/pdp/pdp.pd_linux #16 0x009b6b5c in pdp_base_postprocess () from /home/tom/darcs/pdp/pdp.pd_linux #17 0x009b8d6c in pdp_procqueue_add () from /home/tom/darcs/pdp/pdp.pd_linux #18 0x009b6c5d in pdp_base_bang () from /home/tom/darcs/pdp/pdp.pd_linux #19 0x009b6d34 in pdp_base_input_hot () from /home/tom/darcs/pdp/pdp.pd_linux #20 0x080af90b in pd_typedmess () #21 0x080b16cf in outlet_anything () #22 0x009b73d7 in outlet_pdp_process () from /home/tom/darcs/pdp/pdp.pd_linux #23 0x009b7546 in pdp_packet_pass_if_valid () from /home/tom/darcs/pdp/pdp.pd_linux #24 0x00991f3b in pdp_plasma_postproc () from /home/tom/darcs/pdp/pdp.pd_linux #25 0x009b6b46 in pdp_base_postprocess () from /home/tom/darcs/pdp/pdp.pd_linux #26 0x009b8d6c in pdp_procqueue_add () from /home/tom/darcs/pdp/pdp.pd_linux #27 0x009b6c5d in pdp_base_bang () from /home/tom/darcs/pdp/pdp.pd_linux #28 0x00991e3b in pdp_plasma_bang () from /home/tom/darcs/pdp/pdp.pd_linux Maybe conversion of bitmap to texture should just be removed. I.e. only do this in 3dp object? Entry: fixing scaf Date: Tue Oct 29 09:44:07 EDT 2013 Probably best to make a different architecture. It doesn't seem too hard to write this in pure C in an unrolled/tiled loop. Hmm... no. That's not a good tap point. It might be simplest to keep the code in 386 bit mode and do the ABI adaptation in the feeder routine. How to switch to 386 bit mode? Maybe only the OS can do that? Doesn't look like this will work. What is the code that goes into the assembler? In scafmacro.s the memory references are through %edi and %esi. Changing these to the 64 bit equivalents should be enough. Then fix the feeder to use a 64bit ABI. esi -> rsi edi -> rdi To make this work, make sure all .s files pass through the C preprocessor, then use: // 32bit #define SI %esi #define SI %esi // 64bit #define SI %rsi #define SI %rsi http://stackoverflow.com/questions/2500362/running-32-bit-assembly-code-on-a-64-bit-linux-64-bit-processor-explain-the Entry: Fix scaf Date: Sun Nov 3 12:52:07 EST 2013 - convert pdp_ca.c to fixed size ints from stdint.h - use minimal %esi / %edi fix for core routines - create inline asm feeder EDIT: Tried on Acer One 32bit, but pdp_opengl gives problems after recompile. Should do a fresh configure & compile and find out what's wrong.. No protocol specified pdp: x11: can't open display :0 It also happened a launching xterm, but now xterm works again. Not sure what the difference was. Let's restart X server. Yep, that fixed it. Guess is that there is another bug in the 3Dcontext -> Xlib calls that exposes a bug in the X server. Entry: Next: scaf Date: Thu Dec 5 09:40:02 EST 2013 - build feeder in C - check if it works on x86 - verify on amd64 Entry: TODO 3dp Date: Sun Oct 27 12:34:23 EDT 2013 Last note was: example 5,6,8,11,12,13,15 crash: 5, behavior: 6, Entry: Release notes Date: Fri Dec 13 13:00:31 EST 2013 updates to pdp_scaf and pdp_opengl (3dp) SCAF (Simple Cellular Automata Forth) is ported to x86_64 ABI. It still uses the old MMX integer code which makes little sense on x86_64, but at least it works. 3dp +- works. Some known issues in corner cases (pdp/opengl/doc/examples) - example05.pd : multiple window render contexts - example06.pd : bug in scaf CA grid -> texture conversion ? Entry: glxcontext Date: Sat Dec 21 17:55:00 EST 2013 void zl_3Dcontext_glx_setup(void) { ... glx_env.glx = zl_glx_new(); ... } There's some confusion about context and drawables... Find out exactly what the relation is between these. The bug is probably just a misunderstanding of what is what. glXMakeCurrent takes: - Display - GLXDrawable (window) - GLXContext When a 3dp window is closed and reopened, the drawable should change, but the display and context should remain the same. The problem seems to be that the drawable is gone. Maybe this is just a flush problem? Or, does the closing of the window also delete the context? no Something non-obvious is going on here. It doesn't look like the swapbuffer call is the source of the problem, just a symptom. X Error of failed request: BadMatch (invalid parameter attributes) Major opcode of failed request: 154 (GLX) Minor opcode of failed request: 11 (X_GLXSwapBuffers) Serial number of failed request: 320 Current serial number in output stream: 321 I'm guessing this is just fallout from a dangling reference issue. Entry: Cleanup Date: Sun Dec 22 14:43:23 EST 2013 So I really want to clean up PDP to make it maintainable. What that means in practice is to _remove_ stuff. One of the complications is the procqueue. I wonder if it is actually used for anything essential. It can probably be replaced with abstract interpretation. The problem here is time. This is not someting for an incremental job. Or at least, the increments will be fairly large. Entry: Debug GLX error Date: Mon Dec 30 17:35:38 EST 2013 .. glXSwapBuffers(0x7fb9f0000950,0x1600003) glXSwapBuffers(0x7fb9f0000950,0x1600003) zl_3Dcontext_free(0x1d2baf0,(nil)) glXSwapBuffers(0x7fb9f0000950,0x160000a) glXSwapBuffers(0x7fb9f0000950,0x160000a) glXSwapBuffers(0x7fb9f0000950,0x160000a) X Error of failed request: BadMatch (invalid parameter attributes) Major opcode of failed request: 154 (GLX) Minor opcode of failed request: 11 (X_GLXSwapBuffers) Serial number of failed request: 592 Current serial number in output stream: 594 I'd like to really know what is going on here, i.e. go into the graphics driver and see why it raises a BadMatch, which is not what it's supposed to do. At least I find no valid reason. Maybe mesa debug would help here? Entry: Better errors on Acer Revo / Ubuntu Date: Mon Jan 6 11:36:08 EST 2014 glXSwapBuffers(0xb35004e0,0x1800003) glXSwapBuffers(0xb35004e0,0x1800003) glXSwapBuffers(0xb35004e0,0x1800003) glXSwapBuffers(0xb35004e0,0x1800003) zl_3Dcontext_free(0x87364e8,(nil)) glXSwapBuffers(0xb35004e0,0x180000a) glXSwapBuffers(0xb35004e0,0x180000a) X Error of failed request: GLXBadDrawable Major opcode of failed request: 153 (GLX) Minor opcode of failed request: 11 (X_GLXSwapBuffers) Serial number of failed request: 81 Current serial number in output stream: 82 Entry: Main 3D rendering objects Date: Mon Jan 6 11:36:55 EST 2014 The problem is one of organization. - X server connection - GLX contex - X window (drawable) How to fix? Probably best to trace all gl calls. Is there a simple way to do this without manual edit? Entry: gdb Date: Mon Jan 6 12:13:00 EST 2014 Is this just me getting old and confused, or did the buggy nature of emacs / gdb just get worse over time? I'm gessing the problem is that the process stdout/stderr is not tagged with target-stream-output '@'. Entry: zl updates Date: Sat Aug 16 12:08:04 EDT 2014 Looks like this broke: pdp_3d_windowcontext.c:133:5: warning: implicit declaration of function ‘pdp_packet_3Dcontext_event_out’ [-Wimplicit-function-declaration] pdp_packet_3Dcontext_event_out(p, x->x_eventout); Entry: __attribute__((unused)) Date: Sat Aug 16 12:08:16 EDT 2014 A useful warning, so added the attribute to all dummy variables. Entry: cleanup Date: Mon Jan 6 13:52:35 EST 2014 Is there a way to clean up PDP to make it easier to maintain? What I want to do is to reduce everything to a libprim core, then port it to the existing PDP api. I.e. I want to toss it all out. This however is not realistic without a design of what PDP is supposed to be. The trouble is feature creep. Obtaining a design would require a review of each file to understand how it actually works and where it is broken due to bad interactions. Some elements of the API that are a bit crooked: - planar processing (e.g. chanmask) - autoconvert - procqueue - refcount mechanism - dpd / 3dp "serial programming" idea Practically, moving part by part to libprim or other libraries is probably the best approach. I don't have the time/energy/motivation to turn this into a large sprint. The best I can do for now is incremental increases. Entry: Picking up again Date: Sat Oct 31 08:59:29 EDT 2015 For those who lost track: this got off the rails a little. PDP/PF have been stepping-stone projects towards learning more about designing programs, virtual machines, programming languages and compilers. The idea has been to keep PDP and PF up with the development in that area, which has largely been infeasbile due to the large amount of design errors made in the process. Today, another attempt to fix things. Current state: libprim: simple object system zl: bindings to (linux) libraries The idea was to build PF and possibly PDP on those two libraries, and then use RAI to generate DSP code. Entry: PF fixes Date: Mon Nov 2 07:57:08 EST 2015 Spent this weekend propagating some changes in libprim/leaf to libprim/pf: - leaf_object has a built in rc count, which is used to create composite (tree-structured) leaf objects. - removed the RC wrapper used in PF, and renamed the LIN wrapper to UNIQ. It looks like the PF design is sound, however its implementation could probably be made a little simpler. pdp-0.14.1+darcs20180201/doc/reference.txt000066400000000000000000000117531266045153600175510ustar00rootroot00000000000000This is a list of all pdp objects and abstractions with a minimal description. Take a look at the patches in the doc/ directory for more info. (Messy doc & test patches can be found in the test/ directory.) general purpose pdp modules: pdp_del a packet delay line pdp_reg a packet register pdp_snap takes a snapshot of a packet stream pdp_trigger similar to pd's trigger object pdp_route routes a packet to a specific outlet pdp_loop a packet loop sampler (packet array) pdp_description output a symbol describing the packet type pdp_convert convert between packet types pdp_metro~ audio/video sync object image inputs/outputs: pdp_xv displays images using the xvideo extension pdp_glx displays images using opengl pdp_v4l reads images from a video4linux device pdp_qt reads quicktime movies pdp_rawin read packets from pipe or file pdp_rawout write packets to pipe or file pdp_rawout~ write audio to pipe or file image processors: pdp_abs absolute value pdp_add adds two images pdp_and bitwize and pdp_array2grey convert pd array to greyscale image pdp_grey2array convert greyscale image to pd array pdp_bitdepth set bit depth pdp_bitmask apply a bit mask pdp_bq spatial biquad filter pdp_bqt temporal biquad filter pdp_cog gaussian blob estimator pdp_constant fills an image with a constant pdp_conv horizontal/vertical seperable convolution filter pdp_cheby chebyshev color shaper pdp_chrot rotates the chroma components pdp_flip_lr flip left <-> right pdp_flip_tb flip top <-> bottom pdp_grey converts an image to greyscale pdp_grey2mask converts a greyscale image to an image mask pdp_hthresh hard thresholding pdp_mul multiplies two images pdp_mix crossfade between 2 images pdp_mix2 mixes 2 images after applying a gain to each of them pdp_noise a noise generator pdp_not bitwize not pdp_or bitwize or pdp_plasma plasma generator pdp_pointcloud convert an image to a point cloud pdp_positive sign function that creates a bitmask pdp_randmix crossfades 2 images by taking random pixels pdp_rotate tiled rotate pdp_scale rescale an image pdp_sign sign function pdp_sthresh soft thresholding pdp_zoom tiled zoom pdp_zrot tiled zoom + rotate pdp_zthresh zero threshold (x<0 -> 0) pdp_xor bitwize xor dsp objects pdp_scope~ a very simple oscilloscope pdp_scan~ phase input scanned synthesis oscillator pdp_scanxy~ x,y coordinate input scanned synthesis oscillator utility abstractions pdp_pps computes the packet rate in packets/sec image abstractions pdp_affine scale (gain) + offset pdp_agc automatic gain control (intensity maximizer) pdp_alledge an all edge detector pdp_blur blurs an image pdp_blur_hor horizontal blur pdp_blur_ver vertical blur pdp_contrast contrast enhancement pdp_conv_alledge edge detector pdp_conv_emboss emboss effect pdp_conv_smooth smoothing pdp_conv_sobel_hor horizontal sobel edge detector pdp_conv_sobel_ver vertical sobel edge detector pdp_conv_sobel_edge sum of squares of hor and ver edge detector pdp_dither a dither effect pdp_gain3 independent channel gains pdp_gradient grayscale to colour gradient conversion pdp_grey convert image to greyscale pdp_invert invert video pdp_motion_blur blurs motion pdp_motion_fade motion triggered fade out pdp_motion_phase phase shifts motion pdp_offset add an offset to an image pdp_phase applies an allpass filter to an image pdp_phase_hor horizontal allpass pdp_phase_ver vertical allpass pdp_png_to convert a png file (on disk) to a certain packet type pdp_qt_control movie file controller (different play modes) pdp_qtloop~ varispeed (interpolated) looper pdp_qtloop2~ same, but depends on tabreadmix~ from creb pdp_saturation change colour saturation pdp_save_png_sequence save png sequence in /tmp dir pdp_sub subtract 2 images pdp_invert inverse video pdp_tag tag a packet (to use it with route) pdp_xv_keycursor a keyboard/mouse controller using pdp_xv matrix processors pdp_m_mv matrix vector multiply pdp_m_mm matrix matrix multiply pdp_m_+=mm matrix matrix multiply add pdp_m_LU compute LU decomposition pdp_m_LU_inverse compute matrix inverse from LU decomp pdp_m_LU_solve solve a linear system using LU decomp matrix abstractions pdp_m_inverse compute matrix inverse SEPARATE LIBRARIES: cellular automata (pdp_scaf) pdp_ca computes a cellular automaton (as a generator or a filter) pdp_ca2image convert a CA packet to a greyscale image (obsolete: use pdp_convert) pdp_image2ca convert an image to a CA packet (black and white) (obsolete: use pdp_convert) 3d drawing objects (pdp_opengl) 3dp_windowcontext a drawable window 3dp_draw draw objects (cube, sphere, ...) 3dp_view viewing transforms (rotate, translate, ...) 3dp_light light source 3dp_push push a matrix (modelview, texture, ...) 3dp_dlist compile a display list 3dp_snap copies the drawing buffer to a texture packet 3dp_mode set the current matrix mode 3dp_toggle set some opengl state variables 3d drawing abstractions (pdp_opengl) 3dp_mouserotate connect to 3dp_windowcontext to rotate the scene 3dp_blend turn on accumulative blending mode pdp-0.14.1+darcs20180201/include/000077500000000000000000000000001266045153600157215ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/include/Makefile000066400000000000000000000000351266045153600173570ustar00rootroot00000000000000current: clean: rm -f *~ pdp-0.14.1+darcs20180201/include/pdp.h000066400000000000000000000100001266045153600166440ustar00rootroot00000000000000/* * Pure Data Packet header file. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_H #define PDP_H /* header and subheader size in bytes */ #include #include #include "pdp_pd.h" /* config stuff */ #include "pdp_config.h" /* debug stuff */ #include "pdp_debug.h" /* some typedefs */ #include "pdp_types.h" /* pdp's symbol handling */ #include "pdp_symbol.h" /* the list object */ #include "pdp_list.h" /* memory management */ #include "pdp_mem.h" /* console messages */ #include "pdp_post.h" /* PDP_IMAGE COMPONENTS */ /* header and methods for the built in image packet type */ #include "pdp_image.h" /* low level image processing and high level dispatching routines */ #include "pdp_imageproc.h" /* low level image conversion routines */ #include "pdp_llconv.h" /* low level image resampling routines */ #include "pdp_resample.h" /* PDP_BITMAP COMPONENTS */ /* header and methods for the built in bitmap packet type */ #include "pdp_bitmap.h" /* PDP_MATRIX COMPONENTS */ #include "pdp_matrix.h" /* PDP SYSTEM COMPONENTS */ /* packet pool stuff */ #include "pdp_packet.h" /* processing queue object */ #include "pdp_queue.h" /* several communication helper methods (pd specific) */ #include "pdp_comm.h" /* type handling subsystem */ #include "pdp_type.h" /* dpd command stuff */ #include "pdp_dpd_command.h" /* BACKWARDS COMPAT STUFF */ #include "pdp_compat.h" #endif /* PDP CORE API OVERVIEW pdp_packet_* : packet methods, first argument is packet id new: construct a raw packet (depreciated) new_*: construct packet of specific type/subtype/... mark_unused: release mark_passing: conditional release (release on first copy ro/rw) copy_ro: readonly (shared) copy copy_rw: private copy clone_rw: private copy (copies only meta data, not the content) header: get the raw header (t_pdp *) data: get the raw data (void *) pass_if_valid: send a packet to pd outlet, if it is valid replace_if_valid delete packet and replace with new one, if new is valid copy_ro_or_drop: copy readonly, or don't copy if dest slot is full + send drop notify copy_rw_or_drop: same, but private copy get_description: retrieve type info convert_ro: same as copy_ro, but with an automatic conversion matching a type template convert_rw: same as convert_ro, but producing a private copy pdp_pool_* : packet pool methods collect_garbage: manually free all unused resources in packet pool pdp_queue_* : processing queue methods add: add a process method + callback finish: wait until a specific task is done wait: wait until processing queue is done pdp_control_* : central pdp control hub methods notify_drop: notify that a packet has been dropped pdp_type_* : packet type mediator methods description_match: check if two type templates match register_conversion: register a type conversion program NOTE: it is advised to derive your module from the pdp base class defined in pdp_base.h instead of communicating directly with the pdp core */ pdp-0.14.1+darcs20180201/include/pdp_ascii.h000066400000000000000000000026131266045153600200270ustar00rootroot00000000000000/* * Pure Data Packet header file. ascii packet type. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_H #define PDP_H /* ascii data packet */ typedef struct { unsigned int encoding; /* image encoding (data format) */ unsigned int width; /* image width in pixels */ unsigned int height; /* image height in pixels */ } t_ascii; /* ascii encodings */ #define PDP_ASCII_BW 1 /* 8 bit per character black and white.*/ #define PDP_ASCII_IBM 2 /* 16 bit per character colour (8 bit character, 8 bit colour, like good old text framebuffers.*/ #define PDP_ASCII_RGB 3 /* 64 bit per character colour (8 bit character, 3x8 bit RGB */ #endif pdp-0.14.1+darcs20180201/include/pdp_base.h000066400000000000000000000111241266045153600176460ustar00rootroot00000000000000/* * Pure Data Packet base class header file. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains the specification of the pdp base class. It is derived from t_object, the basic pd object (like any other pd extern). Have a look at pdp_add, pdp_gain and pdp_noise to see how to use this. */ #define MAX_NB_PDP_BASE_INLETS 4 #define MAX_NB_PDP_BASE_OUTLETS 4 #include "pdp_pd.h" #include "pdp_symbol.h" #include "pdp_types.h" #include "pdp_queue.h" #include "pdp_comm.h" #include "pdp_compat.h" #include "pdp_packet.h" typedef void (*t_pdp_method)(void *); typedef void* (*t_pdp_newmethod)(void *); typedef struct { t_object x_obj; int b_inlets; // the number of pdp inlets int b_outlets; // the number of pdp outlets // registers to store incoming packets int b_packet[MAX_NB_PDP_BASE_INLETS]; int b_packet_next[MAX_NB_PDP_BASE_INLETS]; t_pdp_symbol *b_type_template[MAX_NB_PDP_BASE_INLETS]; int b_queue_id; // task id in process queue (for callback cancelling) //int b_dropped; // indicate if a packet was dropped during register_rw cycle // wil the default (left) active inlet accept pdp messages ? int b_active_inlet_enabled; int b_active_inlet_readonly; // the process callbacks t_pdp_method b_process_method; // called in pdp thread t_pdp_method b_preproc_method; // called before thread (for packet alloc and checking) t_pdp_method b_postproc_method; // called after thread (for outlet stuff other than default active packet->out0) // packet outlets t_outlet *b_outlet[MAX_NB_PDP_BASE_OUTLETS]; u32 b_channel_mask; // channel mask int b_thread_enabled; // thread enable switch t_pdp_procqueue *b_q; // queue object } t_pdp_base; /* setup base class. call this in your derived class setup method */ void pdp_base_setup(t_class *c); /* base class constructor/destructor. call this in your base class constructor/destructor */ void pdp_base_init(void *x); void pdp_base_free(void *x); /* register processing callbacks */ void pdp_base_set_process_method(void *x, t_pdp_method m); //process callback (called from pdp thread) void pdp_base_set_preproc_method(void *x, t_pdp_method m); //pre-process callback (called before process from pd thread) void pdp_base_set_postproc_method(void *x, t_pdp_method m); //post-process callback (called after process from pd thread) /* configure inlets/outlets */ void pdp_base_add_pdp_inlet(void *x); t_outlet *pdp_base_add_pdp_outlet(void *x); void pdp_base_disable_active_inlet(void *x); //use this for pdp generators void pdp_base_readonly_active_inlet(void *x); //use this for pdp converters ("out of place" processing) void pdp_base_add_gen_inlet(void *x, t_symbol *from, t_symbol *to); // generic inlet /* bang method */ void pdp_base_bang(void *x); /* move delayed passive packets in place */ void pdp_base_movepassive(void *x); /* packet manipulation methods 0 active inlet (left) if enabled >0 additional pdp inlets created with pdp_base_add_pdp_inlet */ int pdp_base_get_packet(void *x, int inlet); // get the packet from an inlet int pdp_base_move_packet(void *x, int inlet); // same as get, but it removes the reference in the base class void pdp_base_set_packet(void *x, int inlet, int packet); // set (replace) the active packet (will be sent to outlet) /* getters for base class data */ u32 pdp_base_get_chanmask(void *x); t_object *pdp_base_get_object(void *x); /* thread control */ void pdp_base_disable_thread(void *x); /* type control */ void pdp_base_set_type_template(void *x, int inlet, t_pdp_symbol *type_template); /* queue control */ void pdp_base_queue_wait(void *x); void pdp_base_set_queue(void *x, t_pdp_procqueue *q); t_pdp_procqueue *pdp_base_get_queue(void *x); pdp-0.14.1+darcs20180201/include/pdp_bitmap.h000066400000000000000000000046551266045153600202230ustar00rootroot00000000000000/* * Pure Data Packet system implementation. 8 bit image packet interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains methods for the image packets pdp_packet_new_* methods are several image packet constructors It also contains some pdp_type_ methods, for type checking and conversion. */ #ifndef PDP_BITMAP_H #define PDP_BITMAP_H /* bitmap data packet */ typedef struct _bitmap { /* standard images */ unsigned int encoding; /* image encoding (fourcc data format) */ unsigned int width; /* image width in pixels */ unsigned int height; /* image height in pixels */ unsigned int bpp; /* bits per pixel (0 == standard) */ } t_bitmap; /* supported encodings (fourcc) */ /* special */ #define PDP_BITMAP_RGB 0x32424752 #define PDP_BITMAP_RGBA 0x41424752 #define PDP_BITMAP_GREY 0x59455247 /* packet yuv */ #define PDP_BITMAP_YUY2 0x32595559 #define PDP_BITMAP_UYVY 0x59565955 /* planar yuv */ #define PDP_BITMAP_I420 0x30323449 #define PDP_BITMAP_YV12 0x32315659 /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* bitmap constructors*/ int pdp_packet_new_bitmap_yv12(u32 width, u32 height); int pdp_packet_new_bitmap_grey(u32 width, u32 height); int pdp_packet_new_bitmap_rgb(u32 width, u32 height); int pdp_packet_new_bitmap_rgba(u32 width, u32 height); int pdp_packet_new_bitmap(int type, u32 width, u32 height); /* utility methids */ void pdp_packet_bitmap_flip_top_bottom(int packet); /* get description */ t_pdp_symbol *pdp_packet_bitmap_get_description(int packet); /* get subheader */ t_bitmap *pdp_packet_bitmap_info(int packet); int pdp_packet_bitmap_isvalid(int packet); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_comm.h000066400000000000000000000100221266045153600176630ustar00rootroot00000000000000/* * Pure Data Packet system implementation. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains misc communication methods */ #ifndef PDP_COMM_H #define PDP_COMM_H #include "pdp_symbol.h" #include "pdp_list.h" /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* pdp's pd symbols for communication don't use these directly!! use the macros instead, in case this is proven to be too much of a hack.. it's too much of a hack. getting rid of them. */ #define PDP_SYMBOL_HACK 0 #if PDP_SYMBOL_HACK extern t_symbol s_pdp; extern t_symbol s_register_ro; extern t_symbol s_register_rw; extern t_symbol s_process; extern t_symbol s_dpd; extern t_symbol s_inspect; extern t_symbol s_accumulate; extern t_symbol s_chanmask; #define S_PDP &s_pdp #define S_REGISTER_RO &s_register_ro #define S_REGISTER_RW &s_register_rw #define S_PROCESS &s_process #define S_DPD &s_dpd #define S_INSPECT &s_inspect #define S_ACCUMULATE &s_accumulate #define S_CHANMASK &s_chanmask #else #define S_PDP gensym("pdp") #define S_REGISTER_RO gensym("register_ro") #define S_REGISTER_RW gensym("register_rw") #define S_PROCESS gensym("process") #define S_DPD gensym("dpd") #define S_INSPECT gensym("inspect") #define S_ACCUMULATE gensym("accumulate") #define S_CHANMASK gensym("chanmask") #endif /* utility methods */ /* if packet is valid, mark it unused and send it to an outlet */ void pdp_packet_pass_if_valid(t_outlet *outlet, int *packet); /* if source packet is valid, release dest packet and move src->dest */ void pdp_packet_replace_if_valid(int *dpacket, int *spacket); /* copy_ro if dest packet if invalid, else drop source (don't copy) + send drop notif to pdp system returns 1 if dropped, 0 if copied */ int pdp_packet_copy_ro_or_drop(int *dpacket, int spacket); int pdp_packet_convert_ro_or_drop(int *dpacket, int spacket, t_pdp_symbol *type_template); /* copy_rw if dest packit is invalid, else drop source (don't copy) + send drop notif to pdp system returns 1 if dropped, zero if copied */ int pdp_packet_copy_rw_or_drop(int *dpacket, int spacket); int pdp_packet_convert_rw_or_drop(int *dpacket, int spacket, t_pdp_symbol *type_template); /* pd and pdp conversion stuff */ void pd_atom_to_pdp_atom(t_atom *pdatom, t_pdp_atom *pdpatom); /* send pdp lists and atoms */ void outlet_pdp_atom(t_outlet *out, struct _pdp_atom *a); void outlet_pdp_list(t_outlet *out, struct _pdp_list *l); /* send a packet to an outlet: it is only legal to call this on a "passing packet" or a "read only packet". this means it is illegal to change a packet after you have passed it to others, since this would mess up all read only references to the packet. */ /* this seems like a nice place to hide a comment on the notion of read/write in pdp which packets are writable? all packets with exactly 1 user. this includes all packets aquired with pdp_packet_*_rw or a constructor, and all packets that are not registered after being sent out by outlet_pdp. which packets are readable? all packets */ void outlet_pdp(t_outlet *out, int packetid); /* send an accumulation (context) packet to an outlet. this is for usage in the dpd base class. */ void outlet_dpd(t_outlet *out, int packetid); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_compat.h000066400000000000000000000003611266045153600202200ustar00rootroot00000000000000 /* please don't use any of these. for backwards compatibility only */ #ifndef PDP_COMPAT_H #define PDP_COMPAT_H void pdp_pass_if_valid(t_outlet *outlet, int *packet); void pdp_replace_if_valid(int *dpacket, int *spacket); #endif pdp-0.14.1+darcs20180201/include/pdp_config.h.in000066400000000000000000000042461266045153600206150ustar00rootroot00000000000000/* include/pdp_config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `gslcblas' library (-lgslcblas). */ #undef HAVE_LIBGSLCBLAS /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the header file. */ #undef HAVE_LIBV4L1_VIDEODEV_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_VIDEODEV_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* build pdp_glx */ #undef HAVE_PDP_GLX /* gsl support */ #undef HAVE_PDP_GSL /* build pdp_v4l with libv4l */ #undef HAVE_PDP_LIBV4L /* build png support */ #undef HAVE_PDP_PNG /* build pdp_qt */ #undef HAVE_PDP_QT /* build pdp_sdl */ #undef HAVE_PDP_SDL /* build pdp_v4l */ #undef HAVE_PDP_V4L /* build X11 support */ #undef HAVE_PDP_X /* build pdp_xv */ #undef HAVE_PDP_XV /* enable forced pwc v4l support */ #undef HAVE_PWCV4L /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* "disable debugging support" */ #undef PDP_DEBUG /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS pdp-0.14.1+darcs20180201/include/pdp_control.h000066400000000000000000000004511266045153600204150ustar00rootroot00000000000000#ifndef __PDP_CONTROL_H__ #define __PDP_CONTROL_H__ #include "pdp_pd.h" struct _pdp_control; typedef void (t_pdp_control_method_notify)(struct _pdp_control *x); void pdp_control_notify_broadcast(t_pdp_control_method_notify *notify); void pdp_control_addmethod(t_method m, t_symbol *s); #endif pdp-0.14.1+darcs20180201/include/pdp_debug.h000066400000000000000000000004751266045153600200310ustar00rootroot00000000000000#ifndef __PDP_DEBUG_H_ #define __PDP_DEBUG_H_ #include "pdp_config.h" // needed for PDP_DEBUG define void pdp_assert_hook (char *condition, char *file, int line); #if PDP_DEBUG #define PDP_ASSERT(x) if (!(x)) {pdp_assert_hook(#x, __FILE__, __LINE__);} #else #define PDP_ASSERT(x) #endif #endif //__PDP_DEBUG_H_ pdp-0.14.1+darcs20180201/include/pdp_dpd_base.h000066400000000000000000000125411266045153600205010ustar00rootroot00000000000000/* * Pure Data Packet header file. DPD base class * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* dpd base class for context based processors (for pd-fying standard stack based serial languages) not all of pdp is used here, but the class is derived from the pdp base class to enable mixing standard pdp (data flow packet processing) and dpd (context based serial languages) dpd is short for "upside down pdp". the name stems from the observation of opengl code in pd (like in gem) having an upside down feel when looking through dataflow eyes. i.e.: the target (window context) is on top, while the objects (geos) are at the bottom connected by a chain of geometric transforms the principles of dpd are simple: * there is only one main packet, received on the left inlet. * this packet is called the "context" and is produced by and returned to a top context source/sink * additional pd messages and pdp packets can be received on the cold inlets * as opposed to pdp, no copies are made of this context packet, all operations on it are accumulative. * the protocol is different because fanout is prohibited (so no ro/rw registering) * the only exception for fanout are inspectors, which have precedence over normal processors * all processors and inspectors for a single context type must use the pdp thread, to preserve execution order */ #include "pdp_base.h" #define PDP_DPD_MAX_CONTEXT_OUTLETS 4 typedef struct pdp_dpd_base_struct { t_pdp_base b_base; /* pdp base class */ int b_nb_context_outlets; t_outlet *b_context_outlet[PDP_DPD_MAX_CONTEXT_OUTLETS]; /* dpd outlets */ int b_outlet_enable[PDP_DPD_MAX_CONTEXT_OUTLETS]; /* dpd outlets */ t_pdp_method b_accum_method[PDP_DPD_MAX_CONTEXT_OUTLETS]; /* accumulation methods for each outlet */ t_pdp_method b_accum_callback[PDP_DPD_MAX_CONTEXT_OUTLETS]; /* pd callback methods for each outlet */ //int b_accum_queue_id[PDP_DPD_MAX_CONTEXT_OUTLETS]; /* accumulator queue id's */ t_pdp_method b_inspector_method; /* pdp thread inspector callback */ t_pdp_method b_inspector_callback; /* main thread inspector callback */ //int b_inspector_queue_id; t_pdp_method b_cleanup_method; /* queued after propagation is done */ t_pdp_method b_cleanup_callback; /* queued after propagation is done */ //int b_cleanup_queue_id; t_pdp_method b_complete_notify; /* method called after packet output is done */ t_pdp_newmethod b_command_factory_method; /* command factory method */ int b_context_packet; /* the current context packet */ int b_dpd_active_inlet_disabled; } t_pdp_dpd_base; #ifdef __cplusplus extern "C" { #endif /* bang method (propagate context to outlets & register callbacks) mainly for context source/sinks it is not registered as a pd message by default ! */ void pdp_dpd_base_bang(void *x); /* get/set the context packet */ int pdp_dpd_base_get_context_packet(void *x); void pdp_dpd_base_set_context_packet(void *x, int p); int pdp_dpd_base_move_context_packet(void *x); /* add a context outlet and it's corresponding accumulation (process) and callback method */ t_outlet *pdp_dpd_base_add_outlet(void *x, t_pdp_method accum_method, t_pdp_method accum_callback); /* add a cleanup callback (called after all propagation is finished) for sources/sinks */ void pdp_dpd_base_add_cleanup(void *x, t_pdp_method cleanup_method, t_pdp_method accum_callback); /* add an inspector callback */ void pdp_dpd_base_add_inspector(void *x, t_pdp_method inspector_method); /* destructor */ void pdp_dpd_base_free(void *x); /* init method */ void pdp_dpd_base_init(void *x); /* disable dpd active inlet */ void pdp_dpd_base_disable_active_inlet(void *x); /* enable/disable outlet */ void pdp_dpd_base_enable_outlet(void *x, int outlet, int toggle); /* register notify method (called from the end of pdp_dpd_base_bang) */ void pdp_dpd_base_register_complete_notify(void *x, t_pdp_method method); /* register a command init (factory) method this method should return a command object to place in the queue */ void pdp_dpd_base_register_command_factory_method(void *x, t_pdp_newmethod command_factory_method); /* class setup method */ void pdp_dpd_base_setup(t_class *class); /* add a command to the process queue */ void pdp_dpd_base_queue_command(void *x, void *c, t_pdp_method process, t_pdp_method callback, int *id); /* get/set the queue instance (thread) used for scheduling */ #define pdp_dpd_base_set_queue pdp_base_set_queue #define pdp_dpd_base_get_queue pdp_base_get_queue #define pdp_dpd_base_queue_wait pdp_base_queue_wait #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/include/pdp_dpd_command.h000066400000000000000000000046411266045153600212070ustar00rootroot00000000000000 /* * Pure Data Packet header file. DPD command class * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this object implements a dpd command 'factory and recycling center' */ /* a small note on commands & dpd dpd uses a different synchronization model than pdp. in pdp, objects only pass once the process method in the process thread has finished. in dpd a context packet propagates a context trough an tree of objects, depth first, following the pd messages. it is possible to send a list of contexts trough a tree before the actual processing starts. therefore, each time a context passes trough an object, a new command object (or memento) needs to be created that saves the state of the rendering context. the command factory class can be used to create these commands. the dpd base class queues a command object and calls the registered method on the object instead of the dpd object. so a command object is in fact a delegate of the dpd object in question. */ #ifndef PDP_DPD_COMMAND #define PDP_DPD_COMMAND #include "pdp_types.h" /* COMMAND BASE CLASS */ typedef struct _pdp_dpd_command { struct _pdp_dpd_command *next; u32 used; } t_pdp_dpd_command; /* COMMAND LIST (COMMAND FACTORY) CLASS */ typedef struct _pdp_dpd_commandfactory { u32 nb_commands; u32 command_size; t_pdp_dpd_command *command; } t_pdp_dpd_commandfactory; /* COMMAND LIST METHODS */ void pdp_dpd_commandfactory_init(t_pdp_dpd_commandfactory *x, u32 size); void pdp_dpd_commandfactory_free(t_pdp_dpd_commandfactory *x); t_pdp_dpd_command *pdp_dpd_commandfactory_get_new_command(t_pdp_dpd_commandfactory *x); /* COMMAND METHODS */ void pdp_dpd_command_suicide(void *); #endif pdp-0.14.1+darcs20180201/include/pdp_image.h000066400000000000000000000053631266045153600200260ustar00rootroot00000000000000/* * Pure Data Packet system implementation. Image packet interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains methods for the image packets pdp_packet_new_* methods are several image packet constructors It also contains some pdp_type_ methods, for type checking and conversion. */ #ifndef PDP_IMAGE_H #define PDP_IMAGE_H #include "pdp_symbol.h" #include "pdp_types.h" /* image subheader */ typedef struct _image { /* standard images */ unsigned int encoding; /* image encoding (data format) */ unsigned int width; /* image width in pixels */ unsigned int height; /* image height in pixels */ unsigned int depth; /* number of colour planes if PDP_IMAGE_MCHP */ unsigned int chanmask; /* channel bitmask to mask out inactive channels (0 == not used) */ } t_image; /* image encodings */ #define PDP_IMAGE_YV12 1 /* 24bbp: 16 bit Y plane followed by 16 bit 2x2 subsampled V and U planes.*/ #define PDP_IMAGE_GREY 2 /* 16bbp: 16 bit Y plane */ #define PDP_IMAGE_MCHP 4 /* generic 16bit multi channel planar (16 bit 3D tensor) */ /* slice synchro information */ #define PDP_IMAGE_SLICE_FIRST (1<<0) #define PDP_IMAGE_SLICE_LAST (1<<1) #define PDP_IMAGE_SLICE_BODY (1<<2) /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* validate and compat check */ int pdp_packet_image_isvalid(int packet); int pdp_packet_image_compat(int packet0, int packet1); /* short cuts to create specific packets */ int pdp_packet_new_image(u32 encoding, u32 width, u32 height); int pdp_packet_new_image_YCrCb(u32 width, u32 height); int pdp_packet_new_image_grey(u32 width, u32 height); int pdp_packet_new_image_mchp(u32 width, u32 height, u32 depth); #define pdp_packet_new_image_multi pdp_packet_new_image_mchp /* get info */ t_pdp_symbol *pdp_packet_image_get_description(int packet); t_image *pdp_packet_image_info(int packet); /* set props */ void pdp_packet_image_set_chanmask(int packet, unsigned int chanmask); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_imagebase.h000066400000000000000000000030201266045153600206450ustar00rootroot00000000000000/* * Pure Data Packet image processor base class header file. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains the specification of the pdp base class. It is derived from t_object, the basic pd object (like any other pd extern). Have a look at pdp_add, pdp_gain and pdp_noise to see how to use this. */ #include "pdp_base.h" typedef struct { t_pdp_base x_obj; u32 b_channel_mask; // channel mask } t_pdp_imagebase; /* setup base class. call this in your derived class setup method */ void pdp_imagebase_setup(t_class *c); /* base class constructor/destructor. call this in your base class constructor/destructor */ void pdp_imagebase_init(void *x); void pdp_imagebase_free(void *x); /* getters for image base class data */ u32 pdp_imagebase_get_chanmask(void *x); pdp-0.14.1+darcs20180201/include/pdp_imageproc.h000066400000000000000000000211251266045153600207040ustar00rootroot00000000000000 /* * Pure Data Packet. Header file for image processing routines (used in modules). * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this is a c wrapper around platform specific (mmx) code */ #include "pdp_types.h" #ifndef PDP_IMAGEPROC_H #define PDP_IMAGEPROC_H #ifdef __cplusplus extern "C" { #endif /* the basic allocation unit, for stack alignment */ typedef long long t_pdp_imageproc_stackword; /* convert byte size to nb of stack words */ #define PDP_IMAGEPROC_NB_STACKWORDS(x) (((x-1)/sizeof(t_pdp_imageproc_stackword))+1) /* the packet types should be the same for the dispatchers. packet0 is the dominant packet */ /* image processing dispatchers */ void pdp_imageproc_dispatch_1buf(void (*process_routine)(void*, u32, u32, s16*), void *x, u32 chanmask, int packet0); void pdp_imageproc_dispatch_2buf(void (*process_routine)(void*, u32, u32, s16*, s16 *), void *x, u32 chanmask, int packet0, int packet1); void pdp_imageproc_dispatch_3buf(void (*process_routine)(void*, u32, u32, s16*, s16 *, s16*), void *x, u32 chanmask, int packet0, int packet1, int packet2); /* get legal image dimensions */ /* this is a fix for the dimension problem */ /* some imageproc implementations require the dims to be a multiple of some square */ u32 pdp_imageproc_legalwidth(int i); u32 pdp_imageproc_legalheight(int i); u32 pdp_imageproc_legalwidth_round_down(int i); u32 pdp_imageproc_legalheight_round_down(int i); /****************************** 16 bit signed (pixel) routines ***************************************/ // mix 2 images void *pdp_imageproc_mix_new(void); int pdp_imageproc_mix_nb_stackwords(void); void pdp_imageproc_mix_delete(void *x); void pdp_imageproc_mix_setleftgain(void *x, float gain); void pdp_imageproc_mix_setrightgain(void *x, float gain); void pdp_imageproc_mix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); // random mix 2 images // note: random number generator can be platform specific // however, it should be seeded. (same seed produces the same result) // threshold = 0 -> left image // threshold = 1 -> right image void *pdp_imageproc_randmix_new(void); int pdp_imageproc_randmix_nb_stackwords(void); void pdp_imageproc_randmix_delete(void *x); void pdp_imageproc_randmix_setthreshold(void *x, float threshold); void pdp_imageproc_randmix_setseed(void *x, float seed); void pdp_imageproc_randmix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); // produce a random image // note: random number generator can be platform specific // however, it should be seeded. (same seed produces the same result) void *pdp_imageproc_random_new(void); void pdp_imageproc_random_delete(void *x); void pdp_imageproc_random_setseed(void *x, float seed); void pdp_imageproc_random_process(void *x, u32 width, u32 height, s16 *image); // produce a plasma image // note: random number generator can be platform specific // however, it should be seeded. (same seed produces the same result) void *pdp_imageproc_plasma_new(void); void pdp_imageproc_plasma_delete(void *x); void pdp_imageproc_plasma_setseed(void *x, float seed); void pdp_imageproc_plasma_setturbulence(void *x, float seed); void pdp_imageproc_plasma_process(void *x, u32 width, u32 height, s16 *image); // apply a gain to an image void *pdp_imageproc_gain_new(void); void pdp_imageproc_gain_delete(void *x); void pdp_imageproc_gain_setgain(void *x, float gain); void pdp_imageproc_gain_process(void *x, u32 width, u32 height, s16 *image); // add two images void pdp_imageproc_add_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); // mul two images void pdp_imageproc_mul_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); // 3x1 or 1x3 in place convolution // orientation #define PDP_IMAGEPROC_CONV_HORIZONTAL 0 #define PDP_IMAGEPROC_CONV_VERTICAL 1 void *pdp_imageproc_conv_new(void); void pdp_imageproc_conv_delete(void *x); void pdp_imageproc_conv_setmin1(void *x, float val); void pdp_imageproc_conv_setzero(void *x, float val); void pdp_imageproc_conv_setplus1(void *x, float val); void pdp_imageproc_conv_setbordercolor(void *x, float intensity); void pdp_imageproc_conv_setorientation(void *x, u32 val); void pdp_imageproc_conv_setnbpasses(void *x, u32 val); void pdp_imageproc_conv_process(void *x, u32 width, u32 height, s16 *image); // colour rotation for 2 colour planes ($$$TODO: change interface) // matrix is column encoded void *pdp_imageproc_crot2d_new(void); void pdp_imageproc_crot2d_delete(void *x); void pdp_imageproc_crot2d_setmatrix(void *x, float *matrix); void pdp_imageproc_crot2d_process(void *x, s16 *image, u32 width, u32 height); // colour rotation for 3 colour planes ($$$TODO: change interface) void *pdp_imageproc_crot3d_new(void); void pdp_imageproc_crot3d_delete(void *x); void pdp_imageproc_crot3d_setmatrix(void *x, float *matrix); void pdp_imageproc_crot3d_process(void *x, s16 *image, u32 width, u32 height); // biquad space // directions #define PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM (1<<0) #define PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP (1<<1) #define PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT (1<<2) #define PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT (1<<3) void *pdp_imageproc_bq_new(void); void pdp_imageproc_bq_delete(void *x); void pdp_imageproc_bq_setcoef(void *x, float *coef); // a0,a1,a2,b0,b1,b2 void pdp_imageproc_bq_setnbpasses(void *x, u32 nbpasses); void pdp_imageproc_bq_setdirection(void *x, u32 direction); void pdp_imageproc_bq_process(void *x, u32 width, u32 height, s16* image); // biquad time //void *pdp_imageproc_bqt_new(void); //void pdp_imageproc_bqt_delete(void *x); //void pdp_imageproc_bqt_setcoef(void *x, float *coef); // a0,a1,a2,b0,b1,b2 void pdp_imageproc_bqt_process(void *x, u32 width, u32 height, s16 *image, s16 *state0, s16 *state1); // zoom object void *pdp_imageproc_resample_affinemap_new(void); void pdp_imageproc_resample_affinemap_delete(void *x); void pdp_imageproc_resample_affinemap_setcenterx(void *x, float f); void pdp_imageproc_resample_affinemap_setcentery(void *x, float f); void pdp_imageproc_resample_affinemap_setzoomx(void *x, float f); void pdp_imageproc_resample_affinemap_setzoomy(void *x, float f); void pdp_imageproc_resample_affinemap_setangle(void *x, float f); void pdp_imageproc_resample_affinemap_process(void *x, u32 width, u32 height, s16 *srcimage, s16 *dstimage); //chebyshev poly void *pdp_imageproc_cheby_new(int order); void pdp_imageproc_cheby_delete(void *x); void pdp_imageproc_cheby_setcoef(void *x, u32 n, float f); void pdp_imageproc_cheby_setnbpasses(void *x, u32 n); void pdp_imageproc_cheby_process(void *x, u32 width, u32 height, s16 *image); //logic ops void pdp_imageproc_xor_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); void pdp_imageproc_or_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); void pdp_imageproc_and_process(void *x, u32 width, u32 height, s16 *image, s16 *image2); void pdp_imageproc_mask_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_not_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_hardthresh_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_softthresh_process(void *x, u32 width, u32 height, s16 *image); //other stateles operators void pdp_imageproc_abs_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_zthresh_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_plasma_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_ispositive_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_sign_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_flip_lr_process(void *dummy, u32 width, u32 height, s16 *image); void pdp_imageproc_flip_tb_process(void *dummy, u32 width, u32 height, s16 *image); //set to zero void pdp_imageproc_zero_process(void *x, u32 width, u32 height, s16 *image); void pdp_imageproc_constant_process(void *x, u32 width, u32 height, s16 *image); #ifdef __cplusplus } #endif #endif //PDP_IMAGEPROC_H pdp-0.14.1+darcs20180201/include/pdp_internals.h000066400000000000000000000026071266045153600207410ustar00rootroot00000000000000 /* * Pure Data Packet internal header file. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains prototypes for "private" pdp methods. DON'T CALL THESE FROM OUTSIDE OF PDP! unless you really know what you are doing. */ #ifndef PDP_INTERNALS_H #define PDP_INTERNALS_H #ifdef __cplusplus extern "C" { #endif /* INTERNAL SYSTEM METHODS */ /* set/unset main pdp thread usage */ void pdp_queue_use_thread(int t); /* INTERNAL PACKET METHODS */ /* create a new packet, reuse if possible. ONLY USE THIS IN A TYPE SPECIFIC CONSTRUCTOR! */ int pdp_packet_new(unsigned int datatype, unsigned int datasize); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_list.h000066400000000000000000000215341266045153600177150ustar00rootroot00000000000000 /* * Pure Data Packet header file. List class * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* the pdp list is composed of atoms. the default atom is a pointer. lists can be recursed into trees. note: all functions that return t_pdp_word and don't take a type argument obviously don't perform any type checking. if you have heterogenous lists, you should use atom iterators or direct access. functions starting with "pdp_tree" recurse through sublists. functions starting with "pdp_list" stay at the top level. */ #ifndef PDP_LIST_H #define PDP_LIST_H struct _pdp_list; struct _pdp_atom; /* THE LIST OBJECT */ typedef enum { /* generic atoms */ a_undef = 0, a_pointer, a_float, a_int, a_symbol, a_packet, a_list, a_atom_pointer, /* forth atoms */ a_forthword, /* forth word operating on a stack */ a_vmword, /* forth word operating on a virtual machine */ a_vmmacro /* forth word operating on vm, manipilating current def */ } t_pdp_word_type; typedef union _pdp_word { void* w_pointer; float w_float; int w_int; struct _pdp_symbol* w_symbol; int w_packet; struct _pdp_list* w_list; struct _pdp_atom* w_atom_pointer; } t_pdp_word; /* a list element */ typedef struct _pdp_atom { struct _pdp_atom *next; t_pdp_word w; t_pdp_word_type t; } t_pdp_atom; /* a list container */ typedef struct _pdp_list { int elements; t_pdp_atom *first; t_pdp_atom *last; } t_pdp_list; /* CONVENTION: trees stacks and lists. * all operations with "list" in them operate on flat lists. all the items contained in the list are either pure atoms (floats, ints, or symbols) or references (packets, pointers, lists) * all operations with "tree" in them, operate on recursive lists (trees) all sublists of the list (tree) are owned by the parent list, so you can't build trees from references to other lists. * stacks are trees (the forth can have tree's on a stack, or have recursive stacks) (WAS: stacks are by definition flat lists, so they can not contains sublists) */ typedef void (*t_pdp_atom_method)(t_pdp_atom *); typedef void (*t_pdp_word_method)(t_pdp_word); typedef void (*t_pdp_pword_method)(t_pdp_word *); typedef void (*t_pdp_free_method)(void *); /* creation / destruction */ t_pdp_atom* pdp_atom_new (void); void pdp_atom_free (t_pdp_atom *); t_pdp_list* pdp_list_new (int elements); void pdp_list_free (t_pdp_list *l); void pdp_list_clear (t_pdp_list *l); void pdp_tree_free (t_pdp_list *l); void pdp_tree_clear (t_pdp_list *l); /* call a free method on all pointers in a tree */ void pdp_tree_strip_pointers (t_pdp_list *l, t_pdp_free_method f); /* strip all packets from a tree. i.e. call pdp_packet_mark_unused on them */ void pdp_tree_strip_packets (t_pdp_list *l); /* copy a tree, and copy all packets readonly */ t_pdp_list *pdp_tree_copy_ro(t_pdp_list *l); t_pdp_list* pdp_tree_from_cstring(char *chardef, char **nextchar); /* check type syntax of list */ int pdp_tree_check_syntax(t_pdp_list *list, t_pdp_list *syntax); t_pdp_atom *pdp_atom_from_cstring(char *chardef, char **nextchar); //void pdp_atom_from_cstring(t_pdp_atom *a, char *string); /* traversal routines (map functions) */ /* use these in conjunction with gcc local functions if there's ever a portability problem: add a void* data argument to implement closures */ void pdp_list_apply (t_pdp_list *l, t_pdp_atom_method am); void pdp_tree_apply (t_pdp_list *l, t_pdp_atom_method am); void pdp_list_apply_word_method (t_pdp_list *l, t_pdp_word_type t, t_pdp_word_method wm); void pdp_tree_apply_word_method (t_pdp_list *l, t_pdp_word_type t, t_pdp_word_method wm); void pdp_list_apply_pword_method (t_pdp_list *l, t_pdp_word_type t, t_pdp_pword_method pwm); void pdp_tree_apply_pword_method (t_pdp_list *l, t_pdp_word_type t, t_pdp_pword_method pwm); /* copy: (reverse) copies a list. */ /* list copy is flat. pointers and packets are copied. so you need to ensure reference consistency yourself. */ t_pdp_list* pdp_list_copy (t_pdp_list *l); t_pdp_list* pdp_list_copy_reverse (t_pdp_list *l); t_pdp_list* pdp_tree_copy (t_pdp_list *l); t_pdp_list* pdp_tree_copy_reverse (t_pdp_list *l); /* cat: this makes a copy of the second list and adds it at the end of the first one */ void pdp_list_cat (t_pdp_list *l, t_pdp_list *tail); /* information */ int pdp_list_contains (t_pdp_list *l, t_pdp_word_type t, t_pdp_word w); int pdp_list_size (t_pdp_list *l); void pdp_list_print (t_pdp_list *l); void pdp_atom_print (t_pdp_atom *a); /* access */ void pdp_list_add (t_pdp_list *l, t_pdp_word_type t, t_pdp_word w); void pdp_list_add_back (t_pdp_list *l, t_pdp_word_type t, t_pdp_word w); void pdp_list_add_to_set (t_pdp_list *l, t_pdp_word_type t, t_pdp_word w); void pdp_list_remove (t_pdp_list *l, t_pdp_word_type t, t_pdp_word w); void pdp_list_add_atom(t_pdp_list *l, t_pdp_atom *a); void pdp_list_add_back_atom(t_pdp_list *l, t_pdp_atom *a); /* these don't do error checking. out of bound == error */ t_pdp_atom *pdp_list_pop_atom (t_pdp_list *l); t_pdp_word pdp_list_pop (t_pdp_list *l); t_pdp_word pdp_list_index (t_pdp_list *l, int indx); void pdp_list_pop_push (t_pdp_list *source, t_pdp_list *dest); /* some aliases */ #define pdp_list_add_front pdp_list_add #define pdp_list_push pdp_list_add #define pdp_list_queue pdp_list_add_end #define pdp_list_unqueue pdp_list_pop /* util */ void pdp_list_reverse(t_pdp_list *l); /* generic atom iterator */ #define PDP_ATOM_IN(list,atom) for (atom = list->first ; atom ; atom = atom->next) /* fast single type iterators */ /* generic */ #define PDP_WORD_IN(list, atom, word, type) for (atom=list->first ;atom && ((word = atom -> w . type) || 1); atom=atom->next) /* type specific */ #define PDP_POINTER_IN(list, atom, x) PDP_WORD_IN(list, atom, x, w_pointer) #define PDP_INT_IN(list, atom, x) PDP_WORD_IN(list, atom, x, w_int) #define PDP_FLOAT_IN(list, atom, x) PDP_WORD_IN(list, atom, x, w_float) #define PDP_SYMBOL_IN(list, atom, x) PDP_WORD_IN(list, atom, x, w_symbol) #define PDP_PACKET_IN(list, atom, x) PDP_WORD_IN(list, atom, x, w_packet) #define PDP_LIST_IN(list, atom, x) PDP_WORD_IN(list, atom, x, w_list) /* some macros for the pointer type */ #define pdp_list_add_pointer(l,p) pdp_list_add(l, a_pointer, ((t_pdp_word)((void *)(p)))) #define pdp_list_add_back_pointer(l,p) pdp_list_add_back(l, a_pointer, ((t_pdp_word)((void *)(p)))) #define pdp_list_add_pointer_to_set(l,p) pdp_list_add_to_set(l, a_pointer, ((t_pdp_word)((void *)(p)))) #define pdp_list_remove_pointer(l,p) pdp_list_remove(l, a_pointer, ((t_pdp_word)((void *)(p)))) #define pdp_list_contains_pointer(l,p) pdp_list_contains(l, a_pointer, ((t_pdp_word)((void *)(p)))) /* atom access */ #define PDP_LIST_ATOM_0(x) ((x)->first) #define PDP_LIST_ATOM_1(x) ((x)->first->next) #define PDP_LIST_ATOM_2(x) ((x)->first->next->next) #define PDP_LIST_ATOM_3(x) ((x)->first->next->next->next) #define PDP_LIST_ATOM_4(x) ((x)->first->next->next->next->next) /* array like setters */ static inline void pdp_atom_set(t_pdp_atom *a, t_pdp_word_type t, t_pdp_word w) {a->t = t; a->w = w;} static inline void pdp_list_set_0(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w) {pdp_atom_set(l->first, t, w);} static inline void pdp_list_set_1(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w) {pdp_atom_set(l->first->next, t, w);} static inline void pdp_list_set_2(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w) {pdp_atom_set(l->first->next->next, t, w);} /* evaluator (tiny lisp) */ typedef t_pdp_list* (*t_pdp_list_evaluator_function)(t_pdp_list *); #endif pdp-0.14.1+darcs20180201/include/pdp_list_macros.h000066400000000000000000000015741266045153600212630ustar00rootroot00000000000000#ifndef __PDP_LIST_MACROS__ #define __PDP_LIST_MACROS__ /* some additional (short named) list macros mainly for manipulationg argument lists. needs to be included locally. */ /* reading a list */ #define FIRST(l) ((l)->first) #define SIZE(l) ((l)->elements) #define NEXT(a) ((a)->next) #define N(a) (a = a->next) #define FLOAT(a) ((a)->t == a_float ? (a)->w.w_float : 0.0f) #define PACKET(a) ((a)->t == a_packet ? (a)->w.w_packet : -1) #define INT(a) ((a)->t == a_int ? (a)->w.w_packet : 0) /* creating a list, and adding stuff to the end (queueing) */ #define LIST(n) pdp_list_new(n) #define LFREE(l) pdp_list_free(l) #define QFLOAT(l, x) pdp_list_add_back(l, a_float, ((t_pdp_word)(float)(x))) #define QINT(l, x) pdp_list_add_back(l, a_int, ((t_pdp_word)(int)(x))) #define QPACKET(l, x) pdp_list_add_back(l, a_packet,((t_pdp_word)(int)(x))) #endif pdp-0.14.1+darcs20180201/include/pdp_llconv.h000066400000000000000000000042021266045153600202300ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : low level format conversion code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains low level conversion code it is a wrapper around some machine code routines padded with some extra c code */ /* don't rely too much on the calling conventions here this is mainly to tuck away "ugly" parts of the code that come up in several places */ #ifndef PDP_LLCONV_H #define PDP_LLCONV_H /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* raw image formats (RIF) descriptions used for low level conversion routines format: RIF_[component names and order]_[data arganization]_[data type] component names: R(red), G(green), B(blue), Y(chroma), V(chroma red), U(chroma blue) component type: [S/U][nb bits] ex: S16, U8 data organization: [P/P[samplefrequency]] ex: P(packed) P411(planar, 2nd and 3rd 2x2 subsampled) */ enum RIF { RIF_YVU__P411_U8, RIF_YUV__P411_U8, RIF_YVU__P411_S16, RIF_YVU__P444_S16, RIF_UYVY_P____U8, RIF_YUYV_P____U8, RIF_RGB__P____U8, RIF_RGBA_P____U8, RIF_RGB__P444_S16, RIF_GREY______S16, RIF_GREY______U8, RIF_BGR__P____U8, RIF_BGRA_P____U8 }; /* pdp_llconv is NOT thread safe !*/ /* gain = 1.0 means maximal */ /* low level convert 2 images */ void pdp_llconv(void *src, int stype, void *dest, int dtype, int w, int h); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_matrix.h000066400000000000000000000056421266045153600202500ustar00rootroot00000000000000/* * Pure Data Packet system implementation. matrix packet interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_MATRIX_H #define PDP_MATRIX_H #include "pdp_config.h" #ifdef HAVE_PDP_GSL #include #include #include #include #include #include #include "pdp_types.h" #define gsl_rows size1 #define gsl_columns size2 typedef struct _matrix { /* meta data */ u32 type; /* float/double real/complex */ u32 rows; u32 columns; /* gsl structures: these will be cast to the correct type on use */ gsl_block block; /* gsl block meta data */ gsl_vector vector; /* gsl vector meta data */ gsl_matrix matrix; /* gsl matrix meta data */ gsl_permutation perm; /* permutation data for storing an LU decomposition */ int signum; /* sign of permutation matrix */ } t_matrix; #define PDP_MATRIX 7 #define PDP_MATRIX_TYPE_RFLOAT 1 #define PDP_MATRIX_TYPE_CFLOAT 2 #define PDP_MATRIX_TYPE_RDOUBLE 3 #define PDP_MATRIX_TYPE_CDOUBLE 4 int pdp_packet_matrix_isvalid(int p); int pdp_packet_matrix_isvector(int p); int pdp_packet_matrix_ismatrix(int p); int pdp_packet_new_matrix(u32 rows, u32 columns, u32 type); int pdp_packet_new_matrix_product_result(CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, int pA, int pB); void pdp_packet_matrix_setzero(int p); /* getters: returns 0 if type is incorrect */ void *pdp_packet_matrix_get_gsl_matrix(int p, u32 type); void *pdp_packet_matrix_get_gsl_vector(int p, u32 type); int pdp_packet_matrix_get_type(int p); /* type transparent matrix operations */ /* blas wrappers */ /* C += scale op(A) op(B) */ int pdp_packet_matrix_blas_mm(CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, int pA, int pB, int pC, float scale_r, float scale_i); /* c += scale op(A) b */ int pdp_packet_matrix_blas_mv(CBLAS_TRANSPOSE_t TransA, int pA, int pb, int pc, float scale_r, float scale_i); /* other gsl wrappers */ int pdp_packet_matrix_LU(int p_matrix); int pdp_packet_matrix_LU_to_inverse(int p_matrix); int pdp_packet_matrix_LU_solve(int p_matrix, int p_vector); #endif #endif pdp-0.14.1+darcs20180201/include/pdp_mem.h000066400000000000000000000026221266045153600175150ustar00rootroot00000000000000/* * Pure Data Packet header file: memory allocation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _PDP_MEM_H_ #define _PDP_MEM_H_ #include /* a wrapper around malloc and free to keep track of pdp's memory usage */ void *pdp_alloc(int size); void pdp_dealloc(void *stuff); /* fast allocator object (for lists and atoms) */ typedef struct _pdp_fastalloc { unsigned int atom_size; unsigned int block_elements; pthread_mutex_t mut; struct _fastalloc *freelist; } t_pdp_fastalloc; void *pdp_fastalloc_new_atom(t_pdp_fastalloc *x); void pdp_fastalloc_save_atom(t_pdp_fastalloc *x, void *atom); t_pdp_fastalloc *pdp_fastalloc_new(unsigned int size); #endif pdp-0.14.1+darcs20180201/include/pdp_mmx.h000066400000000000000000000111271266045153600175400ustar00rootroot00000000000000 /* * Pure Data Packet. Header file for mmx routines. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_MMX_H #define PDP_MMX_H #ifdef __cplusplus extern "C" { #endif /****************************** 16 bit signed (pixel) routines ***************************************/ /* pack: gain is 8.8 fixed point */ void pixel_pack_s16u8_y(short int *input_pixels, unsigned char *output_pixels, int nb_pixels_div_8); void pixel_pack_s16u8_uv(short int *input_pixels, unsigned char *output_pixels, int nb_pixels_div_8); /* unpack: gain is not used -> full scale unpack */ void pixel_unpack_u8s16_y(unsigned char *input_pixels, short int *output_pixels, int nb_pixels_div_8); void pixel_unpack_u8s16_uv(unsigned char *input_pixels, short int *output_pixels, int nb_pixels_div_8); /* gain */ /* gain = integer */ /* shift is down shift count */ void pixel_gain_s16(short int *image, int nb_4pixel_vectors, short int gain[4], unsigned long long *shift); /* mix: left = gain_left * left + gain_right * right / gains are s.15 fixed point */ void pixel_mix_s16(short int *left, short int *right, int nb_4pixel_vectors, short int gain_left[4], short int gain_right[4]); void pixel_randmix_s16(short int *left, short int *right, int nb_4pixel_vectors, short int random_seed[4], short int threshold[4]); void pixel_rand_s16(short int *image, int nb_4pixel_vectors, short int random_seed[4]); void pixel_add_s16(short int *left, short int *right, int nb_4pixel_vectors); void pixel_mul_s16(short int *left, short int *right, int nb_4pixel_vectors); /* affine transfo */ void pixel_affine_s16(short int *buf, int nb_4pixel_vectors, short int gain[4], short int offset[4]); /* conv */ void pixel_conv_hor_s16(short int *pixel_array, int nb_4_pixel_vectors, short int border[4], short int mask[12]); void pixel_conv_ver_s16(short int *pixel_array, int nb_4_pixel_vectors, int row_byte_size, short int border[4], short int mask[12]); /* biquad */ void pixel_biquad_vertb_s16(short int *pixel_array, int nb_4x4_pixblocks, int linewidth, short int coef[20], short int state[8]); void pixel_biquad_verbt_s16(short int *pixel_array, int nb_4x4_pixblocks, int linewidth, short int coef[20], short int state[8]); void pixel_biquad_horlr_s16(short int *pixel_array, int nb_4x4_pixblocks, int linewidth, short int coef[20], short int state[8]); void pixel_biquad_horrl_s16(short int *pixel_array, int nb_4x4_pixblocks, int linewidth, short int coef[20], short int state[8]); void pixel_biquad_time_s16(short int *pixel_array, short int *state_array1, short int *state_array2, short int *coefs, int nb_4_pix_vectors); /********************************** PLANAR COLOUR OPERATIONS ***************************************/ /* color rotation for 3 colour planes */ void pixel_crot3d_s16(short int *pixel_array, int nb_4pixel_vectors_per_plane, short int *row_encoded_vector_matrix); /* color rotation for 2 colour planes */ void pixel_crot2d_s16(short int *pixel_array, int nb_4pixel_vectors_per_plane, short int *row_encoded_vector_matrix); /********************************** RESAMPLE OPERATIONS *******************************************/ // affine transformation (called linear map, but that's flou terminology) void pixel_resample_linmap_s16(void *x); /********************************** POLYNOMIAL OPERATIONS *****************************************/ // chebychev polynomial void pixel_cheby_s16_3plus(short int *buf, int nb_8pixel_vectors, int orderplusone, short int *coefs); #ifdef __cplusplus } #endif #endif //PDP_MMX_H pdp-0.14.1+darcs20180201/include/pdp_net.h000066400000000000000000000143531266045153600175310ustar00rootroot00000000000000#ifndef __PDP_UDP_H_ #define __PDP_UDP_H_ /* * Pure Data Packet header: UDP protocol for raw packets * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains the specification of the pdp UDP transport protocol. It is a very basic binary protocol, not very fool proof. The protocol: A header packet is transmitted first. This contains mime type information, and the size of and number of packets to be received. The connection id: Currently it is just a random number from the libc rand() function this should be accurate enough. */ #include #include #include #include #include #include #include #include #include #include /* some defs */ #define MAX_UDP_PACKET 1472 #define RESEND_MAX_CHUNKS ((MAX_UDP_PACKET - sizeof(t_pdp_udp_header))/sizeof(unsigned int)) #define PDP_UDP_VERSION 1 /* a pdp udp packet is prepended with this header */ typedef struct _pdp_udp_header { char signature[4]; /* must be "PDP" */; unsigned int version; /* protocol version */ unsigned int connection_id; /* the 'connection' id */ unsigned int sequence_number; /* sequence number. negative: control packet: body contains meta info */ } t_pdp_udp_header; /* the data part for a new connection */ #define PDP_UDP_NEW -1 /* start a new transmission */ typedef struct _pdp_udp_new { unsigned int data_size; /* the size of the packets */ unsigned int nb_chunks; /* number of chunks in pdp to be transmitted */ unsigned int chunk_size; /* the maximum chunk size */ char type[0]; /* the packet type */ // the tail part is the mime type, for creation and reassembly } t_pdp_udp_newpacket; #define PDP_UDP_DONE -2 /* transmission is done */ #define PDP_UDP_RESEND -3 /* request retransmission of certain chunks. empty: transmission ok */ #define PDP_UDP_ACKNEW -4 /* acknowledge reception of new packet header */ /* receiver and sender classes (transport layer) */ #define PDP_UDP_BUFSIZE 0xF000 /* RECEIVER */ typedef struct _pdp_udp_receiver { // buffer for receiving t_pdp_udp_header x_header; //pdp over udp header char x_buf[PDP_UDP_BUFSIZE]; //send buffer unsigned int x_zero_terminator; // to prevent runaway strings unsigned int x_buf_size; //size of the received data in the buffer (excluding the header) // buffer for sending t_pdp_udp_header x_resend_header; // header of the resend packet unsigned int x_resend_chunks[RESEND_MAX_CHUNKS]; // body contains the chunks to resend unsigned int x_resend_udp_packet_size; // transmission info unsigned int x_connection_id; unsigned int x_nb_chunks; unsigned int x_chunk_size; unsigned int *x_chunk_list; char *x_data_type; unsigned int x_data_size; void *x_data; struct sockaddr_in x_source_socket; socklen_t x_sslen; int x_receive_finished; int x_packet_transferred; int x_socket; //socket used for sending struct sockaddr_in x_sa; //address struct } t_pdp_udp_receiver; /* setup */ t_pdp_udp_receiver *pdp_udp_receiver_new(int port); void pdp_udp_receiver_free(t_pdp_udp_receiver *x); /* reset connection (wait for new packet) */ void pdp_udp_receiver_reset(t_pdp_udp_receiver *x); /* receive, returns 1 on success, 0 on timeout, -1 on error */ int pdp_udp_receiver_receive(t_pdp_udp_receiver *x, unsigned int timeout_ms); /* get meta & data */ char *pdp_udp_receiver_type(t_pdp_udp_receiver *x); unsigned int pdp_udp_receiver_size(t_pdp_udp_receiver *x); void *pdp_udp_receiver_data(t_pdp_udp_receiver *x); /* SENDER */ typedef struct _pdp_udp_sender { // desired udp packet size unsigned int x_udp_payload_size; // current packet && communication info unsigned int x_connection_id; char *x_data_type; void *x_data; unsigned int x_data_size; unsigned int x_chunk_size; unsigned int *x_chunk_list; unsigned int x_nb_chunks; unsigned int x_chunk_list_size; // connection data int x_socket; //socket used for sending struct sockaddr_in x_sa; //address struct unsigned int x_sleepgrain_us; //pause between sends (the poor man's flow control) (0 == no sleep) unsigned int x_sleep_count; unsigned int x_sleep_period; unsigned int x_timeout_us; // temp buffer for sending t_pdp_udp_header x_header; char x_buf[PDP_UDP_BUFSIZE]; unsigned int x_buf_size; // temp buffer for receiving t_pdp_udp_header x_resend_header; unsigned int x_resend_chunks[RESEND_MAX_CHUNKS]; unsigned int x_resend_items; } t_pdp_udp_sender; /* some flow control variables */ void pdp_udp_sender_timeout_us(t_pdp_udp_sender *x, unsigned int timeout_us); void pdp_udp_sender_sleepgrain_us(t_pdp_udp_sender *x, unsigned int sleepgrain_us); void pdp_udp_sender_sleepperiod(t_pdp_udp_sender *x, unsigned int sleepperiod); void pdp_udp_sender_udp_packet_size(t_pdp_udp_sender *x, unsigned int udp_packet_size); /* setup */ t_pdp_udp_sender *pdp_udp_sender_new(void); void pdp_udp_sender_free(t_pdp_udp_sender *x); /* connect */ void pdp_udp_sender_connect(t_pdp_udp_sender *x, char *host, unsigned int port); /* send, returns 1 on success, 0 on error */ int pdp_udp_sender_send(t_pdp_udp_sender *x, char* type, unsigned int size, void *data); #endif pdp-0.14.1+darcs20180201/include/pdp_packet.h000066400000000000000000000210621266045153600202050ustar00rootroot00000000000000/* * Pure Data Packet system implementation: Packet Manager Interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains the pdp packet manager interface specification. It is an implementation of the "Object Pool" pattern with lazy instantiation and lazy destruction. The pool is a growable array. It can only grow larger. Packets are represented by an integer, which is an index in this array. The standard "pure" packets (the ones which use a flat memory buffer) have recovery for resource depletion (main memory). If an out of memory condition is met on allocation of a new package, the garbage collector kicks in and frees unused packets until the out of memory condition is solved. Since an out of memory condition can be fatal for other parts of the program, pdp also supports a memory limit, to ensure some kind of safety margin. The "not so pure" packets should resolve resource conflicts in their own factory method, since the constructor is responsible for allocating external resources. The standard way to do this is to allocate a packet, free it's resources and allocate a new packet until the resource allocation succeeds. Especially for these kinds of packets, the pdp pool supports an explicit reuse method. This returns a valid packet if it can reuse one (based on the high level type description). Packets that don't have memory managing methods defined in the packet class (Standard packets) are treated as a header concatenated with a flat memory buffer, and can be copied and cloned without problems. So, if a packet contains pointers to other data or code, it can't be a pure packet. The interface to the packet manager contains the following managing methods: * pdp_packet_create: create a new packet * pdp_packet_mark_unused: release a packet * pdp_packet_copy_ro: register a packet for read only use * pdp_packet_copy_rw: register a packet for read/write use (this creates a copy if necessary) * pdp_packet_clone_rw: create a new packet using a template, but don't copy the data ( some types have shortcut methods pdp_packet_new_ which create/reuse a packet unless you are writing a factory method for a packet, you should NEVER call a _create method ) And two methods for raw data access * pdp_packet_header: retreive the header of the packet * pdp_packet_data: retreive the data buffer of the packet (only for static packets) All the methods declared in this header are supposed to be thread safe, so you can call them from the pd and pdp thread. */ #ifndef PDP_PACKET_H #define PDP_PACKET_H #include "pdp_symbol.h" #include "pdp_types.h" // this is legacy stuff: images are basic types #include "pdp_image.h" #include "pdp_bitmap.h" #define PDP_HEADER_SIZE 256 /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif typedef int (*t_pdp_factory_method)(t_pdp_symbol *); //returns bool success /* packet class header */ typedef struct _pdp_class { /* packet manips: non-pure data packets (using external resources) must define these */ t_pdp_packet_method1 wakeup; /* called before returning a reused packet (rc:0->1) */ t_pdp_packet_method2 copy; /* copy data from source packet to destination packet */ t_pdp_packet_method1 cleanup; /* free packet's resources (destructor) */ t_pdp_packet_method1 sleep; /* mark_unused notify: called when refcount reaches zero */ t_pdp_symbol *type; /* type template for packet class */ t_pdp_factory_method create; /* the constructor: create a packet with uninitialized data */ }t_pdp_class; /* TODO: implement garbage collection for fobs. (fobs are forth object dictionaries, but for the gc these count as lists) */ #define PDP_GC_COLOUR_GREY 0 /* 0 == default: object is reachable */ #define PDP_GC_COLOUR_WHITE 1 #define PDP_GC_COLOUR_BLACK 2 /* packet object header */ struct _pdp { /* meta info */ unsigned int type; /* main datatype of this object */ t_pdp_symbol *desc; /* high level type description (sort of a mime type) */ unsigned int size; /* datasize including header */ unsigned int flags; /* packet flags */ /* reference count */ unsigned int users; /* nb users of this object, readonly if > 1 */ /* class object */ t_pdp_class *theclass; /* if zero, the packet is a pure packet (just data, no member functions) */ u32 pad[10]; /* LATER: reserve bytes to provide compatibility with future extensions */ union /* each packet type has a unique subheader */ { t_raw raw; /* raw subheader (for extensions unkown to pdp core system) */ struct _image image; /* (nonstandard internal) 16 bit signed planar bitmap image format */ struct _bitmap bitmap; /* (standard) bitmap image (fourcc coded) */ //t_ca ca; /* cellular automaton state data */ //t_ascii ascii; /* ascii packet */ } info; }; /* pdp data packet type id */ #define PDP_IMAGE 1 /* 16bit signed planar scanline encoded image packet */ //RESERVED: #define PDP_CA 2 /* 1bit toroidial shifted scanline encoded cellular automaton */ //RESERVED: #define PDP_ASCII 3 /* ascii packet */ //RESERVED: #define PDP_TEXTURE 4 /* opengl texture object */ //RESERVED: #define PDP_3DCONTEXT 5 /* opengl render context */ #define PDP_BITMAP 6 /* 8bit image packet (fourcc coded??) */ //RESERVED: #define PDP_MATRIX 7 /* floating point/double matrix/vector packet (from gsl) */ #define PDP_FOB 8 /* small c->forth object wrapper */ /* PACKET FLAGS */ #define PDP_FLAG_DONOTCOPY (1<<0) /* don't copy the packet on register_rw, instead return an invalid packet */ /* class methods */ t_pdp_class *pdp_class_new(t_pdp_symbol *type, t_pdp_factory_method create); #if 0 void pdp_class_addmethod(t_pdp_class *c, t_pdp_symbol *name, t_pdp_attribute_method method, struct _pdp_list *in_spec, struct _pdp_list *out_spec); #endif /* packet factory method + registration */ int pdp_factory_newpacket(t_pdp_symbol *type); #if 0 /* send a message to a packet (packet polymorphy) this returns NULL on failure, or a return list the return list should be freed by the caller */ int pdp_packet_op(t_pdp_symbol *operation, struct _pdp_list *stack); #endif /* debug */ void pdp_packet_print_debug(int packet); /* hard coded packet methods */ int pdp_packet_copy_ro(int handle); /* get a read only copy */ int pdp_packet_copy_rw(int handle); /* get a read/write copy */ int pdp_packet_clone_rw(int handle); /* get an empty read/write packet of the same type (only copy header) */ void pdp_packet_mark_unused(int handle); /* indicate that you're done with the packet */ void pdp_packet_delete(int packet); /* like mark_unused, but really delete when refcount == 0 */ t_pdp* pdp_packet_header(int handle); /* get packet header */ void* pdp_packet_subheader(int handle); /* get packet subheader */ void* pdp_packet_data(int handle); /* get packet raw data */ int pdp_packet_data_size(int handle); /* get packet raw data size */ int pdp_packet_compat(int packet0, int packet1); int pdp_packet_reuse(t_pdp_symbol *description); int pdp_packet_create(unsigned int datatype, unsigned int datasize); /* create a new packet, don't reuse */ int pdp_packet_writable(int packet); /* returns true if packet is writable */ void pdp_packet_replace_with_writable(int *packet); /* replaces a packet with a writable copy */ //void pdp_packet_mark_unused_atomic(int *handle); /* mark unused + set reference to -1 (for thread synchro) */ /* pool stuff */ int pdp_pool_collect_garbage(void); /* free all unused packets */ void pdp_pool_set_max_mem_usage(int max); /* set max mem usage */ #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_pd.h000066400000000000000000000001241266045153600173350ustar00rootroot00000000000000/* pdp_pd.h wrapper */ #ifndef _M_PD_H_ #define _M_PD_H_ #include "m_pd.h" #endif pdp-0.14.1+darcs20180201/include/pdp_png.h000066400000000000000000000017561266045153600175320ustar00rootroot00000000000000/* * Pure Data Packet header file. png glue code. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __PDP_PNG_H__ #define __PDP_PNG_H__ int pdp_packet_bitmap_save_png_file(int packet, char *filename); int pdp_packet_bitmap_from_png_file(char *filename); #endif pdp-0.14.1+darcs20180201/include/pdp_post.h000066400000000000000000000022521266045153600177230ustar00rootroot00000000000000 /* * Pure Data Packet header file. pdp logging. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _PDP_POST_H_ #define _PDP_POST_H_ #include #include /* write a message to log (console) */ #include // old //void pdp_post_n(char *fmt, ...); //void pdp_post(char *fmt, ...); // new //void startpost(const char *fmt, ...); //void post(const char *fmt, ...); #define pdp_post_n startpost #define pdp_post post #endif pdp-0.14.1+darcs20180201/include/pdp_queue.h000066400000000000000000000064511266045153600200670ustar00rootroot00000000000000/* * Pure Data Packet - processor queue interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_QUEUE_H #define PDP_QUEUE_H #include "pdp_pd.h" #include /********************* general purpose pd process queue class *********************/ typedef void (*t_pdpmethod)(void *client); /* the process queue data record */ typedef struct process_queue_struct { void *x_owner; /* the object we are dealing with */ t_pdpmethod x_process; /* the process method */ t_pdpmethod x_callback; /* the function to be called when finished */ int *x_queue_id; /* place to store the queue id for task */ } t_process_queue_item; /* a pd process queue object */ typedef struct _pd_queue { /* clock members */ t_clock *pdp_clock; double deltime; /* some bookkeeping vars */ long long ticks; long long packets; /* queue members */ t_process_queue_item *q; /* queue */ int mask; int head; /* last entry in queue + 1 */ int tail; /* first entry in queque */ int curr; /* the object currently processed in other thread */ /* pthread vars */ pthread_mutex_t mut; pthread_cond_t cond_dataready; pthread_cond_t cond_processingdone; pthread_t thread_id; /* toggle for thread usage */ int use_thread; } t_pdp_procqueue; /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif /* returns 1 if full, 0 if there's space available */ int pdp_procqueue_full(t_pdp_procqueue *q); void pdp_procqueue_flush(t_pdp_procqueue *q); void pdp_procqueue_wait(t_pdp_procqueue *q); void pdp_procqueue_finish(t_pdp_procqueue *q, int indx); void pdp_procqueue_add(t_pdp_procqueue *q, void *owner, void *process, void *callback, int *queue_id); void pdp_procqueue_use_thread(t_pdp_procqueue* q, int t); void pdp_procqueue_init(t_pdp_procqueue *q, double milliseconds, int logsize); /********************* interface to pdp process queue singleton *********************/ /* processor queue methods, callable from main pd thread */ /* get the default queue */ t_pdp_procqueue *pdp_queue_get_queue(void); #if 1 /* add a method to the processing queue */ void pdp_queue_add(void *owner, void *process, void *callback, int *queue_id); /* halt main tread until processing is done */ void pdp_queue_wait(void); /* halt main tread until processing is done and remove callback from queue(for destructors) */ void pdp_queue_finish(int queue_id); #endif /* misc signals to pdp */ void pdp_control_notify_drop(int packet); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_resample.h000066400000000000000000000034001266045153600205420ustar00rootroot00000000000000/* * Pure Data Packet header file. - image resampling prototypes * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_RESAMPLE_H #define PDP_RESAMPLE_H #include "pdp_types.h" /* image resampling methods */ void pdp_resample_scale_bilin(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h); void pdp_resample_scale_nn(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h); /* USE pdp_imageproc_resample_affinemap void pdp_resample_zoom_tiled_bilin(s16 *src_image, s16 *dst_image, s32 w, s32 h, float zoom_x, float zoom_y, float center_x_relative, float center_y_relative); */ //void pdp_resample_zoom_tiled_nn(s16 *src_image, s16 *dst_image, s32 w, s32 h, float zoom_x, float zoom_y); /* power of 2 resamplers */ void pdp_resample_halve(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h); void pdp_resample_double(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h); /* core routines */ //s32 pdp_resample_bilin(s16 *image, s32 width, s32 height, s32 virt_x, s32 virt_y); #endif pdp-0.14.1+darcs20180201/include/pdp_symbol.h000066400000000000000000000100061266045153600202370ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : symbol and namespace stuff * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _PDP_SYMBOL_ #define _PDP_SYMBOL_ /* pdp's symbols are derived from pd's symbols there is one symbol hash. each symbol has a meaning in several name spaces. * forth words * type description lists (for accelerating type matching) */ #include "pdp_list.h" /* the pdp symbol type */ typedef struct _pdp_symbol { /* next */ struct _pdp_symbol *s_next; /* the symbol name */ char *s_name; /* forth symbol->atom */ struct _pdp_atom s_forth; /* packet handling cache */ struct _pdp_list *s_type; // a parsed type description: a/b/c -> (a,b,c) struct _pdp_list *s_reusefifo; // packet pool fifo for this type } t_pdp_symbol; #ifdef __cplusplus extern "C" { #endif /* namespace stuff */ int pdp_symbol_set_typelist(t_pdp_symbol *s, struct _pdp_list *typelist); /* get symbol from char */ t_pdp_symbol *pdp_gensym(char *s); /* iterate over all symbols */ typedef void (*t_pdp_symbol_iterator)(t_pdp_symbol *s); void pdp_symbol_apply_all(t_pdp_symbol_iterator ir); // don't use these directly, use the macros extern t_pdp_symbol _pdp_sym_wildcard; extern t_pdp_symbol _pdp_sym_float; extern t_pdp_symbol _pdp_sym_int; extern t_pdp_symbol _pdp_sym_symbol; extern t_pdp_symbol _pdp_sym_packet; extern t_pdp_symbol _pdp_sym_pointer; extern t_pdp_symbol _pdp_sym_list; extern t_pdp_symbol _pdp_sym_invalid; extern t_pdp_symbol _pdp_sym_question_mark; extern t_pdp_symbol _pdp_sym_atom; extern t_pdp_symbol _pdp_sym_null; extern t_pdp_symbol _pdp_sym_quote_start; extern t_pdp_symbol _pdp_sym_quote_end; extern t_pdp_symbol _pdp_sym_return; extern t_pdp_symbol _pdp_sym_nreturn; extern t_pdp_symbol _pdp_sym_defstart; extern t_pdp_symbol _pdp_sym_defend; extern t_pdp_symbol _pdp_sym_if; extern t_pdp_symbol _pdp_sym_then; extern t_pdp_symbol _pdp_sym_local; extern t_pdp_symbol _pdp_sym_forth; extern t_pdp_symbol _pdp_sym_call; extern t_pdp_symbol _pdp_sym_push; extern t_pdp_symbol _pdp_sym_pop; #ifdef __cplusplus } #endif // these symbols are used a lot in critical parts // optimize later #define PDP_SYM_WILDCARD &_pdp_sym_wildcard #define PDP_SYM_FLOAT &_pdp_sym_float #define PDP_SYM_INT &_pdp_sym_int #define PDP_SYM_SYMBOL &_pdp_sym_symbol #define PDP_SYM_PACKET &_pdp_sym_packet #define PDP_SYM_POINTER &_pdp_sym_pointer #define PDP_SYM_LIST &_pdp_sym_list #define PDP_SYM_INVALID &_pdp_sym_invalid #define PDP_SYM_QUESTION_MARK &_pdp_sym_question_mark #define PDP_SYM_ATOM &_pdp_sym_atom #define PDP_SYM_NULL &_pdp_sym_null #define PDP_SYM_QUOTE_START &_pdp_sym_quote_start #define PDP_SYM_QUOTE_END &_pdp_sym_quote_end #define PDP_SYM_RETURN &_pdp_sym_return #define PDP_SYM_NRETURN &_pdp_sym_nreturn #define PDP_SYM_DEF_START &_pdp_sym_defstart #define PDP_SYM_DEF_END &_pdp_sym_defend #define PDP_SYM_IF &_pdp_sym_if #define PDP_SYM_THEN &_pdp_sym_then #define PDP_SYM_LOCAL &_pdp_sym_local #define PDP_SYM_FORTH &_pdp_sym_forth #define PDP_SYM_CALL &_pdp_sym_call #define PDP_SYM_PUSH &_pdp_sym_push #define PDP_SYM_POP &_pdp_sym_pop #endif pdp-0.14.1+darcs20180201/include/pdp_type.h000066400000000000000000000146511266045153600177250ustar00rootroot00000000000000/* * Pure Data Packet system implementation. Type handling interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* COMMENTS Since version 0.11 all packets have an (optional) high level type description. This can be thought of as their mime type. It has several uses: * automatic type conversion * better reuse strategy for non pure packets * debugging The description is text-encoded, in the following form: type/subtype/subsubtype/.. This is implemented using t_pdp_symbol. Type descriptors can have wildcards. This is to give some freedom to a desired type conversion. The following are all compatible: */ // image/grey/320x240 // image/*/320x240 // image/*/* /* From a user pov, the type conversion is centralized. A single object (pdp_convert) can do most of the conversions. Type conversion implementation has to be done decentralized. It is subdivided into two steps: inter-type and intra-type conversions. Intra-type is the full responsability of each type implementation and can be handled in a decentralized way (at linkage the type central intra-converter is registered at the pdp framework. Inter-type conversion is harder to do decentralized, therefore each new type should provide some conversions to the basic built in types. (internal image, bitmap or matrix types. The point of this whole business is to * enable automatic conversion from anything to a desired type for operators that combine objects. i.e. pdp_add but receive incompatible objects. * enable manual anything to anything conversion using a pdp_convert object, i.e. have a consistent packet conversion api for users. The solution is type conversion programs. A program's behaviour is specified as follows: * the program is registered with a source and destination (result) template * it is passed a packet and a destination template * it can assume the source packet complies to the program's registerd source template * it should convert the packet to a packet that will comply to it's registered destination template * if for some reason a conversion fails, an invalid packet (handle == -1) should be returned about type templates: * they are hierarchical, with subtypes separated by a '/' character * they can contain a wildcard '*', meaning that a certain level in the type hierarchy is: - a don't care value, when the wildcard is used -> as a destination template in a requested conversion -> as a source template in a conversion program's specification - uspecified, when the wildcard is used -> as a destination template in a conversion program's specification NOTE: a wildcard can't be used in a source template for a conversion request this assymetry requires there be 2 kinds of template matching mechanisms: - source type description (without wildcards) to conversion program source template matching - destination type description (with wildcards) to conversion program destination template matching since a packet's type description cannot have wildcards, a symmetric matching (both sides have wildcards) can be used for matching. */ /* implementation: there are 2 lists with conversion progams: * the global list, containing all registered programs. * the cached list, containing all recently used registered programs, or combinations thereof if there is no cached, perfectly matching rule, a new one will be created, and added to the head of the conversion list. all conversion methods should keep their hands off the source packet. it is treated as readonly. this is to ensure a more flexible operation (i.e. be able to put the conversion at the register_ro level) TODO: add a breadth first search algorithm to do multiple stage conversion. */ #ifndef PDP_TYPE_H #define PDP_TYPE_H #include "pdp_symbol.h" #include "pdp_list.h" /* the conversion method accepts a packet (which is freed) and a destination wildcard and produces a new packet, or the invalid packet if the conversion failed */ typedef int (*t_pdp_conversion_method)(int, t_pdp_symbol *); /* a conversion program is alist of conversion methods */ typedef t_pdp_list t_pdp_conversion_program; /* a conversion has source and dest wildcards, and a conversion program */ typedef struct _pdp_conversion { t_pdp_symbol *src_pattern; // source type pattern t_pdp_symbol *dst_pattern; // destination type pattern t_pdp_conversion_program *program; // the conversion program for this conversion } t_pdp_conversion; /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* pdp_packet methods */ t_pdp_symbol *pdp_packet_get_description(int packet); int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_pattern); int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_pattern); /* pdp_conversion_program methods */ void pdp_conversion_program_free(t_pdp_conversion_program *program); t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...); t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program); void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail); /* pdp_type (central type object) methods */ int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern); void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program); void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program); //t_pdp_symbol *pdp_type_gendesc(char *desc); //generate a type description (with description list attached) t_pdp_list *pdp_type_to_list(t_pdp_symbol *type); /* pdp's (threadsafe) symbol */ t_pdp_symbol *pdp_gensym(char *s); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_type.h_old000066400000000000000000000151521266045153600205600ustar00rootroot00000000000000/* * Pure Data Packet system implementation. Type handling interface * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* COMMENTS Since version 0.11 all packets have an (optional) high level type description. This can be thought of as their mime type. It has several uses: * automatic type conversion * better reuse strategy for non pure packets * debugging The description is text-encoded, in the following form: type/subtype/subsubtype/.. This is implemented using t_pdp_symbol. Type descriptors can have wildcards. This is to give some freedom to a desired type conversion. The following are all compatible: */ // image/grey/320x240 // image/*/320x240 // image/*/* /* From a user pov, the type conversion is centralized. A single object (pdp_convert) can do most of the conversions. Type conversion implementation has to be done decentralized. It is subdivided into two steps: inter-type and intra-type conversions. Intra-type is the full responsability of each type implementation and can be handled in a decentralized way (at linkage the type central intra-converter is registered at the pdp framework. Inter-type conversion is harder to do decentralized, therefore each new type should provide some conversions to the basic built in types. (internal image, bitmap or matrix types. The point of this whole business is to * enable automatic conversion from anything to a desired type for operators that combine objects. i.e. pdp_add but receive incompatible objects. * enable manual anything to anything conversion using a pdp_convert object, i.e. have a consistent package conversion api for users. The solution is type conversion programs. A program's behaviour is specified as follows: * the program is registered with a source and destination (result) template * it is passed a packet and a destination template * it can assume the source packet complies to the program's registerd source template * it should convert the packet to a packet that will comply to it's registered destination template * if for some reason a conversion fails, an invalid packet (handle == -1) should be returned about type templates: * they are hierarchical, with subtypes separated by a '/' character * they can contain a wildcard '*', meaning that a certain level in the type hierarchy is: - a don't care value, when the wildcard is used -> as a destination template in a requested conversion -> as a source template in a conversion program's specification - uspecified, when the wildcard is used -> as a destination template in a conversion program's specification NOTE: a wildcard can't be used in a source template for a conversion request this assymetry requires there be 2 kinds of template matching mechanisms: - source type description (without wildcards) to conversion program source template matching - destination type description (with wildcards) to conversion program destination template matching since a packet's type description cannot have wildcards, a symmetric matching (both sides have wildcards) can be used for matching. */ /* implementation: there are 2 lists with conversion progams: * the global list, containing all registered programs. * the cached list, containing all recently used registered programs, or combinations thereof if there is no cached, perfectly matching rule, a new one will be created, and added to the head of the conversion list. all conversion methods should keep their hand's off the source packet. it is treated as readonly. this is to ensure a more flexible operation (i.e. be able to put the conversion at the register_ro level) this will need a bit more logic in running the conversion program though.. */ #ifndef PDP_TYPE_H #define PDP_TYPE_H /* the conversion method accepts a packet (which is freed) and a destination wildcard and produces a new packet, or the invalid packet if the conversion failed */ typedef int (*t_pdp_conversion_method)(int, t_pdp_symbol *); /* a conversion program is alist of conversion methods */ typedef struct _pdp_conversion_program { t_pdp_conversion_method method; // conversion method struct _pdp_conversion_program *next; // next method in program } t_pdp_conversion_program; /* a conversion has source and dest wildcards, and a conversion program */ typedef struct _pdp_conversion { t_pdp_symbol *src_pattern; // source type pattern t_pdp_symbol *dst_pattern; // destination type pattern t_pdp_conversion_program *program; // the conversion program for this conversion struct _pdp_conversion *next; // next conversion program record } t_pdp_conversion; /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* pdp_packet methods */ t_pdp_symbol *pdp_packet_get_description(int packet); int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_pattern); int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_pattern); /* pdp_conversion_program methods */ void pdp_conversion_program_free(t_pdp_conversion_program *program); t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...); t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program); void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail); /* pdp_type (central type object) methods */ int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern); void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program); void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program); //t_pdp_symbol *pdp_type_gendesc(char *desc); //generate a type description (with description list attached) t_pdp_list *pdp_type_to_list(t_pdp_symbol *type); /* pdp's (threadsafe) symbol */ t_pdp_symbol *pdp_gensym(char *s); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/include/pdp_types.h000066400000000000000000000034651266045153600201110ustar00rootroot00000000000000 /* * Pure Data Packet header file. Scalar type definitions. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* some typedefs and utility classes */ #ifndef PDP_TYPES_H #define PDP_TYPES_H /* C99 standard header for bool, true, and false */ #include /* check http://www.unix.org/whitepapers/64bit.html on unix (LP64) int = 32bit it was like this: typedef signed long s32; typedef unsigned long u32; */ typedef signed char s8; typedef signed short s16; typedef signed int s32; typedef signed long long s64; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; typedef unsigned long uptr; /* An unsigned int the size of a pointer. */ typedef signed long sptr; typedef struct _pdp t_pdp; typedef void (*t_pdp_packet_method1)(t_pdp *); /* dst */ typedef void (*t_pdp_packet_method2)(t_pdp *, t_pdp *); /* dst, src */ /* generic packet subheader */ //typedef unsigned char t_raw[PDP_SUBHEADER_SIZE]; typedef unsigned int t_raw; #endif pdp-0.14.1+darcs20180201/include/pdp_xvideo.h000066400000000000000000000037361266045153600202440ustar00rootroot00000000000000 /* * Pure Data Packet header file: xwindow glue code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ // x stuff #include #include #include #include // image formats for communication with the X Server #define FOURCC_YV12 0x32315659 /* YV12 YUV420P */ #define FOURCC_YUV2 0x32595559 /* YUV2 YUV422 */ #define FOURCC_I420 0x30323449 /* I420 Intel Indeo 4 */ /* xvideo class */ typedef struct _pdp_xvideo { t_pdp_xdisplay *xdpy; t_pdp_xwindow *xwin; //Display *dpy; //int screen; //Window win; int xv_format; int xv_port; XvImage *xvi; unsigned char *data; unsigned int width; unsigned int height; int last_encoding; int initialized; } t_pdp_xvideo; /* cons */ void pdp_xvideo_init(t_pdp_xvideo *x); t_pdp_xvideo *pdp_xvideo_new(void); /* des */ void pdp_xvideo_cleanup(t_pdp_xvideo* x); void pdp_xvideo_free(t_pdp_xvideo* x); /* open an xv port (and create XvImage) */ int pdp_xvideo_open_on_display(t_pdp_xvideo *x, t_pdp_xdisplay *d); /* close xv port (and delete XvImage */ void pdp_xvideo_close(t_pdp_xvideo* x); /* display a packet */ void pdp_xvideo_display_packet(t_pdp_xvideo *x, t_pdp_xwindow *w, int packet); pdp-0.14.1+darcs20180201/include/pdp_xwindow.h000066400000000000000000000063611266045153600204420ustar00rootroot00000000000000 /* * Pure Data Packet header file: xwindow glue code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ // x stuff #include #include #include "pdp_list.h" #include "pdp_mem.h" /* x display class */ typedef struct _pdp_xdisplay { Display *dpy; // the display connection int screen; // the screen t_pdp_list *windowlist; // all windows belonging to this connection // this contains (id, eventlist) int dragbutton; } t_pdp_xdisplay; /* cons */ t_pdp_xdisplay *pdp_xdisplay_new(char *dpy_string); /* des */ void pdp_xdisplay_free(t_pdp_xdisplay *d); struct _pdp_xwindow; void pdp_xdisplay_register_window(t_pdp_xdisplay *d, struct _pdp_xwindow *w); void pdp_xdisplay_unregister_window(t_pdp_xdisplay *d, struct _pdp_xwindow *w); /* x window class */ typedef struct _pdp_xwindow { //Display *dpy; //int screen; t_pdp_xdisplay *xdisplay; // the display object Window win; // window reference GC gc; // graphics context Atom WM_DELETE_WINDOW; int winwidth; // dim states int winheight; int winxoffset; int winyoffset; int initialized; int autocreate; char lastbut; // last button pressed (for drag) //t_symbol *dragbutton; float cursor; } t_pdp_xwindow; /* cons */ void pdp_xwindow_init(t_pdp_xwindow *b); t_pdp_xwindow *pdp_xwindow_new(void); /* des */ void pdp_xwindow_cleanup(t_pdp_xwindow *b); void pdp_xwindow_free(t_pdp_xwindow *b); /* move the pointer */ void pdp_xwindow_warppointer(t_pdp_xwindow *xwin, int x, int y); /* fullscreen message */ void pdp_xwindow_fullscreen(t_pdp_xwindow *xwin); /* resize window */ void pdp_xwindow_resize(t_pdp_xwindow *b, int width, int height); /* resize window */ void pdp_xwindow_moveresize(t_pdp_xwindow *b, int xoffset, int yoffset, int width, int height); /* fill a tile of the screen */ void pdp_xwindow_tile(t_pdp_xwindow *xwin, int x_tiles, int y_tiles, int i, int j); /* move window */ void pdp_xwindow_move(t_pdp_xwindow *xwin, int xoffset, int yoffset); /* receive events */ t_pdp_list *pdp_xwindow_get_eventlist(t_pdp_xwindow *xwin); /* enable/disable cursor */ void pdp_xwindow_cursor(t_pdp_xwindow *b, int flag); /* create xwindow. return code != NULL on succes */ int pdp_xwindow_create_on_display(t_pdp_xwindow *b, t_pdp_xdisplay *d); /* close window */ void pdp_xwindow_close(t_pdp_xwindow *b); /* set title */ void pdp_xwindow_title(t_pdp_xwindow *xwin, char *title); pdp-0.14.1+darcs20180201/modules/000077500000000000000000000000001266045153600157465ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/Makefile000066400000000000000000000005021266045153600174030ustar00rootroot00000000000000# build subdirs current: make -C generic make -C image_basic make -C image_io make -C image_special make -C matrix_basic make -C test clean: make -C generic clean make -C image_basic clean make -C image_io clean make -C image_special clean make -C matrix_basic clean make -C test clean rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/README000066400000000000000000000020431266045153600166250ustar00rootroot00000000000000This file describes the protocol used for communicating packets. See include/pdp.h and the sources in this directory for more info. There are 3 kinds of pdp messages: [pdp register_ro ] [pdp register_rw ] [pdp process] Together they form the pdp protocol. An object can receive a packet by catching the 3 kinds of messages: When a register_ro message is received, the object can call pdp_packet_copy_ro(packet) to reserve a read only copy for itself. The same goes for handling the register_rw message. You can reserve a read/write copy by using pdp_packet_copy_rw(packet) When a process message is received, the object is allowed to start processing the packet data end send the resulting packet(s) out. To send out a packet, use the pdp_packet_pass_if_valid(outlet, &packet) method. It passes a packet, and sets the reference to -1 (the undefined packet id). If you want to write pdp externs, consider using the pdp_base object to derive your object from. Have a look at pdp_add, pdp_gain, pdp_noise to see how to do this. pdp-0.14.1+darcs20180201/modules/generic/000077500000000000000000000000001266045153600173625ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/generic/Makefile000066400000000000000000000005141266045153600210220ustar00rootroot00000000000000current: all_modules include ../../Makefile.config PDP_MOD = pdp_reg.o pdp_del.o pdp_snap.o pdp_trigger.o \ pdp_route.o pdp_inspect.o pdp_loop.o pdp_description.o pdp_convert.o \ pdp_udp_send.o pdp_udp_receive.o pdp_rawin.o pdp_rawout.o pdp_metro.o # build generic modules all_modules: $(PDP_MOD) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/generic/README000066400000000000000000000001471266045153600202440ustar00rootroot00000000000000This directory contains generic packet processors (i.e. containers). Should work with any packet type. pdp-0.14.1+darcs20180201/modules/generic/pdp_convert.c000066400000000000000000000045221266045153600220540ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" typedef struct pdp_convert_struct { t_object x_obj; t_symbol *x_type_mask; t_outlet *x_outlet0; int x_packet0; } t_pdp_convert; static void pdp_convert_type_mask(t_pdp_convert *x, t_symbol *s) { x->x_type_mask = s; } static void pdp_convert_input_0(t_pdp_convert *x, t_symbol *s, t_floatarg f) { int p = (int)f; int passes, i; if (s== gensym("register_ro")){ pdp_packet_mark_unused(x->x_packet0); if (x->x_type_mask->s_name[0]) x->x_packet0 = pdp_packet_convert_ro(p, pdp_gensym(x->x_type_mask->s_name)); else x->x_packet0 = pdp_packet_copy_ro(p); } if ((s == gensym("process")) && (-1 != x->x_packet0)){ pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } } t_class *pdp_convert_class; void pdp_convert_free(t_pdp_convert *x) { pdp_packet_mark_unused(x->x_packet0); } void *pdp_convert_new(t_symbol *s) { t_pdp_convert *x = (t_pdp_convert *)pd_new(pdp_convert_class); x->x_type_mask = s; x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_convert_setup(void) { pdp_convert_class = class_new(gensym("pdp_convert"), (t_newmethod)pdp_convert_new, (t_method)pdp_convert_free, sizeof(t_pdp_convert), 0, A_DEFSYMBOL, A_NULL); class_addmethod(pdp_convert_class, (t_method)pdp_convert_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addsymbol(pdp_convert_class, (t_method)pdp_convert_type_mask); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_del.c000066400000000000000000000111351266045153600211360ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" typedef struct pdp_del_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet **x_outlet; int *x_packet; int x_order; int x_head; int x_delay; } t_pdp_del; static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f) { int in; int out; int packet; /* if this is a register_ro message or register_rw message, register with packet factory */ /* if this is a process message, start the processing + propagate stuff to outputs */ if (s == gensym("register_ro")){ in = (x->x_head % x->x_order); //post("pdp_del: marking unused packed id=%d on loc %d", x->x_packet[0], in); pdp_packet_mark_unused(x->x_packet[in]); packet = pdp_packet_copy_ro((int)f); // TODO TODO TODO !!!! //pdp_packet_print_debug((int)f); x->x_packet[in] = packet; //post("pdp_del: writing packed id=%d on loc %d", packet, in); } else if (s == gensym("process")){ out = (((x->x_head + x->x_delay)) % x->x_order); packet = x->x_packet[out]; // originally, we wouldn't keep the packet in the delay line to save memory // however, this behaviour is very annoying, and doesn't allow ''scratching'' // so we send out a copy instead. // pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet[out]); int p = pdp_packet_copy_ro(packet); pdp_packet_pass_if_valid(x->x_outlet0, &p); /* if (-1 != packet){ //post("pdp_del: packet %d has id %d", out, packet); pdp_packet_mark_unused(packet); outlet_pdp(x->x_outlet0, packet); x->x_packet[out] = -1; } else { //post("pdp_del: packet %d is empty", out); } */ x->x_head = (x->x_head + x->x_order - 1) % x->x_order; /* int i; for (i=0; ix_order; i++){ fprintf(stderr, " %d", x->x_packet[i]); } fprintf(stderr, "\n"); */ } } static void pdp_del_delay(t_pdp_del *x, t_floatarg fdel) { int del = (int)fdel; if (del < 0) del = 0; if (del >= x->x_order) del = x->x_order - 1; x->x_delay = del; } static void pdp_del_reset(t_pdp_del *x) { int i; for (i=0; ix_order; i++) { pdp_packet_mark_unused(x->x_packet[i]); x->x_packet[i] = -1; } x->x_head = 0; } static void pdp_del_debug(t_pdp_del *x) { int i; post ("order %d", x->x_order); post ("delay %d", x->x_delay); post ("head %d", x->x_head); for (i=0; ix_order; i++) { post("%d ", x->x_packet[i]); } } static void pdp_del_free(t_pdp_del *x) { pdp_del_reset(x); pdp_dealloc (x->x_packet); } t_class *pdp_del_class; void *pdp_del_new(t_floatarg forder, t_floatarg __attribute__((unused)) fdel) { int order = (int)forder; int del; int logorder; int i; t_pdp_del *x = (t_pdp_del *)pd_new(pdp_del_class); del = order; order++; if (del < 0) del = 0; if (order <= 2) order = 2; //post("pdp_del: order = %d", order); x->x_order = order; x->x_packet = (int *)pdp_alloc(sizeof(int)*order); for(i=0; ix_packet[i] = -1; x->x_delay = del; inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("delay")); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_del_setup(void) { pdp_del_class = class_new(gensym("pdp_del"), (t_newmethod)pdp_del_new, (t_method)pdp_del_free, sizeof(t_pdp_del), 0, A_DEFFLOAT, A_NULL); class_addmethod(pdp_del_class, (t_method)pdp_del_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_del_class, (t_method)pdp_del_delay, gensym("delay"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_del_class, (t_method)pdp_del_reset, gensym("reset"), A_NULL); class_addmethod(pdp_del_class, (t_method)pdp_del_debug, gensym("_debug"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_description.c000066400000000000000000000046471266045153600227270ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" typedef struct pdp_description_struct { t_object x_obj; t_outlet *x_outlet; } t_pdp_description; static void pdp_description_input_pdp(t_pdp_description *x, t_symbol *s, t_floatarg f) { int p = (int)f; t_symbol *rro = S_REGISTER_RO; if (rro == s){ outlet_symbol(x->x_outlet, gensym(pdp_packet_get_description(p)->s_name)); } } static void pdp_description_input_dpd(t_pdp_description *x, t_symbol *s, t_floatarg f) { int p = (int)f; t_symbol *ins = S_INSPECT; if (ins == s){ outlet_symbol(x->x_outlet, gensym(pdp_packet_get_description(p)->s_name)); } } static void pdp_description_free(t_pdp_description __attribute__((unused)) *x) { } t_class *pdp_description_class; static void *pdp_description_new(t_symbol __attribute__((unused)) *s, int __attribute__((unused)) argc, t_atom __attribute__((unused)) *argv) { t_pdp_description *x = (t_pdp_description *)pd_new(pdp_description_class); x->x_outlet = outlet_new(&x->x_obj, &s_symbol); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_description_setup(void) { pdp_description_class = class_new(gensym("pdp_description"), (t_newmethod)pdp_description_new, (t_method)pdp_description_free, sizeof(t_pdp_description), 0, A_NULL); class_addmethod(pdp_description_class, (t_method)pdp_description_input_pdp, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_description_class, (t_method)pdp_description_input_dpd, gensym("dpd"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_inspect.c000066400000000000000000000051571266045153600220460ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" /* adapted from the pd trigger object */ #define TR_BANG 0 #define TR_FLOAT 1 #define TR_SYMBOL 2 #define TR_POINTER 3 #define TR_LIST 4 #define TR_ANYTHING 5 #define TR_PDP 6 /* $$$TODO: emplement so that it behaves like the standard trigger object i.e. [trigger bang pdp pdp bang pdp] register_ro and register_rw messages pass right trough, since they're not action events, only configure events. a bang is made equivalent to a process event. */ typedef struct pdp_inspect_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet; } t_pdp_inspect; static void pdp_inspect_input_0(t_pdp_inspect *x, t_symbol *s, t_floatarg f) { t_atom atom[2]; t_symbol *pdp = gensym("pdp"); t_symbol *prc = gensym("process"); t_symbol *rro = gensym("register_ro"); int i; /* if there is a reg_ro, shortcut the right outlet */ if (s == rro){ SETSYMBOL(atom+0, s); SETFLOAT(atom+1, f); outlet_anything(x->x_outlet, pdp, 2, atom); SETSYMBOL(atom+0, prc); outlet_anything(x->x_outlet, pdp, 1, atom); } } static void pdp_inspect_free(t_pdp_inspect __attribute__((unused)) *x) { } t_class *pdp_inspect_class; static void *pdp_inspect_new(void) { t_pdp_inspect *x = (t_pdp_inspect *)pd_new(pdp_inspect_class); x->x_outlet = outlet_new(&x->x_obj, &s_anything); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_inspect_setup(void) { pdp_inspect_class = class_new(gensym("pdp_inspect_ro"), (t_newmethod)pdp_inspect_new, (t_method)pdp_inspect_free, sizeof(t_pdp_inspect), 0, A_GIMME, A_NULL); // class_addcreator((t_newmethod)pdp_inspect_new, gensym("pdp_t"), A_GIMME, 0); class_addmethod(pdp_inspect_class, (t_method)pdp_inspect_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_loop.c000066400000000000000000000157121266045153600213500ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* pdp_loop: a looping packet delay line messages: record x: start recording at position x (default = 0) stop: stop recording float: output packet at position bang: output next packet rewind: rewind loop: set looping mode */ #include "pdp.h" #include "pdp_internals.h" typedef struct pdp_loop_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet *x_outlet1; int *x_packet; int x_order; /* size of the packet loop */ int x_play_head; /* next position to play back */ int x_record_head; /* next position to record to */ int x_loop; int x_recording_frames; /* nb frames left to record */ //int x_recording_shot; /* single frame recording is on */ } t_pdp_loop; static void pdp_loop_input_0(t_pdp_loop *x, t_symbol *s, t_floatarg f) { int in; int out; int packet; /* if recording is off, ignore packet */ if ((!x->x_recording_frames)) return; /* store a packet on register ro */ if (s == gensym("register_ro")){ /* delete old & store new */ in = x->x_record_head; //% x->x_order; pdp_packet_mark_unused(x->x_packet[in]); packet = pdp_packet_copy_ro((int)f); x->x_packet[in] = packet; /* advance head & decrease record counter */ x->x_recording_frames--; x->x_record_head++; /* turn off recording if we are at the end */ if (x->x_record_head == x->x_order) x->x_recording_frames = 0; } } static void pdp_loop_bang(t_pdp_loop *x){ int out; int packet; out = x->x_play_head; /* don't play if we're at the end of the sequence and looping is disabled */ if ((!x->x_loop) && (out >= x->x_order)) return; /* wrap index */ out %= x->x_order; /* output the current packet */ packet = x->x_packet[out]; outlet_float(x->x_outlet1, (float)out); // output location if (-1 != packet) outlet_pdp(x->x_outlet0, packet); // output packet /* advance playback head */ x->x_play_head++; } static void pdp_loop_reset(t_pdp_loop *x) { int i; for (i=0; ix_order; i++) { pdp_packet_mark_unused(x->x_packet[i]); x->x_packet[i] = -1; } x->x_play_head = 0; x->x_record_head = 0; } static void pdp_loop_record(t_pdp_loop *x, t_floatarg fstart, t_floatarg fdur) { int istart = (int)fstart; int idur = (int)fdur; istart %= x->x_order; if (istart<0) istart+= x->x_order; if (idur <= 0) idur = x->x_order - istart; x->x_record_head = istart; x->x_recording_frames = idur; } static void pdp_loop_store(t_pdp_loop *x, t_floatarg f) { int i = (int)f; i %= x->x_order; if (i<0) i+= x->x_order; x->x_record_head = i; x->x_recording_frames = 1; } static void pdp_loop_seek(t_pdp_loop *x, t_floatarg f) { int i = (int)f; i %= x->x_order; if (i<0) i+= x->x_order; x->x_play_head = i; } static void pdp_loop_seek_hot(t_pdp_loop *x, t_floatarg f) { pdp_loop_seek(x, f); pdp_loop_bang(x); } static void pdp_loop_stop(t_pdp_loop *x) { x->x_recording_frames = 0; } static void pdp_loop_loop(t_pdp_loop *x, t_floatarg f) { if (f == 0.0f) x->x_loop = 0; if (f == 1.0f) x->x_loop = 1; } static void pdp_loop_free(t_pdp_loop *x) { pdp_loop_reset(x); pdp_dealloc (x->x_packet); } static int pdp_loop_realsize(float f) { int order = (int)f; if (order <= 2) order = 2; return order; } static void pdp_loop_resize(t_pdp_loop *x, t_floatarg f) { int i; int order = pdp_loop_realsize(f); int *newloop; /* if size didn't change, do nothing */ if (x->x_order == order) return; /* create new array */ newloop = (int *)pdp_alloc(sizeof(int) * order); /* extend it */ if (x->x_order < order){ /* copy old packets */ for (i=0; ix_order; i++) newloop[i] = x->x_packet[i]; /* loop extend the rest */ for (i=x->x_order; ix_packet[i % x->x_order]); } /* or shrink it */ else { /* copy part of old packets */ for (i=0; ix_packet[i]; /* delete the other part of old packets */ for (i=order; ix_order; i++) pdp_packet_mark_unused(x->x_packet[i]); /* adjust heads */ x->x_play_head %= order; x->x_record_head %= order; } /* delete old line & store new */ pdp_dealloc (x->x_packet); x->x_packet = newloop; x->x_order = order; } t_class *pdp_loop_class; void *pdp_loop_new(t_floatarg f) { int i; int order = pdp_loop_realsize(f); t_pdp_loop *x = (t_pdp_loop *)pd_new(pdp_loop_class); x->x_order = order; x->x_packet = (int *)pdp_alloc(sizeof(int)*order); for(i=0; ix_packet[i] = -1; x->x_play_head = 0; x->x_record_head = 0; x->x_recording_frames = 0; inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("seek")); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_outlet1 = outlet_new(&x->x_obj, &s_anything); x->x_loop = 1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_loop_setup(void) { pdp_loop_class = class_new(gensym("pdp_loop"), (t_newmethod)pdp_loop_new, (t_method)pdp_loop_free, sizeof(t_pdp_loop), 0, A_DEFFLOAT, A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_record, gensym("record"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_store, gensym("store"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_reset, gensym("reset"), A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_bang, gensym("bang"), A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_stop, gensym("stop"), A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_seek, gensym("seek"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_resize, gensym("size"), A_FLOAT, A_NULL); class_addmethod(pdp_loop_class, (t_method)pdp_loop_loop, gensym("loop"), A_FLOAT, A_NULL); class_addfloat(pdp_loop_class, (t_method)pdp_loop_seek_hot); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_metro.c000066400000000000000000000066721266045153600215320ustar00rootroot00000000000000/* * Pure Data Packet module. Standard sync rates. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* pdp_metro this is the main audio/video sync module. use this if you need to produce synchronized raw output. this uses 'industry standard' integer sampling ratios. it works like this. for example, the most awkward 30 * 999/1000 Hz rate. */ #include "pdp.h" typedef struct _metro_struct { t_object x_obj; t_float x_f; t_clock *x_clock; t_outlet *x_outlet; t_int x_count; // current count for (upsampled) audio ticks t_int x_den; // video framerate denominator and nominator t_int x_nom; } t_metro; static t_int *metro_perform(t_int *w); #define DSP_ARG(type, name, source) type name = (type)source static void metro_dsp(t_metro *x, t_signal **sp) { dsp_add(metro_perform, 3, x, sp[0]->s_n, (int)sys_getsr()); } static t_int *metro_perform(t_int *w){ DSP_ARG(t_metro*, x, w[1]); DSP_ARG(t_int, n, w[2]); DSP_ARG(t_int, sr, w[3]); t_int period = sr * x->x_nom; t_int upsample = x->x_den; t_int dobang = 0; //fprintf(stderr, "%d/%d\t%d\t%d\n", x->x_den, x->x_nom, x->x_count, period); x->x_count += n * upsample; while (x->x_count > period) { dobang = 1; x->x_count -= period; } if (dobang) clock_set(x->x_clock, 0); return w+4; } static void metro_tick(t_metro *x) { outlet_bang(x->x_outlet); } static void metro_reset(t_metro *x){ x->x_count = 0; } static void metro_fps(t_metro *x, t_float fden, t_float fnom) { int den = (int)fden; int nom = (int)fnom; if (den < 1) den = 1; if (nom < 1) nom = 1; x->x_den = den; x->x_nom = nom; } static void metro_free(t_metro *x) { clock_unset(x->x_clock); } static t_class *metro_class; static void *metro_new(t_symbol __attribute__((unused)) *s, int __attribute__((unused)) argc, __attribute__((unused)) t_atom *argv) { t_metro *x = (t_metro *)pd_new(metro_class); x->x_outlet = outlet_new(&x->x_obj, &s_bang); x->x_clock = clock_new(x, (t_method)metro_tick); x->x_count = 0; metro_fps(x, 1, 1); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_metro_setup(void) { metro_class = class_new(gensym("pdp_metro~"), (t_newmethod)metro_new, (t_method)metro_free, sizeof(t_metro), 0, A_NULL); CLASS_MAINSIGNALIN(metro_class, t_metro, x_f); class_addmethod(metro_class, (t_method)metro_tick, gensym("tick"), A_NULL); class_addmethod(metro_class, (t_method)metro_dsp, gensym("dsp"), A_NULL); class_addmethod(metro_class, (t_method)metro_fps, gensym("fps"), A_FLOAT, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_rawin.c000066400000000000000000000205671266045153600215230ustar00rootroot00000000000000/* * Pure Data Packet module. Raw packet input * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "pdp_pd.h" #include "pdp_debug.h" #include "pdp_list.h" #include "pdp_comm.h" #include "pdp_post.h" #include "pdp_packet.h" #define PERIOD 1.0f #define D if (1) /* TODO: add flow control reminder: pthread condition values for synchro writing to a queue goes like this: * pthread_mutex_lock * atomic op (write) * pthread_cond_signal * pthread_mutex_unlock reading from a queue goes like this: * pthread_mutex_lock * while (!CONDITION) pthread_cond_wait * atomic op (read) * pthread_mutex_unlock in this case, there is a reader and a writer, AND a maximum size of the buffer between them (1 atom) so both reader and writer might block. compare this to the 'command queue' in libpf, where only the reader blocks. so the course of events is: READER * wait for data ready (COND_READ) this blocks pd, it is assumed data is always ready in normal operation * consume * signal writer (COND_WRITE) WRITER * wait for space ready (COND_WRITE) * write * signal reader one remark though: is this machinery really necessary? ----------------------------------- it might be easier to just read in the pd thread. the only problem this gives is when data really arrives not in a single chunk, but as a stream. to me that seems a really awkward special case which can be solved using another PROCESS to do the buffering / dropping. so, for now, it's just synchronous, no threads for sync reading. */ /* raw input from a unix pipe */ typedef struct rawin_struct { /* pd */ t_object x_obj; t_outlet *x_outlet; t_outlet *x_sync_outlet; t_clock *x_clock; /* comm */ t_pdp_list *x_queue; // packet queue int x_pipefd; /* thread */ pthread_mutex_t x_mut; pthread_attr_t x_attr; pthread_t x_thread; /* sync */ int x_mode; // 1-> sync to input int x_giveup; // 1-> terminate reader thread int x_active; // 1-> reader thread is launched /* config */ t_symbol *x_pipe; t_pdp_symbol *x_type; } t_rawin; static inline void lock(t_rawin *x){pthread_mutex_lock(&x->x_mut);} static inline void unlock(t_rawin *x){pthread_mutex_unlock(&x->x_mut);} static void rawin_close(t_rawin *x); static int read_packet(t_rawin *x){ int packet = -1; void *data = 0; int left = -1; int period_sec; int period_usec; /* create packet */ if (-1 != packet){ pdp_post("WARNING: deleting stale packet"); pdp_packet_mark_unused(packet); } packet = pdp_factory_newpacket(x->x_type); if (-1 == packet){ pdp_post("ERROR: can't create packet. type = %s", x->x_type->s_name); goto close; } /* fill packet */ data = pdp_packet_data(packet); left = pdp_packet_data_size(packet); // D pdp_post("packet %d, data %x, size %d", packet, data, left); /* inner loop: pipe reads */ while(left){ fd_set inset; struct timeval tv = {0,10000}; /* check if we need to stop */ if (x->x_giveup){ pdp_packet_mark_unused(packet); goto close; } /* select, with timeout */ FD_ZERO(&inset); FD_SET(x->x_pipefd, &inset); if (-1 == select(x->x_pipefd+1, &inset, NULL,NULL, &tv)){ pdp_post("select error"); goto close; } /* if ready, read, else retry */ if (FD_ISSET(x->x_pipefd, &inset)){ int bytes = read(x->x_pipefd, data, left); if (!bytes){ /* if no bytes are read, pipe is closed */ goto close; } data += bytes; left -= bytes; } } return packet; close: return -1; } /* reader thread syncs to pipe */ static void *rawin_thread(void *y) { t_rawin *x = (t_rawin *)y; int packet = -1; /* loop until error or close */ while (-1 != (packet = read_packet(x))) { lock(x); pdp_list_add_back(x->x_queue, a_packet, (t_pdp_word)packet); unlock(x); } return 0; } /* sync to stream: tick polls the receive queue */ static void rawin_tick(t_rawin *x) { int p = -1; /* send all packets in queue to outlet */ while (x->x_queue->elements){ lock(x); //pdp_post("%d", x->x_queue->elements); p = pdp_list_pop(x->x_queue).w_packet; unlock(x); //pdp_post_n("%d ", p); pdp_packet_pass_if_valid(x->x_outlet, &p); //pdp_post("%d",p); } clock_delay(x->x_clock, PERIOD); } /* sync to bang: this runs the reader in the pd thread */ static void rawin_bang(t_rawin *x){ if (!x->x_active) return; if (x->x_mode) return; int packet = read_packet(x); if (-1 == packet) rawin_close(x); // close on error pdp_packet_pass_if_valid(x->x_outlet, &packet); } static void rawin_type(t_rawin *x, t_symbol *type) { x->x_type = pdp_gensym(type->s_name); } static void rawin_close(t_rawin *x) { if (!x->x_active) return; /* stop thread: set giveup + wait */ x->x_giveup = 1; if (x->x_mode) pthread_join(x->x_thread, NULL); x->x_active = 0; /* close pipe */ close(x->x_pipefd); /* notify */ outlet_bang(x->x_sync_outlet); pdp_post("pdp_rawin: connection to %s closed", x->x_pipe->s_name); } static void rawin_open(t_rawin *x, t_symbol *spipe) { /* save pipe name if not empty */ if (spipe->s_name[0]) {x->x_pipe = spipe;} if (x->x_active) { pdp_post("pdp_rawin: already open"); return; } /* open pipe */ if (-1 == (x->x_pipefd = open(x->x_pipe->s_name, O_RDONLY|O_NONBLOCK))){ perror(x->x_pipe->s_name); return; } /* thread control vars */ x->x_giveup = 0; x->x_active = 1; /* start thread if sync mode */ if (x->x_mode) pthread_create(&x->x_thread, &x->x_attr, rawin_thread , x); } static void rawin_sync(t_rawin *x, t_float fmode){ rawin_close(x); x->x_mode = (int)fmode; } static void rawin_free(t_rawin *x) { rawin_close(x); clock_free(x->x_clock); pdp_tree_strip_packets(x->x_queue); pdp_tree_free(x->x_queue); } t_class *rawin_class; static void *rawin_new(t_symbol *spipe, t_symbol *type) { t_rawin *x; pdp_post("%s %s", spipe->s_name, type->s_name); /* allocate & init */ x = (t_rawin *)pd_new(rawin_class); x->x_outlet = outlet_new(&x->x_obj, &s_anything); x->x_sync_outlet = outlet_new(&x->x_obj, &s_anything); x->x_clock = clock_new(x, (t_method)rawin_tick); x->x_queue = pdp_list_new(0); x->x_active = 0; x->x_giveup = 0; x->x_mode = 0; x->x_type = pdp_gensym("image/YCrCb/320x240"); //default x->x_pipe = gensym("/tmp/pdpraw"); // default pthread_attr_init(&x->x_attr); pthread_mutex_init(&x->x_mut, NULL); clock_delay(x->x_clock, PERIOD); /* args */ rawin_type(x, type); if (spipe->s_name[0]) x->x_pipe = spipe; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_rawin_setup(void) { int i; /* create a standard pd class: [pdp_rawin pipe type] */ rawin_class = class_new(gensym("pdp_rawin"), (t_newmethod)rawin_new, (t_method)rawin_free, sizeof(t_rawin), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL); /* add global message handlers */ class_addmethod(rawin_class, (t_method)rawin_type, gensym("type"), A_SYMBOL, A_NULL); class_addmethod(rawin_class, (t_method)rawin_open, gensym("open"), A_DEFSYMBOL, A_NULL); class_addmethod(rawin_class, (t_method)rawin_close, gensym("close"), A_NULL); class_addmethod(rawin_class, (t_method)rawin_sync, gensym("sync"), A_FLOAT, A_NULL); class_addmethod(rawin_class, (t_method)rawin_bang, gensym("bang"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_rawout.c000066400000000000000000000315001266045153600217110ustar00rootroot00000000000000/* * Pure Data Packet module. Raw packet output. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This is the most straightforward way to get data out of pdp. The internals follow the simple reader/writer pattern * writer: runs in pd thread, accepts packets from inlet and stores in queue * reader: runs in own thread, reads packets from queue and writes to pipe Since there is no communication from reader to writer, we need a watchdog timer to check the status of the writer. Mainly to close when necessary. To enable audio recording, pdp_rawout will also produce interleaved 16bit audio. You will need to instantiate it with [pdp_rawout~ nbchans] */ /* TODO: make audio buffer smaller (128 bytes writes is too heavy) */ #include #include #include #include #include #include #include #include #include #include #include #include #include "pdp_pd.h" #include "pdp_debug.h" #include "pdp_list.h" #include "pdp_comm.h" #include "pdp_post.h" #include "pdp_packet.h" #define D if (1) #define DEF_QUEUESIZE 100 #define PIPE_BLOCKSIZE 4096 #define POLLTIME 20 /* raw input from a unix pipe */ typedef struct rawout_struct { /* pd */ t_object x_obj; t_float x_f; //t_outlet *x_outlet; t_outlet *x_sync_outlet; /* comm */ t_pdp_list *x_queue; // packet queue t_clock *x_clock; // watchdog timer t_float x_deltime; // watchdog period int x_verbose; int x_packet; // dsp fillup state int x_countdown; // amount of packet filled up short int * x_needle; // start writing here /* thread */ pthread_mutex_t x_mut; pthread_attr_t x_attr; pthread_t x_thread; /* sync */ int x_giveup; // 1-> terminate writer thread int x_active; // 1-> writer thread is launched int x_done; // 1-> writer thread has exited /* config */ t_symbol *x_pipe; int x_chans; // nb audio channels t_pdp_symbol *x_tmptype; int x_max_queuesize; // buffer size ( < 0 = infty ) } t_rawout; static inline void lock(t_rawout *x){pthread_mutex_lock(&x->x_mut);} static inline void unlock(t_rawout *x){pthread_mutex_unlock(&x->x_mut);} static void rawout_close(t_rawout *x); /* READER THREAD: reads from queue, writes to pipe */ static void *rawout_thread(void *y) { int pipefd; int packet = -1; t_rawout *x = (t_rawout *)y; int period_sec; int period_usec; sigset_t _sigvec; /* signal handling */ char me[1024]; sprintf(me, "pdp_rawout: %s", x->x_pipe->s_name); /* ignore pipe signal */ sigemptyset(&_sigvec); sigaddset(&_sigvec,SIGPIPE); pthread_sigmask(SIG_BLOCK, &_sigvec, 0); //D pdp_post("pipe: %s", x->x_pipe->s_name); //D pdp_post("type: %s", x->x_type->s_name); /* open pipe */ if (-1 == (pipefd = open(x->x_pipe->s_name, O_WRONLY|O_NONBLOCK|O_APPEND))){ if (-1 == (pipefd = open(x->x_pipe->s_name, O_WRONLY|O_CREAT, 0600))){ perror(me); goto exit; } } pdp_post("pdp_rawout: opened %s", x->x_pipe->s_name); /* main loop (packets) */ while(1){ void *data = 0; int left = -1; /* try again if queue is empty */ if (!x->x_queue->elements){ /* check if we need to stop */ if (x->x_giveup){ goto close; } else { usleep(1000.0f); // sleep before polling again continue; } } /* get packet from queue */ lock(x); packet = pdp_list_pop(x->x_queue).w_packet; unlock(x); /* send packet */ //t_pdp *h = pdp_packet_header(packet); //fprintf(stderr, "users %d\n", h->users); data = pdp_packet_data(packet); left = pdp_packet_data_size(packet); //int i; for (i = 0; ix_giveup){ pdp_packet_mark_unused(packet); goto close; } /* select, with timeout */ FD_ZERO(&outset); FD_SET(pipefd, &outset); if (-1 == select(pipefd+1, NULL, &outset, NULL, &tv)){ pdp_post("select error"); goto close; } /* if ready, read, else retry */ if (FD_ISSET(pipefd, &outset)){ int bytes = write(pipefd, data, left); /* handle errors */ if (bytes <= 0){ perror(me); if (errno != EAGAIN) goto close; } /* or update pointers */ else{ data += bytes; left -= bytes; //pdp_post("left %d", left); } } else { //pdp_post("retrying write"); } } /* discard packet */ pdp_packet_mark_unused(packet); } close: /* close pipe */ close(pipefd); exit: x->x_done = 1; return 0; } /* DSP INPUT */ #define DSP_ARG(type, name, source) type name = (type)source static t_int *rawout_perform(t_int *w); static void rawout_dsp(t_rawout *x, t_signal **sp){ int nargs = 2 + x->x_chans; t_int args[nargs]; args[0] = (t_int)x; args[1] = (t_int)sp[0]->s_n; float **in = (float **)(args+2); int i; for (i=0; ix_chans; i++) in[i] = sp[i]->s_vec; dsp_addv(rawout_perform, nargs, args); } static t_int *rawout_perform(t_int *w) { DSP_ARG(t_rawout*, x, w[1]); DSP_ARG(t_int, n, w[2]); DSP_ARG(t_float**, in, &w[3]); short int *out; int i,c,k; if (x->x_queue->elements >= x->x_max_queuesize){ // drop if (x->x_verbose && x->x_active) pdp_post_n("."); } else { // create packet if (x->x_countdown) { out = x->x_needle; } else { int p = pdp_factory_newpacket(x->x_tmptype); pdp_packet_mark_unused(x->x_packet); // if (-1 == p) pdp_post("pdp_rawout~: can't create packet"); x->x_needle = out = (short int *)pdp_packet_data(p); x->x_packet = p; x->x_countdown = pdp_packet_data_size(p) / 2; } //pdp_post("data size = %d bytes", pdp_packet_data_size(p)); //memset(out, 0, pdp_packet_data_size(p)); // convert & interleave for (k=0,i=0; ix_chans; c++,k++){ float val = (in[c])[i]; val *= (float)((1<<15)-1); out[k] = (short int)(val); //out[k] = 0x1234; //fprintf(stderr, "(%d,%d,%d) %d\n", c, i, k, (int)out[k]); } } x->x_needle += k; x->x_countdown -= k; if (!x->x_countdown){ // transfer lock(x); pdp_list_add_back(x->x_queue, a_packet, (t_pdp_word)x->x_packet); x->x_packet = -1; unlock(x); } } return w+3+x->x_chans; } /* PACKET INPUT */ static void pdp_in(t_rawout *x, t_symbol *s, t_float f) { /* save packet to pdp queue, if size is smaller than maxsize */ if (s == S_REGISTER_RO){ if (x->x_queue->elements < x->x_max_queuesize){ int p = (int)f; p = pdp_packet_copy_ro(p); if (p != -1){ lock(x); pdp_list_add_back(x->x_queue, a_packet, (t_pdp_word)p); unlock(x); } } else { //pdp_post("pdp_rawout: dropping packet: (queue full)", x->x_max_queuesize); if (x->x_active && x->x_verbose) pdp_post_n("."); } } /* check if thread is done */ if (x->x_done) rawout_close(x); } /* CONTROL */ //static void rawout_type(t_rawout *x, t_symbol *type) //{ //x->x_type = pdp_gensym(type->s_name); //} static void clear_queue(t_rawout *x); static void rawout_open(t_rawout *x, t_symbol *spipe) { /* save pipe name if not empty */ if (spipe->s_name[0]) {x->x_pipe = spipe;} if (x->x_active) { pdp_post("already open"); return; } /* start thread */ x->x_giveup = 0; x->x_done = 0; clear_queue(x); pthread_create(&x->x_thread, &x->x_attr, rawout_thread , x); x->x_active = 1; } static void rawout_stopthread(t_rawout *x){ if (!x->x_active) return; /* stop thread: set giveup + wait */ x->x_giveup = 1; pthread_join(x->x_thread, NULL); x->x_active = 0; clear_queue(x); } static void rawout_close(t_rawout *x) { if (!x->x_active) return; rawout_stopthread(x); /* notify */ outlet_bang(x->x_sync_outlet); pdp_post("pdp_rawout: closed %s", x->x_pipe->s_name); } static void rawout_verbose(t_rawout *x, t_float fverbose){ x->x_verbose = (int)fverbose; } static void rawout_tick(t_rawout *x){ if (x->x_done) rawout_close(x); clock_delay(x->x_clock, x->x_deltime); } static void clear_queue(t_rawout *x){ lock(x); while(x->x_queue->elements){ pdp_packet_mark_unused(pdp_list_pop(x->x_queue).w_packet); } unlock(x); } #define MAXINT (0x80 << ((sizeof(int)-1)*8)) static void rawout_queuesize(t_rawout *x, t_float fbufsize){ int bufsize = (int)fbufsize; if (fbufsize < 1) fbufsize = MAXINT; x->x_max_queuesize = bufsize; } static void rawout_free(t_rawout *x) { // terminate thread rawout_stopthread(x); // cleanup clock_unset(x->x_clock); clear_queue(x); pdp_tree_free(x->x_queue); pdp_packet_mark_unused(x->x_packet); } t_class *rawout_class; t_class *rawout_dsp_class; // shared stuff static void rawout_init(t_rawout *x, t_symbol *spipe){ //x->x_outlet = outlet_new(&x->x_obj, &s_anything); x->x_sync_outlet = outlet_new(&x->x_obj, &s_anything); x->x_queue = pdp_list_new(0); x->x_active = 0; x->x_giveup = 0; x->x_done = 0; x->x_packet = -1; x->x_countdown = 0; x->x_max_queuesize = DEF_QUEUESIZE; //x->x_type = pdp_gensym("image/YCrCb/320x240"); //default x->x_pipe = gensym("/tmp/pdpraw"); // default x->x_deltime = POLLTIME; x->x_clock = clock_new(x, (t_method)rawout_tick); pthread_attr_init(&x->x_attr); pthread_mutex_init(&x->x_mut, NULL); /* args */ //rawout_type(x, type); if (spipe && spipe->s_name[0]) x->x_pipe = spipe; rawout_tick(x); rawout_verbose(x,0); } // [pdp_rawout] static void *rawout_new(t_symbol *spipe /* , t_symbol *type */) { t_rawout *x; /* allocate & init */ x = (t_rawout *)pd_new(rawout_class); rawout_init(x, spipe); return (void *)x; } // [pdp_rawout~] // HUH??? why do i get the symbol first, then the float???? // see http://lists.puredata.info/pipermail/pd-dev/2003-09/001618.html //static void *rawout_dsp_new(t_float fchans, t_symbol *spipe){ static void *rawout_dsp_new(t_symbol *spipe, t_float fchans){ int chans = (int)fchans; if (chans < 1) chans = 1; if (chans > 64) return 0; // this is just a safety measure t_rawout *x = (t_rawout *)pd_new(rawout_dsp_class); rawout_init(x, spipe); // hack: temp packet char temp_packet[1024]; sprintf(temp_packet, "image/grey/256x%d", 8 * chans); pdp_post("pdp_rawout: using fake packet %s", temp_packet); x->x_tmptype = pdp_gensym(temp_packet); // create audio inlets x->x_chans = chans; while (--chans) inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); return (void *)x; } #ifdef __cplusplus extern "C" { #endif #define COMMON(base_class)\ class_addmethod(base_class, (t_method)rawout_open, gensym("open"), A_DEFSYMBOL, A_NULL);\ class_addmethod(base_class, (t_method)rawout_close, gensym("close"), A_NULL);\ class_addmethod(base_class, (t_method)rawout_verbose, gensym("verbose"), A_FLOAT, A_NULL);\ class_addmethod(base_class, (t_method)rawout_queuesize, gensym("bufsize"), A_FLOAT, A_NULL); void pdp_rawout_setup(void){ int i; /* PACKETS */ /* create a standard pd class: [pdp_rawout pipe type] */ rawout_class = class_new(gensym("pdp_rawout"), (t_newmethod)rawout_new, (t_method)rawout_free, sizeof(t_rawout), 0, A_DEFSYMBOL, A_NULL); /* add global message handler */ class_addmethod(rawout_class, (t_method)pdp_in, gensym("pdp"), A_SYMBOL, A_FLOAT, A_NULL); COMMON(rawout_class); /* DSP */ /* create a standard pd class: [pdp_rawout pipe type] */ rawout_dsp_class = class_new(gensym("pdp_rawout~"), (t_newmethod)rawout_dsp_new, (t_method)rawout_free, sizeof(t_rawout), 0, A_DEFFLOAT, A_DEFSYMBOL, A_NULL); /* add signal input */ CLASS_MAINSIGNALIN(rawout_dsp_class, t_rawout, x_f); class_addmethod(rawout_dsp_class, (t_method)rawout_dsp, gensym("dsp"), 0); COMMON(rawout_dsp_class); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_reg.c000066400000000000000000000075731266045153600211620ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_png.h" #include "pdp_internals.h" typedef struct pdp_reg_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; int x_packet0; } t_pdp_reg; static void pdp_reg_load_png(t_pdp_reg *x, t_symbol *s) { int packet; //post("sym: %s", s->s_name); packet = pdp_packet_bitmap_from_png_file(s->s_name); if (-1 == packet){ post("pdp_reg: error loading png file %s", s->s_name); } else{ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = packet; } } static void pdp_reg_save_png(t_pdp_reg *x, t_symbol *s) { int newpacket = pdp_packet_convert_ro(x->x_packet0, pdp_gensym("bitmap/*/*")); if (-1 == newpacket){ post("pdp_reg: nothing to save"); return; } if (!(pdp_packet_bitmap_save_png_file(newpacket, s->s_name))){ post("pdp_reg: error saving png file %s", s->s_name); } pdp_packet_mark_unused(newpacket); } static void pdp_reg_bang(t_pdp_reg *x) { if (-1 != x->x_packet0) outlet_pdp(x->x_outlet0, x->x_packet0); } static void pdp_reg_input_0(t_pdp_reg *x, t_symbol *s, t_floatarg f) { /* if this is a register_ro message or register_rw message, register with packet factory */ /* if this is a process message, start the processing + propagate stuff to outputs */ if (s == gensym("register_ro")){ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_copy_ro((int)f); //post("in0ro: requested %d, got %d", (int)f, x->x_packet0); } else if (s == gensym("process")){ pdp_reg_bang(x); } } static void pdp_reg_input_1(t_pdp_reg *x, t_symbol *s, t_floatarg f) { /* if this is a register_ro message or register_rw message, register with packet factory */ /* if this is a process message, start the processing + propagate stuff to outputs */ if (s == gensym("register_ro")){ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_copy_ro((int)f); //post("in0ro: requested %d, got %d", (int)f, x->x_packet0); } } static void pdp_reg_free(t_pdp_reg *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_reg_class; void *pdp_reg_new(void) { t_pdp_reg *x = (t_pdp_reg *)pd_new(pdp_reg_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1")); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_reg_setup(void) { pdp_reg_class = class_new(gensym("pdp_reg"), (t_newmethod)pdp_reg_new, (t_method)pdp_reg_free, sizeof(t_pdp_reg), 0, A_NULL); class_addmethod(pdp_reg_class, (t_method)pdp_reg_bang, gensym("bang"), A_NULL); class_addmethod(pdp_reg_class, (t_method)pdp_reg_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_reg_class, (t_method)pdp_reg_input_1, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_reg_class, (t_method)pdp_reg_save_png, gensym("save_png"), A_SYMBOL, A_NULL); class_addmethod(pdp_reg_class, (t_method)pdp_reg_load_png, gensym("load_png"), A_SYMBOL, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_route.c000066400000000000000000000062551266045153600215370ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_internals.h" // dynamic ???? #define PDP_ROUTE_MAX_NB_OUTLETS 100 typedef struct pdp_route_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet[PDP_ROUTE_MAX_NB_OUTLETS]; int x_nb_outlets; int x_route; int x_route_next; } t_pdp_route; static void pdp_route_input_0(t_pdp_route *x, t_symbol *s, t_floatarg f) { t_atom atom[2]; t_symbol *pdp = gensym("pdp"); /* trigger on register_ro */ if (s == gensym("register_ro")){ x->x_route = x->x_route_next; } /* propagate the pdp message */ SETSYMBOL(atom+0, s); SETFLOAT(atom+1, f); outlet_anything(x->x_outlet[x->x_route], pdp, 2, atom); } static void pdp_route_input_0_dpd(t_pdp_route *x, t_symbol *s, t_floatarg f) { /* trigger on accumulate */ if (s == gensym("accumulate")){ x->x_route = x->x_route_next; } /* propagate the dpd message */ outlet_dpd(x->x_outlet[x->x_route], (int)f); } static void pdp_route_route(t_pdp_route *x, t_floatarg f) { int route = (int)f; if (route < 0) route = 0; if (route >= x->x_nb_outlets) route = x->x_nb_outlets - 1; x->x_route_next = route; } static void pdp_route_free(t_pdp_route __attribute__((unused)) *x) { } t_class *pdp_route_class; void *pdp_route_new(t_floatarg f) { int nboutlets = (int)f; int i; t_pdp_route *x = (t_pdp_route *)pd_new(pdp_route_class); if (nboutlets < 2) nboutlets = 2; if (nboutlets >= PDP_ROUTE_MAX_NB_OUTLETS) nboutlets = PDP_ROUTE_MAX_NB_OUTLETS - 1; inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("route")); x->x_nb_outlets = nboutlets; x->x_route = 0; x->x_route_next = 0; for (i=0; ix_outlet[i] = outlet_new(&x->x_obj, &s_anything); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_route_setup(void) { pdp_route_class = class_new(gensym("pdp_route"), (t_newmethod)pdp_route_new, (t_method)pdp_route_free, sizeof(t_pdp_route), 0, A_DEFFLOAT, A_NULL); class_addmethod(pdp_route_class, (t_method)pdp_route_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_route_class, (t_method)pdp_route_input_0_dpd, gensym("dpd"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_route_class, (t_method)pdp_route_route, gensym("route"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_snap.c000066400000000000000000000050521266045153600213340ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_internals.h" typedef struct pdp_snap_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; int x_packet0; bool x_snapnext; } t_pdp_snap; static void pdp_snap_bang(t_pdp_snap *x) { if (-1 != x->x_packet0) outlet_pdp(x->x_outlet0, x->x_packet0); } static void pdp_snap_input_1(t_pdp_snap *x, t_symbol *s, t_floatarg f) { /* if this is a register_ro message or register_rw message, register with packet factory */ /* if this is a process message, start the processing + propagate stuff to outputs */ if (s == gensym("register_ro")){ if(x->x_snapnext) { pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_copy_ro((int)f); x->x_snapnext = false; } } } static void pdp_snap_snap(t_pdp_snap *x) { x->x_snapnext = true; } static void pdp_snap_free(t_pdp_snap *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_snap_class; void *pdp_snap_new(void) { t_pdp_snap *x = (t_pdp_snap *)pd_new(pdp_snap_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1")); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; x->x_snapnext = false; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_snap_setup(void) { pdp_snap_class = class_new(gensym("pdp_snap"), (t_newmethod)pdp_snap_new, (t_method)pdp_snap_free, sizeof(t_pdp_snap), 0, A_NULL); class_addmethod(pdp_snap_class, (t_method)pdp_snap_bang, gensym("bang"), A_NULL); class_addmethod(pdp_snap_class, (t_method)pdp_snap_snap, gensym("snap"), A_NULL); class_addmethod(pdp_snap_class, (t_method)pdp_snap_input_1, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_trigger.c000066400000000000000000000110761266045153600220410ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_internals.h" /* adapted from the pd trigger object */ #define TR_BANG 0 #define TR_FLOAT 1 #define TR_SYMBOL 2 #define TR_POINTER 3 #define TR_LIST 4 #define TR_ANYTHING 5 #define TR_PDP 6 /* $$$TODO: emplement so that it behaves like the standard trigger object i.e. [trigger bang pdp pdp bang pdp] register_ro and register_rw messages pass right trough, since they're not action events, only configure events. a bang is made equivalent to a process event. */ typedef struct triggerout { int u_type; /* outlet type from above */ t_outlet *u_outlet; } t_triggerout; typedef struct pdp_trigger_struct { t_object x_obj; t_float x_f; int x_n; t_triggerout *x_vec; } t_pdp_trigger; static void pdp_trigger_input_pdp(t_pdp_trigger *x, t_symbol *s, t_floatarg f) { t_atom atom[2]; t_symbol *pdp = S_PDP; t_symbol *prc = S_PROCESS; t_triggerout *u; int i; for (i = x->x_n, u = x->x_vec + i; u--, i--;){ /* trigger bang outlet only when a process event is recieved */ if ((u->u_type == TR_BANG) && (s == prc)){ outlet_bang(u->u_outlet); } /* just pass the message if it is a pdp outlet */ if ((u->u_type) == TR_PDP){ SETSYMBOL(atom+0, s); SETFLOAT(atom+1, f); if (s == prc) outlet_anything(u->u_outlet, pdp, 1, atom); else outlet_anything(u->u_outlet, pdp, 2, atom); } } } static void pdp_trigger_input_dpd(t_pdp_trigger *x, t_symbol *s, t_floatarg f) { t_atom atom[2]; t_symbol *dpd = S_DPD; t_symbol *acc = S_ACCUMULATE; t_triggerout *u; int i; int p = (int)f; for (i = x->x_n, u = x->x_vec + i; u--, i--;){ /* trigger outlet only when an accumulate event is recieved */ if (s == acc){ /* output bang */ if (u->u_type == TR_BANG) outlet_bang(u->u_outlet); /* output a complete dpd message if it is a pdp outlet */ if ((u->u_type) == TR_PDP){ outlet_dpd(u->u_outlet, p); } } } } static void pdp_trigger_free(t_pdp_trigger *x) { pdp_dealloc(x->x_vec); } t_class *pdp_trigger_class; static void *pdp_trigger_new(t_symbol __attribute__((unused)) *s, int argc, t_atom *argv) { t_pdp_trigger *x = (t_pdp_trigger *)pd_new(pdp_trigger_class); t_atom defarg[2], *ap; t_triggerout *u; int i; if (!argc) { argv = defarg; argc = 2; SETSYMBOL(&defarg[0], gensym("pdp")); SETSYMBOL(&defarg[1], gensym("bang")); } x->x_n = argc; x->x_vec = pdp_alloc(argc * sizeof(*x->x_vec)); for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++) { t_atomtype thistype = ap->a_type; char c; if (thistype == TR_SYMBOL) c = ap->a_w.w_symbol->s_name[0]; else c = 0; if (c == 'p') u->u_type = TR_PDP, u->u_outlet = outlet_new(&x->x_obj, &s_anything); else if (c == 'b') u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang); else { pd_error(x, "pdp_trigger: %s: bad type", ap->a_w.w_symbol->s_name); u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang); } } return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_trigger_setup(void) { pdp_trigger_class = class_new(gensym("pdp_trigger"), (t_newmethod)pdp_trigger_new, (t_method)pdp_trigger_free, sizeof(t_pdp_trigger), 0, A_GIMME, A_NULL); class_addcreator((t_newmethod)pdp_trigger_new, gensym("pdp_t"), A_GIMME, 0); class_addmethod(pdp_trigger_class, (t_method)pdp_trigger_input_pdp, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_trigger_class, (t_method)pdp_trigger_input_dpd, gensym("dpd"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_udp_receive.c000066400000000000000000000110601266045153600226610ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this module sends receives an udp packet stream and converts to pdp packet */ #include "pdp_net.h" #include "pdp.h" #include "pdp_resample.h" #define D if(0) typedef struct pdp_udp_receive_struct { t_object x_obj; t_float x_f; /* receiver object */ t_pdp_udp_receiver *x_receiver; /* thread vars */ pthread_attr_t x_attr; pthread_t x_thread; int x_exit_thread; /* packet queue */ int x_index; int x_packet[2]; /* polling clock */ t_clock *x_clock; /* outlet */ t_outlet *x_outlet0; } t_pdp_udp_receive; static void clock_tick(t_pdp_udp_receive *x) { /* poll for new packet */ pdp_pass_if_valid(x->x_outlet0, &x->x_packet[!x->x_index]); clock_delay(x->x_clock, 1.0f); } static void *receive_thread(void *threaddata) { t_pdp_udp_receive *x = (t_pdp_udp_receive *)threaddata; t_pdp *pdp_header = 0; void *pdp_data = 0; int tmp_packet = -1; char *type = 0; unsigned int size = 0; /* listen for packets */ while (!x->x_exit_thread){ switch(pdp_udp_receiver_receive(x->x_receiver, 100)){ case -1: /* error */ goto exit; case 0: /* timeout */ continue; case 1: /* data ready */ break; } /* create a new packet */ type = pdp_udp_receiver_type(x->x_receiver); tmp_packet = pdp_factory_newpacket(pdp_gensym(type)); pdp_header = pdp_packet_header(tmp_packet); pdp_data = pdp_packet_data(tmp_packet); /* check if we were able to create the pdp packet */ if (!(pdp_header && pdp_data)){ post("pdp_netreceive: can't create packet (type %s)", type); pdp_udp_receiver_reset(x->x_receiver); continue; } /* check size */ size = pdp_udp_receiver_size(x->x_receiver); if ((pdp_header->size - PDP_HEADER_SIZE) != size){ pdp_packet_mark_unused(tmp_packet); tmp_packet = -1; post("pdp_netreceive: invalid packet size %d (pdp packet size = %d)", size, pdp_header->size - PDP_HEADER_SIZE); continue; } /* copy the data */ memcpy(pdp_data, pdp_udp_receiver_data(x->x_receiver), size); /* copy the packet into queue */ x->x_index ^= 1; pdp_packet_mark_unused(x->x_packet[x->x_index]); x->x_packet[x->x_index] = tmp_packet; } exit: post("thread exiting"); return 0; } static void pdp_udp_receive_free(t_pdp_udp_receive *x) { int i; void* retval; x->x_exit_thread = 1; // wait for thread to finish pthread_join(x->x_thread, &retval); pdp_udp_receiver_free(x->x_receiver); pdp_packet_mark_unused(x->x_packet[0]); pdp_packet_mark_unused(x->x_packet[1]); } t_class *pdp_udp_receive_class; void *pdp_udp_receive_new(t_floatarg fport) { int i; int port; struct hostent *hp; t_pdp_udp_receive *x = (t_pdp_udp_receive *)pd_new(pdp_udp_receive_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet[0] = -1; x->x_packet[1] = -1; x->x_index = 0; port = (fport == 0.0f) ? 7777 : fport; x->x_receiver = pdp_udp_receiver_new(port); /* setup thread stuff & create thread */ x->x_exit_thread = 0; pthread_attr_init(&x->x_attr); pthread_attr_setschedpolicy(&x->x_attr, SCHED_OTHER); pthread_create(&x->x_thread, &x->x_attr, receive_thread, x); /* setup the clock */ x->x_clock = clock_new(x, (t_method)clock_tick); clock_delay(x->x_clock, 0); post("pdp_netreceive: WARNING: experimental object"); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_udp_receive_setup(void) { pdp_udp_receive_class = class_new(gensym("pdp_netreceive"), (t_newmethod)pdp_udp_receive_new, (t_method)pdp_udp_receive_free, sizeof(t_pdp_udp_receive), 0, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/generic/pdp_udp_send.c000066400000000000000000000200621266045153600221720ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this module sends a pure packet out as an udp packet stream */ #include "pdp_net.h" #include "pdp.h" #include "pdp_resample.h" #include #include #include #include #include #include #define DD if(0) // print DROP debug info #define D if(0) // print extra connection debug info #define V if(0) // be verbose (parameter setting feedback) typedef struct pdp_udp_send_struct { t_object x_obj; t_float x_f; /* sender object */ t_pdp_udp_sender *x_sender; /* pthread vars */ pthread_mutex_t x_mut; pthread_cond_t x_cond_data_ready; pthread_cond_t x_cond_send_done; pthread_t x_thread; int x_exit_thread; // drop info unsigned int x_drop; t_outlet *x_outlet0; // packet queue int x_nb_packets; int x_read_packet; int x_write_packet; int *x_packet; } t_pdp_udp_send; /* some synchro code */ static int _wait_for_feeder(t_pdp_udp_send *x) { /* only use locking when there is no data */ if (x->x_packet[x->x_read_packet] == -1){ /* signal sending is done */ pthread_mutex_lock(&x->x_mut); pthread_cond_signal(&x->x_cond_send_done); /* wait until there is an item in the queue */ while((x->x_packet[x->x_read_packet] == -1) && (!x->x_exit_thread)){ pthread_cond_wait(&x->x_cond_data_ready, &x->x_mut); } pthread_mutex_unlock(&x->x_mut); /* check if we need to stop the thread */ if (x->x_exit_thread) return 0; } return !x->x_exit_thread; } static void _signal_sender(t_pdp_udp_send *x) { pthread_mutex_lock(&x->x_mut); pthread_cond_signal(&x->x_cond_data_ready); pthread_mutex_unlock(&x->x_mut); } static void _wait_until_done(t_pdp_udp_send *x) { pthread_mutex_lock(&x->x_mut); while (x->x_packet[x->x_read_packet] != -1){ pthread_cond_wait(&x->x_cond_send_done, &x->x_mut); } pthread_mutex_unlock(&x->x_mut); } static void _remove_packet_from_queue(t_pdp_udp_send __attribute__((unused)) *x) { } static void *send_thread(void *threaddata) { t_pdp_udp_send *x = (t_pdp_udp_send *)threaddata; /* main thread loop */ /* get a pdp packet from queue */ /* send header packet and make sure it has arrived */ /* send a chunk burst */ /* send done packet and get the resend list */ /* repeat until send list is empty */ while (_wait_for_feeder(x)){ t_pdp *header; void *data; /* check if we have a valid pdp packet */ if ((!(header = pdp_packet_header(x->x_packet[x->x_read_packet]))) ||(!(data = pdp_packet_data(x->x_packet[x->x_read_packet]))) ||(0 == header->desc)) goto remove; /* nothing to transmit */ /* send it */ pdp_udp_sender_send(x->x_sender, header->desc->s_name, header->size - PDP_HEADER_SIZE, data); remove: /* remove packet from queue */ pdp_packet_mark_unused(x->x_packet[x->x_read_packet]); x->x_packet[x->x_read_packet] = -1; x->x_read_packet++; x->x_read_packet %= x->x_nb_packets; } return 0; } static void pdp_udp_send_input_0(t_pdp_udp_send *x, t_symbol *s, t_floatarg f) { int p = (int)f; int my_p; int transferred = 0; if (s== gensym("register_ro")){ // check if packet can be stored in the queue // this is possible if the current write location does not contain a packet if (x->x_packet[x->x_write_packet] == -1){ // get the packet outside of the lock my_p = pdp_packet_copy_ro(p); // add to queue (do we really need to lock here?> //pthread_mutex_lock(&x->x_mut); // LOCK x->x_packet[x->x_write_packet] = my_p; x->x_write_packet++; x->x_write_packet %= x->x_nb_packets; transferred = 1; //pthread_mutex_unlock(&x->x_mut); // UNLOCK } // signal sender if transfer succeded if (transferred) _signal_sender(x); // else send a float indicating the number of drops so far else{ x->x_drop++; //outlet_float(x->x_outlet0, (float)x->x_drop); DD post ("pdp_netsend: DROP: queue full"); } } } /* some flow control hacks */ static void pdp_udp_send_timeout(t_pdp_udp_send *x, float f) { if (f < 0.0f) f = 0.0f; pdp_udp_sender_timeout_us(x->x_sender, 1000.0f * f); } static void pdp_udp_send_sleepgrain(t_pdp_udp_send *x, float f) { if (f < 0.0f) f = 0.0f; pdp_udp_sender_sleepgrain_us(x->x_sender, 1000.0f * f); } static void pdp_udp_send_sleepperiod(t_pdp_udp_send *x, float f) { if (f < 0.0f) f = 0.0f; pdp_udp_sender_sleepperiod(x->x_sender, f); } static void pdp_udp_send_udpsize(t_pdp_udp_send *x, float f) { if (f < 0.0f) f = 0.0f; pdp_udp_sender_udp_packet_size(x->x_sender, f); } static void pdp_udp_send_connect(t_pdp_udp_send *x, t_symbol *shost, t_float fport) { unsigned int port; struct hostent *hp; /* suspend until sending thread is finished */ _wait_until_done(x); /* set target address */ port = (fport == 0.0f) ? 7777 : fport; if (shost == gensym("")) shost = gensym("127.0.0.1"); /* connect */ pdp_udp_sender_connect(x->x_sender, shost->s_name, port); } static void pdp_udp_send_free(t_pdp_udp_send *x) { int i; void* retval; _wait_until_done(x); // send all remaining packets x->x_exit_thread = 1; // .. and wait for thread to finish _signal_sender(x); pthread_join(x->x_thread, &retval); pdp_udp_sender_free(x->x_sender); for (i=0; ix_nb_packets; i++) pdp_packet_mark_unused(x->x_packet[i]); pdp_dealloc(x->x_packet); } t_class *pdp_udp_send_class; void *pdp_udp_send_new(void) { int i; pthread_attr_t attr; t_pdp_udp_send *x = (t_pdp_udp_send *)pd_new(pdp_udp_send_class); x->x_sender = pdp_udp_sender_new(); //x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_nb_packets = 4; x->x_packet = malloc(sizeof(int)*x->x_nb_packets); for (i=0; ix_nb_packets; i++) x->x_packet[i] = -1; x->x_read_packet = 0; x->x_write_packet = 0; x->x_drop = 0; /* setup thread stuff & create thread */ x->x_exit_thread = 0; pthread_mutex_init(&x->x_mut, NULL); pthread_cond_init(&x->x_cond_data_ready, NULL); pthread_cond_init(&x->x_cond_send_done, NULL); pthread_attr_init(&attr); //pthread_attr_setschedpolicy(&attr, SCHED_OTHER); pthread_create(&x->x_thread, &attr, send_thread, x); post("pdp_netsend: WARNING: experimental object"); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_udp_send_setup(void) { pdp_udp_send_class = class_new(gensym("pdp_netsend"), (t_newmethod)pdp_udp_send_new, (t_method)pdp_udp_send_free, sizeof(t_pdp_udp_send), 0, A_NULL); class_addmethod(pdp_udp_send_class, (t_method)pdp_udp_send_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_udp_send_class, (t_method)pdp_udp_send_sleepgrain, gensym("sleepgrain"), A_FLOAT, A_NULL); class_addmethod(pdp_udp_send_class, (t_method)pdp_udp_send_sleepperiod, gensym("sleepperiod"), A_FLOAT, A_NULL); class_addmethod(pdp_udp_send_class, (t_method)pdp_udp_send_udpsize, gensym("udpsize"), A_FLOAT, A_NULL); class_addmethod(pdp_udp_send_class, (t_method)pdp_udp_send_timeout, gensym("timeout"), A_FLOAT, A_NULL); class_addmethod(pdp_udp_send_class, (t_method)pdp_udp_send_connect, gensym("connect"), A_SYMBOL, A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/000077500000000000000000000000001266045153600201715ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/image_basic/Makefile000066400000000000000000000005661266045153600216400ustar00rootroot00000000000000current: all_modules include ../../Makefile.config PDP_MOD = pdp_add.o pdp_conv.o \ pdp_mix.o pdp_mul.o pdp_randmix.o \ pdp_bq.o pdp_noise.o \ pdp_gain.o pdp_zoom.o \ pdp_constant.o \ pdp_logic.o pdp_stateless.o pdp_plasma.o $(PDP_IMAGE_BASIC) # build basic image processing modules (derived from base class) all_modules: $(PDP_MOD) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/image_basic/README000066400000000000000000000003461266045153600210540ustar00rootroot00000000000000This directory contains "normal" planar 16 bit unsigned image packet processors, derived from the t_pdp_imagebase class defined in pdp_imagebase.h Most modules are wrappers around monochrome bitmap processors (pdp_imageproc_*) pdp-0.14.1+darcs20180201/modules/image_basic/pdp_add.c000066400000000000000000000053551266045153600217400ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_add_struct { /* a pdp derived class has the t_pdp_imagebase data member as first entry */ /* it contains the pd object and the data members for the pdp_base class */ t_pdp_imagebase x_base; } t_pdp_add; /* the process method */ static void pdp_add_process(t_pdp_add *x) { /* get received packets */ int p0, p1; /* get channel mask */ int mask = pdp_imagebase_get_chanmask(x); /* this processes the packets using a pdp image processor */ /* replace this with your own processing code */ /* for raw packet acces: use pdp_pacjet_header() and pdp_packet_data() */ p0 = pdp_base_get_packet(x,0); p1 = pdp_base_get_packet(x,1); pdp_imageproc_dispatch_2buf(&pdp_imageproc_add_process, 0, mask, p0, p1); } static void pdp_add_free(t_pdp_add *x) { /* free super: this is mandatory (it stops the thread if there is one running and frees all packets) */ pdp_imagebase_free(x); /* if you have allocated more packets this is the place to free them with pdp_mark_unused */ } t_class *pdp_add_class; void *pdp_add_new(void) { /* allocate */ t_pdp_add *x = (t_pdp_add *)pd_new(pdp_add_class); /* init super: this is mandatory */ pdp_imagebase_init(x); /* set the pdp processing method */ pdp_base_set_process_method(x, (t_pdp_method)pdp_add_process); /* create additional cold (readonly) pdp inlets (there is already one pdp inlet) */ pdp_base_add_pdp_inlet(x); /* create a pdp_outlet */ pdp_base_add_pdp_outlet(x); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_add_setup(void) { /* create a standard pd class */ pdp_add_class = class_new(gensym("pdp_add"), (t_newmethod)pdp_add_new, (t_method)pdp_add_free, sizeof(t_pdp_add), 0, A_NULL); /* inherit pdp base class methods */ pdp_imagebase_setup(pdp_add_class); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_bq.c000066400000000000000000000267421266045153600216150ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" #include /* computes a transfer function: * * b0 + b1 z^(-1) + b2 z^(-2) * T(z) = -------------------------- * 1 + a1 z^(-1) + a2 z^(-2) * */ typedef struct pdp_bq_struct { t_pdp_imagebase x_base; //pdp_bq derives from pdp_base /* state packets for bqt */ int x_packet1; int x_packet2; unsigned int x_nbpasses; /* single direction */ unsigned int x_direction; bool x_reset_on_formatchange; void *x_biquad; float x_coefs_a[3]; // a0, -a1, -a2 float x_coefs_b[3]; // b0, b1, b2 float x_state_u[2]; // u0, u1 float x_state_u_save[2]; // u0, u1 (for reset) } t_pdp_bq; /************************* COEFFICIENT METHODS ****************************/ static void pdp_bq_a0(t_pdp_bq *x, t_floatarg f){x->x_coefs_a[0] = f;} static void pdp_bq_a1(t_pdp_bq *x, t_floatarg f){x->x_coefs_a[1] = -f;} static void pdp_bq_a2(t_pdp_bq *x, t_floatarg f){x->x_coefs_a[2] = -f;} static void pdp_bq_b0(t_pdp_bq *x, t_floatarg f){x->x_coefs_b[0] = f;} static void pdp_bq_b1(t_pdp_bq *x, t_floatarg f){x->x_coefs_b[1] = f;} static void pdp_bq_b2(t_pdp_bq *x, t_floatarg f){x->x_coefs_b[2] = f;} static void pdp_bq_u0(t_pdp_bq *x, t_floatarg f){x->x_state_u_save[0] = f;} static void pdp_bq_u1(t_pdp_bq *x, t_floatarg f){x->x_state_u_save[1] = f;} static void pdp_bq_setcoefs(t_pdp_bq *x, float a0, float a1, float a2, float b0, float b1, float b2) { pdp_bq_a0(x,a0); pdp_bq_a1(x,a1); pdp_bq_a2(x,a2); pdp_bq_b0(x,b0); pdp_bq_b1(x,b1); pdp_bq_b2(x,b2); pdp_imageproc_bq_setcoef(x->x_biquad, x->x_coefs_a); } static void pdp_bq_setstate(t_pdp_bq *x, float u0, float u1) { pdp_bq_u0(x,u0); pdp_bq_u1(x,u1); pdp_imageproc_bq_setcoef(x->x_biquad, x->x_coefs_a); } /* reso lowpass */ static void pdp_bq_lpf(t_pdp_bq *x, t_floatarg f, t_floatarg Q) { float a0, a1, a2, b0, b1, b2, cs, sn, w, alpha; w = 2.0 * M_PI * f; cs = cos(w); sn = sin(w); alpha = sn*sinh(1.0f/(2.0f*Q)); b0 = (1.0 - cs)/2.0; b1 = 1.0 - cs; b2 = (1.0 - cs)/2.0; a0 = (1.0 + alpha); a1 = -2.0*cs; a2 = 1.0 - alpha; pdp_bq_setcoefs(x, a0, a1, a2, b0, b1, b2); } /* reso highpass */ static void pdp_bq_hpf(t_pdp_bq *x, t_floatarg f, t_floatarg Q) { float a0, a1, a2, b0, b1, b2, cs, sn, w, alpha; w = 2.0 * M_PI * f; cs = cos(w); sn = sin(w); alpha = sn*sinh(1.0f/(2.0f*Q)); b0 = (1.0 + cs)/2.0; b1 = -1.0 - cs; b2 = (1.0 + cs)/2.0; a0 = (1.0 + alpha); a1 = -2.0*cs; a2 = 1.0 - alpha; pdp_bq_setcoefs(x, a0, a1, a2, b0, b1, b2); } /* reso allpass */ static void pdp_bq_apf(t_pdp_bq *x, t_floatarg f, t_floatarg Q) { float a0, a1, a2, b0, b1, b2, cs, sn, w, alpha; w = 2.0 * M_PI * f; cs = cos(w); sn = sin(w); alpha = sn*sinh(1.0f/(2.0f*Q)); b0 = (1.0 - alpha); b1 = -2.0 * cs; b2 = (1.0 + alpha); a0 = (1.0 + alpha); a1 = -2.0*cs; a2 = 1.0 - alpha; pdp_bq_setcoefs(x, a0, a1, a2, b0, b1, b2); } /* reso band stop (notch) */ static void pdp_bq_bsf(t_pdp_bq *x, t_floatarg f, t_floatarg Q) { float a0, a1, a2, b0, b1, b2, cs, sn, w, alpha; w = 2.0 * M_PI * f; cs = cos(w); sn = sin(w); alpha = sn*sinh(1.0f/(2.0f*Q)); b0 = 1.0; b1 = -2.0 * cs; b2 = 1.0; a0 = (1.0 + alpha); a1 = -2.0*cs; a2 = 1.0 - alpha; pdp_bq_setcoefs(x, a0, a1, a2, b0, b1, b2); } static void pdp_bq_onep(t_pdp_bq *x, t_floatarg f) { float a0,a1,a2,b0,b1,b2; if (f>1.0f) f = 1.0f; if (f<0.0f) f = 0.0f; a0 = 1.0f; a1 = -(1.0f - f); a2 = 0.0f; b0 = f; b1 = 0.0f; b2 = 0.0f; pdp_bq_setcoefs(x, a0, a1, a2, b0, b1, b2); } static void pdp_bq_twop(t_pdp_bq *x, t_floatarg f) { float f1; float a0,a1,a2,b0,b1,b2; if (f>1.0) f = 1.0; if (f<0.0) f = 0.0; f1 = 1.0 - f; a0 = 1.0f; a1 = -2.0f*f1; a2 = f1*f1; b0 = f*f; b1 = 0.0f; b2 = 0.0f; pdp_bq_setcoefs(x, a0, a1, a2, b0, b1, b2); } /************************* PROCESS METHODS ****************************/ static void pdp_bqt_process(t_pdp_bq *x) { /* get received packets */ int p0 = pdp_base_get_packet(x, 0); /* get channel mask */ u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_3buf(&pdp_imageproc_bqt_process, x->x_biquad, mask, p0, x->x_packet1, x->x_packet2); } static void pdp_bq_process(t_pdp_bq *x) { /* get received packets */ int p0 = pdp_base_get_packet(x, 0); /* get channel mask */ u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_bq_setnbpasses(x->x_biquad, x->x_nbpasses); pdp_imageproc_bq_setdirection(x->x_biquad, x->x_direction); pdp_imageproc_dispatch_1buf(&pdp_imageproc_bq_process, x->x_biquad, mask, p0); } static void pdp_bqt_reset(t_pdp_bq *x) { pdp_imageproc_dispatch_1buf(&pdp_imageproc_zero_process, 0, -1, x->x_packet1); pdp_imageproc_dispatch_1buf(&pdp_imageproc_zero_process, 0, -1, x->x_packet2); } static void pdp_bqt_preproc(t_pdp_bq *x) { /* get received packets */ int p0 = pdp_base_get_packet(x, 0); /* check if state packets are compatible */ if (!(pdp_packet_image_compat(p0, x->x_packet1) && pdp_packet_image_compat(p0, x->x_packet1))){ /* if not, create new state packets by copying the input packets */ post("pdp_bqt: created new state packets"); pdp_packet_mark_unused(x->x_packet1); pdp_packet_mark_unused(x->x_packet2); x->x_packet1 = pdp_packet_clone_rw(p0); x->x_packet2 = pdp_packet_clone_rw(p0); /* reset */ if (x->x_reset_on_formatchange) pdp_bqt_reset(x); } } /************************* CONFIG METHODS ****************************/ static void pdp_bq_passes(t_pdp_bq *x, t_floatarg f) { int passes = (int)f; passes = passes < 0 ? 0 : passes; x->x_nbpasses = passes; } static void pdp_bq_lr(t_pdp_bq *x, t_floatarg f) { if (f == 1.0f) x->x_direction |= PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT; if (f == 0.0f) x->x_direction &= ~PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT; } static void pdp_bq_rl(t_pdp_bq *x, t_floatarg f) { if (f == 1.0f) x->x_direction |= PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT; if (f == 0.0f) x->x_direction &= ~PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT; } static void pdp_bq_tb(t_pdp_bq *x, t_floatarg f) { if (f == 1.0f) x->x_direction |= PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM; if (f == 0.0f) x->x_direction &= ~PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM; } static void pdp_bq_bt(t_pdp_bq *x, t_floatarg f) { if (f == 1.0f) x->x_direction |= PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP; if (f == 0.0f) x->x_direction &= ~PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP; } static void pdp_bq_hor(t_pdp_bq *x, t_floatarg f) { pdp_bq_lr(x, f); pdp_bq_rl(x, f); } static void pdp_bq_ver(t_pdp_bq *x, t_floatarg f) { pdp_bq_tb(x, f); pdp_bq_bt(x, f); } /************************* DES/CONSTRUCTORS ****************************/ static void pdp_bq_free(t_pdp_bq *x) { pdp_imagebase_free(x); pdp_imageproc_bq_delete(x->x_biquad); pdp_packet_mark_unused(x->x_packet1); pdp_packet_mark_unused(x->x_packet2); } void pdp_bq_init(t_pdp_bq *x) { x->x_packet1 = -1; x->x_packet2 = -1; x->x_nbpasses = 1; x->x_reset_on_formatchange = true; x->x_biquad = pdp_imageproc_bq_new(); pdp_bq_setstate(x, 0.0f, 0.0f); pdp_bq_onep(x, 0.1f); } /* class pointers */ t_class *pdp_bq_class; /* biquad spacial processing */ t_class *pdp_bqt_class; /* biquad time processing */ void *pdp_bq_new(void) { t_pdp_bq *x = (t_pdp_bq *)pd_new(pdp_bq_class); pdp_imagebase_init(x); pdp_base_add_pdp_outlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_bq_process); pdp_base_add_gen_inlet(x, gensym("float"), gensym("passes")); pdp_bq_init(x); return (void *)x; } void *pdp_bqt_new(void) { t_pdp_bq *x = (t_pdp_bq *)pd_new(pdp_bqt_class); pdp_imagebase_init(x); pdp_base_add_pdp_outlet(x); pdp_base_set_preproc_method(x, (t_pdp_method)pdp_bqt_preproc); pdp_base_set_process_method(x, (t_pdp_method)pdp_bqt_process); pdp_bq_init(x); return (void *)x; } #ifdef __cplusplus extern "C" { #endif /************************* CLASS CONSTRUCTORS ****************************/ void pdp_bq_coefmethods_setup(t_class *c) { /* raw coefficient methods */ class_addmethod(c, (t_method)pdp_bq_a1, gensym("a1"), A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_a2, gensym("a2"), A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_b0, gensym("b0"), A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_b1, gensym("b1"), A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_b2, gensym("b2"), A_FLOAT, A_NULL); //class_addmethod(c, (t_method)pdp_bq_u1, gensym("u1"), A_FLOAT, A_NULL); //class_addmethod(c, (t_method)pdp_bq_u2, gensym("u2"), A_FLOAT, A_NULL); /* real pole filters */ class_addmethod(c, (t_method)pdp_bq_onep, gensym("onep"), A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_twop, gensym("twop"), A_FLOAT, A_NULL); /* resonnant pole filters */ class_addmethod(c, (t_method)pdp_bq_lpf, gensym("lpf"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_hpf, gensym("hpf"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_apf, gensym("apf"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_bq_bsf, gensym("bsf"), A_FLOAT, A_FLOAT, A_NULL); } void pdp_bq_setup(void) { /* setup spatial processing class */ pdp_bq_class = class_new(gensym("pdp_bq"), (t_newmethod)pdp_bq_new, (t_method)pdp_bq_free, sizeof(t_pdp_bq), 0, A_NULL); pdp_imagebase_setup(pdp_bq_class); pdp_bq_coefmethods_setup(pdp_bq_class); class_addmethod(pdp_bq_class, (t_method)pdp_bq_passes, gensym("passes"), A_FLOAT, A_NULL); class_addmethod(pdp_bq_class, (t_method)pdp_bq_hor, gensym("hor"), A_FLOAT, A_NULL); class_addmethod(pdp_bq_class, (t_method)pdp_bq_ver, gensym("ver"), A_FLOAT, A_NULL); class_addmethod(pdp_bq_class, (t_method)pdp_bq_tb, gensym("tb"), A_FLOAT, A_NULL); class_addmethod(pdp_bq_class, (t_method)pdp_bq_bt, gensym("bt"), A_FLOAT, A_NULL); class_addmethod(pdp_bq_class, (t_method)pdp_bq_lr, gensym("lr"), A_FLOAT, A_NULL); class_addmethod(pdp_bq_class, (t_method)pdp_bq_rl, gensym("rl"), A_FLOAT, A_NULL); /* setup time processing class */ pdp_bqt_class = class_new(gensym("pdp_bqt"), (t_newmethod)pdp_bqt_new, (t_method)pdp_bq_free, sizeof(t_pdp_bq), 0, A_NULL); pdp_imagebase_setup(pdp_bqt_class); pdp_bq_coefmethods_setup(pdp_bqt_class); /* control */ class_addmethod(pdp_bqt_class, (t_method)pdp_bqt_reset, gensym("reset"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_cheby.c000066400000000000000000000105731266045153600223000ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_cheby_struct { t_pdp_imagebase x_base; void *x_cheby; int x_iterations; int x_order; gsl_cheb_series *x_cs; gsl_function x_F; float *x_vec; int x_nbpoints; } t_pdp_cheby; static double pdp_cheby_mappingfunction(double f, void *params) { t_pdp_cheby *x = (t_pdp_cheby *)params; int indx; /* if there's no array, return the identity function */ if (!x->x_vec) return f; /* else interpolate the array */ indx = ((f + 1) * 0.5) * (x->x_nbpoints - 1); return x->x_vec[indx]; } static void pdp_cheby_coef(t_pdp_cheby *x, t_floatarg c, t_floatarg f) { pdp_imageproc_cheby_setcoef(x->x_cheby, (int)c, f); } static void pdp_cheby_approx(t_pdp_cheby *x, t_symbol *s) { int i; t_garray *a; /* check if array is valid */ if (!(a = (t_garray *)pd_findbyclass(s, garray_class))){ post("pdp_cheby: %s: no such array", s->s_name); } /* get data */ else if (!garray_getfloatarray(a, &x->x_nbpoints, &x->x_vec)){ post("pdp_cheby: %s: bad template", s->s_name); } else{ /* calculate approximation */ gsl_cheb_init (x->x_cs, &x->x_F, -1.0, 1.0); /* propagate coefficients */ for (i=0; i<=x->x_order; i++){ pdp_cheby_coef(x, i, x->x_cs->c[i]); } } x->x_vec = 0; return; } static void pdp_cheby_process(t_pdp_cheby *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_cheby_setnbpasses(x->x_cheby, x->x_iterations); pdp_imageproc_dispatch_1buf(&pdp_imageproc_cheby_process, x->x_cheby, mask, p0); } static void pdp_cheby_reset(t_pdp_cheby *x) { int i; for (i = 0; i <= x->x_order; i++) pdp_imageproc_cheby_setcoef(x->x_cheby, i, 0); } static void pdp_cheby_iterations(t_pdp_cheby *x, t_floatarg f) { int i = (int)f; if (i<0) i = 0; x->x_iterations = i; } static void pdp_cheby_free(t_pdp_cheby *x) { pdp_imagebase_free(x); pdp_imageproc_cheby_delete(x->x_cheby); gsl_cheb_free(x->x_cs); } t_class *pdp_cheby_class; void *pdp_cheby_new(t_floatarg f) { t_pdp_cheby *x = (t_pdp_cheby *)pd_new(pdp_cheby_class); int order = (int)(f); /* super init */ pdp_imagebase_init(x); /* create i/o */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("iterations")); pdp_base_add_pdp_outlet(x); /* setup callback */ pdp_base_set_process_method(x, (t_pdp_method)pdp_cheby_process); /* data init */ x->x_cheby = pdp_imageproc_cheby_new(order); x->x_iterations = 1; if (order < 2) order = 2; x->x_order = order; /* init gls chebychev series object */ x->x_cs = gsl_cheb_alloc(order); x->x_F.function = pdp_cheby_mappingfunction; x->x_F.params = x; x->x_vec = 0; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_cheby_setup(void) { pdp_cheby_class = class_new(gensym("pdp_cheby"), (t_newmethod)pdp_cheby_new, (t_method)pdp_cheby_free, sizeof(t_pdp_cheby), 0, A_DEFFLOAT, A_NULL); pdp_imagebase_setup(pdp_cheby_class); class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_coef, gensym("coef"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_iterations, gensym("iterations"), A_FLOAT, A_NULL); class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_reset, gensym("reset"), A_NULL); class_addmethod(pdp_cheby_class, (t_method)pdp_cheby_approx, gensym("approx"), A_SYMBOL, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_constant.c000066400000000000000000000076511266045153600230420ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_constant_struct { t_pdp_imagebase x_base; t_outlet *x_outlet0; int x_packet0; t_symbol *x_type; unsigned int x_width; unsigned int x_height; void *x_constant; } t_pdp_constant; void pdp_constant_type(t_pdp_constant *x, t_symbol *s) { x->x_type = s; } void pdp_constant_value(t_pdp_constant *x, t_floatarg f) { if (f>1.0f) f = 1.0f; if (f<-1.0f) f = -1.0f; x->x_constant = (void *)((sptr)(0x7fff * f)); } static void pdp_constant_process(t_pdp_constant *x) { /* get channel mask */ u32 mask = pdp_imagebase_get_chanmask(x); /* create new packet */ if (x->x_type == gensym("yv12")){x->x_packet0 = pdp_packet_new_image_YCrCb(x->x_width, x->x_height);} else if (x->x_type == gensym("grey")){x->x_packet0 = pdp_packet_new_image_grey(x->x_width, x->x_height);} else return; /* this processes the packets using a pdp image processor */ pdp_imageproc_dispatch_1buf(&pdp_imageproc_constant_process, x->x_constant, mask, x->x_packet0); pdp_imageproc_dispatch_1buf(&pdp_imageproc_constant_process, 0, ~mask, x->x_packet0); return; } static void pdp_constant_postproc(t_pdp_constant *x) { pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } static void pdp_constant_bang(t_pdp_constant *x) { pdp_base_bang(x); } static void pdp_constant_dim(t_pdp_constant *x, t_floatarg w, t_floatarg h) { x->x_width = pdp_imageproc_legalwidth((int)w); x->x_height = pdp_imageproc_legalheight((int)h); //post("dims %d %d", x->x_width, x->x_height); } static void pdp_constant_free(t_pdp_constant *x) { pdp_imagebase_free(x); pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_constant_class; void *pdp_constant_new(void) { int i; t_pdp_constant *x = (t_pdp_constant *)pd_new(pdp_constant_class); /* super init */ pdp_imagebase_init(x); /* in/out*/ pdp_base_add_gen_inlet(x, gensym("float"), gensym("value")); x->x_outlet0 = pdp_base_add_pdp_outlet(x); /* base callbacks */ pdp_base_disable_active_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_constant_process); pdp_base_set_postproc_method(x, (t_pdp_method)pdp_constant_postproc); /* data init */ x->x_packet0 = -1; pdp_constant_dim(x, 320, 240); pdp_constant_value(x, 0.0f); pdp_constant_type(x, gensym("yv12")); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_constant_setup(void) { pdp_constant_class = class_new(gensym("pdp_constant"), (t_newmethod)pdp_constant_new, (t_method)pdp_constant_free, sizeof(t_pdp_constant), 0, A_NULL); pdp_imagebase_setup(pdp_constant_class); class_addmethod(pdp_constant_class, (t_method)pdp_constant_value, gensym("value"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_constant_class, (t_method)pdp_constant_type, gensym("type"), A_SYMBOL, A_NULL); class_addmethod(pdp_constant_class, (t_method)pdp_constant_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_constant_class, (t_method)pdp_constant_bang, gensym("bang"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_conv.c000066400000000000000000000133351266045153600221520ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_conv_struct { t_pdp_imagebase x_base; unsigned int x_nbpasses; bool x_horizontal; bool x_vertical; void *x_convolver_hor; void *x_convolver_ver; } t_pdp_conv; static void pdp_conv_process(t_pdp_conv *x) { int p = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); if (x->x_vertical){ pdp_imageproc_conv_setnbpasses(x->x_convolver_ver, x->x_nbpasses); pdp_imageproc_dispatch_1buf(&pdp_imageproc_conv_process, x->x_convolver_ver, mask, p); } if (x->x_horizontal){ pdp_imageproc_conv_setnbpasses(x->x_convolver_hor, x->x_nbpasses); pdp_imageproc_dispatch_1buf(&pdp_imageproc_conv_process, x->x_convolver_hor, mask, p); } } static void pdp_conv_passes(t_pdp_conv *x, t_floatarg f) { int passes = (int)f; passes = passes < 0 ? 0 : passes; x->x_nbpasses = passes; } static void pdp_conv_hor(t_pdp_conv *x, t_floatarg f) { int hor = (int)f; x->x_horizontal = (hor != 0); } static void pdp_conv_ver(t_pdp_conv *x, t_floatarg f) { int ver = (int)f; x->x_vertical = (ver != 0); } static void pdp_conv_free(t_pdp_conv *x) { pdp_imagebase_free(x); pdp_imageproc_conv_delete(x->x_convolver_hor); pdp_imageproc_conv_delete(x->x_convolver_ver); } /* setup hmask */ static void pdp_conv_hleft(t_pdp_conv *x, t_floatarg f) { pdp_imageproc_conv_setmin1(x->x_convolver_hor, f); } static void pdp_conv_hmiddle(t_pdp_conv *x, t_floatarg f) { pdp_imageproc_conv_setzero(x->x_convolver_hor, f); } static void pdp_conv_hright(t_pdp_conv *x, t_floatarg f) { pdp_imageproc_conv_setplus1(x->x_convolver_hor, f); } static void pdp_conv_hmask(t_pdp_conv *x, t_floatarg l, t_floatarg m, t_floatarg r) { pdp_conv_hleft(x, l); pdp_conv_hmiddle(x, m); pdp_conv_hright(x, r); } static void pdp_conv_vtop(t_pdp_conv *x, t_floatarg f) { pdp_imageproc_conv_setmin1(x->x_convolver_ver, f); } static void pdp_conv_vmiddle(t_pdp_conv *x, t_floatarg f) { pdp_imageproc_conv_setzero(x->x_convolver_ver, f); } static void pdp_conv_vbottom(t_pdp_conv *x, t_floatarg f) { pdp_imageproc_conv_setplus1(x->x_convolver_ver, f); } static void pdp_conv_vmask(t_pdp_conv *x, t_floatarg l, t_floatarg m, t_floatarg r) { pdp_conv_vtop(x, l); pdp_conv_vmiddle(x, m); pdp_conv_vbottom(x, r); } static void pdp_conv_mask(t_pdp_conv *x, t_floatarg l, t_floatarg m, t_floatarg r) { pdp_conv_hmask(x, l, m, r); pdp_conv_vmask(x, l, m, r); } t_class *pdp_conv_class; void *pdp_conv_new(void) { t_pdp_conv *x = (t_pdp_conv *)pd_new(pdp_conv_class); /* super init */ pdp_imagebase_init(x); /* inlets & outlets */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("passes")); pdp_base_add_pdp_outlet(x); /* register */ pdp_base_set_process_method(x, (t_pdp_method)pdp_conv_process); x->x_nbpasses = 1; x->x_horizontal = true; x->x_vertical = true; x->x_convolver_hor = pdp_imageproc_conv_new(); x->x_convolver_ver = pdp_imageproc_conv_new(); pdp_imageproc_conv_setbordercolor(x->x_convolver_hor, 0); pdp_imageproc_conv_setbordercolor(x->x_convolver_ver, 0); pdp_imageproc_conv_setorientation(x->x_convolver_hor, PDP_IMAGEPROC_CONV_HORIZONTAL); pdp_imageproc_conv_setorientation(x->x_convolver_ver, PDP_IMAGEPROC_CONV_VERTICAL); pdp_conv_mask(x, .25,.5,.25); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_conv_setup(void) { pdp_conv_class = class_new(gensym("pdp_conv"), (t_newmethod)pdp_conv_new, (t_method)pdp_conv_free, sizeof(t_pdp_conv), 0, A_NULL); pdp_imagebase_setup(pdp_conv_class); class_addmethod(pdp_conv_class, (t_method)pdp_conv_passes, gensym("passes"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_hor, gensym("hor"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_ver, gensym("ver"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_hleft, gensym("hleft"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_hmiddle, gensym("hmiddle"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_hright, gensym("hright"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_vtop, gensym("vtop"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_vmiddle, gensym("vmiddle"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_vbottom, gensym("vbottom"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_vmask, gensym("vmask"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_hmask, gensym("hmask"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_conv_class, (t_method)pdp_conv_mask, gensym("mask"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_gain.c000066400000000000000000000045031266045153600221200ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_gain_struct { t_pdp_imagebase x_base; void *x_gain; } t_pdp_gain; static void pdp_gain_process(t_pdp_gain *x) { int p = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_packet_image_set_chanmask(p, mask); pdp_imageproc_dispatch_1buf(&pdp_imageproc_gain_process, x->x_gain, 0, p); } static void pdp_gain_gain(t_pdp_gain *x, t_floatarg f) { pdp_imageproc_gain_setgain(x->x_gain, f); } t_class *pdp_gain_class; void pdp_gain_free(t_pdp_gain *x) { pdp_imagebase_free(x); pdp_imageproc_gain_delete(x->x_gain); } void *pdp_gain_new(t_floatarg f) { t_pdp_gain *x = (t_pdp_gain *)pd_new(pdp_gain_class); /* super init */ pdp_imagebase_init(x); /* no arg, or zero -> gain = 1 */ if (f==0.0f) f = 1.0f; /* io */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("gain")); pdp_base_add_pdp_outlet(x); /* callbacks */ pdp_base_set_process_method(x, (t_pdp_method)pdp_gain_process); x->x_gain = pdp_imageproc_gain_new(); pdp_gain_gain(x, f); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_gain_setup(void) { pdp_gain_class = class_new(gensym("pdp_gain"), (t_newmethod)pdp_gain_new, (t_method)pdp_gain_free, sizeof(t_pdp_gain), 0, A_DEFFLOAT, A_NULL); pdp_imagebase_setup(pdp_gain_class); class_addmethod(pdp_gain_class, (t_method)pdp_gain_gain, gensym("gain"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_logic.c000066400000000000000000000156321266045153600223040ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_logic_struct { t_pdp_imagebase x_base; void *x_mask; } t_pdp_logic; static void pdp_logic_process_and(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_and_process, 0, mask, p0, p1); } static void pdp_logic_process_or(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_or_process, 0, mask, p0, p1); } static void pdp_logic_process_xor(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_xor_process, 0, mask, p0, p1); } static void pdp_logic_process_not(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_not_process, 0, mask, p0); } static void pdp_logic_process_mask(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_mask_process, x->x_mask, mask, p0); } static void pdp_logic_process_softthresh(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_softthresh_process, x->x_mask, mask, p0); } static void pdp_logic_process_hardthresh(t_pdp_logic *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_hardthresh_process, x->x_mask, mask, p0); } static void pdp_logic_set_mask(t_pdp_logic *x, t_floatarg f) { /* using a pointer as a variable hmm? */ sptr mask = ((sptr)f) & 0xffff; x->x_mask = ((void * )mask); } static void pdp_logic_set_threshold(t_pdp_logic *x, t_floatarg f) { /* using a pointer as a variable hmm? */ if (f<0.0f) f = 0.0f; if (f>1.0f) f = 1.0f; x->x_mask = (void *)((sptr)(((float)0x7fff) * f)); } static void pdp_logic_set_depth(t_pdp_logic *x, t_floatarg f) { sptr mask; int shift = (16 - ((int)f)); if (shift < 0) shift = 0; if (shift > 16) shift = 16; mask = ((0xffff)<x_mask = (void *)mask; } static void pdp_logic_free(t_pdp_logic *x) { /* remove process method from queue before deleting data */ pdp_imagebase_free(x); } t_class *pdp_logic_class; /* common new method */ void *pdp_logic_new(void) { t_pdp_logic *x = (t_pdp_logic *)pd_new(pdp_logic_class); /* super init */ pdp_imagebase_init(x); /* outlet */ pdp_base_add_pdp_outlet(x); x->x_mask = 0; return (void *)x; } void *pdp_logic_new_and(void) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_pdp_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_and); return (void *)x; } void *pdp_logic_new_or(void) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_pdp_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_or); return (void *)x; } void *pdp_logic_new_xor(void) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_pdp_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_xor); return (void *)x; } void *pdp_logic_new_not(void) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_not); return (void *)x; } void *pdp_logic_new_mask(void) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("mask")); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_mask); x->x_mask = (void *)0xffff; return (void *)x; } void *pdp_logic_new_depth(void) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("depth")); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_mask); x->x_mask = (void *)0xffff; return (void *)x; } void *pdp_logic_new_softthresh(t_floatarg f) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("threshold")); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_softthresh); pdp_logic_set_threshold(x,f); return (void *)x; } void *pdp_logic_new_hardthresh(t_floatarg f) { t_pdp_logic *x = pdp_logic_new(); /* init in/out */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("threshold")); pdp_base_set_process_method(x, (t_pdp_method)pdp_logic_process_hardthresh); pdp_logic_set_threshold(x,f); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_logic_setup(void) { pdp_logic_class = class_new(gensym("pdp_and"), (t_newmethod)pdp_logic_new_and, (t_method)pdp_logic_free, sizeof(t_pdp_logic), 0, A_DEFFLOAT, A_NULL); pdp_imagebase_setup(pdp_logic_class); class_addcreator((t_newmethod)pdp_logic_new_or, gensym("pdp_or"), A_NULL); class_addcreator((t_newmethod)pdp_logic_new_xor, gensym("pdp_xor"), A_NULL); class_addcreator((t_newmethod)pdp_logic_new_not, gensym("pdp_not"), A_NULL); class_addcreator((t_newmethod)pdp_logic_new_mask, gensym("pdp_bitmask"), A_NULL); class_addcreator((t_newmethod)pdp_logic_new_depth, gensym("pdp_bitdepth"), A_NULL); class_addcreator((t_newmethod)pdp_logic_new_softthresh, gensym("pdp_sthresh"), A_NULL); class_addcreator((t_newmethod)pdp_logic_new_hardthresh, gensym("pdp_hthresh"), A_NULL); class_addmethod(pdp_logic_class, (t_method)pdp_logic_set_mask, gensym("mask"), A_FLOAT, A_NULL); class_addmethod(pdp_logic_class, (t_method)pdp_logic_set_depth, gensym("depth"), A_FLOAT, A_NULL); class_addmethod(pdp_logic_class, (t_method)pdp_logic_set_threshold, gensym("threshold"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_mix.c000066400000000000000000000100361266045153600217750ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_mix_struct { t_pdp_imagebase x_base; t_outlet *x_outlet0; t_outlet *x_outlet1; void *x_mixer; int x_extrapolate; } t_pdp_mix; static void pdp_mix_process(t_pdp_mix *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_mix_process, x->x_mixer, mask, p0, p1); } static void pdp_mix_mix(t_pdp_mix *x, t_floatarg f) { float f2; if (!x->x_extrapolate){ if (f < 0.0f) f = 0.0f; if (f > 1.0f) f = 1.0f; } f2 = (1.0f - f); pdp_imageproc_mix_setleftgain(x->x_mixer, f2); pdp_imageproc_mix_setrightgain(x->x_mixer, f); } static void pdp_mix_mix1(t_pdp_mix *x, t_floatarg f) { pdp_imageproc_mix_setleftgain(x->x_mixer, f); } static void pdp_mix_mix2(t_pdp_mix *x, t_floatarg f2) { pdp_imageproc_mix_setrightgain(x->x_mixer, f2); } static void pdp_mix_extrapolate(t_pdp_mix *x, t_floatarg f) { if (f == 0.0f) x->x_extrapolate = 0; if (f == 1.0f) x->x_extrapolate = 1; } static void pdp_mix_free(t_pdp_mix *x) { pdp_imagebase_free(x); pdp_imageproc_mix_delete(x->x_mixer); } t_class *pdp_mix_class; t_class *pdp_mix2_class; void *pdp_mix_common_init(t_pdp_mix *x) { int i; pdp_imagebase_init(x); pdp_base_add_pdp_inlet(x); pdp_base_add_pdp_outlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_mix_process); x->x_extrapolate = 0; x->x_mixer = pdp_imageproc_mix_new(); pdp_mix_mix(x, 0.0f); return (void *)x; } void *pdp_mix_new(t_floatarg mix) { t_pdp_mix *x = (t_pdp_mix *)pd_new(pdp_mix_class); pdp_mix_common_init(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("mix")); if (mix == 0.0f) mix = 0.5f; pdp_mix_mix(x, mix); return (void *)x; } void *pdp_mix2_new(t_floatarg mix1, t_floatarg mix2) { t_pdp_mix *x = (t_pdp_mix *)pd_new(pdp_mix2_class); pdp_mix_common_init(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("mix1")); pdp_base_add_gen_inlet(x, gensym("float"), gensym("mix2")); if ((mix1 == 0.0f) && (mix2 == 0.0f)) mix1 = mix2 = 0.5f; pdp_mix_mix1(x, mix1); pdp_mix_mix2(x, mix2); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_mix_setup(void) { pdp_mix_class = class_new(gensym("pdp_mix"), (t_newmethod)pdp_mix_new, (t_method)pdp_mix_free, sizeof(t_pdp_mix), 0, A_DEFFLOAT, A_NULL); pdp_imagebase_setup(pdp_mix_class); class_addmethod(pdp_mix_class, (t_method)pdp_mix_mix, gensym("mix"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_mix_class, (t_method)pdp_mix_extrapolate, gensym("extrapolate"), A_DEFFLOAT, A_NULL); pdp_mix2_class = class_new(gensym("pdp_mix2"), (t_newmethod)pdp_mix2_new, (t_method)pdp_mix_free, sizeof(t_pdp_mix), 0, A_DEFFLOAT, A_DEFFLOAT, A_NULL); pdp_imagebase_setup(pdp_mix2_class); class_addmethod(pdp_mix2_class, (t_method)pdp_mix_mix1, gensym("mix1"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_mix2_class, (t_method)pdp_mix_mix2, gensym("mix2"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_mix2_class, (t_method)pdp_mix_extrapolate, gensym("extrapolate"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_mul.c000066400000000000000000000035021266045153600217750ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_mul_struct { t_pdp_imagebase x_base; } t_pdp_mul; static void pdp_mul_process(t_pdp_mul *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_mul_process, 0, mask, p0, p1); } static void pdp_mul_free(t_pdp_mul *x) { pdp_imagebase_free(x); } t_class *pdp_mul_class; void *pdp_mul_new(void) { t_pdp_mul *x = (t_pdp_mul *)pd_new(pdp_mul_class); /* super init */ pdp_imagebase_init(x); pdp_base_add_pdp_inlet(x); pdp_base_add_pdp_outlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_mul_process); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_mul_setup(void) { pdp_mul_class = class_new(gensym("pdp_mul"), (t_newmethod)pdp_mul_new, (t_method)pdp_mul_free, sizeof(t_pdp_mul), 0, A_NULL); pdp_imagebase_setup(pdp_mul_class); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_noise.c000066400000000000000000000074311266045153600223220ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_noise_struct { t_pdp_imagebase x_base; int x_packet0; t_outlet *x_outlet0; void *x_noisegen; t_symbol *x_type; unsigned int x_width; unsigned int x_height; } t_pdp_noise; void pdp_noise_type(t_pdp_noise *x, t_symbol *s) { x->x_type = s; } void pdp_noise_random(t_pdp_noise *x, t_floatarg seed) { if (seed == 0.0f) seed = (float)random(); pdp_imageproc_random_setseed(x->x_noisegen, seed); } /* called inside pdp thread */ static void pdp_noise_process(t_pdp_noise *x) { /* seed the 16 bit rng with a new random number from the clib */ pdp_noise_random(x, 0.0f); /* create new packet */ if (x->x_type == gensym("grey")) { x->x_packet0 = pdp_packet_new_image_grey(x->x_width, x->x_height); } else if (x->x_type == gensym("yv12")) { x->x_packet0 = pdp_packet_new_image_YCrCb(x->x_width, x->x_height); } else return; /* call the image processor */ pdp_imageproc_dispatch_1buf(&pdp_imageproc_random_process, x->x_noisegen, -1, x->x_packet0); } /* called inside pd thread: involves an outlet */ static void pdp_noise_postproc(t_pdp_noise *x) { pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } static void pdp_noise_bang(t_pdp_noise *x) { pdp_base_bang(x); } static void pdp_noise_dim(t_pdp_noise *x, t_floatarg w, t_floatarg h) { x->x_width = pdp_imageproc_legalwidth((int)w); x->x_height = pdp_imageproc_legalheight((int)h); //post("dims %d %d", x->x_width, x->x_height); } static void pdp_noise_free(t_pdp_noise *x) { pdp_imagebase_free(x); /* tidy up */ pdp_packet_mark_unused(x->x_packet0); pdp_imageproc_random_delete(x->x_noisegen); } t_class *pdp_noise_class; void *pdp_noise_new(void) { int i; t_pdp_noise *x = (t_pdp_noise *)pd_new(pdp_noise_class); pdp_imagebase_init(x); pdp_base_disable_active_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_noise_process); pdp_base_set_postproc_method(x, (t_pdp_method)pdp_noise_postproc); x->x_outlet0 = pdp_base_add_pdp_outlet(x); x->x_packet0 = -1; x->x_width = 320; x->x_height = 240; x->x_noisegen = pdp_imageproc_random_new(); pdp_noise_random(x, 0.0f); pdp_noise_type(x, gensym("yv12")); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_noise_setup(void) { pdp_noise_class = class_new(gensym("pdp_noise"), (t_newmethod)pdp_noise_new, (t_method)pdp_noise_free, sizeof(t_pdp_noise), 0, A_NULL); pdp_imagebase_setup(pdp_noise_class); class_addmethod(pdp_noise_class, (t_method)pdp_noise_random, gensym("seed"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_noise_class, (t_method)pdp_noise_type, gensym("type"), A_SYMBOL, A_NULL); class_addmethod(pdp_noise_class, (t_method)pdp_noise_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_noise_class, (t_method)pdp_noise_bang, gensym("bang"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_plasma.c000066400000000000000000000102241266045153600224540ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_plasma_struct { t_pdp_imagebase x_base; int x_packet0; t_outlet *x_outlet0; void *x_plasmagen; t_symbol *x_type; unsigned int x_width; unsigned int x_height; } t_pdp_plasma; void pdp_plasma_type(t_pdp_plasma *x, t_symbol *s) { x->x_type = s; } void pdp_plasma_random(t_pdp_plasma *x, t_floatarg seed) { if (seed == 0.0f) seed = (float)random(); pdp_imageproc_plasma_setseed(x->x_plasmagen, seed); } void pdp_plasma_turbulence(t_pdp_plasma *x, t_floatarg f) { pdp_imageproc_plasma_setturbulence(x->x_plasmagen, f); } /* called inside pdp thread */ static void pdp_plasma_process(t_pdp_plasma *x) { /* seed the 16 bit rng with a new random number from the clib */ pdp_plasma_random(x, 0.0f); /* create new packet */ if (x->x_type == gensym("grey")) {x->x_packet0 = pdp_packet_new_image_grey(x->x_width, x->x_height);} else if (x->x_type == gensym("yv12")) {x->x_packet0 = pdp_packet_new_image_YCrCb(x->x_width, x->x_height);} else return; /* call the image processor */ pdp_imageproc_dispatch_1buf(&pdp_imageproc_plasma_process, x->x_plasmagen, -1, x->x_packet0); } /* called inside pd thread: involves an outlet */ static void pdp_plasma_postproc(t_pdp_plasma *x) { pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } static void pdp_plasma_bang(t_pdp_plasma *x) { pdp_base_bang(x); } static void pdp_plasma_dim(t_pdp_plasma *x, t_floatarg w, t_floatarg h) { x->x_width = pdp_imageproc_legalwidth((int)w); x->x_height = pdp_imageproc_legalheight((int)h); //post("dims %d %d", x->x_width, x->x_height); } static void pdp_plasma_free(t_pdp_plasma *x) { pdp_imagebase_free(x); /* tidy up */ pdp_packet_mark_unused(x->x_packet0); pdp_imageproc_plasma_delete(x->x_plasmagen); } t_class *pdp_plasma_class; void *pdp_plasma_new(void) { int i; t_pdp_plasma *x = (t_pdp_plasma *)pd_new(pdp_plasma_class); pdp_imagebase_init(x); pdp_base_disable_active_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_plasma_process); pdp_base_set_postproc_method(x, (t_pdp_method)pdp_plasma_postproc); pdp_base_add_gen_inlet(x, gensym("float"), gensym("turbulence")); x->x_outlet0 = pdp_base_add_pdp_outlet(x); x->x_packet0 = -1; x->x_width = 320; x->x_height = 240; x->x_plasmagen = pdp_imageproc_plasma_new(); pdp_plasma_random(x, 0.0f); pdp_plasma_type(x, gensym("yv12")); pdp_plasma_turbulence(x, 0.1); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_plasma_setup(void) { pdp_plasma_class = class_new(gensym("pdp_plasma"), (t_newmethod)pdp_plasma_new, (t_method)pdp_plasma_free, sizeof(t_pdp_plasma), 0, A_NULL); pdp_imagebase_setup(pdp_plasma_class); class_addmethod(pdp_plasma_class, (t_method)pdp_plasma_random, gensym("seed"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_plasma_class, (t_method)pdp_plasma_turbulence, gensym("turbulence"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_plasma_class, (t_method)pdp_plasma_type, gensym("type"), A_SYMBOL, A_NULL); class_addmethod(pdp_plasma_class, (t_method)pdp_plasma_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_plasma_class, (t_method)pdp_plasma_bang, gensym("bang"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_randmix.c000066400000000000000000000051741266045153600226510ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_randmix_struct { t_pdp_imagebase x_base; void *x_randmixer; } t_pdp_randmix; void pdp_randmix_random(t_pdp_randmix *x, t_floatarg seed) { pdp_imageproc_randmix_setseed(x->x_randmixer, seed); } static void pdp_randmix_process(t_pdp_randmix *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_randmix_process, x->x_randmixer, mask, p0, p1); } static void pdp_randmix_threshold(t_pdp_randmix *x, t_floatarg f) { pdp_imageproc_randmix_setthreshold(x->x_randmixer, f); } static void pdp_randmix_free(t_pdp_randmix *x) { pdp_imagebase_free(x); pdp_imageproc_randmix_delete(x->x_randmixer); } t_class *pdp_randmix_class; void *pdp_randmix_new(void) { int i; t_pdp_randmix *x = (t_pdp_randmix *)pd_new(pdp_randmix_class); pdp_imagebase_init(x); pdp_base_add_pdp_inlet(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("threshold")); pdp_base_set_process_method(x, (t_pdp_method)pdp_randmix_process); pdp_base_add_pdp_outlet(x); x->x_randmixer = pdp_imageproc_randmix_new(); pdp_randmix_threshold(x, 0.5f); pdp_randmix_random(x, 0.0f); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_randmix_setup(void) { pdp_randmix_class = class_new(gensym("pdp_randmix"), (t_newmethod)pdp_randmix_new, (t_method)pdp_randmix_free, sizeof(t_pdp_randmix), 0, A_NULL); pdp_imagebase_setup(pdp_randmix_class); class_addmethod(pdp_randmix_class, (t_method)pdp_randmix_threshold, gensym("threshold"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_randmix_class, (t_method)pdp_randmix_random, gensym("seed"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_stateless.c000066400000000000000000000121611266045153600232100ustar00rootroot00000000000000/* * Pure Data Packet module. Some stateless image operations. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_stateless_struct { t_pdp_imagebase x_base; } t_pdp_stateless; static void pdp_stateless_process_abs(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_abs_process, 0, mask, p0); } static void pdp_stateless_process_hardthresh(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_hardthresh_process, 0, mask, p0); } static void pdp_stateless_process_zthresh(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_zthresh_process, 0, mask, p0); } static void pdp_stateless_process_positive(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_ispositive_process, 0, mask, p0); } static void pdp_stateless_process_sign(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_sign_process, 0, mask, p0); } static void pdp_stateless_process_flip_tb(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_flip_tb_process, 0, mask, p0); } static void pdp_stateless_process_flip_lr(t_pdp_stateless *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_1buf(&pdp_imageproc_flip_lr_process, 0, mask, p0); } static void pdp_stateless_free(t_pdp_stateless *x) { /* remove process method from queue before deleting data */ pdp_imagebase_free(x); } t_class *pdp_stateless_class; /* common new method */ void *pdp_stateless_new(void) { t_pdp_stateless *x = (t_pdp_stateless *)pd_new(pdp_stateless_class); /* super init */ pdp_imagebase_init(x); /* outlet */ pdp_base_add_pdp_outlet(x); return (void *)x; } void *pdp_stateless_new_abs(void) { t_pdp_stateless *x = pdp_stateless_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_stateless_process_abs); return (void *)x; } void *pdp_stateless_new_zthresh(void) { t_pdp_stateless *x = pdp_stateless_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_stateless_process_zthresh); return (void *)x; } void *pdp_stateless_new_positive(void) { t_pdp_stateless *x = pdp_stateless_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_stateless_process_positive); return (void *)x; } void *pdp_stateless_new_sign(void) { t_pdp_stateless *x = pdp_stateless_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_stateless_process_sign); return (void *)x; } void *pdp_stateless_new_flip_tb(void) { t_pdp_stateless *x = pdp_stateless_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_stateless_process_flip_tb); return (void *)x; } void *pdp_stateless_new_flip_lr(void) { t_pdp_stateless *x = pdp_stateless_new(); /* init in/out */ pdp_base_set_process_method(x, (t_pdp_method)pdp_stateless_process_flip_lr); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_stateless_setup(void) { pdp_stateless_class = class_new(gensym("pdp_abs"), (t_newmethod)pdp_stateless_new_abs, (t_method)pdp_stateless_free, sizeof(t_pdp_stateless), 0, A_NULL); pdp_imagebase_setup(pdp_stateless_class); class_addcreator((t_newmethod)pdp_stateless_new_zthresh, gensym("pdp_zthresh"), A_NULL); class_addcreator((t_newmethod)pdp_stateless_new_positive, gensym("pdp_positive"), A_NULL); class_addcreator((t_newmethod)pdp_stateless_new_sign, gensym("pdp_sign"), A_NULL); class_addcreator((t_newmethod)pdp_stateless_new_flip_tb, gensym("pdp_flip_tb"), A_NULL); class_addcreator((t_newmethod)pdp_stateless_new_flip_lr, gensym("pdp_flip_lr"), A_NULL); /* future extensions */ //class_addcreator((t_newmethod)pdp_stateless_new_garble, gensym("pdp_garble"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_basic/pdp_zoom.c000066400000000000000000000133451266045153600221720ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_imagebase.h" typedef struct pdp_zoom_struct { t_pdp_imagebase x_base; int x_packet1; t_outlet *x_outlet0; void *x_zoom; int x_quality; //not used } t_pdp_zoom; static void pdp_zoom_process(t_pdp_zoom *x) { int p0 = pdp_base_get_packet(x, 0); u32 mask = pdp_imagebase_get_chanmask(x); pdp_imageproc_dispatch_2buf(&pdp_imageproc_resample_affinemap_process, x->x_zoom, mask, p0, x->x_packet1); } static void pdp_zoom_postproc(t_pdp_zoom *x) { /* delete source packet */ pdp_packet_mark_unused(pdp_base_move_packet(x, 0)); /* unregister and propagate if valid dest packet */ pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); } static void pdp_zoom_preproc(t_pdp_zoom *x) { int p = pdp_base_get_packet(x, 0); t_pdp *header0 = pdp_packet_header(p); if ((header0) && (PDP_IMAGE == header0->type)){ x->x_packet1 = pdp_packet_clone_rw(p); } } static void pdp_zoom_zoom_x(t_pdp_zoom *x, t_floatarg f) { pdp_imageproc_resample_affinemap_setzoomx(x->x_zoom, f); } static void pdp_zoom_angle(t_pdp_zoom *x, t_floatarg f) { pdp_imageproc_resample_affinemap_setangle(x->x_zoom, f); } static void pdp_zoom_zoom_y(t_pdp_zoom *x, t_floatarg f) { pdp_imageproc_resample_affinemap_setzoomy(x->x_zoom, f); } static void pdp_zoom_zoom(t_pdp_zoom *x, t_floatarg f) { pdp_zoom_zoom_x(x, f); pdp_zoom_zoom_y(x, f); } static void pdp_zoom_center_x(t_pdp_zoom *x, t_floatarg f) { pdp_imageproc_resample_affinemap_setcenterx(x->x_zoom, f); } static void pdp_zoom_center_y(t_pdp_zoom *x, t_floatarg f) { pdp_imageproc_resample_affinemap_setcentery(x->x_zoom, f); } static void pdp_zoom_center(t_pdp_zoom *x, t_floatarg fx, t_floatarg fy) { pdp_zoom_center_x(x, fx); pdp_zoom_center_y(x, fy); } // not used static void pdp_zoom_quality(t_pdp_zoom *x, t_floatarg f) { if (f==0) x->x_quality = 0; if (f==1) x->x_quality = 1; } t_class *pdp_zoom_class; void pdp_zoom_free(t_pdp_zoom *x) { pdp_imagebase_free(x); pdp_imageproc_resample_affinemap_delete(x->x_zoom); pdp_packet_mark_unused(x->x_packet1); } void pdp_zoom_init_common(t_pdp_zoom *x) { pdp_imagebase_init(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_zoom_process); pdp_base_set_postproc_method(x, (t_pdp_method)pdp_zoom_postproc); pdp_base_set_preproc_method(x, (t_pdp_method)pdp_zoom_preproc); x->x_outlet0 = pdp_base_add_pdp_outlet(x); x->x_packet1 = -1; x->x_zoom = pdp_imageproc_resample_affinemap_new(); //quality is not used: all routines are "high quality" bilinear //pdp_zoom_quality(x, 1); pdp_zoom_center_x(x, 0.5f); pdp_zoom_center_y(x, 0.5f); } void *pdp_zoom_new(t_floatarg zoom) { t_pdp_zoom *x = (t_pdp_zoom *)pd_new(pdp_zoom_class); pdp_zoom_init_common(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("zoom")); if (zoom == 0.0f) zoom = 1.0f; pdp_zoom_zoom(x, zoom); pdp_zoom_angle(x, 0.0f); return (void *)x; } void *pdp_zrot_new(t_floatarg zoom, t_floatarg angle) { t_pdp_zoom *x = (t_pdp_zoom *)pd_new(pdp_zoom_class); pdp_zoom_init_common(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("zoom")); pdp_base_add_gen_inlet(x, gensym("float"), gensym("angle")); if (zoom == 0.0f) zoom = 1.0f; pdp_zoom_zoom(x, zoom); pdp_zoom_angle(x, angle); return (void *)x; } void *pdp_rotate_new(t_floatarg angle) { t_pdp_zoom *x = (t_pdp_zoom *)pd_new(pdp_zoom_class); pdp_zoom_init_common(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("angle")); pdp_zoom_zoom(x, 1.0f); pdp_zoom_angle(x, angle); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_zoom_setup(void) { pdp_zoom_class = class_new(gensym("pdp_zoom"), (t_newmethod)pdp_zoom_new, (t_method)pdp_zoom_free, sizeof(t_pdp_zoom), 0, A_DEFFLOAT, A_NULL); class_addcreator((t_newmethod)pdp_zrot_new, gensym("pdp_zrot"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addcreator((t_newmethod)pdp_rotate_new, gensym("pdp_rotate"), A_DEFFLOAT, A_NULL); pdp_imagebase_setup(pdp_zoom_class); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_quality, gensym("quality"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_center_x, gensym("centerx"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_center_y, gensym("centery"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_center, gensym("center"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_zoom_x, gensym("zoomx"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_zoom_y, gensym("zoomy"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_zoom, gensym("zoom"), A_FLOAT, A_NULL); class_addmethod(pdp_zoom_class, (t_method)pdp_zoom_angle, gensym("angle"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_io/000077500000000000000000000000001266045153600175175ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/image_io/Makefile000066400000000000000000000002071266045153600211560ustar00rootroot00000000000000current: all_modules include ../../Makefile.config # build optional modules all_modules: $(PDP_OPTMOD) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/image_io/README000066400000000000000000000002161266045153600203760ustar00rootroot00000000000000This directory contains input/output modules for image packets. Most of this is platform dependent stuff, and will be conditionally compiled. pdp-0.14.1+darcs20180201/modules/image_io/pdp_glx.c000066400000000000000000000222011266045153600213150ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include "zl/xwindow.h" #include "zl/glx.h" #include "zl_pd/zl_pd.h" #include "pdp.h" #include "pdp_llconv.h" /* initial image dimensions */ #define PDP_OGL_W 320 #define PDP_OGL_H 240 #define PDP_GLX_AUTOCREATE_RETRY 10 typedef struct pdp_glx_struct { t_object x_obj; zl_xwindow_p x_xwin; zl_xdisplay_p x_xdpy; zl_glx *x_glx; t_outlet *x_outlet; int x_packet0; t_symbol *x_display; int x_initialized; int x_autocreate; } t_pdp_glx; static void pdp_glx_cursor(t_pdp_glx *x, t_floatarg f) { if (x->x_initialized) zl_xwindow_cursor(x->x_xwin, f); } static void pdp_glx_fullscreen(t_pdp_glx *x) { if (x->x_initialized) zl_xwindow_fullscreen(x->x_xwin); } static void pdp_glx_resize(t_pdp_glx* x, t_floatarg width, t_floatarg height) { if (x->x_initialized) zl_xwindow_resize(x->x_xwin, width, height); } static void pdp_glx_move(t_pdp_glx* x, t_floatarg width, t_floatarg height) { if (x->x_initialized) zl_xwindow_move(x->x_xwin, width, height); } static void pdp_glx_moveresize(t_pdp_glx* x, t_floatarg xoff, t_floatarg yoff, t_floatarg width, t_floatarg height) { if (x->x_initialized) zl_xwindow_moveresize(x->x_xwin, xoff, yoff, width, height); } static void pdp_glx_tile(t_pdp_glx* x, t_floatarg xtiles, t_floatarg ytiles, t_floatarg i, t_floatarg j) { if (x->x_initialized) zl_xwindow_tile(x->x_xwin, xtiles, ytiles, i, j); } static void fill_texture(t_pdp_glx *x) { t_pdp *header = pdp_packet_header(x->x_packet0); void *data = pdp_packet_data (x->x_packet0); int i = header->info.image.width; int w = header->info.image.width; int h = header->info.image.height; void *tex_data = zl_glx_image_data(x->x_glx, x->x_xwin, w, h); switch (header->info.image.encoding){ case PDP_IMAGE_GREY: pdp_llconv(data,RIF_GREY______S16, tex_data, RIF_GREY______U8, w, h); break; case PDP_IMAGE_YV12: pdp_llconv(data,RIF_YVU__P411_S16, tex_data, RIF_RGB__P____U8, w, h); break; default: pdp_post("pdp_glx: unknown encoding %08x", header->info.image.encoding); return; } } static void display_packet(t_pdp_glx *x) { t_pdp *header = pdp_packet_header(x->x_packet0); void *data = pdp_packet_data (x->x_packet0); /* check data packet */ if (!(header)) { post("pdp_glx: invalid packet header"); return; } if (PDP_IMAGE != header->type) { post("pdp_glx: packet is not a PDP_IMAGE"); return; } if ((PDP_IMAGE_YV12 != header->info.image.encoding) && (PDP_IMAGE_GREY != header->info.image.encoding)) { post("pdp_glx: packet is not a PDP_IMAGE_YV12/GREY"); return; } /* fill the texture with the data in the packet */ fill_texture(x); /* display the new image */ zl_glx_image_display(x->x_glx, x->x_xwin); } /* Poll for X11 events. */ static void outlet_event(void *context, int nb_double_args, zl_tag tag, va_list args) { t_pdp_glx *x = context; outlet_zl_float_list(x->x_outlet, nb_double_args, tag, args); } static void pdp_glx_poll(t_pdp_glx *x) { zl_xdisplay_route_events(x->x_xdpy); zl_xwindow_for_parsed_events(x->x_xwin, outlet_event, x); } /* delete all submodules */ static void _pdp_glx_cleanup(t_pdp_glx *x) { if (x->x_xwin) zl_xwindow_free(x->x_xwin); if (x->x_glx) zl_glx_free(x->x_glx); if (x->x_xdpy) zl_xdisplay_free(x->x_xdpy); x->x_xwin = 0; x->x_glx = 0; x->x_xdpy = 0; x->x_initialized = 0; } // this destroys the window and all the x connections static void pdp_glx_destroy(t_pdp_glx* x) { if (x->x_initialized) { _pdp_glx_cleanup(x); // delete all objects x->x_initialized = 0; } pdp_packet_mark_unused(x->x_packet0); // delete packet x->x_packet0 = -1; } /* this creates a window (opens a dpy connection, creates glxideo and xwinow objects) */ static void pdp_glx_create(t_pdp_glx* x) { int i; if(x->x_initialized) return; /* open a display */ if (!(x->x_xdpy = zl_xdisplay_new(x->x_display->s_name))) goto exit; /* create a window on the display */ x->x_xwin = zl_xwindow_new(); /* open an glx context on the display + window */ x->x_glx = zl_glx_new(); if (!zl_glx_open_on_display(x->x_glx, x->x_xwin, x->x_xdpy)) goto exit; /* display the window */ if (!zl_xwindow_config(x->x_xwin, x->x_xdpy)) goto exit; /* done */ x->x_initialized = 1; return; /* cleanup exits */ exit: post("pdp_glx: cant open display %s\n",x->x_display->s_name); _pdp_glx_cleanup(x); } static int pdp_glx_try_autocreate(t_pdp_glx *x) { if (x->x_autocreate){ post("pdp_glx: autocreate window"); pdp_glx_create(x); if (!(x->x_initialized)){ x->x_autocreate--; if (!x->x_autocreate){ post ("pdp_glx: autocreate failed %d times: disabled", PDP_GLX_AUTOCREATE_RETRY); post ("pdp_glx: send [autocreate 1] message to re-enable"); return 0; } } else return 1; } return 0; } static void pdp_glx_bang(t_pdp_glx *x) { /* check if window is initialized */ if (!(x->x_initialized)){ if (!pdp_glx_try_autocreate(x)) return; } /* check if we can proceed */ if (-1 == x->x_packet0) return; /* Display */ display_packet(x); /* release the packet if there is one */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = -1; pdp_glx_poll(x); } static void pdp_glx_input_0(t_pdp_glx *x, t_symbol *s, t_floatarg f) { if (s == gensym("register_ro")) pdp_packet_copy_ro_or_drop(&x->x_packet0, (int)f); if (s == gensym("process")) pdp_glx_bang(x); } static void pdp_glx_vga(t_pdp_glx *x) { pdp_glx_resize(x, 640, 480); } static void pdp_glx_autocreate(t_pdp_glx *x, t_floatarg f) { if (f != 0.0f) x->x_autocreate = PDP_GLX_AUTOCREATE_RETRY; else x->x_autocreate = 0; } static void pdp_glx_display(t_pdp_glx *x, t_symbol *s) { x->x_display = s; if (x->x_initialized) { pdp_glx_destroy(x); pdp_glx_create(x); } } static void pdp_glx_free(t_pdp_glx *x) { pdp_glx_destroy(x); } t_class *pdp_glx_class; void *pdp_glx_new(void) { t_pdp_glx *x = (t_pdp_glx *)pd_new(pdp_glx_class); x->x_xwin = 0; x->x_xdpy = 0; x->x_outlet = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; x->x_display = gensym(":0"); x->x_initialized = 0; pdp_glx_autocreate(x,1); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_glx_setup(void) { pdp_glx_class = class_new(gensym("pdp_glx"), (t_newmethod)pdp_glx_new, (t_method)pdp_glx_free, sizeof(t_pdp_glx), 0, A_NULL); /* add creator for pdp_tex_win */ class_addmethod(pdp_glx_class, (t_method)pdp_glx_bang, gensym("bang"), A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_create, gensym("open"), A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_create, gensym("create"), A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_autocreate, gensym("autocreate"), A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_destroy, gensym("destroy"), A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_destroy, gensym("close"), A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_move, gensym("move"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_move, gensym("pos"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_display, gensym("display"), A_SYMBOL, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_cursor, gensym("cursor"), A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_fullscreen, gensym("fullscreen"), A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_moveresize, gensym("posdim"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_glx_class, (t_method)pdp_glx_tile, gensym("tile"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); /* accept both pdp and pdp_tex packets */ class_addmethod(pdp_glx_class, (t_method)pdp_glx_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); /* some shortcuts for the lazy */ class_addmethod(pdp_glx_class, (t_method)pdp_glx_vga, gensym("vga"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_io/pdp_qt.c000066400000000000000000000616301266045153600211600ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ //#include //#include #include #include #include "pdp.h" #include "pdp_llconv.h" #if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION>=43 #include "s_stuff.h" // need to get sys_libdir for libquicktime plugins #endif #define min(x,y) ((xx_clock); pdp_procqueue_finish(q, x->x_queue_id); if (x->x_initialized){ /* close file */ quicktime_close(x->x_qt); x->x_initialized = 0; /* free video data */ if (x->x_video_tracks){ FREE(x->x_qt_frame); FREE(x->x_qt_rows); x->x_video_tracks = 0; //x->x_qt_rows = 0; //x->x_qt_frame = 0; } /* free audio data */ if (x->x_audio_tracks){ x->x_chunk_used[0] = 0; x->x_chunk_used[1] = 0; FREE(x->x_chunk_buf); FREE(x->x_qt_audiochans); x->x_audio_tracks = 0; //x->x_qt_audiochans = 0; //x->x_chunk_buf = 0; x->x_chunk[0][0] = 0; x->x_chunk[0][1] = 0; x->x_chunk[1][0] = 0; x->x_chunk[1][1] = 0; } } } void pdp_qt_create_pdp_packet(t_pdp_qt *x) { t_pdp *header; t_image *image; /* round to next legal size */ /* if size is illegal, image distortion will occur */ u32 w = pdp_imageproc_legalwidth(x->x_video_width); u32 h = pdp_imageproc_legalheight(x->x_video_height); int nbpixels = w * h; int packet_size = (nbpixels + (nbpixels >> 1)) << 1; pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_new_image_YCrCb(w, h); header = pdp_packet_header(x->x_packet0); image = pdp_packet_image_info(x->x_packet0); if (!header){ post("%s: ERROR: can't create new packet", x->x_name->s_name); return; } //header->info.image.encoding = (x->x_qt_cmodel == BC_RGB888) ? PDP_IMAGE_GREY : PDP_IMAGE_YV12; //image->encoding = PDP_IMAGE_YV12; //image->width = w; //image->height = h; } static void pdp_qt_open(t_pdp_qt *x, t_symbol *name) { unsigned int size; unsigned int i; unsigned int chunk_bytesize; post("%s: opening %s", x->x_name->s_name, name->s_name); /* close previous one */ pdp_qt_close(x); /* check if qt file */ if(0 == quicktime_check_sig(name->s_name)){ pd_error(x,"%s: %s not a quicktime file", x->x_name->s_name, name->s_name); goto exit; } /* open */ DEBUG_MSG(x->x_qt = quicktime_open(name->s_name, 1, 0);) if (!(x->x_qt)){ pd_error(x,"%s: can't open %s", x->x_name->s_name, name->s_name); goto exit; } /* check video */ x->x_video_tracks = 0; if (quicktime_has_video(x->x_qt)) { x->x_video_framerate = quicktime_frame_rate (x->x_qt, 0); x->x_video_length = quicktime_video_length (x->x_qt, 0); x->x_video_width = quicktime_video_width (x->x_qt, 0); x->x_video_height = quicktime_video_height (x->x_qt, 0); post("%s: video stream found (%dx%d pixels, %0.00f fps, %d frames, %s codec)", x->x_name->s_name, x->x_video_width, x->x_video_height, x->x_video_framerate, x->x_video_length, quicktime_video_compressor(x->x_qt, 0)); x->x_video_tracks = quicktime_video_tracks(x->x_qt); } /* check audior */ x->x_audio_tracks = 0; if (quicktime_has_audio(x->x_qt)) { x->x_audio_tracks = quicktime_audio_tracks (x->x_qt); //x->x_audio_channels = quicktime_track_channels (x->x_qt, 0); x->x_audio_channels = lqt_total_channels (x->x_qt); x->x_audio_samplerate = quicktime_sample_rate (x->x_qt, 0); x->x_audio_length = quicktime_audio_length (x->x_qt, 0); x->x_chunk_size = (int)((float)x->x_audio_samplerate / x->x_video_framerate); post("%s: audio stream found (%d channels, %d Hz, %d samples, chunksize %d)", x->x_name->s_name, x->x_audio_channels, x->x_audio_samplerate, x->x_audio_length, x->x_chunk_size); } /* check if video codec is supported */ if (x->x_video_tracks){ if (!quicktime_supported_video(x->x_qt,0)) { post("%s: WARNING: unsupported video codec in %s",x->x_name->s_name); x->x_video_tracks = 0; } } /* check if audio codec is supported */ if (x->x_audio_tracks){ if (!quicktime_supported_audio(x->x_qt,0)) { pd_error(x,"%s: unsupported audio codec in %s", x->x_name->s_name, name->s_name); x->x_audio_tracks = 0; } } /* check which colormodel to use */ if (x->x_video_tracks){ if (quicktime_reads_cmodel(x->x_qt,BC_YUV420P,0)){ post("%s: using colormodel YUV420P", x->x_name->s_name); x->x_qt_cmodel = BC_YUV420P; } else if (quicktime_reads_cmodel(x->x_qt,BC_YUV422,0)){ post("%s: using colormodel YUV422", x->x_name->s_name); x->x_qt_cmodel = BC_YUV422; } else if (quicktime_reads_cmodel(x->x_qt,BC_RGB888,0)){ post("%s: using colormodel RGB888", x->x_name->s_name); x->x_qt_cmodel = BC_RGB888; } else { post("%s: WARNING: can't find a usable colour model for %", x->x_name->s_name); x->x_video_tracks = 0; } } /* no video == errors */ if (!x->x_video_tracks) { pd_error(x,"%s: no usable video stream found in %s", x->x_name->s_name, name->s_name); goto exit_close; } /* initialize video data structures */ if (x->x_video_tracks){ /* allocate enough space for all supported colormodels (24bpp)*/ x->x_frame = 0; x->x_qt_frame = (unsigned char*)pdp_alloc(x->x_video_width * x->x_video_height * 3); x->x_qt_rows = (unsigned char **)pdp_alloc(sizeof(unsigned char *) * x->x_video_height); size = x->x_video_width * x->x_video_height; switch(x->x_qt_cmodel){ case BC_YUV420P: /* planar with u&v 2x2 subsampled */ x->x_qt_rows[0] = &x->x_qt_frame[0]; x->x_qt_rows[2] = &x->x_qt_frame[size]; x->x_qt_rows[1] = &x->x_qt_frame[size + (size>>2)]; break; case BC_YUV422: /* packed with u&v 2x subsampled (lines) */ /* later on we will convert this to planar */ for(i=0; i< x->x_video_height; i++) x->x_qt_rows[i] = &x->x_qt_frame[i * x->x_video_width * 2]; break; case BC_RGB888: /* packed rgb */ /* later on we will convert this to planar */ for(i=0; i< x->x_video_height; i++) x->x_qt_rows[i] = &x->x_qt_frame[i * x->x_video_width * 3]; break; default: post("%s: error on init: unkown colour model",x->x_name->s_name); break; } DEBUG_MSG(quicktime_set_cmodel(x->x_qt, x->x_qt_cmodel);) outlet_float(x->x_outlet2, (float)quicktime_video_length(x->x_qt,0)); } /* initialize audio data structures */ if (x->x_audio_tracks){ x->x_chunk_pos = 0; x->x_chunk_current = 0; chunk_bytesize = sizeof(float)*x->x_chunk_size; x->x_chunk_buf = (float *)pdp_alloc(chunk_bytesize * 4); memset(x->x_chunk_buf, 0, chunk_bytesize * 4); x->x_chunk[0][0] = x->x_chunk_buf; x->x_chunk[0][1] = x->x_chunk_buf + x->x_chunk_size ; x->x_chunk[1][0] = x->x_chunk_buf + x->x_chunk_size * 2; x->x_chunk[1][1] = x->x_chunk_buf + x->x_chunk_size * 3; x->x_chunk_used[0] = 0; x->x_chunk_used[1] = 0; x->x_syncaudio = x->x_istilde; //sync on audio if this is a tilde object DEBUG_MSG(if (x->x_audio_channels == 0) exit(1);) x->x_qt_audiochans = (float **)pdp_alloc(x->x_audio_channels * sizeof(float **)); memset(x->x_qt_audiochans, 0, x->x_audio_channels * sizeof(float **)); } else { x->x_syncaudio = 0; } /* everything went well */ x->x_initialized = 1; /* start playback if outplay is on */ if(x->x_autoplay) clock_delay(x->x_clock, 1000.0L / (double)x->x_video_framerate); /* brag about success */ post("%s: %s opened", x->x_name->s_name, name->s_name); return; /* error exits */ exit_close: DEBUG_MSG(quicktime_close(x->x_qt);) exit: x->x_initialized = 0; x->x_audio_tracks = 0; x->x_video_tracks = 0; return; } //static void pdp_qt_setposition(t_pdp_qt *x, int pos) //{ // x->x_frame = pos; // DEBUG_MSG(if(x->x_video_tracks) quicktime_set_video_position(x->x_qt, pos, 0);) // DEBUG_MSG(if(x->x_audio_tracks) quicktime_set_audio_position(x->x_qt, pos * x->x_chunk_size, 0);) // //} static void pdp_qt_bangaudio(t_pdp_qt *x) { int lefterr=0; int righterr=0; int err=0; int sample = 0; int remaining = 0; int readamount = 0; if (!x->x_initialized){ //post("pdp_qt: no qt file opened"); return; } if (!x->x_audio_tracks){ //post("pdp_qt: no audio stream present"); return; } //DEBUG_MSG(sample = quicktime_audio_position(x->x_qt,0);) // if the active chunk is unused, clear it and mark it used if (!x->x_chunk_used[x->x_chunk_current]){ //post("%s: clearing unused active chunk",x->x_name->s_name); //probably this is the !@#%&*(*)&!$() bug //memset(x->x_chunk[0][x->x_chunk_current], 0, sizeof(float)*2*x->x_chunk_size); //memset(x->x_chunk[1][x->x_chunk_current], 0, sizeof(float)*2*x->x_chunk_size); memset(x->x_chunk[0][x->x_chunk_current], 0, sizeof(float) * x->x_chunk_size); memset(x->x_chunk[1][x->x_chunk_current], 0, sizeof(float) * x->x_chunk_size); x->x_chunk_used[x->x_chunk_current] = 1; } // compute the remaining time DEBUG_MSG(remaining = (int ) ( quicktime_audio_length(x->x_qt, 0) - quicktime_audio_position(x->x_qt, 0) );) readamount = min(remaining, x->x_chunk_size); if (!readamount) return; // if the inactive chunk is unused, fill it with the current frame's audio data and mark it used if (!x->x_chunk_used[!x->x_chunk_current]){ switch(x->x_audio_channels){ case 1: x->x_qt_audiochans[0] = x->x_chunk[0][!x->x_chunk_current]; x->x_qt_audiochans[1] = 0; DEBUG_MSG(err = lqt_decode_audio(x->x_qt, NULL, x->x_qt_audiochans, readamount);) break; default: x->x_qt_audiochans[0] = x->x_chunk[0][!x->x_chunk_current]; x->x_qt_audiochans[1] = x->x_chunk[1][!x->x_chunk_current]; DEBUG_MSG(err = lqt_decode_audio(x->x_qt, NULL, x->x_qt_audiochans, readamount);) break; } x->x_chunk_used[!x->x_chunk_current] = 1; } // if it is used, something went wrong with sync else{ //post("%s: dropping audio chunk %d.",x->x_name->s_name, x->x_frame_thread); } if (err) post("%s: error decoding audio",x->x_name->s_name, x->x_frame_thread); // ensure audio pointer points to next frame's data //DEBUG_MSG(quicktime_set_audio_position(x->x_qt, sample + readamount, 0);) } static void pdp_qt_bangvideo(t_pdp_qt *x) { unsigned int w, h, nbpixels, packet_size, i,j; unsigned int *source, *dest; unsigned int uoffset, voffset; short int* data; t_pdp* header; // check if we want greyscale output or not //int grey = (x->x_qt_cmodel == BC_RGB888); static short int gain[4] = {0x7fff, 0x7fff, 0x7fff, 0x7fff}; if ((!x->x_initialized) || (!x->x_video_tracks)){ //post("pdp_qt: no qt file opened"); return; } w = x->x_video_width; h = x->x_video_height; nbpixels = x->x_video_width * x->x_video_height; // create a new packet pdp_qt_create_pdp_packet(x); header = pdp_packet_header(x->x_packet0); if (!header) { post("%s: ERROR: no packet available", x->x_name->s_name); return; } data = (short int *) pdp_packet_data(x->x_packet0); DEBUG_MSG(lqt_decode_video(x->x_qt, x->x_qt_rows, 0);) switch(x->x_qt_cmodel){ case BC_YUV420P: pdp_llconv(x->x_qt_frame, RIF_YVU__P411_U8, data, RIF_YVU__P411_S16, x->x_video_width, x->x_video_height); break; case BC_YUV422: pdp_llconv(x->x_qt_frame, RIF_YUYV_P____U8, data, RIF_YVU__P411_S16, x->x_video_width, x->x_video_height); break; case BC_RGB888: pdp_llconv(x->x_qt_frame, RIF_RGB__P____U8, data, RIF_YVU__P411_S16, x->x_video_width, x->x_video_height); break; default: post("%s: error on decode: unkown colour model",x->x_name->s_name); break; } } static void pdp_qt_sendpacket(t_pdp_qt *x) { pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); //if (x->x_packet0 != -1){ //pdp_packet_mark_unused(x->x_packet0); //outlet_pdp(x->x_outlet0, x->x_packet0); //x->x_packet0 = -1; //} } static void pdp_qt_thread_bang(t_pdp_qt *x) { // set audio position if(x->x_video_tracks) quicktime_set_video_position(x->x_qt, x->x_frame_thread, 0); // bang video pdp_qt_bangvideo(x); // if it's a tilde object, bang audio if (x->x_istilde && x->x_audio_tracks){ quicktime_set_audio_position(x->x_qt, x->x_frame_thread * x->x_chunk_size, 0); pdp_qt_bangaudio(x); } } static void pdp_qt_bang(t_pdp_qt *x) { int length, pos; t_pdp_procqueue *q = pdp_queue_get_queue(); /* return if not initialized */ if (!x->x_initialized) return; //length = quicktime_video_length(x->x_qt,0); //pos = quicktime_video_position(x->x_qt,0); length = x->x_video_length; pos = x->x_frame; /* check bounds */ if (x->x_loop){ pos = x->x_frame % length; if (pos < 0) pos += length; } else{ if (pos < 0) pos = 0; if (pos >= length) pos = length - 1; } /* store next frame for access in thread */ x->x_frame_thread = pos; // if autoplay is on and we do not have audio synchro // set clock to play next frame if (x->x_autoplay && !x->x_syncaudio) clock_delay(x->x_clock, 1000.0L / (double)x->x_video_framerate); // make sure prev decode is finished don't drop frames in this one pdp_procqueue_finish(q, x->x_queue_id); x->x_queue_id = -1; /* only decode new stuff if previous is done */ if (-1 == x->x_queue_id){ // send the current frame number to outlet outlet_float(x->x_outlet1, (float)pos); //pdp_qt_setposition(x, pos); // start process method if (x->x_process_in_thread) pdp_procqueue_add(q, x, pdp_qt_thread_bang, pdp_qt_sendpacket, &x->x_queue_id); else { pdp_qt_thread_bang(x); pdp_qt_sendpacket(x); } } // advance frame x->x_frame = pos + 1; // send the packet //pdp_qt_sendpacket(x); } //static void pdp_qt_getaudiochunk(t_pdp_qt *x, int channel) //{ // if (!x->x_audio_tracks) return; // quicktime_decode_audio(x->x_qt, NULL, x->x_chunk[channel][x->x_chunk_current], x->x_chunk_size<<1, channel); // //} static void pdp_qt_loop(t_pdp_qt *x, t_floatarg loop) { int loopi = (int)loop; x->x_loop = !(loopi == 0); } static void pdp_qt_autoplay(t_pdp_qt *x, t_floatarg play) { int playi = (int)play; x->x_autoplay = !(playi == 0); // reset clock if autoplay is off if (!x->x_autoplay) clock_unset(x->x_clock); } static void pdp_qt_frame_cold(t_pdp_qt *x, t_floatarg frameindex) { int frame = (int)frameindex; //int length; x->x_frame = frame; //if (!(x->x_initialized)) return; //length = quicktime_video_length(x->x_qt,0); //frame = (frame >= length) ? length-1 : frame; //frame = (frame < 0) ? 0 : frame; //pdp_qt_setposition(x, frame); } static void pdp_qt_frame(t_pdp_qt *x, t_floatarg frameindex) { pdp_qt_frame_cold(x, frameindex); pdp_qt_bang(x); } static void pdp_qt_stop(t_pdp_qt *x) { pdp_qt_autoplay(x, 0); } static void pdp_qt_continue(t_pdp_qt *x) { pdp_qt_autoplay(x, 1); pdp_qt_bang(x); } static void pdp_qt_play(t_pdp_qt *x){ pdp_qt_frame_cold(x, 0); pdp_qt_continue(x); } static void pdp_qt_importaudio(t_pdp_qt *x, t_symbol *array, t_floatarg channel) { t_pdp_procqueue *q = pdp_queue_get_queue(); int c = (int)channel; t_garray *g; int vecsize; int sample; float *f; int i; /* if there's no audio, there's nothing to export */ if (!x->x_audio_tracks) return; /* check audio channel */ if ((c < 0) || (c >= x->x_audio_channels)) return; /* check if array exists */ if (!(g = (t_garray *)pd_findbyclass(array, garray_class))){ pd_error(x, "%s: no such table", array->s_name); return; } post("%s: importing audio channel %d into array %s", x->x_name->s_name, c, array->s_name); // make sure decode is finished pdp_procqueue_finish(q, x->x_queue_id); x->x_queue_id = -1; /* resize array */ garray_resize(g, x->x_audio_length); /* for sanity's sake let's clear the save-in-patch flag here */ garray_setsaveit(g, 0); garray_getfloatarray(g, &vecsize, &f); /* if the resize failed, garray_resize reported the error */ if (vecsize != x->x_audio_length){ pd_error(x, "array resize failed"); return; } /* save pointer in file */ DEBUG_MSG(sample = quicktime_audio_position(x->x_qt, 0);) DEBUG_MSG(quicktime_set_audio_position(x->x_qt, 0, 0);) /* transfer the audio file to the end of the array */ DEBUG_MSG(quicktime_decode_audio(x->x_qt, NULL, f, vecsize, c);) /* restore pointer in file */ DEBUG_MSG(quicktime_set_audio_position(x->x_qt, sample, 0);) } static t_int *pdp_qt_perform(t_int *w) { t_pdp_qt *x = (t_pdp_qt *)w[1]; t_float *out0 = (t_float *)w[2]; t_float *out1 = (t_float *)w[3]; t_int n = (t_int)w[4]; t_int xfer_samples; if (!x->x_initialized || !x->x_audio_tracks) goto zero; while(1){ // check current chunk if (!x->x_chunk_used[x->x_chunk_current]) goto zero; // transfer from chunk to output xfer_samples = min(n, x->x_chunk_size - x->x_chunk_pos); //x->x_audio_channels = 1; if (x->x_audio_channels == 1){ memcpy(out0, x->x_chunk[0][x->x_chunk_current] + x->x_chunk_pos, sizeof(float)*xfer_samples); memcpy(out1, x->x_chunk[0][x->x_chunk_current] + x->x_chunk_pos, sizeof(float)*xfer_samples); } else { memcpy(out0, x->x_chunk[0][x->x_chunk_current] + x->x_chunk_pos, sizeof(float)*xfer_samples); memcpy(out1, x->x_chunk[1][x->x_chunk_current] + x->x_chunk_pos, sizeof(float)*xfer_samples); } out0 += xfer_samples; out1 += xfer_samples; n -= xfer_samples; x->x_chunk_pos += xfer_samples; // check if chunk is finished, if so mark unused, swap buffers and set clock if (x->x_chunk_size == x->x_chunk_pos){ x->x_chunk_used[x->x_chunk_current] = 0; x->x_chunk_pos = 0; x->x_chunk_current ^= 1; if (x->x_autoplay) clock_delay(x->x_clock, 0L); } // if chunk is not finished, the output buffer is full else{ goto exit; } } zero: // fill the rest of the output with zeros memset(out0, 0, sizeof(float)*n); memset(out1, 0, sizeof(float)*n); exit: return(w+5); } static void pdp_qt_dsp(t_pdp_qt *x, t_signal **sp) { dsp_add(pdp_qt_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); } static void pdp_qt_process_in_thread(t_pdp_qt *x, t_float f) { int t = (f != 0.0f); x->x_process_in_thread = t; post("pdp_qt: thread processing switched %d", t ? "on" : "off"); } static void pdp_qt_tick(t_pdp_qt *x) { // bang audio/video pdp_qt_bang(x); } static void pdp_qt_free(t_pdp_qt *x) { clock_unset(x->x_clock); pdp_qt_close(x); clock_free(x->x_clock); //free (x->x_state_data); } t_class *pdp_qt_class; t_class *pdp_qt_tilde_class; void pdp_qt_init_common(t_pdp_qt *x) { inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("frame_cold")); /* add common outlets */ x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_outlet1 = outlet_new(&x->x_obj, &s_float); x->x_outlet2 = outlet_new(&x->x_obj, &s_float); /* init */ x->x_gain = 1.0f; x->x_process_in_thread = 0; x->x_packet0 = -1; x->x_queue_id = -1; x->x_initialized = 0; x->x_audio_tracks = 0; x->x_video_tracks = 0; x->x_loop = 0; x->x_autoplay = 0; x->x_chunk[0][0] = 0; x->x_chunk[0][1] = 0; x->x_chunk[1][0] = 0; x->x_chunk[1][1] = 0; /* initialize clock object */ x->x_clock = clock_new(x, (t_method)pdp_qt_tick); } void *pdp_qt_new(void) { t_pdp_qt *x = (t_pdp_qt *)pd_new(pdp_qt_class); x->x_name = gensym("pdp_qt"); x->x_istilde = 0; pdp_qt_init_common(x); return (void *)x; } void *pdp_qt_tilde_new(void) { t_pdp_qt *x = (t_pdp_qt *)pd_new(pdp_qt_tilde_class); x->x_name = gensym("pdp_qt"); x->x_istilde = 1; pdp_qt_init_common(x); /* add outlets to the right so pdp_qt~ can replace pdp_qt without breaking a patch */ x->x_outleft = outlet_new(&x->x_obj, &s_signal); x->x_outright = outlet_new(&x->x_obj, &s_signal); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_qt_setup_common(t_class *class) { class_addmethod(class, (t_method)pdp_qt_bang, gensym("bang"), A_NULL); class_addmethod(class, (t_method)pdp_qt_close, gensym("close"), A_NULL); class_addmethod(class, (t_method)pdp_qt_open, gensym("open"), A_SYMBOL, A_NULL); class_addmethod(class, (t_method)pdp_qt_autoplay, gensym("autoplay"), A_DEFFLOAT, A_NULL); class_addmethod(class, (t_method)pdp_qt_stop, gensym("stop"), A_NULL); class_addmethod(class, (t_method)pdp_qt_play, gensym("play"), A_NULL); class_addmethod(class, (t_method)pdp_qt_continue, gensym("cont"), A_NULL); class_addmethod(class, (t_method)pdp_qt_loop, gensym("loop"), A_DEFFLOAT, A_NULL); class_addfloat (class, (t_method)pdp_qt_frame); class_addmethod(class, (t_method)pdp_qt_frame_cold, gensym("frame_cold"), A_FLOAT, A_NULL); class_addmethod(class, (t_method)pdp_qt_process_in_thread, gensym("thread"), A_FLOAT, A_NULL); class_addmethod(class, (t_method)pdp_qt_importaudio, gensym("importaudio"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(class, (t_method)pdp_qt_importaudio, gensym("dump"), A_SYMBOL, A_DEFFLOAT, A_NULL); } void pdp_qt_setup(void) { /* plain class */ pdp_qt_class = class_new(gensym("pdp_qt"), (t_newmethod)pdp_qt_new, (t_method)pdp_qt_free, sizeof(t_pdp_qt), 0, A_NULL); pdp_qt_setup_common(pdp_qt_class); /* tilde class */ pdp_qt_tilde_class = class_new(gensym("pdp_qt~"), (t_newmethod)pdp_qt_tilde_new, (t_method)pdp_qt_free, sizeof(t_pdp_qt), 0, A_NULL); pdp_qt_setup_common(pdp_qt_tilde_class); class_addmethod(pdp_qt_tilde_class, (t_method)pdp_qt_dsp, gensym("dsp"), 0); #ifdef __APPLE__ /* this is necessary for pdp_qt to find the embedded libquicktime plugins */ char buf[FILENAME_MAX]; char realpath_buf[FILENAME_MAX]; strncpy(buf, sys_libdir->s_name, FILENAME_MAX - 20); strcat(buf, "/../lib/libquicktime1"); if(realpath(buf, realpath_buf)) { if(sys_verbose) post("[pdp_qt]: setting LIBQUICKTIME_PLUGIN_DIR to:\n %s", realpath_buf); setenv("LIBQUICKTIME_PLUGIN_DIR", realpath_buf, 0); // 0 means don't overwrite existing value } #endif } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_io/pdp_sdl.c000066400000000000000000000200271266045153600213110ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) 2003 by martin pi * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* pdp sdl output DONE: TODO: * close window (event) * fullscreen chose resolution * event handling in different object (and look at mplayer for that!) */ #include #include #include "pdp.h" #include "pdp_llconv.h" /* initial image dimensions */ //#define WINWIDTH 640 //#define WINHEIGHT 480 #define WINWIDTH 320 #define WINHEIGHT 240 #define OVERLAYWIDTH 320 #define OVERLAYHEIGHT 240 typedef struct pdp_sdl_struct { t_object x_obj; SDL_Surface *x_surface; SDL_Overlay *x_overlay; int x_surface_flags; // current values int x_surface_width; int x_surface_height; unsigned int x_overlay_width; unsigned int x_overlay_height; // object creation args (wanted) int x_w; int x_h; t_outlet *x_outlet; } t_pdp_sdl; static int pdp_sdl_open(t_pdp_sdl *x); #define IF_NO_OVERLAY(x) if (!pdp_sdl_open(x)) static t_pdp_sdl *sdl_singleton; // only one instance allowed static void destroy_overlay(t_pdp_sdl *x) { if (x->x_overlay){ SDL_FreeYUVOverlay(x->x_overlay); x->x_overlay = 0; } } static void create_overlay(t_pdp_sdl *x, int width, int height) { if (x->x_surface){ if (x->x_overlay = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, x->x_surface)){ x->x_overlay_width = width; x->x_overlay_height = height; return; } } pdp_post("SDL: can't create overlay."); } static void check_overlay(t_pdp_sdl *x, unsigned int width, unsigned int height){ if (!x->x_overlay || (x->x_overlay_width != width) || (x->x_overlay_height != height)){ destroy_overlay(x); create_overlay(x, width, height); } } static void create_surface(t_pdp_sdl *x, int width, int height, int flags) { flags |= SDL_HWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE; // add default flags // flags |= SDL_HWSURFACE|SDL_ANYFORMAT; // add default flags // flags |= SDL_SWSURFACE|SDL_ANYFORMAT; // add default flags /* flags: SDL_HWSURFACE use hardware surface SDL_ANYFORMAT return current surface, even if it doesn't match SDL_OPENGL|SDL_DOUBLEBUF double buffer and opengl SDL_RLEACCEL rle accelleration for blitting SDL_FULLSCREEN fullscreen window */ //pdp_post("create_surface %d %d %d", width, height, flags); /* check args */ if (width < 1) width = 1; if (height < 1) height = 1; /* free old stuff */ if (x->x_overlay) destroy_overlay(x); /* form manpage: The framebuffer surface, or NULL if it fails. The surface returned is freed by SDL_Quit() and should nt be freed by the caller. */ if (x->x_surface) { /*SDL_FreeSurface(surface);*/ } /* create new surface */ if (!(x->x_surface = SDL_SetVideoMode(width, height, 16, flags))){ pdp_post("SDL: Couldn't create a surface: %s", SDL_GetError()); return; } /* setup surface */ SDL_WM_SetCaption("pdp", "pdp"); SDL_ShowCursor(0); /* set event mask to something conservative and add a word to ask for some types of events */ x->x_surface_width = width; x->x_surface_height = height; x->x_surface_flags = flags; } static void poll_events(t_pdp_sdl *x){ IF_NO_OVERLAY(x) { return; } SDL_Event event; static t_symbol *keydown=0, *keyup, *quit, *motion; t_atom atom; /* cache symbols */ if (!keydown){ keydown = gensym("keypress"); keyup = gensym("keyrelease"); quit = gensym("quit"); } if (!x->x_surface) return; /* poll events */ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_KEYDOWN: SETFLOAT(&atom, (float)event.key.keysym.scancode); outlet_anything(x->x_outlet, keydown, 1, &atom); break; case SDL_KEYUP: SETFLOAT(&atom, (float)event.key.keysym.scancode); outlet_anything(x->x_outlet, keyup, 1, &atom); break; case SDL_QUIT: outlet_symbol(x->x_outlet, quit); break; case SDL_VIDEORESIZE: create_surface(x, event.resize.w, event.resize.h, x->x_surface_flags); break; } } } static void fullscreen(t_pdp_sdl *x, t_floatarg f) { post("fullscreen not implemented"); } static void resize(t_pdp_sdl *x, t_floatarg fw, t_floatarg fh) { create_surface(x, (int)fw, (int)fh, 0); } static void input_0(t_pdp_sdl *x, t_symbol *s, t_floatarg f) { IF_NO_OVERLAY(x) { return; } int input_packet = (int)f; if (s == gensym("register_ro")){ int p = pdp_packet_convert_ro(input_packet, pdp_gensym("bitmap/yv12/*")); /* poll anyway. */ //poll_events(x); /* check packet */ if (-1 == p){ post("SDL: can't convert image to bitmap/yv12/*"); return; } else { t_bitmap *bitmap = pdp_packet_subheader(p); unsigned char *data = pdp_packet_data(p); int planesize = bitmap->width * bitmap->height; check_overlay(x, bitmap->width, bitmap->height); if (x->x_overlay){ SDL_Rect rect = {0, 0, x->x_surface_width, x->x_surface_height}; /* copy */ SDL_LockYUVOverlay(x->x_overlay); memcpy(x->x_overlay->pixels[0], data, planesize); data += planesize; memcpy(x->x_overlay->pixels[1], data, planesize >> 2); data += (planesize >> 2); memcpy(x->x_overlay->pixels[2], data, planesize >> 2); SDL_UnlockYUVOverlay(x->x_overlay); /* display */ if (SDL_DisplayYUVOverlay(x->x_overlay, &rect)){ pdp_post("SDL: can't display overlay"); return; } } else { PDP_ASSERT(0); } pdp_packet_mark_unused(p); return; } } } static void pdp_sdl_free(t_pdp_sdl *x) { destroy_overlay(x); sdl_singleton = 0; SDL_Quit(); } t_class *pdp_sdl_class; static int pdp_sdl_open(t_pdp_sdl *x){ if (x->x_overlay) return -1; /* try to create a surface */ create_surface(x, x->x_w ? x->x_w : WINWIDTH, x->x_h ? x->x_h : WINHEIGHT, 0); if (!x->x_surface){ pdp_post("Can't create surface"); goto error_cleanup; } /* try to create overlay */ check_overlay(x, OVERLAYHEIGHT, OVERLAYWIDTH); if (!x->x_overlay){ pdp_post("Can't create overlay"); goto error_cleanup; } return -1; error_cleanup: pdp_sdl_free(x); return 0; } static void *pdp_sdl_new(t_floatarg width, t_floatarg height) { t_pdp_sdl *x; if (sdl_singleton) { post("Only one sdl object allowed."); return 0; } if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { pdp_post("Could not initialize SDL: %s", SDL_GetError()); return 0; } atexit(SDL_Quit); x = (t_pdp_sdl *)pd_new(pdp_sdl_class); sdl_singleton = x; x->x_surface = NULL; x->x_overlay = NULL; x->x_w = (int)width; x->x_h = (int)height; x->x_outlet = outlet_new(&x->x_obj, &s_anything); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_sdl_setup(void) { sdl_singleton = 0; pdp_sdl_class = class_new(gensym("pdp_sdl"), (t_newmethod)pdp_sdl_new, (t_method)pdp_sdl_free, sizeof(t_pdp_sdl), 0, A_NULL); class_addmethod(pdp_sdl_class, (t_method)resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_sdl_class, (t_method)poll_events, gensym("poll"), A_NULL); class_addmethod(pdp_sdl_class, (t_method)fullscreen, gensym("fullscreen"), A_FLOAT, A_NULL); class_addmethod(pdp_sdl_class, (t_method)input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_io/pdp_v4l.c000066400000000000000000000326611266045153600212430ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * 2012-10-29 : V4L2 support from Pidip's pdp_v4l2 * Thanks to Yves Degoyon, Lluis Gomez i Bigorda, Gerd Knorr) * */ #include "pdp_config.h" #include "pdp.h" #include "pdp_llconv.h" #include "pdp_imageproc.h" #include "zl/v4l.h" #include static const int UVTranslate[32] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31}; static const int Y_coords_624x[128][2] = { { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7, 0}, { 0, 1}, { 1, 1}, { 2, 1}, { 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1}, { 0, 2}, { 1, 2}, { 2, 2}, { 3, 2}, { 4, 2}, { 5, 2}, { 6, 2}, { 7, 2}, { 0, 3}, { 1, 3}, { 2, 3}, { 3, 3}, { 4, 3}, { 5, 3}, { 6, 3}, { 7, 3}, { 0, 4}, { 1, 4}, { 2, 4}, { 3, 4}, { 4, 4}, { 5, 4}, { 6, 4}, { 7, 4}, { 0, 5}, { 1, 5}, { 2, 5}, { 3, 5}, { 4, 5}, { 5, 5}, { 6, 5}, { 7, 5}, { 0, 6}, { 1, 6}, { 2, 6}, { 3, 6}, { 4, 6}, { 5, 6}, { 6, 6}, { 7, 6}, { 0, 7}, { 1, 7}, { 2, 7}, { 3, 7}, { 4, 7}, { 5, 7}, { 6, 7}, { 7, 7}, { 8, 0}, { 9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15, 0}, { 8, 1}, { 9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1}, { 8, 2}, { 9, 2}, {10, 2}, {11, 2}, {12, 2}, {13, 2}, {14, 2}, {15, 2}, { 8, 3}, { 9, 3}, {10, 3}, {11, 3}, {12, 3}, {13, 3}, {14, 3}, {15, 3}, { 8, 4}, { 9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4}, { 8, 5}, { 9, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5}, {14, 5}, {15, 5}, { 8, 6}, { 9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6}, { 8, 7}, { 9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15, 7} }; static void do_write_u(const unsigned char *buf, unsigned char *ptr, int i, int j) { *ptr = buf[i + 128 + j]; } static void do_write_v(const unsigned char *buf, unsigned char *ptr, int i, int j) { *ptr = buf[i + 160 + j]; } void v4lconvert_sn9c20x_to_yuv420(const unsigned char *raw, unsigned char *i420, int width, int height, int yvu) { int i = 0, x = 0, y = 0, j, relX, relY, x_div2, y_div2; const unsigned char *buf = raw; unsigned char *ptr; int frame_size = width * height; int frame_size_div2 = frame_size >> 1; int frame_size_div4 = frame_size >> 2; int width_div2 = width >> 1; int height_div2 = height >> 1; void (*do_write_uv1)(const unsigned char *buf, unsigned char *ptr, int i, int j) = NULL; void (*do_write_uv2)(const unsigned char *buf, unsigned char *ptr, int i, int j) = NULL; if (yvu) { do_write_uv1 = do_write_v; do_write_uv2 = do_write_u; } else { do_write_uv1 = do_write_u; do_write_uv2 = do_write_v; } while (i < (frame_size + frame_size_div2)) { for (j = 0; j < 128; j++) { relX = x + Y_coords_624x[j][0]; relY = y + Y_coords_624x[j][1]; #if (DO_SANITY_CHECKS==1) if ((relX < width) && (relY < height)) { #endif ptr = i420 + relY * width + relX; *ptr = buf[i + j]; #if (DO_SANITY_CHECKS==1) } #endif } x_div2 = x >> 1; y_div2 = y >> 1; for (j = 0; j < 32; j++) { relX = (x_div2) + (j & 0x07); relY = (y_div2) + (j >> 3); #if (DO_SANITY_CHECKS==1) if ((relX < width_div2) && (relY < height_div2)) { #endif ptr = i420 + frame_size + relY * width_div2 + relX; do_write_uv1(buf, ptr, i, j); ptr += frame_size_div4; do_write_uv2(buf, ptr, i, j); #if (DO_SANITY_CHECKS==1) } #endif } i += 192; x += 16; if (x >= width) { x = 0; y += 8; } } } /* Pd / PDP stuff */ typedef struct pdp_v4l_struct { /* Pd stuff */ t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet *x_outlet1; t_symbol *x_device; t_symbol *x_image_type; #if 0 // FIXME: not used u32 x_minwidth; u32 x_maxwidth; u32 x_minheight; u32 x_maxheight; #endif /* Most of the work is done in the atapter object. */ struct zl_v4l zl; /* Generic */ } t_pdp_v4l; /* Shared code (independent of V4L1/V4L2) */ static void pdp_v4l_close(t_pdp_v4l *x) { zl_v4l_close(&x->zl); } static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name) { zl_v4l_open(&x->zl, name->s_name, true); } static void pdp_v4l_close_error(t_pdp_v4l *x) { zl_v4l_close_error(&x->zl); } static void control(t_pdp_v4l *x, int id, int value) { const char *name = zl_v4l_control_name(id); post("pdp_v4l: control (%08x) %s %d", id, name, value); zl_v4l_control(&x->zl, id, value); } static void pdp_v4l_control(t_pdp_v4l *x, t_symbol *s, t_float f1, t_float f2) { /* | "id" id value < */ if (s == gensym("id")) { control(x, f1, f2); } /* Named controls. These come straight from /usr/include/linux/0videodev2.h */ #define ZL_V4L_CTRL(id,...) else if (s == gensym(#id)) control(x, V4L2_CID_ ##id, f1); ZL_V4L_CTRL_LIST #undef ZL_V4L_CTRL else { post("pdp_v4l: unknown control %s", s->s_name); } } static void pdp_v4l_input(t_pdp_v4l *x, t_float f) { zl_v4l_input(&x->zl, f); } static void pdp_v4l_standard(t_pdp_v4l *x, t_float f) { zl_v4l_standard(&x->zl, f); } static void pdp_v4l_freq(t_pdp_v4l *x, t_float f) { zl_v4l_freq(&x->zl, f); } static void pdp_v4l_freqMHz(t_pdp_v4l *x, t_float f) { zl_v4l_freq(&x->zl, f*16.0f); } static void pdp_v4l_bang(t_pdp_v4l *x) { /* Make some effort to have an open device. */ int tries = 3; while (tries--) zl_v4l_open_if_necessary(&x->zl); /* Get raw image data */ unsigned char *newimage = NULL; zl_v4l_next(&x->zl, &newimage, 0); if (NULL == newimage) return; unsigned int fourcc; unsigned int w,h; zl_v4l_get_format(&x->zl, &fourcc, &w, &h); int pdp_packt = pdp_packet_new_image(PDP_IMAGE_YV12, w, h); t_pdp* header = pdp_packet_header(pdp_packt); if (!header){ post("pdp_v4l: ERROR: can't allocate packet"); return; } t_image *image = pdp_packet_image_info(pdp_packt); short int *data = (short int *) pdp_packet_data(pdp_packt); /* convert data to pdp packet */ switch(fourcc) { case V4L2_PIX_FMT_YUV420: pdp_llconv(newimage, RIF_YUV__P411_U8, data, RIF_YVU__P411_S16, w, h); break; case V4L2_PIX_FMT_RGB24: pdp_llconv(newimage, RIF_BGR__P____U8, data, RIF_YVU__P411_S16, w, h); break; case V4L2_PIX_FMT_RGB32: pdp_llconv(newimage, RIF_BGRA_P____U8, data, RIF_YVU__P411_S16, w, h); break; case V4L2_PIX_FMT_YUYV: pdp_llconv(newimage, RIF_YUYV_P____U8, data, RIF_YVU__P411_S16, w, h); break; case V4L2_PIX_FMT_UYVY: pdp_llconv(newimage, RIF_UYVY_P____U8, data, RIF_YVU__P411_S16, w, h); break; case v4l2_fourcc('S', '9', '2', '0'): v4lconvert_sn9c20x_to_yuv420( newimage, (unsigned char*)data, w, h, 1); pdp_llconv(data, RIF_YUV__P411_U8, newimage, RIF_YVU__P411_S16, w, h); memcpy(data, newimage, w * h *2); break; case V4L2_PIX_FMT_PAC207: /* GSPCA compressed ompressed RGGB bayer */ default: /* For more inspiration see: http://www.lavrsen.dk/svn/motion/trunk/video2.c http://www.lavrsen.dk/svn/motion/trunk/video_common.c http://www.siliconimaging.com/RGB%20Bayer.htm */ post("pdp_v4l: unsupported color model: %08x", fourcc); break; } pdp_packet_pass_if_valid(x->x_outlet0, &pdp_packt); } static void pdp_v4l_dim(t_pdp_v4l *x, t_floatarg xx, t_floatarg yy) { unsigned int w,h; w = pdp_imageproc_legalwidth((int)xx); h = pdp_imageproc_legalheight((int)yy); post("dim %d x %d (%f x %f)\n", w,h,xx,yy); #if 0 // FIXME: not used w = (w < x->x_maxwidth) ? w : x->x_maxwidth; w = (w > x->x_minwidth) ? w : x->x_minwidth; h = (h < x->x_maxheight) ? h : x->x_maxheight; h = (h > x->x_minheight) ? h : x->x_minheight; #endif zl_v4l_set_dim(&x->zl, w, h); } static void pdp_v4l_free(t_pdp_v4l *x) { pdp_v4l_close(x); } static void pdp_v4l_norm(t_pdp_v4l __attribute__((unused)) *x, t_symbol __attribute__((unused)) *s) { #ifdef HAVE_V4L1 unsigned int norm; if (gensym("PAL") == s) norm = VIDEO_MODE_PAL; else if (gensym("NTSC") == s) norm = VIDEO_MODE_NTSC; else if (gensym("SECAM") == s) norm = VIDEO_MODE_SECAM; else norm = VIDEO_MODE_AUTO; zl_v4l_set_norm(&x->zl, norm); #endif } static void pdp_v4l_format(t_pdp_v4l *x, t_symbol *s) { unsigned int format = 0; if (s == gensym("YUV420P")) format = 1; else if (s == gensym("YUV422")) format = 2; else if (s == gensym("RGB24")) format = 3; else if (s == gensym("RGB32")) format = 4; else if (s == gensym("auto")) format = 0; else { post("pdp_v4l: format %s unknown, using autodetect", s->s_name); format = 0; } zl_v4l_set_format(&x->zl, format); } static void pdp_v4l_channel(t_pdp_v4l *x, t_float channel) { zl_v4l_set_channel(&x->zl, channel); } static void pdp_v4l_info(t_pdp_v4l *x) { const char *card = zl_v4l_card(&x->zl); char c, nospace_card[strlen(card)+1]; int i = 0; while (0 != (c = card[i])) { nospace_card[i++] = isalnum(c) ? c : '_'; } nospace_card[i] = 0; t_atom atom[2]; SETSYMBOL(atom+0, gensym("card")); SETSYMBOL(atom+1, gensym(nospace_card)); #if 0 // "list" may not be the proper way to do this... outlet_anything(x->x_outlet1, gensym("list"), 2, atom); #else outlet_anything(x->x_outlet1, atom[0].a_w.w_symbol, 1, atom+1); #endif } static void pdp_v4l_pwc_agc(t_pdp_v4l *x, t_float gain) { return zl_v4l_pwc_agc(&x->zl, gain); } static void pdp_v4l_fps(t_pdp_v4l *x, t_floatarg num, t_floatarg den) { int iden = den; if (iden == 0) iden = 1; return zl_v4l_set_fps(&x->zl, num, iden); } t_class *pdp_v4l_class; void *pdp_v4l_new(t_symbol __attribute__((unused)) *vdef, t_symbol *format) { t_pdp_v4l *x = (t_pdp_v4l *)pd_new(pdp_v4l_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_outlet1 = outlet_new(&x->x_obj, &s_anything); zl_v4l_init(&x->zl, true); if (format != gensym("")){ pdp_v4l_format(x, format); } return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_v4l_setup(void) { pdp_v4l_class = class_new(gensym("pdp_v4l"), (t_newmethod)pdp_v4l_new, (t_method)pdp_v4l_free, sizeof(t_pdp_v4l), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_bang, gensym("bang"), A_NULL); // class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_audio, gensym("audio"), A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_close, gensym("close"), A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_open, gensym("open"), A_SYMBOL, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_channel, gensym("channel"), A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_norm, gensym("norm"), A_SYMBOL, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_standard, gensym("standard"), A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_input, gensym("input"), A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_freq, gensym("freq"), A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_freqMHz, gensym("freqMHz"), A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_pwc_agc, gensym("gain"), A_FLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_fps, gensym("fps"), A_FLOAT, A_DEFFLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_format, gensym("captureformat"), A_SYMBOL, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_control, gensym("control"), A_SYMBOL, A_FLOAT, A_DEFFLOAT, A_NULL); class_addmethod(pdp_v4l_class, (t_method)pdp_v4l_info, gensym("info"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_io/pdp_xv.c000066400000000000000000000217401266045153600211670ustar00rootroot00000000000000/* * Pure Data Packet module. Xvideo image packet output * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include "zl/xwindow.h" #include "zl/xv.h" #include "zl_pd/zl_pd.h" #include #define PDP_XV_AUTOCREATE_RETRY 10 typedef struct pdp_xv_struct { t_object x_obj; zl_xdisplay_p x_xdpy; zl_xwindow_p x_xwin; zl_xv_p x_xvid; t_outlet *x_outlet; int x_packet0; t_symbol *x_display; //Display *x_dpy; int x_initialized; int x_autocreate; } t_pdp_xv; static void pdp_xv_cursor(t_pdp_xv *x, t_floatarg f) { if (x->x_xwin) zl_xwindow_cursor(x->x_xwin, f); } /* delete all submodules */ static void _pdp_xv_cleanup(t_pdp_xv *x) { if (x->x_xwin) zl_xwindow_free(x->x_xwin); if (x->x_xvid) zl_xv_free(x->x_xvid); if (x->x_xdpy) zl_xdisplay_free(x->x_xdpy); x->x_xwin = 0; x->x_xvid = 0; x->x_xdpy = 0; x->x_initialized = 0; } // this destroys the window and all the x connections static void pdp_xv_destroy(t_pdp_xv* x) { if (x->x_initialized) { _pdp_xv_cleanup(x); // delete all objects pdp_packet_mark_unused(x->x_packet0); // delete packet x->x_packet0 = -1; x->x_initialized = 0; } } /* this creates a window (opens a dpy connection, creates xvideo and xwinow objects) */ static void pdp_xv_create(t_pdp_xv* x) { int i; if(x->x_initialized) return; /* open a display */ if (!(x->x_xdpy = zl_xdisplay_new(x->x_display->s_name))) goto exit; /* open an xv port on the display */ x->x_xvid = zl_xv_new(FOURCC_YV12); if (!zl_xv_open_on_display(x->x_xvid, x->x_xdpy, 0)) goto exit; /* create a window on the display */ x->x_xwin = zl_xwindow_new(); if (!zl_xwindow_config(x->x_xwin, x->x_xdpy)) goto exit; /* done */ x->x_initialized = 1; return; /* cleanup exits */ exit: post("pdp_xv: cant open display %s\n",x->x_display->s_name); _pdp_xv_cleanup(x); } static int pdp_xv_try_autocreate(t_pdp_xv *x) { if (x->x_autocreate){ post("pdp_xv: autocreate window"); pdp_xv_create(x); if (!(x->x_initialized)){ x->x_autocreate--; if (!x->x_autocreate){ post ("pdp_xv: autocreate failed %d times: disabled", PDP_XV_AUTOCREATE_RETRY); post ("pdp_xv: send [autocreate 1] message to re-enable"); return 0; } } else return 1; } return 0; } static void pdp_xv_bang(t_pdp_xv *x); static void display_packet(zl_xv_p xvid, zl_xwindow_p xwin, int packet) { t_pdp *header = pdp_packet_header(packet); void *data = pdp_packet_data(packet); t_bitmap * bm = pdp_packet_bitmap_info(packet); unsigned int width, height, encoding, size, nbpixels; /* some checks: only display when initialized and when pacet is bitmap YV12 */ if (!header) return; if (!bm) return; width = bm->width; height = bm->height; encoding = bm->encoding; size = (width * height + (((width>>1)*(height>>1))<<1)); nbpixels = width * height; if (PDP_BITMAP != header->type) { pdp_post("pdp_xv: not a bitmap"); return; } if (PDP_BITMAP_YV12 != encoding) { pdp_post("pdp_xv: not a YV12 bitmap"); return; } void *xv_data = zl_xv_image_data(xvid, xwin, width, height); if (xv_data) { // Always OK? /* Copy the data to the XvImage buffer */ memcpy(xv_data, data, size); /* Send it to the adapter. */ zl_xv_image_display(xvid, xwin); } } /* Poll for X11 events. */ static void outlet_event(void *context, int nb_double_args, zl_tag tag, va_list args) { t_pdp_xv *x = context; outlet_zl_float_list(x->x_outlet, nb_double_args, tag, args); } static void pdp_xv_poll(t_pdp_xv *x) { zl_xdisplay_route_events(x->x_xdpy); zl_xwindow_for_parsed_events(x->x_xwin, outlet_event, x); } static void pdp_xv_bang(t_pdp_xv *x) { /* check if window is initialized */ if (!(x->x_initialized)){ if (!pdp_xv_try_autocreate(x)) return; } /* check if we can proceed */ if (-1 == x->x_packet0) return; display_packet(x->x_xvid, x->x_xwin, x->x_packet0); /* Release packet */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = -1; /* Get events. */ pdp_xv_poll(x); } static void pdp_xv_input_0(t_pdp_xv *x, t_symbol *s, t_floatarg f) { if (s == gensym("register_ro")) { pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("bitmap/yv12/*")); } if (s == gensym("process")) pdp_xv_bang(x); } static void pdp_xv_autocreate(t_pdp_xv *x, t_floatarg f) { if (f != 0.0f) x->x_autocreate = PDP_XV_AUTOCREATE_RETRY; else x->x_autocreate = 0; } static void pdp_xv_display(t_pdp_xv *x, t_symbol *s) { x->x_display = s; /* only create if already active */ if (x->x_initialized){ pdp_xv_destroy(x); pdp_xv_create(x); } } static void pdp_xv_movecursor(t_pdp_xv *x, float cx, float cy) { if (x->x_initialized) { zl_xwindow_warppointer_rel(x->x_xwin, cx, cy); } } static void pdp_xv_fullscreen(t_pdp_xv *x) { if (x->x_initialized) zl_xwindow_fullscreen(x->x_xwin); } static void pdp_xv_resize(t_pdp_xv* x, t_floatarg width, t_floatarg height) { if (x->x_initialized) zl_xwindow_resize(x->x_xwin, width, height); } static void pdp_xv_move(t_pdp_xv* x, t_floatarg width, t_floatarg height) { if (x->x_initialized) zl_xwindow_move(x->x_xwin, width, height); } static void pdp_xv_moveresize(t_pdp_xv* x, t_floatarg xoff, t_floatarg yoff, t_floatarg width, t_floatarg height) { if (x->x_initialized) zl_xwindow_moveresize(x->x_xwin, xoff, yoff, width, height); } static void pdp_xv_tile(t_pdp_xv* x, t_floatarg xtiles, t_floatarg ytiles, t_floatarg i, t_floatarg j) { if (x->x_initialized) zl_xwindow_tile(x->x_xwin, xtiles, ytiles, i, j); } static void pdp_xv_vga(t_pdp_xv *x) { pdp_xv_resize(x, 640, 480); } static void pdp_xv_free(t_pdp_xv *x) { pdp_xv_destroy(x); } t_class *pdp_xv_class; void *pdp_xv_new(void) { t_pdp_xv *x = (t_pdp_xv *)pd_new(pdp_xv_class); x->x_outlet = outlet_new(&x->x_obj, &s_anything); x->x_xwin = 0; x->x_xvid = 0; x->x_xdpy = 0; x->x_packet0 = -1; x->x_display = gensym(":0"); x->x_xdpy = 0; pdp_xv_autocreate(x,1); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_xv_setup(void) { pdp_xv_class = class_new(gensym("pdp_xv"), (t_newmethod)pdp_xv_new, (t_method)pdp_xv_free, sizeof(t_pdp_xv), 0, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_bang, gensym("bang"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_create, gensym("open"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_create, gensym("create"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_autocreate, gensym("autocreate"), A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_destroy, gensym("destroy"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_destroy, gensym("close"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_move, gensym("move"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_move, gensym("pos"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_display, gensym("display"), A_SYMBOL, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_cursor, gensym("cursor"), A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_movecursor, gensym("movecursor"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_fullscreen, gensym("fullscreen"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_poll, gensym("poll"), A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_moveresize, gensym("posdim"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_xv_class, (t_method)pdp_xv_tile, gensym("tile"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); /* some shortcuts for the lazy */ class_addmethod(pdp_xv_class, (t_method)pdp_xv_vga, gensym("vga"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/000077500000000000000000000000001266045153600205305ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/image_special/Makefile000066400000000000000000000004641266045153600221740ustar00rootroot00000000000000current: all_modules include ../../Makefile.config PDP_MOD = pdp_chrot.o pdp_grey2mask.o pdp_scale.o pdp_scan.o \ pdp_scanxy.o pdp_scope.o \ pdp_cog.o pdp_array.o $(PDP_IMAGE_SPECIAL) # build special case image (and sound) processing modules all_modules: $(PDP_MOD) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/image_special/README000066400000000000000000000001331266045153600214050ustar00rootroot00000000000000This directory contains image processors that don't fit into the basic and io categories. pdp-0.14.1+darcs20180201/modules/image_special/pdp_array.c000066400000000000000000000134231266045153600226600ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) 2003 by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp.h" #include "pdp_base.h" typedef struct _pdp_array { t_object x_obj; t_symbol *x_array_sym; t_outlet *x_outlet0; // for array->pdp t_int x_rows; // transposed /* packet creation */ t_int x_width; t_int x_height; /* only valid after "get array" */ float *x_vec; int x_nbpoints; /* the packet */ int x_packet0; } t_pdp_array; static void get_array(t_pdp_array *x){ t_garray *a; x->x_vec = 0; /* dump to array if possible */ if (!x->x_array_sym) return; /* check if array is valid */ if (!(a = (t_garray *)pd_findbyclass(x->x_array_sym, garray_class))){ post("pdp_array: %s: no such array", x->x_array_sym->s_name); return; } /* get data */ if (!garray_getfloatarray(a, &x->x_nbpoints, &x->x_vec)){ post("pdp_array: %s: bad template", x->x_array_sym->s_name); return; } } static void pdp_array_bang(t_pdp_array *x) { PDP_ASSERT(-1 == x->x_packet0); x->x_packet0 = pdp_packet_new_image_grey(x->x_width, x->x_height); if (-1 != x->x_packet0){ t_pdp *header = pdp_packet_header(x->x_packet0); short int *data = (short int*)pdp_packet_data(x->x_packet0); get_array(x); if (x->x_vec){ int i; int w = header->info.image.width; int h = header->info.image.height; int N = w*h; N = (x->x_nbpoints < N) ? x->x_nbpoints : N; /* scan rows */ if (1 || x->x_rows){ // FIXME: saturation for (i=0; ix_vec[i] * max; int l = (int)f; l = (l > 0x8000) ? 0x7fff : l; l = (l < -0x8000) ? -0x8000 : l; data[i] = (short int)l; } } } pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } } static void pdp_array_input_0(t_pdp_array *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s == gensym("register_ro")){ /* replace if not compatible or we are not interpolating */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_convert_ro(packet, pdp_gensym("image/grey/*")); } /* process */ if (s == gensym("process")){ t_garray *a; t_pdp *header = pdp_packet_header(x->x_packet0); short int *data = pdp_packet_data(x->x_packet0); if (!header || !data) return; get_array(x); if (x->x_vec){ int i; int w = header->info.image.width; int h = header->info.image.height; int N = w*h; N = (x->x_nbpoints < N) ? x->x_nbpoints : N; /* scan rows */ if (x->x_rows){ for (i=0; ix_vec[i] = (float)data[i] * (1.0f / (float)0x8000); } /* scan columns */ else{ for (i=0; ix_vec[i] = (float)data[xx+(h-yy-1)*w] * (1.0f / (float)0x8000); } } } } } static void pdp_array_array(t_pdp_array *x, t_symbol *s) { //post("setting symbol %x", s); x->x_array_sym = s; x->x_packet0 = -1; } static void pdp_array_free(t_pdp_array *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_array2grey_class; t_class *pdp_grey2array_class; void *pdp_array2grey_new(t_symbol *s, t_symbol __attribute__((unused)) *r) { t_pdp_array *x = (t_pdp_array *)pd_new(pdp_array2grey_class); pdp_array_array(x, s); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_width = 320; x->x_height = 240; return (void *)x; } void *pdp_grey2array_new(t_symbol *s, t_symbol *r) { t_pdp_array *x = (t_pdp_array *)pd_new(pdp_grey2array_class); pdp_array_array(x, s); if (r == gensym("rows")){ x->x_rows = 1; post("pdp_grey2array: scanning rows"); } else { x->x_rows = 0; post("pdp_grey2array: scanning columns"); } return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_array_setup(void) { pdp_array2grey_class = class_new(gensym("pdp_array2grey"), (t_newmethod)pdp_array2grey_new, (t_method)pdp_array_free, sizeof(t_pdp_array), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL); pdp_grey2array_class = class_new(gensym("pdp_grey2array"), (t_newmethod)pdp_grey2array_new, (t_method)pdp_array_free, sizeof(t_pdp_array), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL); /* packet input */ class_addmethod(pdp_grey2array_class, (t_method)pdp_array_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); /* bang method */ class_addmethod(pdp_array2grey_class, (t_method)pdp_array_bang, gensym("bang"), A_NULL); /* bookkeeping */ class_addmethod(pdp_array2grey_class, (t_method)pdp_array_array, gensym("array"), A_SYMBOL, A_NULL); class_addmethod(pdp_grey2array_class, (t_method)pdp_array_array, gensym("array"), A_SYMBOL, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_chrot.c000066400000000000000000000063221266045153600226610ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include typedef struct pdp_chrot_struct { t_pdp_base x_base; float x_matrix[4]; void *x_crot2d; } t_pdp_chrot; static void pdp_chrot_process(t_pdp_chrot *x) { int packet; t_pdp *header; void *data; unsigned int w,h,size,v_offset; short int *idata; /* get packet & info */ packet = pdp_base_get_packet(x, 0); header = pdp_packet_header(packet); data = pdp_packet_data (packet); /* only process if we have a vlid yv12 image */ if ((header) && (PDP_IMAGE == header->type) && (PDP_IMAGE_YV12 == header->info.image.encoding)){ w = header->info.image.width; h = header->info.image.height; size = w*h; v_offset = size; idata = (short int *)data; /* color rotation for 2 colour planes */ pdp_imageproc_crot2d_process(x->x_crot2d, idata + v_offset, w>>1, h>>1); } return; } static void pdp_chrot_setelement(t_pdp_chrot *x, int element, float f) { x->x_matrix[element] = f; } static void pdp_chrot_angle_radians(t_pdp_chrot *x, t_floatarg angle) { float c = cos(angle); float s = sin(angle); pdp_chrot_setelement(x, 0, c); pdp_chrot_setelement(x, 1, s); pdp_chrot_setelement(x, 2, -s); pdp_chrot_setelement(x, 3, c); pdp_imageproc_crot2d_setmatrix(x->x_crot2d, x->x_matrix); } static void pdp_chrot_angle_degrees(t_pdp_chrot *x, t_floatarg angle) { pdp_chrot_angle_radians(x, (angle * (M_PI / 180.f))); } static void pdp_chrot_free(t_pdp_chrot *x) { pdp_base_free(x); pdp_imageproc_crot2d_delete(x->x_crot2d); } t_class *pdp_chrot_class; void *pdp_chrot_new(t_floatarg __attribute__((unused)) f) { t_pdp_chrot *x = (t_pdp_chrot *)pd_new(pdp_chrot_class); pdp_base_init(x); pdp_base_add_gen_inlet(x, gensym("float"), gensym("angle")); pdp_base_add_pdp_outlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_chrot_process); x->x_crot2d = pdp_imageproc_crot2d_new(); pdp_chrot_angle_radians(x, 0.0f); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_chrot_setup(void) { pdp_chrot_class = class_new(gensym("pdp_chrot"), (t_newmethod)pdp_chrot_new, (t_method)pdp_chrot_free, sizeof(t_pdp_chrot), 0, A_DEFFLOAT, A_NULL); pdp_base_setup(pdp_chrot_class); class_addmethod(pdp_chrot_class, (t_method)pdp_chrot_angle_degrees, gensym("angle"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_cog.c000066400000000000000000000125251266045153600223140ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) 2003 by Johannes Taelman * API updates by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include typedef struct pdp_cog_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet *x_outlet1; t_outlet *x_outlet2; t_outlet *x_outlet3; t_outlet *x_outlet4; int x_packet0; int x_threshold; int x_do_thresholding; } t_pdp_cog; static void _pdp_cog_perform(t_pdp_cog *x, int width, int height, short int *data0) { short int *pp; int nbpixels; int y; int h,v; int rowsums[width]; int columnsums[height]; float vsum,vvar,vcog,vstd; float hsum,hvar,hcog,hstd; pp=data0; nbpixels=width*height; for (h=0;hx_do_thresholding){ for (v=0;vx->x_threshold) ? d : ((d<-x->x_threshold)?(-d):0); columnsums[h]+= d; rs+=d; } rowsums[v]=rs; } } /* don't perform thresholding */ else{ for (v=0;vx_outlet4,vstd); outlet_float(x->x_outlet3,hstd); outlet_float(x->x_outlet2,vcog/height); outlet_float(x->x_outlet1,hcog/width); outlet_float(x->x_outlet0,(1.0f / (float)(0x7fff)) * hsum/(height*width)); } // packet is an image/*/* packet or invalid */ static void pdp_cog_perform(t_pdp_cog *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); void *data0 = pdp_packet_data(x->x_packet0); if (!header0 || !data0) return; _pdp_cog_perform(x, header0->info.image.width, header0->info.image.height, data0); } static void pdp_cog_input_0(t_pdp_cog *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s == gensym("register_ro")){ /* replace if not compatible or we are not interpolating */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_convert_ro(packet, pdp_gensym("image/*/*")); } if (s == gensym("process")){ pdp_cog_perform(x); } } static void pdp_cog_threshold(t_pdp_cog *x, t_floatarg f) { x->x_threshold=(int) (f * ((float) 0x7fff)); } static void pdp_cog_free(t_pdp_cog *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_cog_class; void *pdp_cog_new(void) { t_pdp_cog *x = (t_pdp_cog *)pd_new(pdp_cog_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_float); x->x_outlet1 = outlet_new(&x->x_obj, &s_float); x->x_outlet2 = outlet_new(&x->x_obj, &s_float); x->x_outlet3 = outlet_new(&x->x_obj, &s_float); x->x_outlet4 = outlet_new(&x->x_obj, &s_float); x->x_packet0 = -1; x->x_do_thresholding = 0; return (void *)x; } void *pdp_cog_abs_thresh_new(t_floatarg f) { t_pdp_cog *x = (t_pdp_cog *)pdp_cog_new(); inlet_new((void *)x, &x->x_obj.ob_pd, gensym("float"),gensym("threshold")); pdp_cog_threshold(x, f); x->x_do_thresholding = 1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_cog_setup(void) { pdp_cog_class = class_new(gensym("pdp_cog"), (t_newmethod)pdp_cog_new, (t_method)pdp_cog_free, sizeof(t_pdp_cog), 0,A_NULL); class_addcreator((t_newmethod)pdp_cog_abs_thresh_new, gensym("pdp_cog_abs_thresh"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_cog_class, (t_method)pdp_cog_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_cog_class, (t_method)pdp_cog_threshold, gensym("threshold"),A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_grey2mask.c000066400000000000000000000112101266045153600234360ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this module converts a greyscale image or the luma channel of a colour image to a colour image intensity mask, usable for multiplication */ #include "pdp.h" #include "pdp_resample.h" typedef struct pdp_grey2mask_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; int x_packet0; int x_dropped; int x_queue_id; } t_pdp_grey2mask; static void pdp_grey2mask_process_grey(t_pdp_grey2mask *x) { t_pdp *header = pdp_packet_header(x->x_packet0); short int *data = (short int *)pdp_packet_data (x->x_packet0); t_pdp *newheader = 0; short int *newdata = 0; int newpacket = -1; unsigned int w = header->info.image.width; unsigned int h = header->info.image.height; unsigned int size = w*h; unsigned int totalnbpixels = size; unsigned int u_offset = size; unsigned int v_offset = size + (size>>2); unsigned int row, col; newpacket = pdp_packet_new_image_YCrCb(w, h); newheader = pdp_packet_header(newpacket); newdata = (short int *)pdp_packet_data(newpacket); /* copy luma channel */ memcpy(newdata, data, size * sizeof(s16)); /* subsample luma -> chroma channel */ pdp_resample_halve(data, newdata+u_offset, w, h); /* copy this to the other chroma channel */ memcpy(newdata+v_offset, newdata+u_offset, (size>>2)*sizeof(s16)); /* delete source packet and replace with new packet */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = newpacket; return; } static void pdp_grey2mask_process_yv12(t_pdp_grey2mask *x) { /* process only the luminance channel */ pdp_grey2mask_process_grey(x); } static void pdp_grey2mask_process(t_pdp_grey2mask *x) { int encoding; t_pdp *header = 0; /* check if image data packets are compatible */ if ( (header = pdp_packet_header(x->x_packet0)) && (PDP_IMAGE == header->type)){ /* pdp_grey2mask_process inputs and write into active inlet */ switch(pdp_packet_header(x->x_packet0)->info.image.encoding){ case PDP_IMAGE_YV12: pdp_grey2mask_process_yv12(x); break; case PDP_IMAGE_GREY: pdp_grey2mask_process_grey(x); break; default: /* don't know the type, so dont pdp_grey2mask_process */ break; } } } static void pdp_grey2mask_sendpacket(t_pdp_grey2mask *x) { /* unregister and propagate if valid packet */ pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } static void pdp_grey2mask_input_0(t_pdp_grey2mask *x, t_symbol *s, t_floatarg f) { int p = (int)f; if (s== gensym("register_ro")) x->x_dropped = pdp_packet_copy_ro_or_drop(&x->x_packet0, p); if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ /* add the process method and callback to the process queue */ //pdp_queue_add(x, pdp_grey2mask_process, pdp_grey2mask_sendpacket, &x->x_queue_id); // since the process method creates a packet, this is not processed in the thread // $$$TODO: fix this pdp_grey2mask_process(x); pdp_grey2mask_sendpacket(x); } } static void pdp_grey2mask_free(t_pdp_grey2mask *x) { t_pdp_procqueue *q = pdp_queue_get_queue(); pdp_procqueue_finish(q, x->x_queue_id); pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_grey2mask_class; void *pdp_grey2mask_new(void) { int i; t_pdp_grey2mask *x = (t_pdp_grey2mask *)pd_new(pdp_grey2mask_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; x->x_queue_id = -1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_grey2mask_setup(void) { pdp_grey2mask_class = class_new(gensym("pdp_grey2mask"), (t_newmethod)pdp_grey2mask_new, (t_method)pdp_grey2mask_free, sizeof(t_pdp_grey2mask), 0, A_NULL); class_addmethod(pdp_grey2mask_class, (t_method)pdp_grey2mask_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_histo.c000066400000000000000000000243511266045153600226720ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) 2003 by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include struct _pdp_histo; typedef void (*t_histo_proc)(struct _pdp_histo *); typedef struct _pdp_histo { t_object x_obj; t_int x_logN; t_symbol *x_array_sym; t_float x_scale; t_int x_debug; t_int x_sample_size; /* pointcloud size */ t_histo_proc x_process_method; /* what to do with the histogram */ t_outlet *x_outlet0; int x_matrix_output; /* the packet */ int x_packet0; /* packet data */ short int *x_data; int x_width; int x_height; int x_nb_pixels; /* histo data for processor: these are stored on the stack */ int *x_histo; } t_pdp_histo; static int round_up_2log(int i) { int l = 0; i--; while (i) { i >>= 1; l++; } //post("log is %d, 2^n is %d", l, 1 << l); l = (l < 16) ? l : 15; return l; } static void dump_to_array(t_pdp_histo *x) { float *vec; int nbpoints; t_garray *a; int i; int *histo = x->x_histo; int N = 1 << (x->x_logN); float scale = 1.0f / (float)(x->x_nb_pixels); /* dump to array if possible */ if (!x->x_array_sym){ } /* check if array is valid */ else if (!(a = (t_garray *)pd_findbyclass(x->x_array_sym, garray_class))){ post("pdp_histo: %s: no such array", x->x_array_sym->s_name); } /* get data */ else if (!garray_getfloatarray(a, &nbpoints, &vec)){ post("pdp_histo: %s: bad template", x->x_array_sym->s_name); } /* scale and dump in array */ else{ N = (nbpoints < N) ? nbpoints : N; for (i=0; ix_scale; //garray_redraw(a); } } static void get_sampleset(t_pdp_histo *x, int log_tmp_size, int threshold) { int N = 1 << log_tmp_size; int mask = N-1; int index, nbpoints, i; t_atom a[2]; double scalex = 1.0f / (double)(x->x_width); double scaley = 1.0f / (double)(x->x_height); t_symbol *s = gensym("list"); int matrix_packet; double *mat_data; /* store the offsets of the points in a in an oversized array the oversizing is to eliminate a division and to limit the searching for a free location after a random index is generated */ int offset[N]; /* reset the array */ memset(offset, -1, N * sizeof(int)); /* get the coordinates of the tempsize brightest points and store them in a random location in the hash */ for (i=0; ix_nb_pixels; i++){ if (x->x_data[i] >= threshold){ /* get a random index */ int ri = random(); //int ri = 0; /* find an empty spot to store it */ while (-1 != offset[ri & mask]) ri++; offset[ri & mask] = i; } } /* repack the array to get the requested sample size at the start */ index = 0; nbpoints = 0; while (nbpoints < x->x_sample_size){ while (-1 == offset[index]) index++; // ffwd to next nonepty slot offset[nbpoints++] = offset[index++]; // move slot } /* MATRIX OUTPUT */ if (x->x_matrix_output){ matrix_packet = pdp_packet_new_matrix(x->x_sample_size, 2, PDP_MATRIX_TYPE_RDOUBLE); mat_data = pdp_packet_data(matrix_packet); if (mat_data){ /* build the cluster data struct */ for (i=0; ix_sample_size; i++){ mat_data[2*i] = ((double)(offset[i] % x->x_width)) * scalex; mat_data[2*i+1] = ((double)(offset[i] / x->x_width)) * scaley; } pdp_pass_if_valid(x->x_outlet0, &matrix_packet); pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = -1; } } /* IMAGE OUTPUT */ else { /* get rw copy */ pdp_packet_replace_with_writable(&x->x_packet0); x->x_data = pdp_packet_data(x->x_packet0); /* mark output packet samples */ if (x->x_data){ memset(x->x_data, 0, 2*x->x_nb_pixels); for (i=0; ix_sample_size; i++){ x->x_data[offset[i]] = 0x7fff; } } /* send packet to left outlet */ pdp_pass_if_valid(x->x_outlet0, &x->x_packet0); } } static void get_brightest(t_pdp_histo *x) { int i; int *histo = x->x_histo; int N = 1 << (x->x_logN); int index, nsamps; /* check requested size */ if (x->x_sample_size > x->x_nb_pixels){ post("WARNING: more samples requested than pixels in image"); x->x_sample_size = x->x_nb_pixels; } /* find limiting index */ index = N; nsamps = 0; while (nsamps < x->x_sample_size){ index--; nsamps += histo[index]; } /* status report */ if (x->x_debug){ post("found %d samples between h[%d] and h[%d]", nsamps, index, N-1); } /* get a representative set from the candidates the tempbuf is the rounded log of the nb of samples + 1 so it is at least 50% sparse */ get_sampleset(x, round_up_2log(nsamps) + 1, index << (15-x->x_logN)); } static void _pdp_histo_perform(t_pdp_histo *x) { short int *pp; int N = 1 << x->x_logN; int nbpixels = x->x_width * x->x_height, i; int histo[N]; /* init */ for (i=0; ix_data[i] >> (15 - x->x_logN); if (index < 0) index = 0; /* negative -> zero */ histo[index]++; } /* save the histo stack location */ x->x_histo = histo; /* print it */ if (x->x_debug){ post("histogram:"); for (i=0; ix_process_method(x); } // packet is an image/*/* packet or invalid */ static void pdp_histo_perform(t_pdp_histo *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); void *data0 = pdp_packet_data(x->x_packet0); if (!header0 || !data0) return; x->x_width = header0->info.image.width; x->x_height = header0->info.image.height; x->x_nb_pixels = x->x_width * x->x_height; x->x_data = data0; _pdp_histo_perform(x); } static void pdp_histo_input_0(t_pdp_histo *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s == gensym("register_rw")){ /* replace if not compatible or we are not interpolating */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_convert_ro(packet, pdp_gensym("image/grey/*")); } if (s == gensym("process")){ pdp_histo_perform(x); } } static void pdp_histo_samplesize(t_pdp_histo *x, t_floatarg f) { int i = (int)f; if (i > 0) x->x_sample_size = i; } static void pdp_histo_scale(t_pdp_histo *x, t_floatarg f){x->x_scale = f;} static void pdp_histo_size(t_pdp_histo *x, t_floatarg f) { int i = (int)f; if (i < 1) return; x->x_logN = round_up_2log(i); } static void pdp_histo_array(t_pdp_histo *x, t_symbol *s) { //post("setting symbol %x", s); x->x_array_sym = s; } static void pdp_histo_free(t_pdp_histo *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_histo_class; void *pdp_histo_new(t_floatarg f) { t_pdp_histo *x = (t_pdp_histo *)pd_new(pdp_histo_class); if (f == 0.0f) f = 64; pdp_histo_size(x, f); x->x_packet0 = -1; x->x_debug = 0; x->x_sample_size = 16; return (void *)x; } void *pdp_histo_array_new(t_symbol *s, t_float f, t_float f2) { t_pdp_histo *x = (t_pdp_histo *)pdp_histo_new(f); if (f2 == 0.0f) f2 = 1.0f; pdp_histo_scale(x, f2); pdp_histo_array(x, s); x->x_process_method = dump_to_array; return (void *)x; } void *pdp_histo_sample_new(t_float nbsamples, t_float histosize) { t_pdp_histo *x; if (histosize == 0.0f) histosize = 256.0f; x = (t_pdp_histo *)pdp_histo_new(histosize); if (nbsamples == 0.0f) nbsamples = 16.0f; pdp_histo_samplesize(x, nbsamples); x->x_process_method = get_brightest; x->x_outlet0 = outlet_new(&x->x_obj, gensym("anything")); x->x_matrix_output = 0; inlet_new((t_object *)x, (t_pd *)&x->x_obj, gensym("float"), gensym("nbpoints")); return (void *)x; } void *pdp_histo_sample_matrix_new(t_float nbsamples, t_float histosize) { t_pdp_histo *x = pdp_histo_sample_new(nbsamples, histosize); if (x) x->x_matrix_output = 1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_histo_setup(void) { pdp_histo_class = class_new(gensym("pdp_histo"), (t_newmethod)pdp_histo_array_new, (t_method)pdp_histo_free, sizeof(t_pdp_histo), 0, A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addcreator((t_newmethod)pdp_histo_sample_new, gensym("pdp_pointcloud"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addcreator((t_newmethod)pdp_histo_sample_matrix_new, gensym("pdp_pointcloud_matrix"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_size, gensym("size"), A_FLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_size, gensym("scale"), A_FLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_array, gensym("array"), A_SYMBOL, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_samplesize, gensym("nbpoints"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_scale.c000066400000000000000000000161671266045153600226410ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_resample.h" typedef struct pdp_scale_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; int x_packet0; int x_packet1; int x_dropped; int x_queue_id; unsigned int x_width; unsigned int x_height; int x_quality; } t_pdp_scale; static void pdp_scale_process_yv12(t_pdp_scale *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); t_pdp *header1 = pdp_packet_header(x->x_packet1); void *data0 = pdp_packet_data (x->x_packet0); void *data1 = pdp_packet_data (x->x_packet1); unsigned int src_w = header0->info.image.width; unsigned int src_h = header0->info.image.height; unsigned int dst_w = header1->info.image.width; unsigned int dst_h = header1->info.image.height; short int *src_image = (short int *)data0; short int *dst_image = (short int *)data1; unsigned int src_size = src_w*src_h; unsigned int src_voffset = src_size; unsigned int src_uoffset = src_size + (src_size>>2); unsigned int dst_size = dst_w*dst_h; unsigned int dst_voffset = dst_size; unsigned int dst_uoffset = dst_size + (dst_size>>2); if (x->x_quality){ pdp_resample_scale_bilin(src_image, dst_image, src_w, src_h, dst_w, dst_h); pdp_resample_scale_bilin(src_image+src_voffset, dst_image+dst_voffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); pdp_resample_scale_bilin(src_image+src_uoffset, dst_image+dst_uoffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); } else{ pdp_resample_scale_nn(src_image, dst_image, src_w, src_h, dst_w, dst_h); pdp_resample_scale_nn(src_image+src_voffset, dst_image+dst_voffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); pdp_resample_scale_nn(src_image+src_uoffset, dst_image+dst_uoffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); } return; } static void pdp_scale_process_grey(t_pdp_scale *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); t_pdp *header1 = pdp_packet_header(x->x_packet1); void *data0 = pdp_packet_data (x->x_packet0); void *data1 = pdp_packet_data (x->x_packet1); unsigned int src_w = header0->info.image.width; unsigned int src_h = header0->info.image.height; unsigned int dst_w = header1->info.image.width; unsigned int dst_h = header1->info.image.height; short int *src_image = (short int *)data0; short int *dst_image = (short int *)data1; if (x->x_quality) pdp_resample_scale_bilin(src_image, dst_image, src_w, src_h, dst_w, dst_h); else pdp_resample_scale_nn(src_image, dst_image, src_w, src_h, dst_w, dst_h); return; } static void pdp_scale_sendpacket(t_pdp_scale *x) { /* delete source packet */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = -1; /* unregister and propagate if valid dest packet */ pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); } static void pdp_scale_process(t_pdp_scale *x) { t_pdp_procqueue *q = pdp_queue_get_queue(); t_pdp *header0 = pdp_packet_header(x->x_packet0); /* check data packets */ if ((header0) && (PDP_IMAGE == header0->type)){ /* if dims are equal, just send the packet */ if ((header0->info.image.width == x->x_width) && (header0->info.image.height == x->x_height)){ x->x_packet1 = x->x_packet0; x->x_packet0 = -1; pdp_scale_sendpacket(x); return; } /* type hub */ switch(header0->info.image.encoding){ case PDP_IMAGE_YV12: x->x_packet1 = pdp_packet_new_image_YCrCb(x->x_width, x->x_height); if(x->x_packet1 == -1){ post("pdp_scale: can't allocate packet"); return; } pdp_procqueue_add(q, x, pdp_scale_process_yv12, pdp_scale_sendpacket, &x->x_queue_id); break; case PDP_IMAGE_GREY: x->x_packet1 = pdp_packet_new_image_grey(x->x_width, x->x_height); if(x->x_packet1 == -1){ post("pdp_scale: can't allocate packet"); return; } pdp_procqueue_add(q, x, pdp_scale_process_grey, pdp_scale_sendpacket, &x->x_queue_id); break; default: break; /* don't know the type, so dont process */ } } } static void pdp_scale_input_0(t_pdp_scale *x, t_symbol *s, t_floatarg f) { int p = (int)f; int passes, i; if (s== gensym("register_rw")) x->x_dropped = pdp_packet_copy_ro_or_drop(&x->x_packet0, p); if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ /* add the process method and callback to the process queue */ pdp_scale_process(x); } } static void pdp_scale_width(t_pdp_scale *x, t_floatarg f) { int i = (int)f; if (i < 32) i = 32; x->x_width = i; } static void pdp_scale_height(t_pdp_scale *x, t_floatarg f) { int i = (int)f; if (i < 32) i = 32; x->x_height = i; } static void pdp_scale_dim(t_pdp_scale *x, t_floatarg w, t_floatarg h) { pdp_scale_width(x, w); pdp_scale_height(x, h); } static void pdp_scale_quality(t_pdp_scale *x, t_floatarg f) { if (f==0) x->x_quality = 0; if (f==1) x->x_quality = 1; } t_class *pdp_scale_class; void pdp_scale_free(t_pdp_scale *x) { t_pdp_procqueue *q = pdp_queue_get_queue(); pdp_procqueue_finish(q, x->x_queue_id); pdp_packet_mark_unused(x->x_packet0); pdp_packet_mark_unused(x->x_packet1); } void *pdp_scale_new(t_floatarg fw, t_floatarg fh) { t_pdp_scale *x = (t_pdp_scale *)pd_new(pdp_scale_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; x->x_packet1 = -1; x->x_queue_id = -1; if ((fw != 0.0f) && (fh != 0.0f)) pdp_scale_dim(x, fw, fh); else pdp_scale_dim(x, 320, 240); pdp_scale_quality(x, 1); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_scale_setup(void) { pdp_scale_class = class_new(gensym("pdp_scale"), (t_newmethod)pdp_scale_new, (t_method)pdp_scale_free, sizeof(t_pdp_scale), 0, A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addmethod(pdp_scale_class, (t_method)pdp_scale_quality, gensym("quality"), A_FLOAT, A_NULL); class_addmethod(pdp_scale_class, (t_method)pdp_scale_width, gensym("width"), A_FLOAT, A_NULL); class_addmethod(pdp_scale_class, (t_method)pdp_scale_height, gensym("height"), A_FLOAT, A_NULL); class_addmethod(pdp_scale_class, (t_method)pdp_scale_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_scale_class, (t_method)pdp_scale_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_scan.c000066400000000000000000000133341266045153600224670ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_mmx.h" #include #define PDP_SCAN_COSTABLE_SIZE 1024 static float pdp_cos[PDP_SCAN_COSTABLE_SIZE]; typedef struct pdp_scan_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet *x_outlet1; float x_centerx; float x_centery; float x_sizeh; float x_sizev; int x_packet0; int x_packet1; int x_interpolate; } t_pdp_scan; static t_int *pdp_scan_perform(t_int *w) { t_pdp_scan *x = (t_pdp_scan *)(w[1]); t_int n = (t_int)(w[2]); t_float *in = (float *)(w[3]); t_float *out = (float *)(w[4]); /* check if valid image */ if (-1 == x->x_packet0){ while (n--) *out++ = 0; return (w+5); } else{ t_pdp *header0 = pdp_packet_header(x->x_packet0); short int *data0 = (short int *)pdp_packet_data (x->x_packet0); short int *data1 = (short int *)pdp_packet_data (x->x_packet1); int width = (float)header0->info.image.width; float widthm1 = (float)header0->info.image.width - 1; float heightm1 = (float)header0->info.image.height - 1; int i; float scale = 1.0f / 32767.0f; if (x->x_interpolate && (-1 != x->x_packet1)){ float a_old = 1.0f; float a_new = 0.0f; float a_inc = 1.0f / (float)n; float old, new; while(n--){ float phase = *in++; int iphase = (int)(phase * PDP_SCAN_COSTABLE_SIZE); float c = pdp_cos[iphase & (PDP_SCAN_COSTABLE_SIZE - 1)]; float s = pdp_cos[(iphase - (PDP_SCAN_COSTABLE_SIZE>>1)) & (PDP_SCAN_COSTABLE_SIZE - 1)]; int xxx = (int)((x->x_centerx + x->x_sizeh * c) * widthm1); int yyy = (int)((x->x_centery + x->x_sizev * c) * heightm1); int offset = yyy*width+xxx; new = ((float)(data0[offset])) * scale; old = ((float)(data1[offset])) * scale; *out++ = a_old * old + a_new * new; a_new += a_inc; a_old -= a_inc; } pdp_packet_mark_unused(x->x_packet1); x->x_packet1 = -1; } else{ while(n--){ float phase = *in++; int iphase = (int)(phase * PDP_SCAN_COSTABLE_SIZE); float c = pdp_cos[iphase & (PDP_SCAN_COSTABLE_SIZE - 1)]; float s = pdp_cos[(iphase - (PDP_SCAN_COSTABLE_SIZE>>1)) & (PDP_SCAN_COSTABLE_SIZE - 1)]; int xxx = (int)((x->x_centerx + x->x_sizeh * c) * widthm1); int yyy = (int)((x->x_centery + x->x_sizev * c) * heightm1); *out++ = ((float)(data0[yyy*width+xxx])) * scale; } } return (w+5); } } static void pdp_scan_input_0(t_pdp_scan *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s== gensym("register_ro")){ t_pdp *header = pdp_packet_header(packet); if (!header) return; if (PDP_IMAGE != header->type) return; if ((header->info.image.encoding != PDP_IMAGE_YV12) && (header->info.image.encoding != PDP_IMAGE_GREY)) return; /* replace if not compatible or we are not interpolating */ if (!x->x_interpolate || (!pdp_packet_image_compat(x->x_packet0, packet))){ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_copy_ro(packet); } /* otherwize keep the old one */ else{ pdp_packet_mark_unused(x->x_packet1); x->x_packet1 = x->x_packet0; x->x_packet0 = pdp_packet_copy_ro(packet); } } /* pass packet */ if (s== gensym("process")){ //if (-1 != x->x_packet0) outlet_pdp (x->x_outlet0, x->x_packet0); } } static void pdp_scan_dsp (t_pdp_scan *x, t_signal **sp) { dsp_add(pdp_scan_perform, 4, x, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); } static void pdp_scan_interpolate(t_pdp_scan *x, t_floatarg f) { if (0.0 == f){ x->x_interpolate = 0; pdp_packet_mark_unused(x->x_packet1); } if (1.0 == f) x->x_interpolate = 1; } static void pdp_scan_free(t_pdp_scan *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_scan_class; void *pdp_scan_new(void) { t_pdp_scan *x = (t_pdp_scan *)pd_new(pdp_scan_class); //x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_outlet1 = outlet_new(&x->x_obj, &s_signal); x->x_packet0 = -1; x->x_packet1 = -1; x->x_centerx = 0.5f; x->x_centery = 0.5f; x->x_sizeh = 0.3; x->x_sizev = 0.3; pdp_scan_interpolate(x, 0); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_scan_setup(void) { int i; for (i=0; i * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include typedef struct pdp_scanxy_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_outlet *x_outlet1; int x_packet0; int x_packet1; int x_interpolate; } t_pdp_scanxy; static t_int *pdp_scanxy_perform(t_int *w) { t_pdp_scanxy *x = (t_pdp_scanxy *)(w[1]); t_int n = (t_int)(w[2]); t_float *inx = (float *)(w[3]); t_float *iny = (float *)(w[4]); t_float *out = (float *)(w[5]); /* check if valid image */ if (-1 == x->x_packet0){ while (n--) *out++ = 0; return (w+6); } else{ t_pdp *header0 = pdp_packet_header(x->x_packet0); short int *data0 = (short int *)pdp_packet_data (x->x_packet0); short int *data1 = (short int *)pdp_packet_data (x->x_packet1); int width = (float)header0->info.image.width; int height = (float)header0->info.image.height; int i; float scale = 1.0f / 32767.0f; float scalein = 0x10000; if (x->x_interpolate && (-1 != x->x_packet1)){ float a_old = 1.0f; float a_new = 0.0f; float a_inc = 1.0f / (float)n; float old, new; while(n--){ int xxx = ((((int)(scalein * *inx++)) & 0xffff) * width) >> 16; int yyy = ((((int)(scalein * *iny++)) & 0xffff) * height) >> 16; int offset = yyy*width+xxx; new = ((float)(data0[offset])) * scale; old = ((float)(data1[offset])) * scale; *out++ = a_old * old + a_new * new; a_new += a_inc; a_old -= a_inc; } pdp_packet_mark_unused(x->x_packet1); x->x_packet1 = -1; } else{ while(n--){ int xxx = ((((int)(scalein * *inx++)) & 0xffff) * width) >> 16; int yyy = ((((int)(scalein * *iny++)) & 0xffff) * height) >> 16; int offset = yyy*width+xxx; *out++ = ((float)(data0[offset])) * scale; } } return (w+6); } } static void pdp_scanxy_input_0(t_pdp_scanxy *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s== gensym("register_ro")){ t_pdp *header = pdp_packet_header(packet); if (!header) return; if (PDP_IMAGE != header->type) return; if ((header->info.image.encoding != PDP_IMAGE_YV12) && (header->info.image.encoding != PDP_IMAGE_GREY)) return; /* replace if not compatible or we are not interpolating */ if (!x->x_interpolate || (!pdp_packet_image_compat(x->x_packet0, packet))){ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_copy_ro(packet); } /* otherwize keep the old one */ else{ pdp_packet_mark_unused(x->x_packet1); x->x_packet1 = x->x_packet0; x->x_packet0 = pdp_packet_copy_ro(packet); } } /* pass packet */ if (s== gensym("process")){ //if (-1 != x->x_packet0) outlet_pdp (x->x_outlet0, x->x_packet0); } } static void pdp_scanxy_dsp (t_pdp_scanxy *x, t_signal **sp) { dsp_add(pdp_scanxy_perform, 5, x, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec); } static void pdp_scanxy_interpolate(t_pdp_scanxy *x, t_floatarg f) { if (0.0 == f){ x->x_interpolate = 0; pdp_packet_mark_unused(x->x_packet1); } if (1.0 == f) x->x_interpolate = 1; } static void pdp_scanxy_free(t_pdp_scanxy *x) { pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_scanxy_class; void *pdp_scanxy_new(void) { t_pdp_scanxy *x = (t_pdp_scanxy *)pd_new(pdp_scanxy_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); x->x_outlet1 = outlet_new(&x->x_obj, &s_signal); x->x_packet0 = -1; x->x_packet1 = -1; pdp_scanxy_interpolate(x, 0); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_scanxy_setup(void) { pdp_scanxy_class = class_new(gensym("pdp_scanxy~"), (t_newmethod)pdp_scanxy_new, (t_method)pdp_scanxy_free, sizeof(t_pdp_scanxy), 0, A_NULL); CLASS_MAINSIGNALIN(pdp_scanxy_class, t_pdp_scanxy, x_f); class_addmethod(pdp_scanxy_class, (t_method)pdp_scanxy_interpolate, gensym("interpolate"), A_FLOAT, A_NULL); class_addmethod(pdp_scanxy_class, (t_method)pdp_scanxy_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_scanxy_class, (t_method)pdp_scanxy_dsp, gensym("dsp"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/image_special/pdp_scope.c000066400000000000000000000153011266045153600226500ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include #define BUFSIZE 2048 typedef struct pdp_scope_data { short int random_seed[4]; }t_pdp_scope_data; typedef struct pdp_scope_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; t_pdp_scope_data *x_data; int x_packet0; int x_queue_id; int x_pdp_image_type; unsigned int x_width; unsigned int x_height; float *x_buffer; int x_needle; } t_pdp_scope; void pdp_scope_type(t_pdp_scope *x, t_symbol *s) { if (gensym("yv12") == s) {x->x_pdp_image_type = PDP_IMAGE_YV12; return;} if (gensym("grey") == s) {x->x_pdp_image_type = PDP_IMAGE_GREY; return;} x->x_pdp_image_type = -1; } static void pdp_scope_createpacket_yv12(t_pdp_scope *x) { t_pdp *header; unsigned int w = x->x_width; unsigned int h = x->x_height; unsigned int size = w*h; unsigned int totalnbpixels = size + (size >> 1); unsigned int packet_size = totalnbpixels << 1; x->x_packet0 = pdp_packet_new_image_YCrCb(w, h); if(x->x_packet0 == -1){ post("pdp_scope: can't allocate packet"); return; } header = pdp_packet_header(x->x_packet0); memset(pdp_packet_data(x->x_packet0), 0, packet_size); } static void pdp_scope_generate_yv12(t_pdp_scope *x) { unsigned int w = x->x_width; unsigned int h = x->x_height; unsigned int size = w*h; unsigned int totalnbpixels = size + (size >> 1); short int *data = (short int *) pdp_packet_data(x->x_packet0); unsigned int i; int offset = x->x_needle; int val; unsigned int y; float fh2 = (float)(h/2); if (!data) return; for (i=0; ix_buffer[(offset - w + i) & (BUFSIZE - 1)]); if (y>=h) y = h-1; data[i + y*w] = 0x7fff; } return; } static void pdp_scope_createpacket_grey(t_pdp_scope *x) { t_pdp *header; short int *data; unsigned int w = x->x_width; unsigned int h = x->x_height; unsigned int size = w*h; unsigned int totalnbpixels = size; unsigned int packet_size = totalnbpixels << 1; /* create new packet */ x->x_packet0 = pdp_packet_new_image_grey(w,h); if(x->x_packet0 == -1){ post("pdp_scope: can't allocate packet"); return; } header = pdp_packet_header(x->x_packet0); data = (short int *) pdp_packet_data(x->x_packet0); memset(pdp_packet_data(x->x_packet0), 0, packet_size); } static void pdp_scope_generate_grey(t_pdp_scope *x) { unsigned int w = x->x_width; unsigned int h = x->x_height; unsigned int totalnbpixels = x->x_width * x->x_height; short int *data = (short int *) pdp_packet_data(x->x_packet0); unsigned int i; int offset = x->x_needle; int val; unsigned int y; float fh2 = (float)(h/2); if (!data) return; for (i=0; ix_buffer[(offset - w + i) & (BUFSIZE - 1)]); if (y>=h) y = h-1; data[i + y*w] = 0x7fff; } return; } static void pdp_scope_sendpacket(t_pdp_scope *x) { /* propagate if valid */ pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet0); } static void pdp_scope_bang(t_pdp_scope *x) { int encoding; /* if we have an active packet, don't do anything */ if (-1 != x->x_packet0) return; switch(x->x_pdp_image_type){ case PDP_IMAGE_YV12: pdp_scope_createpacket_yv12(x); // don't create inside thread!!! pdp_scope_generate_yv12(x); pdp_scope_sendpacket(x); //pdp_queue_add(x, pdp_scope_generate_yv12, pdp_scope_sendpacket, &x->x_queue_id); break; case PDP_IMAGE_GREY: pdp_scope_createpacket_grey(x); // don't create inside thread!!! pdp_scope_generate_grey(x); pdp_scope_sendpacket(x); //pdp_queue_add(x, pdp_scope_generate_grey, pdp_scope_sendpacket, &x->x_queue_id); break; default: break; } /* release the packet */ } static void pdp_scope_dim(t_pdp_scope *x, t_floatarg w, t_floatarg h) { if (w<32.0f) w = 32.0f; if (h<32.0f) h = 32.0f; x->x_width = (unsigned int)w; x->x_height = (unsigned int)h; } static void pdp_scope_free(t_pdp_scope *x) { /* remove callback from process queue */ t_pdp_procqueue *q = pdp_queue_get_queue(); pdp_procqueue_finish(q, x->x_queue_id); /* tidy up */ pdp_packet_mark_unused(x->x_packet0); pdp_dealloc(x->x_data); } static t_int *pdp_scope_perform(t_int *w) { t_float *in = (float *)(w[3]); t_pdp_scope *x = (t_pdp_scope *)(w[1]); t_int n = (t_int)(w[2]); t_int i; t_int offset = x->x_needle; for (i=0; ix_buffer[(offset+i)&(BUFSIZE-1)] = in[i]; x->x_needle = (offset + n ) & (BUFSIZE - 1); return (w+4); } static void pdp_scope_dsp(t_pdp_scope *x, t_signal **sp) { dsp_add(pdp_scope_perform, 3, x, sp[0]->s_n, sp[0]->s_vec); } t_class *pdp_scope_class; void *pdp_scope_new(void) { int i; t_pdp_scope *x = (t_pdp_scope *)pd_new(pdp_scope_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; x->x_queue_id = -1; x->x_width = 320; x->x_height = 240; x->x_f = 0.0; x->x_data = (t_pdp_scope_data *)pdp_alloc(sizeof(t_pdp_scope_data)); pdp_scope_type(x, gensym("yv12")); x->x_buffer = (float *)pdp_alloc(sizeof(float) * BUFSIZE); x->x_needle = 0; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_scope_setup(void) { pdp_scope_class = class_new(gensym("pdp_scope~"), (t_newmethod)pdp_scope_new, (t_method)pdp_scope_free, sizeof(t_pdp_scope), 0, A_NULL); CLASS_MAINSIGNALIN(pdp_scope_class, t_pdp_scope, x_f); class_addmethod(pdp_scope_class, (t_method)pdp_scope_type, gensym("type"), A_SYMBOL, A_NULL); class_addmethod(pdp_scope_class, (t_method)pdp_scope_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_scope_class, (t_method)pdp_scope_bang, gensym("bang"), A_NULL); class_addmethod(pdp_scope_class, (t_method)pdp_scope_dsp, gensym("dsp"), 0); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/matrix_basic/000077500000000000000000000000001266045153600204135ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/matrix_basic/Makefile000066400000000000000000000002121266045153600220460ustar00rootroot00000000000000current: all_modules include ../../Makefile.config PDP_MOD = $(PDP_MATRIX_BASIC) all_modules: $(PDP_MOD) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/matrix_basic/README000066400000000000000000000002721266045153600212740ustar00rootroot00000000000000This directory contains "normal" matrix packet processors, derived from the t_pdp_base class defined in pdp_base.h Most modules are wrappers around Gnu Scientific Library (gsl) calls pdp-0.14.1+darcs20180201/modules/matrix_basic/clusterstuff.c000066400000000000000000000322141266045153600233120ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) 2003 by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include struct _pdp_histo; typedef void (*t_histo_proc)(struct _pdp_histo *); /* the cluster struct */ typedef struct _cluster { float N; float cx; float cy; } t_cluster; typedef struct _pdp_histo { t_object x_obj; t_int x_logN; t_symbol *x_array_sym; t_float x_scale; t_int x_debug; t_int x_sample_size; /* pointcloud size */ t_int x_nb_clusters; /* nb of clusters */ t_cluster *x_cluster; /* cluster data (for tracking) */ t_histo_proc x_process_method; /* what to do with the histogram */ t_outlet *x_outlet0; t_outlet *x_outlet1; /* the packet */ int x_packet0; /* packet data */ short int *x_data; int x_width; int x_height; int x_nb_pixels; /* histo data for processor: these are stored on the stack */ int *x_histo; int *x_pixel_offset; } t_pdp_histo; // join 2 clusters. clear the second one static void cluster_join(t_cluster *cA, t_cluster *cB) { float scale = 1.0f / (cA->N + cB->N); cA->cx = (cA->N * cA->cx + cB->N * cB->cx) * scale; cA->cy = (cA->N * cA->cy + cB->N * cB->cy) * scale; cA->N += cB->N; cB->N = 0.0f; } static void cluster_copy(t_cluster *cA, t_cluster *cB) { cA->cx = cB->cx; cA->cy = cB->cy; cA->N = cB->N; } static void cluster_clear(t_cluster *c) { c->N = 0.0f; } static void cluster_new(t_cluster *c, float x, float y) { c->N = 1.0f; c->cx = x; c->cy = y; } static float cluster_dsquared(t_cluster *cA, t_cluster *cB) { float dx = cA->cx - cB->cx; float dy = cA->cy - cB->cy; return dx*dx + dy*dy; } static int round_up_2log(int i) { int l = 0; i--; while (i) { i >>= 1; l++; } //post("log is %d, 2^n is %d", l, 1 << l); l = (l < 16) ? l : 15; return l; } static void compute_clusters(t_pdp_histo *x) { t_cluster c[x->x_sample_size]; int i; float scalex = 1.0f / (float)(x->x_width); float scaley = 1.0f / (float)(x->x_height); int nb_clusters = x->x_sample_size; /* build the cluster data struct */ for (i=0; ix_sample_size; i++) cluster_new(c+i, ((float)(x->x_pixel_offset[i] % x->x_width)) * scalex, ((float)(x->x_pixel_offset[i] / x->x_width)) * scaley); /* the clustering loop */ while (nb_clusters > x->x_nb_clusters){ /* initialize cA, cB, d */ int cA=0; int cB=1; float d = cluster_dsquared(c+0, c+1); int i,j; /* find the closest 2 clusters: scan the distance matrix above the diagonal */ for (i=2; ix_cluster){ int size = sizeof(t_cluster) * x->x_nb_clusters; x->x_cluster = (t_cluster *)pdp_alloc(size); memcpy(x->x_cluster, c, size); } /* or perform tracking */ else{ int i,j; /* find best matches for the first couple of clusters */ for (i=0; ix_nb_clusters - 1; i++){ int closest = 0; float d_min = cluster_dsquared(x->x_cluster+i, c); /* get closest cluster */ for (j=1; jx_cluster+i, c+j); if (dj < d_min){ closest = j; d_min = dj; } } /* replace reference cluster with closest match */ cluster_copy(x->x_cluster+i, c+closest); /* shrink matrix (like above) */ nb_clusters--; cluster_copy(c+closest, c+nb_clusters); } /* copy the last cluster */ cluster_copy(x->x_cluster + x->x_nb_clusters - 1, c); } /* print the clusters */ post("clusters:"); post("\tN\tcx\tcy"); for (i=0; ix_nb_clusters; i++){ post("\t%d\t%0.2f\t%0.2f", (int)x->x_cluster[i].N, x->x_cluster[i].cx, x->x_cluster[i].cy); } } static void dump_to_array(t_pdp_histo *x) { float *vec; int nbpoints; t_garray *a; int i; int *histo = x->x_histo; int N = 1 << (x->x_logN); float scale = 1.0f / (float)(x->x_nb_pixels); /* dump to array if possible */ if (!x->x_array_sym){ } /* check if array is valid */ else if (!(a = (t_garray *)pd_findbyclass(x->x_array_sym, garray_class))){ post("pdp_histo: %s: no such array", x->x_array_sym->s_name); } /* get data */ else if (!garray_getfloatarray(a, &nbpoints, &vec)){ post("pdp_histo: %s: bad template", x->x_array_sym->s_name); } /* scale and dump in array */ else{ N = (nbpoints < N) ? nbpoints : N; for (i=0; ix_scale; //garray_redraw(a); } } static void get_sampleset(t_pdp_histo *x, int log_tmp_size, int threshold) { int N = 1 << log_tmp_size; int mask = N-1; int index, nbpoints, i; t_atom a[2]; float scalex = 1.0f / (float)(x->x_width); float scaley = 1.0f / (float)(x->x_height); t_symbol *s = gensym("list"); /* store the offsets of the points in a in an oversized array the oversizing is to eliminate a division and to limit the searching for a free location after a random index is generated */ int offset[N]; /* float versions of the coordinates */ float fx[x->x_sample_size]; float fy[x->x_sample_size]; float max_x, min_x, max_y, min_y; /* reset the array */ memset(offset, -1, N * sizeof(int)); /* get the coordinates of the tempsize brightest points and store them in a random location in the hash */ for (i=0; ix_nb_pixels; i++){ if (x->x_data[i] >= threshold){ /* get a random index */ int ri = random(); //int ri = 0; /* find an empty spot to store it */ while (-1 != offset[ri & mask]) ri++; offset[ri & mask] = i; } } /* repack the array to get the requested sample size at the start */ index = 0; nbpoints = 0; while (nbpoints < x->x_sample_size){ while (-1 == offset[index]) index++; // ffwd to next nonepty slot offset[nbpoints++] = offset[index++]; // move slot } /* mark output packet samples */ memset(x->x_data, 0, 2*x->x_nb_pixels); for (i=0; ix_sample_size; i++){ x->x_data[offset[i]] = 0x7fff; } /* send packet to left outlet */ pdp_pass_if_valid(x->x_outlet0, &x->x_packet0); /* run the clustering algo */ x->x_pixel_offset = offset; compute_clusters(x); } static void get_brightest(t_pdp_histo *x) { int i; int *histo = x->x_histo; int N = 1 << (x->x_logN); int index, nsamps; /* check requested size */ if (x->x_sample_size > x->x_nb_pixels){ post("WARNING: more samples requested than pixels in image"); x->x_sample_size = x->x_nb_pixels; } /* find limiting index */ index = N; nsamps = 0; while (nsamps < x->x_sample_size){ index--; nsamps += histo[index]; } /* status report */ if (x->x_debug){ post("found %d samples between h[%d] and h[%d]", nsamps, index, N-1); } /* get a representative set from the candidates the tempbuf is the rounded log of the nb of samples + 1 so it is at least 50% sparse */ get_sampleset(x, round_up_2log(nsamps) + 1, index << (15-x->x_logN)); } static void _pdp_histo_perform(t_pdp_histo *x) { short int *pp; int N = 1 << x->x_logN; int nbpixels = x->x_width * x->x_height, i; int histo[N]; /* init */ for (i=0; ix_data[i] >> (15 - x->x_logN); if (index < 0) index = 0; /* negative -> zero */ histo[index]++; } /* save the histo stack location */ x->x_histo = histo; /* print it */ if (x->x_debug){ post("histogram:"); for (i=0; ix_process_method(x); } // packet is an image/*/* packet or invalid */ static void pdp_histo_perform(t_pdp_histo *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); void *data0 = pdp_packet_data(x->x_packet0); if (!header0 || !data0) return; x->x_width = header0->info.image.width; x->x_height = header0->info.image.height; x->x_nb_pixels = x->x_width * x->x_height; x->x_data = data0; _pdp_histo_perform(x); } static void pdp_histo_input_0(t_pdp_histo *x, t_symbol *s, t_floatarg f) { int packet = (int)f; /* register */ if (s == gensym("register_ro")){ /* replace if not compatible or we are not interpolating */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_convert_rw(packet, pdp_gensym("image/grey/*")); } if (s == gensym("process")){ pdp_histo_perform(x); } } static void pdp_histo_samplesize(t_pdp_histo *x, t_floatarg f) { int i = (int)f; if (i >= x->x_nb_clusters ) x->x_sample_size = i; } static void pdp_histo_clusters(t_pdp_histo *x, t_floatarg f) { int i = (int)f; if (i>=2 && i<= x->x_sample_size){ x->x_nb_clusters = i; if (x->x_cluster) pdp_dealloc(x->x_cluster); x->x_cluster = 0; } } static void pdp_histo_scale(t_pdp_histo *x, t_floatarg f){x->x_scale = f;} static void pdp_histo_size(t_pdp_histo *x, t_floatarg f) { int i = (int)f; if (i < 1) return; x->x_logN = round_up_2log(i); } static void pdp_histo_array(t_pdp_histo *x, t_symbol *s) { //post("setting symbol %x", s); x->x_array_sym = s; } static void pdp_histo_free(t_pdp_histo *x) { pdp_packet_mark_unused(x->x_packet0); if (x->x_cluster) pdp_dealloc(x->x_cluster); } t_class *pdp_histo_class; void *pdp_histo_new(t_floatarg f) { t_pdp_histo *x = (t_pdp_histo *)pd_new(pdp_histo_class); if (f == 0.0f) f = 64; pdp_histo_size(x, f); x->x_packet0 = -1; x->x_debug = 0; x->x_sample_size = 16; x->x_nb_clusters = 3; x->x_cluster = 0; return (void *)x; } void *pdp_histo_array_new(t_symbol *s, t_float f, t_float f2) { t_pdp_histo *x = (t_pdp_histo *)pdp_histo_new(f); if (f2 == 0.0f) f2 = 1.0f; pdp_histo_scale(x, f2); pdp_histo_array(x, s); x->x_process_method = dump_to_array; return (void *)x; } void *pdp_histo_sample_new(t_float nbsamples, t_float histosize) { t_pdp_histo *x; if (histosize == 0.0f) histosize = 256.0f; x = (t_pdp_histo *)pdp_histo_new(histosize); if (nbsamples == 0.0f) nbsamples = 16.0f; pdp_histo_samplesize(x, nbsamples); x->x_process_method = get_brightest; x->x_outlet0 = outlet_new(&x->x_obj, gensym("anything")); //x->x_outlet1 = outlet_new(&x->x_obj, gensym("anything")); inlet_new((t_object *)x, (t_pd *)&x->x_obj, gensym("float"), gensym("nbpoints")); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_histo_setup(void) { pdp_histo_class = class_new(gensym("pdp_histo"), (t_newmethod)pdp_histo_array_new, (t_method)pdp_histo_free, sizeof(t_pdp_histo), 0, A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addcreator((t_newmethod)pdp_histo_sample_new, gensym("pdp_pointcloud"), A_DEFFLOAT, A_DEFFLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_size, gensym("size"), A_FLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_size, gensym("scale"), A_FLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_array, gensym("array"), A_SYMBOL, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_samplesize, gensym("nbpoints"), A_FLOAT, A_NULL); class_addmethod(pdp_histo_class, (t_method)pdp_histo_clusters, gensym("nbclusters"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/matrix_basic/pdp_mat_lu.c000066400000000000000000000067071266045153600227150ustar00rootroot00000000000000/* * Pure Data Packet module. LU decomposition module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ //#include //#include //#include //#include #include "pdp.h" #include "pdp_base.h" typedef struct pdp_mat_LU_struct { t_pdp_base x_base; } t_pdp_mat_LU; static void pdp_mat_LU_process_LU_inverse(t_pdp_mat_LU *x) { int p = pdp_base_get_packet(x, 0); int p_LU = pdp_packet_matrix_LU_to_inverse(p); pdp_base_set_packet(x, 0, p_LU); // replace packet } static void pdp_mat_LU_process_LU(t_pdp_mat_LU *x) { int p = pdp_base_get_packet(x, 0); int p_LU = pdp_packet_matrix_LU(p); pdp_base_set_packet(x, 0, p_LU); // replace packet } static void pdp_mat_LU_process_LU_solve(t_pdp_mat_LU *x) { int p0 = pdp_base_get_packet(x, 0); int p1 = pdp_base_get_packet(x, 1); int pvr, pm, pv; /* determine which is vector and which is matrix */ if (pdp_packet_matrix_ismatrix(p0) && pdp_packet_matrix_isvector(p1)){ pm = p0; pv = p1; } else { pm = p1; pv = p0; } /* create the result vector */ pvr = pdp_packet_matrix_LU_solve(pm, pv); /* replace the active packet */ pdp_base_set_packet(x, 0, pvr); } static void pdp_mat_LU_free(t_pdp_mat_LU *x) { /* remove process method from queue before deleting data */ pdp_base_free(x); } t_class *pdp_mat_LU_class; /* common new methods */ t_pdp_mat_LU *pdp_mat_LU_base_new(void) { t_pdp_mat_LU *x = (t_pdp_mat_LU *)pd_new(pdp_mat_LU_class); pdp_base_init(x); pdp_base_add_pdp_outlet(x); return x; } void *pdp_mat_LU_inverse_new(void) { t_pdp_mat_LU *x = pdp_mat_LU_base_new(); pdp_base_set_process_method(x,(t_pdp_method)pdp_mat_LU_process_LU_inverse); pdp_base_readonly_active_inlet(x); return (void *)x; } void *pdp_mat_LU_new(void) { t_pdp_mat_LU *x = pdp_mat_LU_base_new(); pdp_base_set_process_method(x,(t_pdp_method)pdp_mat_LU_process_LU); pdp_base_readonly_active_inlet(x); return (void *)x; } void *pdp_mat_LU_solve_new(void) { t_pdp_mat_LU *x = pdp_mat_LU_base_new(); pdp_base_set_process_method(x,(t_pdp_method)pdp_mat_LU_process_LU_solve); pdp_base_readonly_active_inlet(x); pdp_base_add_pdp_inlet(x); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_mat_lu_setup(void) { pdp_mat_LU_class = class_new(gensym("pdp_m_LU_inverse"), (t_newmethod)pdp_mat_LU_inverse_new, (t_method)pdp_mat_LU_free, sizeof(t_pdp_mat_LU), 0, A_NULL); pdp_base_setup(pdp_mat_LU_class); class_addcreator((t_newmethod)pdp_mat_LU_new, gensym("pdp_m_LU"), A_NULL); class_addcreator((t_newmethod)pdp_mat_LU_solve_new, gensym("pdp_m_LU_solve"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/matrix_basic/pdp_mat_mul.c000066400000000000000000000173461266045153600230730ustar00rootroot00000000000000/* * Pure Data Packet module. Matrix multiplication module * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ //#include //#include //#include //#include #include "pdp.h" #include "pdp_base.h" typedef struct pdp_mat_mm_struct { t_pdp_base x_base; CBLAS_TRANSPOSE_t x_T0; CBLAS_TRANSPOSE_t x_T1; int x_M0; int x_M1; float x_scale_r; float x_scale_i; } t_pdp_mat_mm; static void pdp_mat_mm_rscale(t_pdp_mat_mm *x, t_floatarg r) { x->x_scale_r = r; x->x_scale_i = 0.0f; } static void pdp_mat_mm_cscale(t_pdp_mat_mm *x, t_floatarg r, t_floatarg i) { x->x_scale_r = r; x->x_scale_i = i; } /* matrix multilpy */ static void pdp_mat_mv_process_mul(t_pdp_mat_mm *x) { int pA = pdp_base_get_packet(x, 0); int pB = pdp_base_get_packet(x, 1); int p0, p1, pR; /* determine which one is the vector */ if (pdp_packet_matrix_isvector(pA)){ p0 = pB; p1 = pA; } else { p1 = pB; p0 = pA; } pR = pdp_packet_new_matrix_product_result(x->x_T0, CblasNoTrans, p0, p1); if (-1 != pR){ pdp_packet_matrix_setzero(pR); if (pdp_packet_matrix_blas_mv(x->x_T0, p0, p1, pR, x->x_scale_r, x->x_scale_i)){ //post("pdp_packet_matrix_blas_mm failed"); pdp_packet_mark_unused(pR); pR = -1; } } else { //post("pdp_packet_new_matrix_product_result failed"); } /* replace with result */ pdp_base_set_packet(x, 0, pR); } /* matrix vector multilpy */ static void pdp_mat_mm_process_mul(t_pdp_mat_mm *x) { int pA = pdp_base_get_packet(x, 0); int pB = pdp_base_get_packet(x, 1); int p0, p1, pR; p0 = (x->x_M0) ? pB : pA; p1 = (x->x_M1) ? pB : pA; pR = pdp_packet_new_matrix_product_result(x->x_T0, x->x_T1, p0, p1); if (-1 != pR){ pdp_packet_matrix_setzero(pR); if (pdp_packet_matrix_blas_mm(x->x_T0, x->x_T1, p0, p1, pR, x->x_scale_r, x->x_scale_i)){ //post("pdp_packet_matrix_blas_mm failed"); pdp_packet_mark_unused(pR); pR = -1; } } else { //post("pdp_packet_new_matrix_product_result failed"); } /* replace with result */ pdp_base_set_packet(x, 0, pR); } /* matrix macc */ static void pdp_mat_mm_process_mac(t_pdp_mat_mm *x) { int pC = pdp_base_get_packet(x, 0); int pA = pdp_base_get_packet(x, 1); int pB = pdp_base_get_packet(x, 2); int p0, p1; p0 = (x->x_M0) ? pB : pA; p1 = (x->x_M1) ? pB : pA; if (pdp_packet_matrix_blas_mm(x->x_T0, x->x_T1, p0, p1, pC, x->x_scale_r, x->x_scale_i)){ //post("pdp_packet_matrix_blas_mm failed"); pdp_base_set_packet(x, 0, -1); // delete packet } } static void pdp_mat_mm_free(t_pdp_mat_mm *x) { /* remove process method from queue before deleting data */ pdp_base_free(x); } t_class *pdp_mat_mm_class; /* common new method */ void *pdp_mat_mm_new(void) { int i; t_pdp_mat_mm *x = (t_pdp_mat_mm *)pd_new(pdp_mat_mm_class); /* super init */ pdp_base_init(x); /* outlet */ pdp_base_add_pdp_outlet(x); return (void *)x; } static int pdp_mat_mm_setup_routing_M0(t_pdp_mat_mm *x, t_symbol *s0) { if ('A' == s0->s_name[0]){x->x_M0 = 0;} else if ('B' == s0->s_name[0]) {x->x_M0 = 1;} else return 0; if ((gensym("A") == s0) || (gensym("B") == s0)) x->x_T0 = CblasNoTrans; else if ((gensym("A^T") == s0) || (gensym("B^T") == s0)) x->x_T0 = CblasConjTrans; else if ((gensym("A^H") == s0) || (gensym("B^H") == s0)) x->x_T0 = CblasConjTrans; else return 0; return 1; } static int pdp_mat_mm_setup_routing_M1(t_pdp_mat_mm *x, t_symbol *s1) { if ('A' == s1->s_name[0]){x->x_M1 = 0;} else if ('B' == s1->s_name[0]) {x->x_M1 = 1;} else return 0; /* setup second matrix transpose operation */ if ((gensym("A") == s1) || (gensym("B") == s1)) x->x_T1 = CblasNoTrans; else if ((gensym("A^T") == s1) || (gensym("B^T") == s1)) x->x_T1 = CblasConjTrans; else if ((gensym("A^H") == s1) || (gensym("B^H") == s1)) x->x_T1 = CblasConjTrans; else return 0; return 1; } static int pdp_mat_mm_setup_scaling(t_pdp_mat_mm *x, t_symbol *scale) { int success = 1; /* setup scaling inlet */ if ((gensym ("rscale") == scale) || (gensym("r") == scale)){ pdp_base_add_gen_inlet(x, gensym("float"), gensym("rscale")); } else if ((gensym ("cscale") == scale) || (gensym("c") == scale)){ pdp_base_add_gen_inlet(x, gensym("list"), gensym("cscale")); } else if (gensym ("") != scale) success = 0; return success; } void *pdp_mat_mm_new_mul_common(t_symbol *s0, t_symbol *s1, t_symbol *scale, int ein) { t_pdp_mat_mm *x = pdp_mat_mm_new(); /* add extra pdp inlets */ while (ein--) pdp_base_add_pdp_inlet(x); /* setup routing */ if (!pdp_mat_mm_setup_routing_M0(x, s0)) goto error; if (!pdp_mat_mm_setup_routing_M1(x, s1)) goto error; if (!pdp_mat_mm_setup_scaling(x, scale)) goto error; /* default scale = 1 */ pdp_mat_mm_cscale(x, 1.0f, 0.0f); return (void *)x; error: pd_free((void *)x); return 0; } void *pdp_mat_mv_new_mul_common(t_symbol *s0, t_symbol *scale, int ein) { t_pdp_mat_mm *x = pdp_mat_mm_new(); /* add extra pdp inlets */ while (ein--) pdp_base_add_pdp_inlet(x); /* setup routing */ if (!pdp_mat_mm_setup_routing_M0(x, s0)) goto error; if (!pdp_mat_mm_setup_scaling(x, scale)) goto error; /* default scale = 1 */ pdp_mat_mm_cscale(x, 1.0f, 0.0f); return (void *)x; error: pd_free((void *)x); return 0; } void *pdp_mat_mm_new_mul(t_symbol *s0, t_symbol *s1, t_symbol *scale) { t_pdp_mat_mm *x = pdp_mat_mm_new_mul_common(s0, s1, scale, 1); if(x){ pdp_base_set_process_method(x, (t_pdp_method)pdp_mat_mm_process_mul); pdp_base_readonly_active_inlet(x); } return x; } void *pdp_mat_mv_new_mul(t_symbol *s0, t_symbol *scale) { t_pdp_mat_mm *x = pdp_mat_mv_new_mul_common(s0, scale, 1); if(x){ pdp_base_set_process_method(x, (t_pdp_method)pdp_mat_mv_process_mul); pdp_base_readonly_active_inlet(x); } return x; } void *pdp_mat_mm_new_mac(t_symbol *s0, t_symbol *s1, t_symbol *scale) { t_pdp_mat_mm *x = pdp_mat_mm_new_mul_common(s0, s1, scale, 2); if (x){ pdp_base_set_process_method(x, (t_pdp_method)pdp_mat_mm_process_mac); } return x; } #ifdef __cplusplus extern "C" { #endif void pdp_mat_mul_setup(void) { pdp_mat_mm_class = class_new(gensym("pdp_m_mm"), (t_newmethod)pdp_mat_mm_new_mul, (t_method)pdp_mat_mm_free, sizeof(t_pdp_mat_mm), 0, A_SYMBOL, A_SYMBOL, A_DEFSYMBOL, A_NULL); pdp_base_setup(pdp_mat_mm_class); class_addcreator((t_newmethod)pdp_mat_mm_new_mac, gensym("pdp_m_+=mm"), A_SYMBOL, A_SYMBOL, A_DEFSYMBOL, A_NULL); class_addcreator((t_newmethod)pdp_mat_mv_new_mul, gensym("pdp_m_mv"), A_SYMBOL, A_DEFSYMBOL, A_NULL); class_addmethod(pdp_mat_mm_class, (t_method)pdp_mat_mm_rscale, gensym("rscale"), A_FLOAT, A_NULL); class_addmethod(pdp_mat_mm_class, (t_method)pdp_mat_mm_cscale, gensym("cscale"), A_FLOAT, A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/matrix_basic/pdp_mat_vec.c000066400000000000000000000130501266045153600230370ustar00rootroot00000000000000/* * Pure Data Packet module. Vector modules. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ //#include //#include //#include //#include #include "pdp.h" #include "pdp_base.h" typedef struct pdp_mat_vec_struct { t_pdp_base x_base; int x_type; t_outlet *x_out; int x_accept_list; int x_list_size; t_atom *x_list; } t_pdp_mat_vec; #define GETFLOAT(x) ((x)->a_type == A_FLOAT ? (x)->a_w.w_float : 0.0f) #define GETDOUBLE(x) (double)GETFLOAT(x) static void pdp_mat_vec_list_in(t_pdp_mat_vec *x, t_symbol __attribute__((unused)) *s, int argc, t_atom *argv) { int i; int vp = -1; int f; int dim = argc; if (!x->x_accept_list) return; //check if this handler is enabled if (!argc) return; //reject empty list switch(x->x_type){ case PDP_MATRIX_TYPE_CFLOAT: if (argc & 1) return; //reject odd nb elements dim >>= 1; //halve dimension case PDP_MATRIX_TYPE_RFLOAT: vp = pdp_packet_new_matrix(dim, 1, x->x_type); if (-1 != vp){ float *data = (float *)pdp_packet_data(vp); for (i=0; i>= 1; //halve dimension case PDP_MATRIX_TYPE_RDOUBLE: vp = pdp_packet_new_matrix(dim, 1, x->x_type); if (-1 != vp){ double *data = (double *)pdp_packet_data(vp); for (i=0; isize; if ((type == PDP_MATRIX_TYPE_CFLOAT) || (type == PDP_MATRIX_TYPE_CDOUBLE)) outlist_size <<= 1; /* realloc list if necessary */ if (outlist_size > x->x_list_size){ free(x->x_list); x->x_list = (t_atom *)pdp_alloc(sizeof(t_atom) * outlist_size); x->x_list_size = outlist_size; } /* copy data */ switch(type){ case PDP_MATRIX_TYPE_RFLOAT: case PDP_MATRIX_TYPE_CFLOAT: fdata = (float *)pdp_packet_data(p); for (i=0; ix_list[i], fdata[i]); break; case PDP_MATRIX_TYPE_RDOUBLE: case PDP_MATRIX_TYPE_CDOUBLE: ddata = (double *)pdp_packet_data(p); for (i=0; ix_list[i], (float)ddata[i]); break; } /* dispose of vector packet and output list */ pdp_packet_mark_unused(p); outlet_list(x->x_out, &s_list, outlist_size, x->x_list); } static void pdp_mat_vec_free(t_pdp_mat_vec *x) { /* remove process method from queue before deleting data */ pdp_base_free(x); /* delete list */ if (x->x_list) pdp_dealloc (x->x_list); } t_class *pdp_mat_vec_class; /* common new methods */ t_pdp_mat_vec *pdp_mat_vec_base_new(void) { t_pdp_mat_vec *x = (t_pdp_mat_vec *)pd_new(pdp_mat_vec_class); pdp_base_init(x); x->x_type = PDP_MATRIX_TYPE_CFLOAT; x->x_accept_list = 0; x->x_list_size = 0; x->x_list = 0; return x; } void *pdp_mat_vec_list2vec_new(t_symbol *type) { t_pdp_mat_vec *x = pdp_mat_vec_base_new(); pdp_base_disable_active_inlet(x); pdp_base_add_pdp_outlet(x); x->x_accept_list = 1; if ((gensym ("") == type) || (gensym ("double/real") == type)) x->x_type = PDP_MATRIX_TYPE_RDOUBLE; else if (gensym ("double/complex") == type) x->x_type = PDP_MATRIX_TYPE_CDOUBLE; else if (gensym ("float/real") == type) x->x_type = PDP_MATRIX_TYPE_RFLOAT; else if (gensym ("float/complex") == type) x->x_type = PDP_MATRIX_TYPE_CFLOAT; else { pd_free((t_pd *)x); x = 0; } return (void *)x; } void *pdp_mat_vec_vec2list_new(t_symbol __attribute__((unused)) *type) { t_pdp_mat_vec *x = pdp_mat_vec_base_new(); x->x_out = outlet_new((t_object *)x, &s_anything); pdp_base_set_postproc_method(x,(t_pdp_method)pdp_mat_vec_list_out); pdp_base_readonly_active_inlet(x); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_mat_vec_setup(void) { pdp_mat_vec_class = class_new(gensym("pdp_m_list2vec"), (t_newmethod)pdp_mat_vec_list2vec_new, (t_method)pdp_mat_vec_free, sizeof(t_pdp_mat_vec), 0, A_DEFSYMBOL, A_NULL); pdp_base_setup(pdp_mat_vec_class); class_addcreator((t_newmethod)pdp_mat_vec_vec2list_new, gensym("pdp_m_vec2list"), A_NULL); class_addlist(pdp_mat_vec_class, (t_method)pdp_mat_vec_list_in); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/modules/test/000077500000000000000000000000001266045153600167255ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/modules/test/Makefile000066400000000000000000000002571266045153600203710ustar00rootroot00000000000000#current: all_modules current: clean include ../../Makefile.config all_modules: pdp_forthtest.o # build test modules # all_modules: $(PDP_MOD) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/modules/test/README000066400000000000000000000000461266045153600176050ustar00rootroot00000000000000This directory contains test modules. pdp-0.14.1+darcs20180201/modules/test/pdp_dpd_test.c000066400000000000000000000052671266045153600215540ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #if 0 // Does not compile #include "pdp.h" #include "pdp_dpd_base.h" typedef struct pdp_dpd_test_struct { t_pdp_dpd_base x_base; } t_pdp_dpd_test; /* outlet methods */ static void pdp_dpd_test_1(t_pdp_dpd_test *x){post("%x: one", x);} static void pdp_dpd_test_2(t_pdp_dpd_test *x){post("%x: two", x);} static void pdp_dpd_test_3(t_pdp_dpd_test *x){post("%x: three", x);} static void pdp_dpd_test_cleanup(t_pdp_dpd_test *x){post("%x: cleanup", x);} static void pdp_dpd_test_inspect(t_pdp_dpd_test *x){post("%x: inspect", x);} static void pdp_dpd_test_bang(t_pdp_dpd_test *x) { /* store a dummy packet */ pdp_dpd_base_set_context_packet(x, pdp_packet_new(PDP_IMAGE, 4096)); /* bang base */ pdp_dpd_base_bang(x); } static void pdp_dpd_test_free(t_pdp_dpd_test *x) { pdp_dpd_base_free(x); } t_class *pdp_dpd_test_class; void *pdp_dpd_test_new(void) { /* allocate */ t_pdp_dpd_test *x = (t_pdp_dpd_test *)pd_new(pdp_dpd_test_class); /* init super: this is mandatory */ pdp_dpd_base_init(x); /* set the dpd processing methods & outlets */ pdp_dpd_base_add_outlet(x, (t_pdp_method)pdp_dpd_test_1); pdp_dpd_base_add_outlet(x, (t_pdp_method)pdp_dpd_test_2); pdp_dpd_base_add_outlet(x, (t_pdp_method)pdp_dpd_test_3); pdp_dpd_base_add_cleanup(x, (t_pdp_method)pdp_dpd_test_cleanup); pdp_dpd_base_add_inspector(x, (t_pdp_method)pdp_dpd_test_inspect); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_dpd_test_setup(void) { /* create a standard pd class */ pdp_dpd_test_class = class_new(gensym("pdp_dpd_test"), (t_newmethod)pdp_dpd_test_new, (t_method)pdp_dpd_test_free, sizeof(t_pdp_dpd_test), 0, A_NULL); /* inherit pdp base class methods */ pdp_dpd_base_setup(pdp_dpd_test_class); /* add bang method */ class_addbang(pdp_dpd_test_class, pdp_dpd_test_bang); } #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/opengl/000077500000000000000000000000001266045153600155625ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/Makefile000066400000000000000000000032301266045153600172200ustar00rootroot00000000000000include Makefile.config all: $(TARGET) linux_gcc_mmx: linux linux: pdp_opengl.pd_linux darwin: pdp_opengl.pd_darwin subdirs: make -C system make -C modules make -C include clean: make -C system clean make -C modules clean make -C include clean rm -f pdp_opengl.pd_linux rm -f *~ # 3DP depends on glut for old drawing routines like "3dp_draw torus" LDFLAGS_3DP := $(LDFLAGS) -lglut pdp_opengl.pd_linux: subdirs rm -f pdp_opengl.pd_linux $(CC) -rdynamic -shared -o pdp_opengl.pd_linux modules/*.o system/*.o $(LDFLAGS_3DP) -g pdp_opengl.pd_darwin: subdirs rm -f pdp_opengl.pd_linux $(CC) $(LDFLAGS_3DP) -o pdp_opengl.pd_darwin ../modules/*/*.o ../system/pdp.o ../system/*/*.o ../puredata/*.o modules/*.o system/*.o $(PDP_LIBS) -bundle -undefined dynamic_lookup -bundle_loader $(PD_EXECUTABLE) # $(CC) -o pdp_opengl.pd_pd_darwin modules/*.o system/*.o $(LDFLAGS) -g -dynamic -bundle -flat_namespace -undefined suppress # $(CC) -o pdp_opengl.pd_pd_darwin modules/*.o system/*.o $(LDFLAGS) -g -bundle -bundle_loader $(PD_EXECUTABLE) install: all test -d $(prefix)/lib/pd #check if pd is installed. if this fails make install will stop here. install -d $(prefix)/lib/pd/extra install -m 755 $(PDP_OPENGL_LIBRARY_NAME) $(prefix)/lib/pd/extra install -m 644 abstractions/*.pd $(prefix)/lib/pd/extra install -m 644 doc/objects/*.pd $(prefix)/lib/pd/doc/5.reference install -m 755 -d $(prefix)/lib/pd/doc/pdp install -m 755 -d $(prefix)/lib/pd/doc/pdp/introduction install -m 755 -d $(prefix)/lib/pd/doc/pdp/examples_opengl install -m 644 doc/reference_opengl.txt $(prefix)/lib/pd/doc/pdp install -m 644 doc/examples/*.pd $(prefix)/lib/pd/doc/pdp/examples_opengl pdp-0.14.1+darcs20180201/opengl/Makefile.config000066400000000000000000000035041266045153600204700ustar00rootroot00000000000000# if configure can't find the m_pd.h header # specify pd's include path here and ignore the warning # #PD_CPPFLAGS=-I/path_to_pd_dir/src #PD_EXECUTABLE=/path_to_pd_dir/bin/pd PD_CPPFLAGS= PD_EXECUTABLE= PDP_CFLAGS=-DPD -Wall -W -Wstrict-prototypes -Wno-unused -Wno-parentheses -Wno-switch -fPIC -O2 -funroll-loops -fomit-frame-pointer -ffast-math -mmmx # these are reused in opengl module prefix=/usr/local PDP_VERSION=0.14.1 PDP_TARGET=linux_gcc_mmx PDP_LIBRARY_NAME = pdp.pd_linux PDP_EXTRA_CPPFLAGS = PDP_EXTRA_CFLAGS = SDL_FLAGS = -D_REENTRANT # optional objects PDP_OPTMOD = pdp_v4l.o pdp_xv.o pdp_qt.o pdp_glx.o pdp_sdl.o PDP_X11MOD = @PDP_X11MOD@ PDP_PDMOD = PDP_OPTTYPES = pdp_matrix.o PDP_MATRIX_BASIC = pdp_mat_mul.o pdp_mat_lu.o pdp_mat_vec.o PDP_IMAGE_BASIC = pdp_cheby.o PDP_IMAGE_SPECIAL = pdp_histo.o ZL_OPTMOD = v4l.o xwindow.o xv.o glx.o PDP_CPPFLAGS = -I. -I../../system -I/usr/X11R6/include -I../include -I../../include $(PD_CPPFLAGS) $(PDP_EXTRA_CPPFLAGS) -DPDP_TARGET=$(PDP_TARGET) PDP_LIBS = -lgslcblas -lm -lv4l2 -lgsl -lgslcblas -lm -lz -lpng -L/usr/X11R6/lib -lX11 -lXv -lXext -lquicktime -lGL -lGLU -lSDL PDP_AFLAGS = #--gstabs PDP_CFLAGS += $(SDL_CFLAGS) $(PDP_EXTRA_CFLAGS) -DPDP_VERSION=\"$(PDP_VERSION)\" ifeq ($(shell uname -s),Darwin) PDP_CFLAGS += -fnested-functions endif #PDP_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ # -Wall -W -Wstrict-prototypes \ # -Wno-unused -Wno-parentheses -Wno-switch -DPDP_VERSION=\"$(PDP_VERSION)\" \ # -g $(SDL_CFLAGS) $(PDP_EXTRA_CFLAGS) # -Werror # -Wshadow # compiler and assembler #CC = gcc-3.2 #CC = gcc #AS = as CC = gcc # build rules .c.o: $(CC) $(PDP_CFLAGS) $(PDP_CPPFLAGS) -o $*.o -c $*.c .s.o: $(AS) -o $*.o $*.s $(PDP_AFLAGS) PDP_OPENGL_LIBRARY_NAME=pdp_opengl.pd_linux_gcc_mmx TARGET=linux_gcc_mmx pdp-0.14.1+darcs20180201/opengl/README000066400000000000000000000255261266045153600164540ustar00rootroot00000000000000pdp_opengl (3dp): opengl extensions for pdp warning: this is still experimental and incomplete this library extends pdp with texture and render context packets, to use some of the power of current video hardware. it is very much like gem (sort of a redesign, filled with my own idiosyncrasies). gem, like it is now, is not very suited for interaction with pdp image processing because of its hardcoded window centric rendering, so i thought i'd write some gem like stuff on top of pdp myself. (3dp right now only supports window centric rendering itself, but adding pbuffer or pixmap rendering is easy enough, though it requires a rather new glx library) so, 3dp is an experimental gem clone with tight pdp integration. unless you like experiments, use gem, since it is better supported, has more features and runs on linux, windows and mac osx. requires glx (opengl on x window). building: edit Makefile.config to reflect your system and run make. the library is pdp_opengl.pd_linux some of the examples use the abstractions in opengl/abstractions. best to add this to your pd path. there are some fatal X bugs floating around, so be careful with resizing windows and closing patches. there are a lot of other, non-fatal bugs or badly implemented features. if you have remarks, just let me know. i'll move to autoconf once i no longer consider it experimental. TIPS & TRICKS * the 3dp_windowcontext creates a window to draw in. the window packet will be be output to the left outlet when a bang is received. control flow for context is right to left, this means if a 3dp object has 2 context outlets, the rightmost will be propagated before the leftmost. there is no fanout. all operations are accumulative, including the geometric transformations. if you need to branch use a 3dp_push object. * geometric transformations can be done using the 3dp_view object. the first argument is the kind of transformation: scale, scalex, scaley, scalez, rotx, roty, rotz, rota, transx, transy, transz, transxyz. repectively this scales the object, the x, y, z axis, rotates around the x, y, z axis, rotates around an arbitrary axis, translates in the x, y, z directions and translates along a vector. the initial parameters can be specified as creation arguments, i.e.: [3dp_view rota 1 1 1 90] rotates by 90 degrees around axis (1,1,1). * some simple objects can be drawn using the pdp_draw object. the first argument is the object: square, cube, sphere, torus, cone, teapot, dodeca, icosa, octa, tetra. prepending the names with a w draws the wireframe version. (i.e. wcube is a wireframe cube). the first inlet of the object is a texture inlet. not all objects support this, but cube, square and sphere do. other inlets set some parameters like size, nb of segments for sphere, etc.. they can be specified by creation arguments too. * saving a (matrix) state can be accomplished by the 3dp_push object. the default matrix is the modelview matrix. it works as follows: both the right and the left outlet propagate the same matrix state as the input. so in short you can use 3dp_push to split your rendering tree into parallel branches. the matrix types that can be pushed are: modelview, texture, color, projection. * setting a current matrix can be done using the 3dp_mode object. i.e. [3dp_mode texture] will map all geometric transforms to the texture matrix, for texture coordinate animation. the left outlet restores the current matrix back to the modelview matrix. * it is possible to send a render context trough a drawing/view transforming object multiple times. the easy way is to use 3dp_for, but other ways are legal too. this can be done to draw different versions of the same object. have a look at example01 how this can be done. it is also possible to send multiple render contexts trought the same rendering tree (i.e. multiple windows). if you use different viewing transformations on the top of the rendering chain, you can view a scene trough different angles. * light sources can be introduces using 3dp_light. they can be moved with oridinary 3dp_view objects. * 3dp_color changes the current color. right outlet is new color, left outlet is the previous color. * 3dp_toggle toggles a boolean opengl switch. enabled now are: depth_test, blend_add, blend_mix. more to come later. * couping 3dp and pdp can be done using 3dp_snap and pdp_convert. the correct way to do it is to put 3dp_snap in a rendering chain and give it arguments like this: [3dp_snap image/*/* 320 240] if you specify the subtype to be image/multi/*, the packet will not be colour space converted: it will stay rgb. if you want to make a snapshot to store as a high quality png image, snap to bitmap/rgb/* and store it in pdp_reg to save. to convert an image back to a texture, use [pdp_convert texture/*/*] if you snap to a texture (which is the default) the dimensions don't need to be specified. a texture will be allocated that can contain the entire screen. this is because texture coordinates are relative and data is always interpolated. snapping only works correctly when the window is not covered by other windows. * textures can have any dimensions, but only those which have dimensions that are integral powers of two will be tiled correctly. i.e. by using pdp_mode to change to texture mode and doing some coordinate transforms using pdp_view (see example06: this uses a tilable animated cellular automata texture) * multipass rendering is supported trough the objects 3dp_subcontext, "3dp_draw clear" and "3dp_view reset". the idea is as follows: before rendering the final scene, you use (a part of) the drawing buffer to render some things and store them in a texture to be used in your final drawing pass. have a look at examples 11, 12 and 13. in theory you could build a "texture processing" framework on top of 3dp, by using the window buffer as an accumulator and using textures as auxilary registers, and drawing your final texture result using i.e. 3dp_display_texture. while this can be much faster than ordinary pdp image processing, it also requires you to do more bookkeping yourself, since you can only use a "serial" approach because you can't modify textures directly, only trough the use of the render buffer. * 3dp has it's own thread, which is enabled by default. you can enable/disable this by sending a "3dthread 0/1" message to pdp_control. in most cases there's no reason to disable the thread processing, except when you are doing a lot of pdp<->3dp conversions. in that case the delay introduced by the thread processing might become problematic. (the same goes for pdp btw. feedback and threads don't mix too well). it's a tradeoff. thread processing gives priority to the audio, so you can obtain low latency, and you don't have to care about locking up pd by doing too much processing. (instead frames will be dropped). the drawback is of course that video timing becomes unpredictable because it is governed by the system scheduler. so sometimes it can be useful to disable threads and increase the audio latency, so you can have snappy audio and video at the same time. getting this to work well usually requires some experimenting. * if you have an nvidia card, you can set the environment variable __GL_SYNC_TO_VBLANK to 1 to prevent tearing, until 3dp has default support for it. i.e.: export __GL_SYNC_TO_VBLANK=1 enjoy, tom --- some political ranting: gem vs. pdp/3dp first a disclaimer. i'm not into dissing people. i respect and appreciate all the work that has gone into gem, but at the same time i'm not too happy with what gem has become. not so much the functionality, but the way it is built. the original design as a 3d processing extension is not flexible enough to incorporate what's in there now and what could be added in the future.. instead of complaining about it, i decided to be pragmatic and write something from scratch. i think, sometimes this has to be done. for me writing pdp/3dp has been an extremely interesting learning experience. i think i understand the trade-offs better now, and i know now it's not too easy to get it all to work. maybe these remarks can be useful... opengl is not a pure dataflow language. it operates on a global machine state next to the obvious drawing buffer that is passed around. representing opengl code with a graphic tree view has some advantages, though it has a different "feel" than normal pd patches. the fact that opengl transforms object coordinates to screen coordinates, and not vice versa, gives graphicly represented opengl code an "upside down" feel. one of the things i don't like about gem is that it has both the opengl "upside down drawing and coordinate transformation tree" and the pix "data flow image processing tree" in the same network, which i find counterintuitive. it is too monolytic to be truly flexible. in pdp/3dp i try to separate the two explicitly: dataflow where possible (image processing), and serial context based processing where needed (opengl). another disadvantage of gem is its window centric context. by building 3dp around explicit context passing, with explicit context creation objects, i try to avoid this. an advantage of this is the possibility to send multiple contexts trough a rendering tree, i.e. to have 2 different views of the same scene. pdp has implicit fanout for all packets. i think that is its great strength. it enables you to use any kind of media packet like you would use floats. it is very intuitive. however, 3d rendering does not fit this shoe. at least not when you just wrap opengl in the most straightforward way. 3dp is a test case for pdp's "accumulation packets", which is a formal abstraction of a context. pdp processors are nothing more than serial programs working on a context, so in fact it's nothing special. in fact, i'm still in doubt if it is useful besides being able to support opengl.. so, the idea was to improve upon gem a bit, from different angles. i did not succeed in my primary goal: making 3dp more intuitive than gem. it seems this is only possible if you limit some of the flexibility. just wrapping opengl keeps a lot of flexibility, but get's infected with the opengl paradigm. by separating pdp (image processing) and 3dp (drawing and geometry processing) as much as possible i think i've solved some intuition problems, but 3dp itself is still basicly gem, with imho a better overall design, but due to its more low level approach, maybe harder to understand. it seems to me that knowing how opengl works is rather necessary to use 3dp. the same is true for gem. one last philo remark: to me it seems the biggest drawback of gem's design is the processor centric aproach: the only objects are processors, the data is implicit and seemingly global. in pdp/3dp processors and objects are 2 separate entities. i tried to unify them in one object model, but to me it seems the two should really be treated as different complementary entities, to stay close to the dataflow paradigm which makes pd such an intuitive tool. pdp-0.14.1+darcs20180201/opengl/TODO000066400000000000000000000112431266045153600162530ustar00rootroot00000000000000bugs: WARNING: there are still quite a few fatal bugs lurking around. * segfault when combining 3dp_windowcontext and pdp_xv. probably a mistake in the teture<->image conversion or window event handling. * 3dp is not robust against running out of video card resources. if you manage to crash it please consider sending a bug report. * 3dp_dlist triggered a segfault in pdp_mutex(un?)lock. can't reproduce. this also happens on some other occasions where a post() statement is involved: crash in pdp_mutex_lock, called by putc() -> happens in pdp too when calling post from thread (like in pdp_netsend/receive) * pd hangs on save? what happens during save?? -> 0.35 prob? 0.36 seems to work fine. * segfaults when deleting 3dp objects. very unpredictable. todo: * fix flow control for texture conversion * finish mesh object general: * prevent display list recursion: add some state data to the context packet to solve this. redesign: * unify pbuf & window contexts (postponed pbufs because of subcontexts) * cube mapping * bubble object (model + wave equation) * finish 3dp light performance: * why is texture upload so slow? and is there a way to work around it? * (why) is context switching slow? and how to introduce the render context differently. (direct to window?) DESIGN NOTES 3dp is basicly my idea of gem on top of pdp. it is a simple layer around opengl. 3dp_* render and transform objects accept a reference to a rendering context and pass this along. 3dp_* objects DO NOT SUPPORT FANOUT. they do support fanin. multiple contexts can be sent to an object, which will result in drawing in (or other manipulations of) the respective contexts. texture packets can be used to pass bitmap data around. 3dp_tdraw accepts a texture on its second inlet. 3dp_snap dumps the current state of the buffer into a texture packet. object classes: -drawing objects [3dp_draw cube] [3dp_draw sphere] .. -manipulation objects [3dp_view rot2d] -opengl stack objects [3dp_push color view texture] 3dp vs pdp design: a context packet is an accumulation packet, and the order of operations on it (serial) is important. it has elements from a readonly packet (only one instance is passed around) and from a rw packet (it is legal to change it's state and pass it on). opengl in dataflow formulation seems to be read bottom to top. i first thought this was a big drawback of gem, but now that i finally understand how opengl works i think it is ok. it suddenly dawned on me, usually the number of eyes is much smaller than the number of objects in a scene, so it is much more straghtforward to start at the eye instead of the objects. since a simple serial stack mechanism can be used. so opengl is really serial, while pd "looks" parallel, but is serial too. i still think this is a good thing, since it keeps things simple, but for some reason the "upside down & serial" thing about opengl in pd is rather strange.. once you get used to it, and think about rendering a set as a tree rooted at the "context source" like is done in gem,it seems to work out.. i think i'm going to stick to the depth first backtracking a tree serial rendering way of looking at it. since i don't see a way of making this more intuitive without complicating it too much. so no legal fanout of a context packet. ------------------ accumulation packets (buckets) & backtracking buckets add support for "context based" single threaded programs. it basicly allows you to construct data processors represented as a control flow tree. i.e. function calls can be represented by branches in a tree, with each branch rooted at an object's outlet, executed from right to left. a "context packet" (or accumulation packet or bucket) is passed along and acted upon. * fanout is illegal for bucket processors (at least, if they are non cummutative, as is usually the case). this is not explicitly prohibited, since it is hard to check in pd and it allows some hacks. the reason for this is obvious: if you do not know which branch of a tree is executed first, results are undefined. * a new communication protocol needs to be introduced, incompatible with the existing 3 phase protocol: (1) register_ro (2) register_rw (3) process the new dpd (bucket / accumulation packet) protocol is 2 phase: (1) inspect (2) accumulate (1) is only present to give priority to bucket inspectors over accumulators (processors) an accumulation packet will be owned by its creator all the time. accumulation processors do not increase the reference count. only ro inspectors will. note: it is legal for a packet to have a broken register_rw (missing copy constructor, i.e. if a copy is too expensive or impossible. this must be set in the pdp packet header flags by the packet constructor) pdp-0.14.1+darcs20180201/opengl/abstractions/000077500000000000000000000000001266045153600202565ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/abstractions/3dp_basicscene.pd000066400000000000000000000013051266045153600234470ustar00rootroot00000000000000#N canvas 500 522 450 300 10; #X obj 54 72 metro 40; #X obj 54 140 3dp_push; #X floatatom 375 162 5 0 0 0 - - -; #X text 19 12 a basic 3d scene with a light source and mouse view rotation ; #X obj 54 218 outlet; #X obj 54 46 inlet; #X floatatom 340 129 5 0 0 0 - - -; #X floatatom 115 49 5 0 0 0 - - -; #X obj 254 216 3dp_light 0; #X obj 254 158 3dp_view roty; #X obj 254 192 3dp_view transz 10; #X obj 54 169 3dp_mouserotate; #X obj 54 111 3dp_windowcontext; #X connect 0 0 12 0; #X connect 1 0 11 0; #X connect 1 1 9 0; #X connect 2 0 10 1; #X connect 5 0 0 0; #X connect 6 0 9 1; #X connect 7 0 0 1; #X connect 9 0 10 0; #X connect 10 0 8 0; #X connect 11 0 4 0; #X connect 12 0 1 0; #X connect 12 1 11 1; pdp-0.14.1+darcs20180201/opengl/abstractions/3dp_blend.pd000066400000000000000000000007621266045153600224420ustar00rootroot00000000000000#N canvas 554 145 570 225 10; #X obj 25 124 3dp_toggle depth_test 0; #X obj 181 159 3dp_toggle blend_add 1; #X obj 25 90 inlet; #X obj 330 199 outlet; #X text 38 11 use this object for quick and dirty blending effects. it has the depth test disabled and accumulated blending enabled.; #X text 128 60 NOTE: proper transparency is quite hard to do \, because it requires manual depth sorting. there is no real support for this in 3dp yet.; #X connect 0 1 1 0; #X connect 1 1 3 0; #X connect 2 0 0 0; pdp-0.14.1+darcs20180201/opengl/abstractions/3dp_display_texture.pd000066400000000000000000000020041266045153600245720ustar00rootroot00000000000000#N canvas 277 275 874 339 10; #X obj 244 246 3dp_view scale_aspect; #X obj 37 131 inlet; #X obj 222 130 inlet; #X obj 351 131 inlet; #X text 27 107 context inlet; #X text 198 106 texture inlet; #X text 328 106 scaling inlet; #X text 406 244 <- scale the square to the window aspect ratio; #X obj 37 269 outlet; #X text 40 16 this abstraction can be used for texture display. i.e. if you use a subcontext at a fixed resolution to create a texture \, this abstraction stretches the texture to the full size of the window .; #X obj 244 274 3dp_draw square 8; #X obj 244 220 3dp_view scale 1; #X text 405 219 <- extra scaling (i.e. to clip off garbage boundaries) ; #X obj 37 162 3dp_toggle depth_test 0; #X text 404 164 <- disable depth test so the draw will overwrite; #X obj 193 190 3dp_push; #X text 405 193 <- save modelview; #X text 27 295 context outlet; #X connect 0 0 10 0; #X connect 1 0 13 0; #X connect 2 0 10 1; #X connect 3 0 11 1; #X connect 11 0 0 0; #X connect 13 0 8 0; #X connect 13 1 15 0; #X connect 15 1 11 0; pdp-0.14.1+darcs20180201/opengl/abstractions/3dp_fixedsizewindowcontext.pd000066400000000000000000000021401266045153600261750ustar00rootroot00000000000000#N canvas 634 346 592 397 10; #X obj 27 64 inlet; #X obj 27 105 3dp_windowcontext; #X obj 27 138 3dp_subcontext \$1 \$2; #X obj 220 211 outlet; #X obj 370 211 outlet; #X text 350 236 event outlet; #X obj 162 267 3dp_snap; #X obj 27 318 3dp_display_texture; #X text 150 23 a fixed size (window size independent) rendering context that can be used as 3dp_windowcontext replacement.; #X text 151 56 creation arguments are the context dimensions.; #X text 175 87 NOTE: the general subcontext rule applies: if the actual window size is small than the subcontext \, or is covered by other windows \, the results might not be what you expect.; #X text 176 236 context outlet (1); #X text 241 266 <- when the render chain connected to (1) is done; #X text 261 281 it will be snapped to texture; #X text 241 316 <- this texture will then be drawn to cover; #X text 263 332 the entire window size; #X obj 162 177 pdp_t p p; #X obj 184 300 inlet; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 1 1 4 0; #X connect 2 0 7 0; #X connect 2 1 16 0; #X connect 6 1 7 1; #X connect 16 0 6 0; #X connect 16 1 3 0; #X connect 17 0 7 2; pdp-0.14.1+darcs20180201/opengl/abstractions/3dp_mouserotate.pd000066400000000000000000000015051266045153600237210ustar00rootroot00000000000000#N canvas 534 483 533 399 10; #X obj 27 19 inlet; #X obj 27 363 outlet; #X obj 70 152 - 0.5; #X obj 135 151 - 0.5; #X obj 82 214 *; #X obj 135 212 *; #X obj 135 186 t f f; #X obj 82 184 t f f; #X obj 82 243 +; #X obj 113 271 sqrt; #X obj 92 19 inlet; #X obj 113 298 * 360; #X obj 27 329 3dp_view rota; #X text 216 138 convert mouse coordinates to axis and angle; #X obj 70 118 unpack 0 0; #X obj 92 49 route drag1 press1; #X connect 0 0 12 0; #X connect 2 0 7 0; #X connect 2 0 12 2; #X connect 3 0 6 0; #X connect 3 0 12 1; #X connect 4 0 8 0; #X connect 5 0 8 1; #X connect 6 0 5 0; #X connect 6 1 5 1; #X connect 7 0 4 0; #X connect 7 1 4 1; #X connect 8 0 9 0; #X connect 9 0 11 0; #X connect 10 0 15 0; #X connect 11 0 12 4; #X connect 12 0 1 0; #X connect 14 0 2 0; #X connect 14 1 3 0; #X connect 15 0 14 0; #X connect 15 1 14 0; pdp-0.14.1+darcs20180201/opengl/abstractions/3dp_screenshot.pd000066400000000000000000000010611266045153600235240ustar00rootroot00000000000000#N canvas 550 41 714 494 10; #X obj 193 284 pdp_reg; #X obj 193 203 pdp_t b p; #X obj 193 233 symbol \$1; #X msg 193 257 save_png \$1; #X obj 195 110 loadbang; #X msg 195 135 autosnap 0; #X obj 51 111 inlet; #X obj 51 176 3dp_snap bitmap/rgb/*; #X obj 51 285 outlet; #X text 41 22 make a screenshot of a 3dp context. creation argument is filename. send a bang to take a snapshot.; #X connect 1 0 2 0; #X connect 1 1 0 1; #X connect 2 0 3 0; #X connect 3 0 0 0; #X connect 4 0 5 0; #X connect 5 0 7 0; #X connect 6 0 7 0; #X connect 7 0 8 0; #X connect 7 1 1 0; pdp-0.14.1+darcs20180201/opengl/abstractions/elbat.pd000066400000000000000000000017641266045153600217020ustar00rootroot00000000000000#N canvas 431 78 581 572 10; #X obj 23 63 inlet; #X obj 168 211 outlet; #X obj 168 150 tabread \$0-vec; #X msg 15 210 \; \$1 const 0; #X msg 15 159 bang; #X obj 15 183 symbol \$0-vec; #X obj 119 373 until; #X msg 118 270 bang; #X obj 155 414 f 0; #X obj 191 414 + 1; #X msg 163 338 0; #X obj 119 318 t b b; #X obj 156 519 tabwrite \$0-vec; #X obj 155 443 t b f; #X obj 154 478 randomnormal; #X obj 119 348 f \$1; #X obj 23 86 route reset normal; #X text 168 274 fill table with normal distributed random variables ; #X text 19 16 a tabread-like abstraction (with internal table); #X obj 320 108 table \$0-vec \$1; #X connect 0 0 16 0; #X connect 2 0 1 0; #X connect 4 0 5 0; #X connect 5 0 3 0; #X connect 6 0 8 0; #X connect 7 0 11 0; #X connect 8 0 9 0; #X connect 8 0 13 0; #X connect 9 0 8 1; #X connect 10 0 8 1; #X connect 11 0 15 0; #X connect 11 1 10 0; #X connect 13 0 14 0; #X connect 13 1 12 1; #X connect 14 0 12 0; #X connect 15 0 6 0; #X connect 16 0 4 0; #X connect 16 1 7 0; #X connect 16 2 2 0; pdp-0.14.1+darcs20180201/opengl/abstractions/randomnormal.pd000066400000000000000000000015601266045153600232760ustar00rootroot00000000000000#N canvas 614 389 451 505 10; #X obj 48 58 inlet; #X obj 48 88 t b b; #X obj 173 167 * 6.28; #X obj 129 221 cos; #X obj 173 222 sin; #X obj 173 143 / 1e+06; #X obj 173 121 random 1e+06; #X obj 48 220 * -2; #X obj 48 170 / 1e+06; #X obj 48 125 random 1e+06; #X obj 48 148 + 1; #X obj 48 194 log; #X obj 48 327 *; #X obj 108 328 *; #X obj 48 292 t f f; #X obj 48 365 outlet; #X obj 108 365 outlet; #X text 35 10 normal gausian random number generator (box-muller); #X obj 48 253 sqrt; #X connect 0 0 1 0; #X connect 1 0 9 0; #X connect 1 1 6 0; #X connect 2 0 4 0; #X connect 2 0 3 0; #X connect 3 0 12 1; #X connect 4 0 13 1; #X connect 5 0 2 0; #X connect 6 0 5 0; #X connect 7 0 18 0; #X connect 8 0 11 0; #X connect 9 0 10 0; #X connect 10 0 8 0; #X connect 11 0 7 0; #X connect 12 0 15 0; #X connect 13 0 16 0; #X connect 14 0 12 0; #X connect 14 1 13 0; #X connect 18 0 14 0; pdp-0.14.1+darcs20180201/opengl/abstractions/randomwalk2D.pd000066400000000000000000000023541266045153600231340ustar00rootroot00000000000000#N canvas 502 172 600 400 10; #X obj 228 221 tabread \$0-x; #X obj 334 213 tabread \$0-y; #X obj 228 310 tabwrite \$0-x; #X obj 350 330 tabwrite \$0-y; #X obj 244 259 cos; #X obj 350 266 sin; #X obj 351 241 * 0.0628; #X obj 351 185 random 100; #X obj 228 284 +; #X obj 334 291 +; #X obj 228 144 t f b f; #X msg 53 237 \; \$1 const 0; #X obj 20 199 symbol \$0-x; #X obj 108 199 symbol \$0-y; #X msg 88 173 bang; #X obj 228 172 t f f; #X obj 214 337 outlet; #X obj 334 354 outlet; #X obj 156 82 inlet; #X obj 156 106 route reset; #X obj 351 82 table \$0-x \$1; #X obj 351 116 table \$0-y \$1; #X text 37 20 a 2D unit step random walk abstraction for use with 3dp_for ; #X text 335 45 creation argument = nb of vectors; #X text 64 44 inlet = vector to update; #X connect 0 0 8 0; #X connect 1 0 9 0; #X connect 4 0 8 1; #X connect 5 0 9 1; #X connect 6 0 4 0; #X connect 6 0 5 0; #X connect 7 0 6 0; #X connect 8 0 2 0; #X connect 8 0 16 0; #X connect 9 0 3 0; #X connect 9 0 17 0; #X connect 10 0 15 0; #X connect 10 1 7 0; #X connect 10 2 3 1; #X connect 10 2 2 1; #X connect 12 0 11 0; #X connect 13 0 11 0; #X connect 14 0 12 0; #X connect 14 0 13 0; #X connect 15 0 0 0; #X connect 15 1 1 0; #X connect 18 0 19 0; #X connect 19 0 14 0; #X connect 19 1 10 0; pdp-0.14.1+darcs20180201/opengl/abstractions/smoothupdate.pd000066400000000000000000000021371266045153600233220ustar00rootroot00000000000000#N canvas 112 570 450 387 10; #X obj 225 64 inlet; #X text 195 40 element to update; #X obj 23 63 inlet; #X text 39 39 new value; #X obj 55 302 outlet; #X obj 331 173 table \$0-vec; #X obj 168 121 f 0; #X obj 168 150 tabread \$0-vec; #X text 350 41 smooth step; #X obj 354 65 inlet; #X obj 354 90 moses 0; #X obj 366 116 moses 1; #X msg 331 114 0; #X msg 410 140 1; #X obj 135 182 -; #X obj 57 114 t f b; #X obj 332 144 f; #X obj 135 246 +; #X obj 146 282 tabwrite \$0-vec; #X obj 23 86 route reset; #X msg 15 210 \; \$1 const 0; #X msg 15 159 bang; #X obj 15 183 symbol \$0-vec; #X obj 136 215 * 0.1; #X connect 0 0 6 1; #X connect 2 0 19 0; #X connect 6 0 7 0; #X connect 6 0 18 1; #X connect 7 0 14 1; #X connect 7 0 17 1; #X connect 9 0 10 0; #X connect 10 0 12 0; #X connect 10 1 11 0; #X connect 11 0 16 0; #X connect 11 1 13 0; #X connect 12 0 16 0; #X connect 13 0 16 0; #X connect 14 0 23 0; #X connect 15 0 14 0; #X connect 15 1 6 0; #X connect 16 0 23 1; #X connect 17 0 4 0; #X connect 17 0 18 0; #X connect 19 0 21 0; #X connect 19 1 15 0; #X connect 21 0 22 0; #X connect 22 0 20 0; #X connect 23 0 17 0; pdp-0.14.1+darcs20180201/opengl/configure000077500000000000000000000004161266045153600174720ustar00rootroot00000000000000#!/bin/bash # hack: use parent dir's Makefile.config cp ../Makefile.config . TARGET=`cat Makefile.config | grep ^PDP_TARGET | awk -F= '{print $2}'` echo "PDP_OPENGL_LIBRARY_NAME=pdp_opengl.pd_${TARGET}" >> Makefile.config echo "TARGET=${TARGET}" >> Makefile.config pdp-0.14.1+darcs20180201/opengl/doc/000077500000000000000000000000001266045153600163275ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/doc/examples/000077500000000000000000000000001266045153600201455ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/doc/examples/arm.pd000066400000000000000000000017331266045153600212550ustar00rootroot00000000000000#N canvas 475 534 572 380 10; #X obj 43 10 inlet; #X obj 43 227 outlet; #X obj 43 141 3dp_push; #X obj 208 200 3dp_view transx 0.5; #X obj 43 113 3dp_view rotz; #X obj 260 11 inlet; #X obj 208 174 3dp_view scalex \$1; #X obj 43 186 3dp_view transx \$1; #X obj 260 275 r texture; #X obj 43 83 3dp_view roty; #X obj 129 61 r roty; #X obj 329 91 r scale; #X obj 43 37 3dp_draw cube 1; #X obj 143 11 r cubesize; #X obj 208 334 3dp_draw torus 0.25 0.5 6; #X obj 208 256 spigot; #X obj 245 232 r drawtorus; #X obj 276 307 r torusr1; #X obj 353 307 r torusr2; #X text 375 27 draw one arm segment; #X connect 0 0 12 0; #X connect 2 0 7 0; #X connect 2 1 6 0; #X connect 3 0 15 0; #X connect 4 0 2 0; #X connect 5 0 4 1; #X connect 6 0 3 0; #X connect 7 0 1 0; #X connect 8 0 14 1; #X connect 9 0 4 0; #X connect 10 0 9 1; #X connect 11 0 6 1; #X connect 11 0 7 1; #X connect 12 0 9 0; #X connect 13 0 12 2; #X connect 15 0 14 0; #X connect 16 0 15 1; #X connect 17 0 14 2; #X connect 18 0 14 3; pdp-0.14.1+darcs20180201/opengl/doc/examples/example01.pd000066400000000000000000000144321266045153600222720ustar00rootroot00000000000000#N canvas 0 29 681 737 10; #X floatatom 126 37 5 0 0 0 - - -; #X obj 56 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 83 19 stop; #X floatatom 360 431 5 0 0 0 - - -; #X obj 59 103 3dp_push; #X floatatom 672 189 5 0 0 0 - - -; #X obj 546 244 3dp_view transx 3; #X obj 546 270 3dp_light; #X obj 612 97 f; #X floatatom 641 98 5 0 0 0 - - -; #X floatatom 669 370 5 0 0 0 - - -; #X obj 182 491 arm 3; #X obj 182 514 arm 3; #X obj 182 537 arm 3; #X obj 182 467 arm 3; #X floatatom 360 455 5 0 0 0 - - -; #X floatatom 359 478 5 0 0 0 - - -; #X floatatom 358 501 5 0 0 0 - - -; #X floatatom 358 524 5 0 0 0 - - -; #X obj 182 584 arm 3; #X obj 182 607 arm 3; #X obj 182 630 arm 3; #X obj 182 560 arm 3; #X floatatom 358 548 5 0 0 0 - - -; #X floatatom 358 571 5 0 0 0 - - -; #X floatatom 358 594 5 0 0 0 - - -; #X obj 59 224 3dp_view roty; #X obj 284 449 * 1; #X obj 284 589 * -1; #X obj 182 653 arm 3; #X floatatom 358 617 5 0 0 0 - - -; #X obj 284 635 * -1.5; #X obj 663 686 s roty; #X floatatom 615 611 5 0 0 0 - - -; #X floatatom 671 585 5 0 0 0 - - -; #X obj 673 616 s scale; #X floatatom 359 388 5 0 0 0 - - -; #X obj 284 473 * -1.01; #X obj 284 496 * 0.99; #X obj 284 519 * -1.01; #X obj 284 542 * 2.1; #X obj 284 566 * -1.7; #X obj 182 425 3dp_draw cube 1.4; #X obj 182 809 3dp_draw cube 1.4; #X msg 597 536 4; #X obj 59 151 3dp_view transz -3; #X obj 546 216 3dp_view roty 54; #X obj 669 392 s cubesize; #X msg 360 345 3.15; #X msg 126 17 20; #X obj 284 612 * 0.11; #X floatatom 672 220 5 0 0 0 - - -; #X msg 612 72 0; #X obj 342 311 * 1; #X obj 59 201 3dp_view rotx; #X floatatom 164 187 5 0 0 0 - - -; #X floatatom 358 641 5 0 0 0 - - -; #X obj 182 700 arm 3; #X obj 182 724 arm 3; #X obj 182 748 arm 3; #X obj 182 677 arm 3; #X floatatom 359 664 5 0 0 0 - - -; #X floatatom 359 688 5 0 0 0 - - -; #X floatatom 360 712 5 0 0 0 - - -; #X obj 284 706 * -1; #X obj 182 771 arm 3; #X floatatom 360 735 5 0 0 0 - - -; #X obj 283 753 * -1.5; #X obj 284 659 * 2.1; #X obj 284 682 * -1.7; #X obj 283 730 * 0.11; #X obj 9 334 3dp_push; #X obj 182 399 3dp_view transz; #X floatatom 282 369 5 0 0 0 - - -; #X obj 131 371 3dp_view transz; #X obj 231 338 * -1; #X msg 282 341 2; #X obj 564 401 s drawtorus; #X obj 564 374 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 674 496 s torusr1; #X floatatom 672 473 5 0 0 0 - - -; #X floatatom 667 419 5 0 0 0 - - -; #X obj 669 442 s torusr2; #X msg 564 349 1; #X obj 597 645 *; #X obj 59 126 3dp_push; #X obj 9 364 3dp_push; #X obj 9 437 3dp_view rotx; #X floatatom 96 416 5 0 0 0 - - -; #X obj 9 471 3dp_draw sphere 30 40; #X obj 9 593 3dp_snap; #X obj 473 487 / 1000; #X floatatom 473 461 5 0 0 0 - - -; #X obj 430 8 loadbang; #X obj 430 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 59 77 3dp_windowcontext; #X obj 59 274 3dp_push; #X obj 110 303 pdp_t p b; #X obj 9 307 pdp_t p b; #X msg 349 252 400; #X msg 311 252 -400; #X obj 342 287 +; #X msg 473 434 3; #X text 544 189 light source; #X obj 59 248 3dp_view scale 0.4; #X obj 640 157 s counter; #X obj 245 169 r counter; #X text 694 98 speed; #X obj 59 54 metro 20; #X obj 238 207 * 0.05; #X obj 9 570 spigot; #X obj 76 546 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 612 122 + 1; #X text 28 521 texture feedback; #X text 486 751 "no-bots in no-sphere"; #X text 459 768 a double dance of 13 segments; #X text 549 734 ---; #X text 549 787 ---; #X obj 59 176 3dp_mouserotate; #X msg 188 47 close; #X connect 0 0 108 1; #X connect 1 0 108 0; #X connect 2 0 108 0; #X connect 3 0 27 1; #X connect 4 0 85 0; #X connect 4 1 46 0; #X connect 5 0 46 1; #X connect 6 0 7 0; #X connect 8 0 112 0; #X connect 9 0 112 1; #X connect 10 0 47 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 13 0 22 0; #X connect 14 0 11 0; #X connect 15 0 37 1; #X connect 16 0 38 1; #X connect 17 0 39 1; #X connect 18 0 40 1; #X connect 19 0 20 0; #X connect 20 0 21 0; #X connect 21 0 29 0; #X connect 22 0 19 0; #X connect 23 0 41 1; #X connect 24 0 28 1; #X connect 25 0 50 1; #X connect 26 0 104 0; #X connect 27 0 37 0; #X connect 27 0 14 1; #X connect 28 0 50 0; #X connect 28 0 20 1; #X connect 29 0 60 0; #X connect 30 0 31 1; #X connect 31 0 29 1; #X connect 31 0 68 0; #X connect 33 0 84 1; #X connect 34 0 35 0; #X connect 36 0 42 2; #X connect 36 0 43 2; #X connect 37 0 38 0; #X connect 37 0 11 1; #X connect 38 0 39 0; #X connect 38 0 12 1; #X connect 39 0 40 0; #X connect 39 0 13 1; #X connect 40 0 41 0; #X connect 40 0 22 1; #X connect 41 0 28 0; #X connect 41 0 19 1; #X connect 42 0 14 0; #X connect 44 0 34 0; #X connect 45 0 118 0; #X connect 46 0 6 0; #X connect 48 0 36 0; #X connect 48 0 102 0; #X connect 48 0 76 0; #X connect 48 0 83 0; #X connect 49 0 0 0; #X connect 50 0 31 0; #X connect 50 0 21 1; #X connect 51 0 6 1; #X connect 52 0 8 0; #X connect 53 0 27 0; #X connect 54 0 26 0; #X connect 55 0 54 1; #X connect 56 0 68 1; #X connect 57 0 58 0; #X connect 58 0 59 0; #X connect 59 0 65 0; #X connect 60 0 57 0; #X connect 61 0 69 1; #X connect 62 0 64 1; #X connect 63 0 70 1; #X connect 64 0 70 0; #X connect 64 0 58 1; #X connect 65 0 43 0; #X connect 66 0 67 1; #X connect 67 0 65 1; #X connect 68 0 69 0; #X connect 68 0 60 1; #X connect 69 0 64 0; #X connect 69 0 57 1; #X connect 70 0 67 0; #X connect 70 0 59 1; #X connect 71 0 86 0; #X connect 71 1 74 0; #X connect 72 0 42 0; #X connect 73 0 72 1; #X connect 73 0 75 0; #X connect 74 0 42 0; #X connect 75 0 74 1; #X connect 76 0 73 0; #X connect 78 0 77 0; #X connect 80 0 79 0; #X connect 81 0 82 0; #X connect 83 0 78 0; #X connect 84 0 32 0; #X connect 85 0 45 0; #X connect 86 0 87 0; #X connect 87 0 89 0; #X connect 88 0 87 1; #X connect 89 0 110 0; #X connect 90 1 89 1; #X connect 91 0 33 0; #X connect 92 0 91 0; #X connect 93 0 94 0; #X connect 94 0 1 0; #X connect 94 0 48 0; #X connect 95 0 4 0; #X connect 95 1 118 1; #X connect 96 0 98 0; #X connect 96 1 97 0; #X connect 97 0 72 0; #X connect 97 1 100 0; #X connect 98 0 71 0; #X connect 98 1 99 0; #X connect 99 0 101 0; #X connect 100 0 101 0; #X connect 101 0 53 0; #X connect 102 0 92 0; #X connect 102 0 44 0; #X connect 104 0 96 0; #X connect 106 0 109 0; #X connect 108 0 95 0; #X connect 108 0 8 0; #X connect 109 0 26 1; #X connect 110 0 90 0; #X connect 111 0 110 1; #X connect 112 0 8 1; #X connect 112 0 84 0; #X connect 112 0 101 1; #X connect 112 0 105 0; #X connect 118 0 54 0; #X connect 119 0 95 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example02.pd000066400000000000000000000024301266045153600222660ustar00rootroot00000000000000#N canvas 696 306 480 535 10; #X obj 102 73 3dp_windowcontext; #X obj 102 36 metro 20; #X obj 102 122 3dp_push; #X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 253 32 cursor \$1; #X obj 253 12 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 102 209 3dp_mouserotate; #X obj 153 322 3dp_draw cube 1; #X obj 265 139 3dp_view transxyz -4 3 4; #X obj 102 270 3dp_push; #X obj 102 348 3dp_push; #X obj 102 425 3dp_push; #X obj 153 296 3dp_view transx 2; #X obj 153 374 3dp_view transy 2; #X obj 153 451 3dp_view transz 2; #X obj 153 400 3dp_draw cube 1; #X obj 153 477 3dp_draw cube 1; #X obj 102 506 3dp_draw dodeca 1; #X text 25 231 use the mouse to rotate the model (but not the light source since it is rendered before the rotation is applied.); #X obj 265 161 3dp_light; #X connect 0 0 2 0; #X connect 0 1 7 1; #X connect 1 0 0 0; #X connect 2 0 7 0; #X connect 2 1 9 0; #X connect 3 0 1 0; #X connect 4 0 0 0; #X connect 5 0 0 0; #X connect 6 0 5 0; #X connect 7 0 10 0; #X connect 9 0 20 0; #X connect 10 0 11 0; #X connect 10 1 13 0; #X connect 11 0 12 0; #X connect 11 1 14 0; #X connect 12 0 18 0; #X connect 12 1 15 0; #X connect 13 0 8 0; #X connect 14 0 16 0; #X connect 15 0 17 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example03.pd000066400000000000000000000033261266045153600222740ustar00rootroot00000000000000#N canvas 382 102 480 535 10; #X obj 102 73 3dp_windowcontext; #X obj 102 36 metro 20; #X obj 102 139 3dp_push; #X obj 261 185 3dp_light; #X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 253 32 cursor \$1; #X obj 253 12 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 102 209 3dp_mouserotate; #X obj 261 163 3dp_view transxyz -4 3 4; #X obj 102 427 arm 3; #X obj 371 230 loadbang; #X obj 102 333 pdp_t p p p p; #X obj 102 304 pdp_t p p p p; #X floatatom 199 386 5 0 0; #X obj 318 378 s roty; #X floatatom 318 327 5 0 0; #X obj 371 378 s drawtorus; #X obj 371 355 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 102 256 pdp_t p b; #X obj 212 273 f 0; #X obj 302 352 *; #X obj 183 409 *; #X obj 212 307 + 0.1; #X obj 102 105 3dp_view transz -5; #X text 41 471 it is possible to send the rendercontext to the same rendering/transforming chain multiple times. (in other words: 3dp objects do not support fanout \, but they do support fanin.); #X connect 0 0 24 0; #X connect 0 1 8 1; #X connect 1 0 0 0; #X connect 2 0 8 0; #X connect 2 1 9 0; #X connect 4 0 1 0; #X connect 5 0 0 0; #X connect 6 0 0 0; #X connect 7 0 6 0; #X connect 8 0 19 0; #X connect 9 0 3 0; #X connect 11 0 18 0; #X connect 12 0 10 0; #X connect 12 1 10 0; #X connect 12 2 10 0; #X connect 12 3 10 0; #X connect 13 0 12 0; #X connect 13 1 12 0; #X connect 13 2 12 0; #X connect 13 3 12 0; #X connect 14 0 22 1; #X connect 16 0 21 1; #X connect 18 0 17 0; #X connect 19 0 13 0; #X connect 19 1 20 0; #X connect 20 0 23 0; #X connect 21 0 15 0; #X connect 22 0 10 1; #X connect 23 0 20 1; #X connect 23 0 22 0; #X connect 23 0 21 0; #X connect 24 0 2 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example04.pd000066400000000000000000000012401266045153600222660ustar00rootroot00000000000000#N canvas 288 311 566 284 10; #X obj 54 156 3dp_windowcontext; #X obj 54 43 metro 40; #X obj 54 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 54 76 t b b; #X obj 134 120 pdp_convert texture/*/*; #X obj 54 183 3dp_mouserotate; #X floatatom 180 202 5 0 0 0 - - -; #X msg 134 68 open /dev/video1; #X obj 54 227 3dp_draw sphere 5; #X text 132 18 convert pdp image packets to textures and map them on a sphere; #X obj 134 93 pdp_v4l; #X connect 0 0 5 0; #X connect 0 1 5 1; #X connect 1 0 3 0; #X connect 2 0 1 0; #X connect 3 0 0 0; #X connect 3 1 10 0; #X connect 4 0 8 1; #X connect 5 0 8 0; #X connect 6 0 8 2; #X connect 7 0 10 0; #X connect 10 0 4 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example05.pd000066400000000000000000000022241266045153600222720ustar00rootroot00000000000000#N canvas 352 162 732 325 10; #X obj 54 43 metro 40; #X obj 54 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 314 120 pdp_convert texture/*/*; #X floatatom 343 212 5 0 0; #X obj 286 247 3dp_draw sphere 5; #X obj 314 95 pdp_plasma; #X obj 408 48 loadbang; #X msg 408 70 dim 512 256; #X obj 314 65 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 181 144 3dp_windowcontext; #X obj 181 203 3dp_view roty; #X floatatom 267 176 5 0 0; #X obj 31 144 3dp_windowcontext; #X obj 31 203 3dp_view roty; #X floatatom 117 176 5 0 0; #X obj 286 278 3dp_draw cube 2; #X obj 336 164 pdp_del 3; #X text 414 164 <- textures can be stored in a delay line; #X text 133 9 convert pdp image packets to textures and map them on a sphere and cube. create 2 independent viewing windows.; #X connect 0 0 9 0; #X connect 0 0 12 0; #X connect 1 0 0 0; #X connect 2 0 4 1; #X connect 2 0 16 0; #X connect 3 0 4 2; #X connect 4 0 15 0; #X connect 5 0 2 0; #X connect 6 0 7 0; #X connect 7 0 5 0; #X connect 8 0 5 0; #X connect 9 0 10 0; #X connect 10 0 4 0; #X connect 11 0 10 1; #X connect 12 0 13 0; #X connect 13 0 4 0; #X connect 14 0 13 1; #X connect 16 0 15 1; pdp-0.14.1+darcs20180201/opengl/doc/examples/example06.pd000066400000000000000000000044451266045153600223020ustar00rootroot00000000000000#N canvas 516 361 634 497 10; #X obj 23 119 metro 40; #X obj 23 89 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 360 397 pdp_convert texture/*/*; #X obj 23 387 3dp_mouserotate; #X obj 155 255 3dp_light 0; #X obj 23 193 3dp_push; #X floatatom 269 198 5 0 0; #X obj 23 161 3dp_windowcontext; #X obj 360 299 pdp_convert image/grey/*; #X obj 360 184 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 478 163 random; #X msg 479 186 rule gameoflife; #X msg 478 114 rule fire; #X obj 360 270 pdp_ca; #X obj 360 371 pdp_motion_phase; #X floatatom 479 343 5 0 0; #X obj 478 88 loadbang; #X msg 479 322 0.33; #X obj 328 473 3dp_draw sphere 2.6; #X floatatom 463 434 5 0 0; #X obj 155 227 3dp_view transz 5; #X floatatom 480 237 5 0 0; #X msg 517 322 1; #X obj 360 347 pdp_gain; #X floatatom 411 323 5 0 0; #X msg 478 139 dim 256 128; #X obj 179 393 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 328 419 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 23 416 3dp_toggle depth_test 0; #X obj 179 445 3dp_toggle blend_add 1; #X msg 480 213 1; #X obj 23 316 3dp_mode texture; #X floatatom 281 310 5 0 0; #X obj 156 339 3dp_view scale 1; #X floatatom 280 340 5 0 0; #X obj 156 366 3dp_view rotz; #X text 141 197 move light source; #X text 143 294 transform texture coords; #X text 31 12 blending with depth test disabled using 3dp_toggle object. together with a cellular automata texture (you need pdp_scaf for this) and texture coordinate transformation.; #X connect 0 0 7 0; #X connect 0 0 9 0; #X connect 1 0 0 0; #X connect 2 0 18 1; #X connect 3 0 28 0; #X connect 5 0 31 0; #X connect 5 1 20 0; #X connect 6 0 20 1; #X connect 7 0 5 0; #X connect 7 1 3 1; #X connect 8 0 23 0; #X connect 9 0 13 0; #X connect 10 0 13 0; #X connect 11 0 13 0; #X connect 12 0 13 0; #X connect 12 0 25 0; #X connect 13 0 8 0; #X connect 14 0 2 0; #X connect 15 0 14 1; #X connect 16 0 12 0; #X connect 17 0 15 0; #X connect 19 0 18 2; #X connect 20 0 4 0; #X connect 21 0 13 2; #X connect 22 0 15 0; #X connect 23 0 14 0; #X connect 24 0 23 1; #X connect 25 0 13 0; #X connect 25 0 10 0; #X connect 26 0 28 1; #X connect 27 0 29 1; #X connect 28 1 29 0; #X connect 29 1 18 0; #X connect 30 0 21 0; #X connect 31 0 3 0; #X connect 31 1 33 0; #X connect 32 0 33 1; #X connect 33 0 35 0; #X connect 34 0 35 1; pdp-0.14.1+darcs20180201/opengl/doc/examples/example07.pd000066400000000000000000000012661266045153600223010ustar00rootroot00000000000000#N canvas 400 454 637 428 10; #X obj 18 131 3dp_windowcontext; #X obj 18 159 3dp_push; #X obj 201 70 metro 40; #X obj 201 42 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 201 99 pdp_v4l; #X obj 201 131 pdp_convert texture/*/*; #X floatatom 258 265 5 0 0; #X obj 18 218 3dp_view scalex 1.33333; #X obj 18 187 3dp_mouserotate; #X text 15 10 using a square scaled by an aspect ratio to construct an an alternative pdp_glx; #X obj 144 290 3dp_draw square 8; #X connect 0 0 1 0; #X connect 0 1 8 1; #X connect 1 0 8 0; #X connect 2 0 0 0; #X connect 2 0 4 0; #X connect 3 0 2 0; #X connect 4 0 5 0; #X connect 5 0 10 1; #X connect 6 0 10 2; #X connect 7 0 10 0; #X connect 8 0 7 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example08.pd000066400000000000000000000047651266045153600223110ustar00rootroot00000000000000#N canvas 96 78 756 667 10; #X obj 18 131 3dp_windowcontext; #X obj 18 159 3dp_push; #X obj 327 80 metro 40; #X obj 327 52 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 327 224 pdp_v4l; #X obj 431 463 pdp_convert texture/*/*; #X floatatom 488 554 5 0 0; #X obj 18 215 3dp_view scalex 1.33333; #X obj 18 189 3dp_mouserotate; #X floatatom 83 308 5 0 0; #X msg 83 287 10; #X obj 69 428 3dp_view rotx; #X obj 69 475 3dp_view roty; #X obj 69 523 3dp_view rotz; #X obj 155 398 random 360; #X obj 155 453 random 360; #X obj 155 500 random 360; #X obj 155 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 18 366 3dp_push; #X text 132 305 nb of squares; #X floatatom 220 369 5 0 0; #X obj 431 309 pdp_plasma; #X obj 431 256 loadbang; #X obj 327 192 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 397 279 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 417 55 200; #X floatatom 510 364 5 0 0; #X msg 378 55 40; #X obj 327 126 spigot; #X obj 385 106 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 431 395 pdp_gain 0.3; #X obj 18 333 3dp_for 10; #X text 21 12 another example of accumulated blending combined with a 3dp_for object to render multiple randomly rotated squares.; #X msg 386 186 open /dev/video1; #X obj 18 246 3dp_blend; #X text 411 106 switch between video textures and stills; #X msg 386 160 open /dev/video0; #X text 87 246 <-- click for more info; #X msg 431 281 dim 64 64 \, bang; #X obj 548 228 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 548 256 metro 2000; #X obj 374 583 3dp_draw square 8; #X connect 0 0 1 0; #X connect 0 1 8 1; #X connect 1 0 8 0; #X connect 2 0 0 0; #X connect 2 0 28 0; #X connect 3 0 2 0; #X connect 4 0 30 0; #X connect 5 0 41 1; #X connect 6 0 41 2; #X connect 7 0 34 0; #X connect 8 0 7 0; #X connect 9 0 31 1; #X connect 10 0 9 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 13 0 41 0; #X connect 14 0 11 1; #X connect 15 0 12 1; #X connect 16 0 13 1; #X connect 17 0 14 0; #X connect 17 0 15 0; #X connect 17 0 16 0; #X connect 18 1 11 0; #X connect 20 0 14 1; #X connect 20 0 15 1; #X connect 20 0 16 1; #X connect 21 0 30 0; #X connect 22 0 38 0; #X connect 23 0 4 0; #X connect 24 0 21 0; #X connect 25 0 2 1; #X connect 26 0 30 1; #X connect 27 0 2 1; #X connect 28 0 23 0; #X connect 29 0 28 1; #X connect 30 0 5 0; #X connect 31 0 18 0; #X connect 31 1 17 0; #X connect 33 0 4 0; #X connect 34 0 31 0; #X connect 36 0 4 0; #X connect 38 0 21 0; #X connect 39 0 40 0; #X connect 40 0 21 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example09.pd000066400000000000000000000046451266045153600223070ustar00rootroot00000000000000#N canvas 663 191 853 490 10; #X obj 18 111 3dp_windowcontext; #X obj 18 139 3dp_push; #X obj 18 169 3dp_mouserotate; #X floatatom 141 370 5 0 0 0 - - -; #X msg 141 349 10; #X obj 127 490 3dp_view rotx; #X obj 127 537 3dp_view roty; #X obj 127 585 3dp_view rotz; #X obj 213 460 random 360; #X obj 213 515 random 360; #X obj 213 562 random 360; #X obj 213 433 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 76 428 3dp_push; #X floatatom 278 431 5 0 0 0 - - -; #X obj 76 395 3dp_for 10; #X obj 18 226 3dp_blend; #X text 87 226 <-- click for more info; #X obj 18 365 3dp_color; #X floatatom 32 311 5 0 0 0 - - -; #X floatatom 78 311 5 0 0 0 - - -; #X floatatom 123 311 5 0 0 0 - - -; #X floatatom 167 311 5 0 0 0 - - -; #X obj 415 193 3dp_view transz 5; #X obj 415 217 3dp_light; #X obj 18 78 metro 40; #X obj 18 50 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X floatatom 529 166 5 0 0 0 - - -; #X obj 32 252 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 2200 1; #X obj 78 251 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 2100 1; #X obj 123 251 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 3800 1; #X obj 169 250 vsl 15 50 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 1100 1; #X text 209 275 in this blending mode \, alpha is interpreted as a color gain; #X floatatom 515 137 5 0 0 0 - - -; #X floatatom 144 178 5 0 0 0 - - -; #X obj 127 633 3dp_draw tetra 4; #X obj 415 168 3dp_view roty 5; #X obj 18 199 3dp_view scale 4; #X msg 278 406 18; #X msg 515 112 75; #X text 14 13 similar to example08.; #X connect 0 0 1 0; #X connect 0 1 2 1; #X connect 1 0 2 0; #X connect 1 1 35 0; #X connect 2 0 36 0; #X connect 3 0 14 1; #X connect 4 0 3 0; #X connect 5 0 6 0; #X connect 6 0 7 0; #X connect 7 0 34 0; #X connect 8 0 5 1; #X connect 9 0 6 1; #X connect 10 0 7 1; #X connect 11 0 8 0; #X connect 11 0 9 0; #X connect 11 0 10 0; #X connect 12 1 5 0; #X connect 13 0 8 1; #X connect 13 0 9 1; #X connect 13 0 10 1; #X connect 14 0 12 0; #X connect 14 1 11 0; #X connect 15 0 17 0; #X connect 17 1 14 0; #X connect 18 0 17 1; #X connect 19 0 17 2; #X connect 20 0 17 3; #X connect 21 0 17 4; #X connect 22 0 23 0; #X connect 24 0 0 0; #X connect 25 0 24 0; #X connect 26 0 22 1; #X connect 27 0 18 0; #X connect 28 0 19 0; #X connect 29 0 20 0; #X connect 30 0 21 0; #X connect 32 0 35 1; #X connect 33 0 36 1; #X connect 35 0 22 0; #X connect 36 0 15 0; #X connect 37 0 13 0; #X connect 38 0 32 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example10.pd000066400000000000000000000022011266045153600222610ustar00rootroot00000000000000#N canvas 592 340 647 499 10; #X obj 231 344 pdp_xv; #X obj 54 72 metro 40; #X obj 54 47 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 54 140 3dp_push; #X obj 248 158 3dp_view transz 5; #X floatatom 362 126 5 0 0; #X obj 248 182 3dp_light 0; #X obj 54 169 3dp_mouserotate; #X obj 54 111 3dp_windowcontext; #X obj 231 311 pdp_blur; #X obj 285 291 hsl 128 15 0 1 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 8100 1; #X text 104 7 connect 3dp and basic pdp image processing with 3dp_snap ; #X text 105 26 3dp_snap defaults to texture packets \, but you can specify the desired type as a creation argument; #X obj 107 377 pdp_convert texture/*/*; #X obj 54 412 3dp_draw cube 10; #X text 247 233 <- specify packet type and capture area; #X obj 54 200 3dp_draw cube 2; #X obj 54 234 3dp_snap image/*/* 320 240; #X connect 1 0 8 0; #X connect 2 0 1 0; #X connect 3 0 7 0; #X connect 3 1 4 0; #X connect 4 0 6 0; #X connect 5 0 4 1; #X connect 7 0 16 0; #X connect 8 0 3 0; #X connect 8 1 7 1; #X connect 9 0 13 0; #X connect 9 0 0 0; #X connect 10 0 9 1; #X connect 13 0 14 1; #X connect 16 0 17 0; #X connect 17 0 14 0; #X connect 17 1 9 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example11.pd000066400000000000000000000044441266045153600222750ustar00rootroot00000000000000#N canvas 542 122 669 675 10; #X obj 23 70 metro 40; #X obj 23 40 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 23 517 3dp_mouserotate; #X obj 171 520 3dp_light 0; #X obj 23 444 3dp_push; #X obj 171 492 3dp_view transz 5; #X obj 23 112 3dp_windowcontext; #X obj 205 311 3dp_snap; #X obj 205 213 3dp_draw clear; #X obj 23 406 3dp_draw clear; #X obj 60 347 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 23 157 3dp_subcontext 64 64; #X obj 23 380 spigot; #X text 384 210 <- clear it; #X text 380 309 <- snap to texture; #X obj 205 261 3dp_view rota 1 1 0; #X floatatom 333 236 5 0 0; #X text 69 10 multipass rendering to texture using a subcontext (subwindow) ; #X text 381 285 <- draw a wireframe sphere; #X text 383 235 <- rotate around (1 \, 1 \, 0); #X text 135 406 <- clear the window; #X obj 205 286 3dp_draw wsphere 3 10 10; #X obj 323 429 3dp_draw clear; #X obj 323 405 3dp_view reset; #X obj 323 507 3dp_draw wdodeca; #X obj 323 532 3dp_snap; #X obj 22 613 3dp_draw cube 10; #X obj 360 348 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 323 381 spigot; #X text 381 346 <- enable/disable second pass; #X text 87 345 <- enable/disable third pass; #X text 443 404 <- reset context; #X text 442 427 <- clear context; #X text 442 507 <- draw wire dodecahedron; #X text 441 532 <- snap to texture; #X obj 323 483 3dp_view rota 1 1 0; #X floatatom 451 458 5 0 0; #X text 501 457 <- rotate around (1 \, 1 \, 0); #X obj 23 562 3dp_draw cube 2; #X text 204 142 NOTE: the part you use as a subcontext must be visible for the texture snap to work.; #X text 203 91 use the lower left 64x64 part of the window as a subcontext (right outlet) the left outlet is a new full window context reset to default.; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 38 0; #X connect 4 0 2 0; #X connect 4 1 5 0; #X connect 5 0 3 0; #X connect 6 0 11 0; #X connect 6 1 2 1; #X connect 7 0 28 0; #X connect 7 1 38 1; #X connect 8 0 15 0; #X connect 9 0 4 0; #X connect 10 0 12 1; #X connect 11 0 12 0; #X connect 11 1 8 0; #X connect 12 0 9 0; #X connect 15 0 21 0; #X connect 16 0 15 4; #X connect 21 0 7 0; #X connect 22 0 35 0; #X connect 23 0 22 0; #X connect 24 0 25 0; #X connect 25 1 26 1; #X connect 27 0 28 1; #X connect 28 0 23 0; #X connect 35 0 24 0; #X connect 36 0 35 4; #X connect 38 0 26 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example12.pd000066400000000000000000000043571266045153600223010ustar00rootroot00000000000000#N canvas 529 191 669 751 10; #X obj 55 68 metro 40; #X obj 55 38 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 55 515 3dp_mouserotate; #X obj 184 514 3dp_light 0; #X obj 55 442 3dp_push; #X obj 184 486 3dp_view transz 5; #X obj 55 110 3dp_windowcontext; #X obj 343 481 3dp_snap; #X obj 55 404 3dp_draw clear; #X obj 436 272 3dp_light 0; #X obj 436 244 3dp_view transxyz 5 5 0; #X obj 285 226 3dp_push; #X obj 343 449 3dp_draw sphere 7 10 10; #X text 69 10 another multipass rendering example; #X obj 55 576 3dp_draw cube 7; #X obj 55 155 3dp_subcontext 256 256; #X obj 285 260 3dp_mouserotate; #X obj 343 413 3dp_draw icosa 1; #X obj 285 342 3dp_color; #X obj 343 387 3dp_view scale 1; #X floatatom 450 358 5 0 0; #N canvas 0 0 291 420 coord_to_color 0; #X obj 97 85 route drag; #X obj 97 147 *; #X obj 134 146 *; #X obj 97 174 +; #X obj 97 281 sqrt; #X obj 97 225 - 1; #X obj 97 249 * -1; #X obj 97 114 unpack 0 0; #X obj 98 45 inlet; #X obj 53 337 outlet; #X obj 181 332 outlet; #X obj 116 336 outlet; #X connect 0 0 7 0; #X connect 1 0 3 0; #X connect 2 0 3 1; #X connect 3 0 5 0; #X connect 4 0 11 0; #X connect 5 0 6 0; #X connect 6 0 4 0; #X connect 7 0 1 1; #X connect 7 0 1 0; #X connect 7 0 9 0; #X connect 7 1 2 1; #X connect 7 1 2 0; #X connect 7 1 10 0; #X connect 8 0 0 0; #X restore 304 305 pd coord_to_color; #X obj 453 337 hsl 128 15 1 3 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 7900 1; #X obj 285 196 3dp_draw clear; #X obj 92 622 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 55 662 3dp_screenshot /tmp/screenshot.png; #X msg 227 71 dim 1023 768; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 14 0; #X connect 4 0 2 0; #X connect 4 1 5 0; #X connect 5 0 3 0; #X connect 6 0 15 0; #X connect 6 1 2 1; #X connect 6 1 21 0; #X connect 6 1 16 1; #X connect 7 1 12 1; #X connect 7 1 14 1; #X connect 8 0 4 0; #X connect 10 0 9 0; #X connect 11 0 16 0; #X connect 11 1 10 0; #X connect 12 0 7 0; #X connect 14 0 25 0; #X connect 15 0 8 0; #X connect 15 1 23 0; #X connect 16 0 18 0; #X connect 17 0 12 0; #X connect 18 1 19 0; #X connect 19 0 17 0; #X connect 20 0 19 1; #X connect 21 0 18 1; #X connect 21 1 18 2; #X connect 21 2 18 3; #X connect 22 0 20 0; #X connect 23 0 11 0; #X connect 24 0 25 0; #X connect 26 0 6 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example13.pd000066400000000000000000000041731266045153600222760ustar00rootroot00000000000000#N canvas 478 168 669 751 10; #X obj 55 68 metro 40; #X obj 55 38 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 55 110 3dp_windowcontext; #X obj 262 479 3dp_snap; #X obj 355 270 3dp_light 0; #X obj 355 242 3dp_view transxyz 5 5 0; #X obj 204 224 3dp_push; #X obj 262 447 3dp_draw sphere 7 10 10; #X obj 204 258 3dp_mouserotate; #X obj 262 411 3dp_draw icosa 1; #X obj 204 340 3dp_color; #X obj 262 385 3dp_view scale 1; #X floatatom 369 356 5 0 0; #N canvas 0 0 291 420 coord_to_color 0; #X obj 97 85 route drag; #X obj 97 147 *; #X obj 134 146 *; #X obj 97 174 +; #X obj 97 281 sqrt; #X obj 97 225 - 1; #X obj 97 249 * -1; #X obj 97 114 unpack 0 0; #X obj 98 45 inlet; #X obj 53 337 outlet; #X obj 181 332 outlet; #X obj 116 336 outlet; #X connect 0 0 7 0; #X connect 1 0 3 0; #X connect 2 0 3 1; #X connect 3 0 5 0; #X connect 4 0 11 0; #X connect 5 0 6 0; #X connect 6 0 4 0; #X connect 7 0 1 1; #X connect 7 0 1 0; #X connect 7 0 9 0; #X connect 7 1 2 1; #X connect 7 1 2 0; #X connect 7 1 10 0; #X connect 8 0 0 0; #X restore 223 303 pd coord_to_color; #X obj 372 335 hsl 128 15 1 3 0 1 empty empty empty -2 -6 0 8 -262144 -1 -1 7900 1; #X obj 204 194 3dp_draw clear; #X text 209 658 <- stretch the texture to cover the entire window (click for info); #X text 119 13 fixed resolution processing (independent of the display window size) using multipass rendering; #X floatatom 210 631 5 0 0; #X obj 55 658 3dp_display_texture; #X text 338 480 <- snap the result to a texture; #X text 228 154 <- create a subcontext to do some drawing; #X text 402 76 see also; #X obj 405 97 3dp_fixedsizewindowcontext 64 64; #X obj 55 155 3dp_subcontext 320 240; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 2 0 24 0; #X connect 2 1 13 0; #X connect 2 1 8 1; #X connect 3 1 7 1; #X connect 3 1 19 1; #X connect 5 0 4 0; #X connect 6 0 8 0; #X connect 6 1 5 0; #X connect 7 0 3 0; #X connect 8 0 10 0; #X connect 9 0 7 0; #X connect 10 1 11 0; #X connect 11 0 9 0; #X connect 12 0 11 1; #X connect 13 0 10 1; #X connect 13 1 10 2; #X connect 13 2 10 3; #X connect 14 0 12 0; #X connect 15 0 6 0; #X connect 18 0 19 2; #X connect 24 0 19 0; #X connect 24 1 15 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example14.pd000066400000000000000000000035521266045153600222770ustar00rootroot00000000000000#N canvas 586 145 669 674 10; #X obj 67 71 3dp_windowcontext; #X obj 67 46 metro 40; #X obj 67 23 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 67 155 3dp_blend; #X obj 176 423 3dp_view transxyz; #X msg 226 296 reset; #X obj 197 374 *; #X obj 304 375 *; #X floatatom 320 347 5 0 0; #X obj 274 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 700 1; #X obj 316 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 1100 1; #X obj 295 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 1200 1; #X obj 337 154 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 400 1; #X obj 125 253 3dp_push; #X obj 67 95 3dp_mouserotate; #X obj 67 124 3dp_view scale 1; #X floatatom 206 99 5 0 0; #X obj 209 79 hsl 128 15 0.2 5 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 7000 1; #X obj 323 326 hsl 128 15 0.1 2 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 2100 1; #X obj 67 187 3dp_color; #X obj 226 223 route press3; #X text 329 223 <- right click mouse to reset; #X text 211 253 <- remove 3dp_push object to accumulate the translations ; #X obj 197 326 randomwalk2D 100; #X obj 125 224 3dp_for 100; #X text 287 130 R G B I; #X obj 176 460 3dp_draw cube 1; #X text 227 13 using 3dp_for and the randomwalk2D abstraction to create random walking blended cubes.; #X connect 0 0 14 0; #X connect 0 1 14 1; #X connect 0 1 20 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 19 0; #X connect 4 0 26 0; #X connect 5 0 23 0; #X connect 6 0 4 1; #X connect 7 0 4 2; #X connect 8 0 7 1; #X connect 8 0 6 1; #X connect 9 0 19 1; #X connect 10 0 19 3; #X connect 11 0 19 2; #X connect 12 0 19 4; #X connect 13 1 4 0; #X connect 14 0 15 0; #X connect 15 0 3 0; #X connect 16 0 15 1; #X connect 17 0 16 0; #X connect 18 0 8 0; #X connect 19 1 24 0; #X connect 20 0 5 0; #X connect 23 0 6 0; #X connect 23 1 7 0; #X connect 24 0 13 0; #X connect 24 1 23 0; pdp-0.14.1+darcs20180201/opengl/doc/examples/example15.pd000066400000000000000000000066611266045153600223040ustar00rootroot00000000000000#N canvas 269 234 933 697 10; #X obj 67 46 metro 40; #X obj 67 23 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 67 224 3dp_blend; #X obj 176 673 3dp_view transxyz; #X msg 260 342 reset; #X obj 197 497 *; #X obj 304 498 *; #X obj 272 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 1000 1; #X obj 314 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 0 1; #X obj 293 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 100 1; #X obj 335 218 vsl 15 30 0 1 0 1 empty empty empty 0 -8 0 8 -262144 -1 -1 200 1; #X obj 125 304 3dp_push; #X obj 67 119 3dp_mouserotate; #X obj 67 176 3dp_view scale 1; #X floatatom 241 145 5 0 0 0 - - -; #X obj 244 125 hsl 128 15 0.2 5 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 3800 1; #X obj 523 456 hsl 128 15 0.01 2 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 7900 1; #X obj 67 251 3dp_color; #X obj 402 231 route press3; #X text 211 304 <- remove 3dp_push object to accumulate the translations ; #X obj 197 392 randomwalk2D 100; #X obj 125 275 3dp_for 100; #X text 285 185 R G B I; #X obj 197 533 smoothupdate 100; #X obj 304 567 smoothupdate 100; #X obj 524 490 hsl 128 15 0.01 1 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 1300 1; #X obj 67 93 3dp_push; #X obj 476 111 3dp_view transz 5; #X obj 476 171 3dp_light; #X obj 219 351 s i; #X obj 250 511 r i; #X obj 357 543 r i; #X obj 419 716 smoothupdate 100; #X obj 472 692 r i; #X obj 197 325 t f f b; #X obj 419 639 random 100; #X obj 419 662 - 50; #X obj 529 675 hsl 128 15 0.01 1 1 1 empty empty empty -2 -6 0 8 -262144 -1 -1 600 1; #X obj 419 688 / 10; #X msg 418 424 reset; #X obj 148 201 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 67 200 pdp_route; #X obj 176 765 3dp_draw torus 1 2 5 5; #X obj 176 709 pdp_route; #X obj 265 711 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 194 741 3dp_draw cube 2; #X text 315 344 <- reset random walk; #X text 532 554 <- reset smoothed points to origin; #X text 227 13 like example14 but with coordinate smoothing and lighting ; #X text 505 246 <- route mouse buttons; #X obj 481 265 route press2; #X text 666 453 <- walk radius; #X text 667 488 <- walk smoothing; #X obj 67 70 3dp_fixedsizewindowcontext 320 240; #X floatatom 199 250 5 0 0 0 - - -; #X connect 0 0 53 0; #X connect 1 0 0 0; #X connect 2 0 17 0; #X connect 3 0 43 0; #X connect 4 0 20 0; #X connect 5 0 23 0; #X connect 6 0 24 0; #X connect 7 0 17 1; #X connect 8 0 17 3; #X connect 9 0 17 2; #X connect 10 0 17 4; #X connect 11 1 3 0; #X connect 12 0 13 0; #X connect 13 0 41 0; #X connect 14 0 13 1; #X connect 15 0 14 0; #X connect 16 0 6 1; #X connect 16 0 5 1; #X connect 17 1 21 0; #X connect 18 0 4 0; #X connect 18 1 50 0; #X connect 20 0 5 0; #X connect 20 1 6 0; #X connect 21 0 11 0; #X connect 21 1 34 0; #X connect 23 0 3 1; #X connect 24 0 3 2; #X connect 25 0 23 2; #X connect 25 0 24 2; #X connect 26 0 12 0; #X connect 26 1 27 0; #X connect 27 0 28 0; #X connect 30 0 23 1; #X connect 31 0 24 1; #X connect 32 0 3 3; #X connect 33 0 32 1; #X connect 34 0 20 0; #X connect 34 1 29 0; #X connect 34 2 35 0; #X connect 35 0 36 0; #X connect 36 0 38 0; #X connect 37 0 32 2; #X connect 38 0 32 0; #X connect 39 0 23 0; #X connect 39 0 24 0; #X connect 39 0 32 0; #X connect 40 0 41 1; #X connect 41 0 2 0; #X connect 41 1 17 0; #X connect 43 0 42 0; #X connect 43 1 45 0; #X connect 44 0 43 1; #X connect 50 0 39 0; #X connect 53 0 26 0; #X connect 53 1 12 1; #X connect 53 1 18 0; #X connect 54 0 21 1; pdp-0.14.1+darcs20180201/opengl/doc/examples/example16.pd000066400000000000000000000052711266045153600223010ustar00rootroot00000000000000#N canvas 196 0 772 525 10; #X obj 57 25 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 57 153 3dp_blend; #X floatatom 101 237 5 0 0 0 - - -; #X floatatom 149 237 5 0 0 0 - - -; #X floatatom 199 236 5 0 0 0 - - -; #X floatatom 247 236 5 0 0 0 - - -; #X obj 167 364 3dp_push; #X obj 218 434 3dp_view transxyz; #X msg 276 354 normal; #X obj 422 255 f; #X floatatom 484 264 5 0 0 0 - - -; #X msg 422 220 0; #X obj 57 177 pdp_t p b; #X obj 392 185 t b b; #X msg 591 238 0.2; #X msg 484 239 0; #X obj 57 72 3dp_windowcontext; #X obj 392 112 route press3; #X obj 57 49 metro 40; #X obj 167 328 3dp_for 100; #X obj 227 125 3dp_view transz 5; #X obj 227 159 3dp_light; #X obj 57 96 3dp_push; #X obj 422 289 + 0.2; #X obj 497 112 loadbang; #X msg 519 238 0.01; #N canvas 0 0 577 190 coordinates 0; #X obj 51 100 *; #X obj 51 72 elbat 100; #X obj 165 99 *; #X obj 165 71 elbat 100; #X obj 276 97 *; #X obj 276 69 elbat 100; #X obj 51 19 inlet; #X obj 125 18 inlet; #X text 354 69 <- table read abstraction; #X obj 51 130 outlet; #X obj 165 127 outlet; #X obj 276 125 outlet; #X connect 0 0 9 0; #X connect 1 0 0 0; #X connect 2 0 10 0; #X connect 3 0 2 0; #X connect 4 0 11 0; #X connect 5 0 4 0; #X connect 6 0 1 0; #X connect 6 0 3 0; #X connect 6 0 5 0; #X connect 7 0 0 1; #X connect 7 0 2 1; #X connect 7 0 4 1; #X restore 239 403 pd coordinates; #X msg 392 136 bang; #X text 459 219 <- reset scaling to 0 (infinite density); #X text 469 290 <- increment scaling for each new frame; #X text 340 354 <- compute a new normal distributed set of points; #X text 506 371 (velocity vectors); #X text 545 264 <- diffusion speed; #X msg 559 238 0.1; #X text 182 12 explosion using 100 spheres with normal distributed velocity vectors; #X floatatom 367 441 5 0 0 0 - - -; #X obj 57 125 3dp_mouserotate; #X obj 57 278 3dp_color 0.1 0.1 0.1 0.27; #X obj 218 478 3dp_draw sphere 1 8 8; #X connect 0 0 18 0; #X connect 1 0 12 0; #X connect 2 0 37 1; #X connect 3 0 37 2; #X connect 4 0 37 3; #X connect 5 0 37 4; #X connect 6 1 7 0; #X connect 7 0 38 0; #X connect 8 0 26 0; #X connect 9 0 23 0; #X connect 10 0 23 1; #X connect 11 0 9 0; #X connect 12 0 37 0; #X connect 12 1 9 0; #X connect 13 0 8 0; #X connect 13 1 11 0; #X connect 14 0 10 0; #X connect 15 0 10 0; #X connect 16 0 22 0; #X connect 16 1 17 0; #X connect 16 1 36 1; #X connect 17 0 27 0; #X connect 18 0 16 0; #X connect 19 0 6 0; #X connect 19 1 26 0; #X connect 20 0 21 0; #X connect 22 0 36 0; #X connect 22 1 20 0; #X connect 23 0 9 1; #X connect 23 0 26 1; #X connect 24 0 13 0; #X connect 25 0 10 0; #X connect 26 0 7 1; #X connect 26 1 7 2; #X connect 26 2 7 3; #X connect 27 0 13 0; #X connect 33 0 10 0; #X connect 35 0 38 2; #X connect 36 0 1 0; #X connect 37 1 19 0; pdp-0.14.1+darcs20180201/opengl/doc/objects/000077500000000000000000000000001266045153600177605ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/doc/objects/3dp_for-help.pd000066400000000000000000000050341266045153600225710ustar00rootroot00000000000000#N canvas 545 167 607 718 10; #X obj 22 40 3dp_windowcontext; #X obj 22 15 metro 40; #X obj 22 -5 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 22 67 3dp_push; #X obj 180 126 3dp_light; #X floatatom 301 85 5 0 0 0 - - -; #X obj 22 97 3dp_mouserotate; #X floatatom 151 228 5 0 0 0 - - -; #X obj 180 104 3dp_view transz 10; #X floatatom 81 165 5 0 0 0 - - -; #X obj 23 191 3dp_for 3; #X obj 23 251 3dp_view transx 1.5; #X floatatom 130 280 5 0 0 0 - - -; #X obj 23 302 3dp_view roty 45; #X obj 23 389 3dp_draw sphere 1; #X obj 81 365 + 1; #X obj 81 343 *; #X floatatom 129 327 5 0 0 0 - - -; #X text 135 159 3dp_for sends a rendering context trough a chain multiple times. the second outlet is the current number \, starting from zero \, and can be used to change the parameters parameters of the chain. (i.e. by reading from a table); #X text 222 252 all the geometry operations are accumulative \,; #X text 222 266 if you don't want that \, insert a 3dp_push object: ; #X obj 314 313 3dp_for 3; #X obj 314 336 3dp_push; #X obj 365 400 3dp_draw cube 0.5; #X obj 23 140 3dp_push; #X obj 365 374 3dp_view transy; #X obj 465 343 * 1; #X floatatom 481 319 5 0 0 0 - - -; #X obj 86 569 pdp_t p p p; #X obj 86 606 3dp_view transy 1; #X obj 86 630 3dp_draw cube 0.5; #X obj 177 465 3dp_for 3; #X text 72 492 so \, in short \,; #X text 313 492 is equivalent to; #X obj 177 491 3dp_view transy 1; #X obj 177 515 3dp_draw cube 0.5; #X obj 354 539 3dp_view transy 1; #X obj 354 563 3dp_draw cube 0.5; #X obj 354 589 3dp_view transy 1; #X obj 354 613 3dp_draw cube 0.5; #X obj 354 638 3dp_view transy 1; #X obj 354 662 3dp_draw cube 0.5; #X text 256 596 and; #X obj 180 84 3dp_view roty; #X floatatom 266 66 5 0 0 0 - - -; #X connect 0 0 3 0; #X connect 0 1 6 1; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 3 1 43 0; #X connect 5 0 8 1; #X connect 6 0 24 0; #X connect 7 0 11 1; #X connect 8 0 4 0; #X connect 9 0 10 1; #X connect 10 0 11 0; #X connect 10 1 16 0; #X connect 11 0 13 0; #X connect 12 0 13 1; #X connect 13 0 14 0; #X connect 15 0 14 2; #X connect 16 0 15 0; #X connect 17 0 16 1; #X connect 21 0 22 0; #X connect 21 1 26 0; #X connect 22 1 25 0; #X connect 24 0 10 0; #X connect 24 1 21 0; #X connect 25 0 23 0; #X connect 26 0 25 1; #X connect 27 0 26 1; #X connect 28 0 29 0; #X connect 28 1 29 0; #X connect 28 2 29 0; #X connect 29 0 30 0; #X connect 31 0 34 0; #X connect 34 0 35 0; #X connect 36 0 37 0; #X connect 37 0 38 0; #X connect 38 0 39 0; #X connect 39 0 40 0; #X connect 40 0 41 0; #X connect 43 0 8 0; #X connect 44 0 43 1; pdp-0.14.1+darcs20180201/opengl/doc/reference_opengl.txt000066400000000000000000000000001266045153600223600ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/include/000077500000000000000000000000001266045153600172055ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/include/Makefile000066400000000000000000000000311266045153600206370ustar00rootroot00000000000000all: clean: rm -rf *~ pdp-0.14.1+darcs20180201/opengl/include/pdp_3Dcontext.h000066400000000000000000000052151266045153600220770ustar00rootroot00000000000000/* * pdp system module - 3d render context packet type * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* the 3d render context packet: platform independent data structure and method prototypes */ #ifndef PDP_3DCONTEXT_H #define PDP_3DCONTEXT_H #include "pdp.h" #include "zl/3Dcontext.h" #define PDP_3DCONTEXT 5 /* 3d context packet id */ typedef struct _3dcontext { zl_3Dcontext *c; } zl_3Dcontext_wrapper; /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif /* info methods */ u32 pdp_packet_3Dcontext_width(int packet); u32 pdp_packet_3Dcontext_subwidth(int packet); u32 pdp_packet_3Dcontext_height(int packet); u32 pdp_packet_3Dcontext_subheight(int packet); float pdp_packet_3Dcontext_subaspect(int packet); int pdp_packet_3Dcontext_isvalid(int packet); zl_3Dcontext *pdp_packet_3Dcontext_info(int packet); /* setters */ void pdp_packet_3Dcontext_set_subwidth(int packet, u32 w); void pdp_packet_3Dcontext_set_subheight(int packet, u32 h); /* render context activation and initialization */ void pdp_packet_3Dcontext_set_rendering_context(int packet); void pdp_packet_3Dcontext_unset_rendering_context(int packet); void pdp_packet_3Dcontext_setup_3d_context(int p); void pdp_packet_3Dcontext_setup_2d_context(int p); /* constructors */ int pdp_packet_new_3Dcontext_pbuf(u32 width, u32 height, u32 depth); int pdp_packet_new_3Dcontext_win(void); /* window specific methods */ void pdp_packet_3Dcontext_win_resize(int packet, int width, int height); void pdp_pacekt_3Dcontext_event_out(int packet, t_outlet *outlet); void pdp_packet_3Dcontext_win_cursor(int packet, bool toggle); void pdp_packet_3Dcontext_win_swapbuffers(int packet); /* converters */ int pdp_packet_3Dcontext_snap_to_bitmap(int packet, int w, int h); t_pdp_procqueue* pdp_opengl_get_queue(void); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/opengl/include/pdp_3dp_base.h000066400000000000000000000026141266045153600217040ustar00rootroot00000000000000#include "pdp_opengl.h" #include "pdp_dpd_base.h" typedef struct _pdp_3dp_base { t_pdp_dpd_base b_base; } t_pdp_3dp_base; /* destructor */ void pdp_3dp_base_free(void *x); /* init method */ void pdp_3dp_base_init(void *x); /* class setup method */ void pdp_3dp_base_setup(t_class *class); /* base class methods */ #define pdp_3dp_base_get_context_packet pdp_dpd_base_get_context_packet #define pdp_3dp_base_set_context_packet pdp_dpd_base_set_context_packet #define pdp_3dp_base_add_outlet pdp_dpd_base_add_outlet #define pdp_3dp_base_add_cleanup pdp_dpd_base_add_cleanup #define pdp_3dp_base_add_inspect pdp_dpd_base_add_inspect #define pdp_3dp_base_disable_active_inlet pdp_dpd_base_disable_active_inlet #define pdp_3dp_base_move_context_packet pdp_dpd_base_move_context_packet #define pdp_3dp_base_bang pdp_dpd_base_bang #define pdp_3dp_base_get_queue pdp_dpd_base_get_queue #define pdp_3dp_base_enable_outlet pdp_dpd_base_enable_outlet #define pdp_3dp_base_register_complete_notify pdp_dpd_base_register_complete_notify #define pdp_3dp_base_register_get_command_object pdp_dpd_base_register_get_command_object #define pdp_3dp_base_queue_wait pdp_dpd_base_queue_wait #define pdp_3dp_base_queue_command pdp_dpd_base_queue_command pdp-0.14.1+darcs20180201/opengl/include/pdp_mesh.h000066400000000000000000000132031266045153600211540ustar00rootroot00000000000000/* * Pure Data Packet module. mesh object specification * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* a very naive approach to triangular meshes */ #ifndef PDP_MESH_H #define PDP_MESH_H #include "pdp_list.h" /* VERTEX type a vertex has a coordinate and normal vector a list of triangles it is connected to and a list of vertexes it is connected to (these count as links) */ typedef struct _vertex { float c[3]; // coordinates float n[3]; // normal (or force vector) t_pdp_list *trilist; t_pdp_list *vertlist; } t_vertex; /* TRIANGLE type: a triangle consist of - 3 vertices - 3 optional median vertices (subdivision intermediates) */ typedef struct _triangle { t_vertex *v[3]; // vertices t_vertex *m[3]; // median vertices float n[3]; //triangle normal } t_triangle; /* MESH type: a mesh is a list of vertices and a list of triangles (connections) */ typedef struct _mesh { t_pdp_list *triangles; t_pdp_list *vertices; int normal_type; int refine_type; } t_mesh; /* object configuratie */ #define MESH_NORMAL_SPHERE 1 // normal = origin -> vertex #define MESH_NORMAL_PRISM 2 // normal = center of gravity of prism base -> vertex #define MESH_NORMAL_RANDOM 3 // normal = random vector #define MESH_NORMAL_AVERAGE 4 // normal = average of surrounding triangles /* refinement method */ #define MESH_REFINE_THREE 1 // triangle -> 3 triangles connecting center of gravity #define MESH_REFINE_FOUR 2 // triangle -> 4 triangles connecting link medians // vector utility stuff // fixed size iterators for the lazy #define I3(i) for(i=0; i<3; i++) #define I4(i) for(i=0; i<4; i++) static inline float _vector3_dot(float *v0, float *v1) { float d; d = v0[0] * v1[0]; d += v0[1] * v1[1]; d += v0[2] * v1[2]; return d; } static inline void _vector3_scale(float *v, float s) { int k; I3(k) v[k] *= s; } static inline float _vector3_normalize(float *v) { float length = 0; float scale = 0; int k; length = sqrt(_vector3_dot(v,v)); scale = 1.0f / length; _vector3_scale(v, scale); return length; } static inline void _vector3_cross(float *a, float *b, float *r) { r[0] = a[1]*b[2] - a[2]*b[1]; r[1] = a[2]*b[0] - a[0]*b[2]; r[2] = a[0]*b[1] - a[1]*b[0]; } static inline float _rand(void) { long int r = random(); float f; r -= (RAND_MAX >> 1); f = (float)r; f *= (2.0f / (float)RAND_MAX); return f; } /* VERTEX methods */ void vertex_add_triangle(t_vertex *v, t_triangle *t); void vertex_remove_triangle(t_vertex *v, t_triangle *t); void vertex_add_neighbour(t_vertex *v, t_vertex *neighbour); /* constructor/destructors are "private" they may only be called by the mesh object to ensure the vector list stays sound (i.e. without duplicates) */ void _vertex_free(t_vertex *v); t_vertex *_vertex_new(float *c, float *n); void vertex_compute_normal_random(t_vertex *v); void vertex_compute_normal_sphere(t_vertex *v); void vertex_compute_normal_prism(t_vertex *v); float vertex_normalize(t_vertex *v); /* TRIANGLE methods */ /* create triangle (a connection between 3 vertices): counterclockwize with facing front this method is "private" you can only create triangles as part of a mesh */ t_triangle *_triangle_new(t_vertex *v0, t_vertex *v1, t_vertex *v2); /* delete a triangle, disconnecting the vertices */ void _triangle_free(t_triangle *t); /* get triangle that shares the link between v0 and v1 */ t_triangle *triangle_neighbour(t_triangle *t, t_vertex *v0, t_vertex *v1); /* add a median vector to a link in a triangle note: vertices must be in triangle, or behaviour is undefined */ void triangle_add_median(t_triangle *t, t_vertex *v0, t_vertex *v1, t_vertex *median); /* MESH methods */ /* add and remove methods for vertices and triangles */ t_vertex *mesh_vertex_add(t_mesh *m, float *c, float *n); void mesh_vertex_remove(t_mesh *m, t_vertex *v); t_triangle *mesh_triangle_add(t_mesh *m, t_vertex *v0, t_vertex *v1, t_vertex *v2); void mesh_triangle_remove(t_mesh *m, t_triangle *t); /* calculate normals */ void mesh_calculate_normals(t_mesh *m); /* split a triangle in 4, using the intermedia median vertex storage */ void mesh_split_four(t_mesh *m, t_triangle *old_t); /* split a triangle in 3 */ void mesh_split_three(t_mesh *m, t_triangle *old_t); void mesh_split_all_four(t_mesh *m); void mesh_split_all_three(t_mesh *m); void mesh_split_random_three(t_mesh *m); void mesh_free(t_mesh *m); t_mesh *_mesh_new(void); /* new tetra */ t_mesh *mesh_new_tetra(void); void _mesh_relax_compute_resultant_spring(t_mesh *m, float *center, float d0, float r0); void _mesh_relax_apply_force(t_mesh *m, float k); void mesh_compute_center(t_mesh *m, float *c); void mesh_translate(t_mesh *m, float *c); /* relax a mesh (move toward equal link length) */ void mesh_relax(t_mesh *m, float step, float d0, float r0); /* print some debug information */ void mesh_debug(t_mesh *m); #endif pdp-0.14.1+darcs20180201/opengl/include/pdp_opengl.h000066400000000000000000000017611266045153600215120ustar00rootroot00000000000000/* * OpenGL Extension Module for pdp - Main header file * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_OPENGL_H #define PDP_OPENGL_H #include "pdp.h" #include "pdp_texture.h" #include "pdp_3Dcontext.h" t_pdp_procqueue* pdp_opengl_get_queue(void); #endif pdp-0.14.1+darcs20180201/opengl/include/pdp_texture.h000066400000000000000000000055631266045153600217320ustar00rootroot00000000000000/* * pdp system module - texture packet type * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_TEXTURE_H #define PDP_TEXTURE_H //#include //#include //#include //#include #include "pdp.h" /* TEXTURE PACKET */ typedef struct { u32 tex_obj; /* gl texture object */ s32 format; /* texture format */ u32 width; /* dims */ u32 height; u32 sub_width; /* portion of texture used */ u32 sub_height; } t_texture; #define PDP_TEXTURE 4 /* opengl texture object */ /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif /* check if valid texture packet. all other methods assume packet is valid */ int pdp_packet_texture_isvalid(int packet); /* returns a pointer to the packet subheader whem the packet contains a texture */ /* try not to use the header directly, use clone and copy methods instead */ t_texture *pdp_packet_texture_info(int packet); /* texture constructors */ int pdp_packet_new_texture(u32 width, u32 height, s32 format); /* create a texture packet */ /* texture operators */ void pdp_packet_texture_make_current(int packet); /* make a texture the current texture context */ u32 pdp_packet_texture_total_width(int packet); /* width of texture */ u32 pdp_packet_texture_total_height(int packet); /* get heigth of texture */ u32 pdp_packet_texture_sub_width(int packet); /* width of subtexture */ u32 pdp_packet_texture_sub_height(int packet); /* heigth of subtexture */ float pdp_packet_texture_fracx(int packet); /* x fraction */ float pdp_packet_texture_fracy(int packet); /* y fraction */ float pdp_packet_texture_sub_aspect(int packet); /* some utility methods */ void pdp_packet_texture_make_current_enable(int packet); /* make current & enable with default texture settings (for the lazy)*/ void pdp_packet_texture_setup_2d_context(int packet); /* set up 2d context (viewport, projection, modelview) from texture dims */ #ifdef __cplusplus } #endif #endif //PDP_TEXTURE_H pdp-0.14.1+darcs20180201/opengl/modules/000077500000000000000000000000001266045153600172325ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/modules/Makefile000066400000000000000000000004001266045153600206640ustar00rootroot00000000000000include ../Makefile.config all: pdp_3d_windowcontext.o pdp_3d_draw.o pdp_3d_view.o \ pdp_3d_push.o pdp_3d_light.o pdp_3d_dlist.o pdp_3d_color.o \ pdp_3d_snap.o pdp_3d_drawmesh.o pdp_3d_for.o pdp_3d_state.o \ pdp_3d_subcontext.o clean: rm -rf *~ *.o pdp-0.14.1+darcs20180201/opengl/modules/README000066400000000000000000000001051266045153600201060ustar00rootroot00000000000000 This directory contains opengl modules for the pdp_opengl library. pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_color.c000066400000000000000000000105631266045153600217520ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_3dp_base.h" #include "pdp_opengl.h" typedef struct _color_command { t_pdp_dpd_command x_base; int x_context; float x_newcolor[4]; float x_oldcolor[4]; } t_color_command; typedef struct _pdp_3d_color { t_pdp_3dp_base x_base; t_pdp_dpd_commandfactory x_cfact; float x_red; float x_green; float x_blue; float x_alpha; } t_pdp_3d_color; /* COMMAND METHODS */ static void pdp_3d_color_process_right(t_color_command *x) { int p = x->x_context; if (pdp_packet_3Dcontext_isvalid(p)){ pdp_packet_3Dcontext_set_rendering_context(p); /* save old color*/ glGetFloatv(GL_CURRENT_COLOR, x->x_oldcolor); /* set new color */ glColor4fv(x->x_newcolor); } } static void pdp_3d_color_process_left(t_color_command *x) { int p = x->x_context; if (pdp_packet_3Dcontext_isvalid(p)){ pdp_packet_3Dcontext_set_rendering_context(p); /* restore old color */ glColor4fv(x->x_oldcolor); //glColor4f(1,1,1,1); } /* kill self */ pdp_dpd_command_suicide(x); } /* PD OBJECT METHODS */ static void *pdp_3d_color_get_new_command(t_pdp_3d_color *x) { t_color_command *c = (t_color_command *)pdp_dpd_commandfactory_get_new_command(&x->x_cfact); c->x_newcolor[0] = x->x_red; c->x_newcolor[1] = x->x_green; c->x_newcolor[2] = x->x_blue; c->x_newcolor[3] = x->x_alpha; c->x_context = pdp_3dp_base_get_context_packet(x); return (void *)c; } static void pdp_3d_color_set_r(t_pdp_3d_color *x, t_floatarg f) {x->x_red = f;} static void pdp_3d_color_set_g(t_pdp_3d_color *x, t_floatarg f) {x->x_green = f;} static void pdp_3d_color_set_b(t_pdp_3d_color *x, t_floatarg f) {x->x_blue = f;} static void pdp_3d_color_set_a(t_pdp_3d_color *x, t_floatarg f) {x->x_alpha = f;} t_class *pdp_3d_color_class; void pdp_3d_color_free(t_pdp_3d_color *x) { pdp_3dp_base_free(x); } void *pdp_3d_color_new(t_floatarg r, t_floatarg g, t_floatarg b, t_floatarg a) { t_pdp_3d_color *x = (t_pdp_3d_color *)pd_new(pdp_3d_color_class); /* super init */ pdp_3dp_base_init(x); /* input */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("r")); pdp_base_add_gen_inlet(x, gensym("float"), gensym("g")); pdp_base_add_gen_inlet(x, gensym("float"), gensym("b")); pdp_base_add_gen_inlet(x, gensym("float"), gensym("a")); /* output */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_color_process_left, 0); pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_color_process_right, 0); x->x_red = r; x->x_green = g; x->x_blue = b; x->x_alpha = a; /* init factory */ pdp_dpd_commandfactory_init(&x->x_cfact, sizeof(t_color_command)); /* register command factory method */ pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_color_get_new_command); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_color_setup(void) { pdp_3d_color_class = class_new(gensym("3dp_color"), (t_newmethod)pdp_3d_color_new, (t_method)pdp_3d_color_free, sizeof(t_pdp_3d_color), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_color_class); class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_r, gensym("r"), A_FLOAT, A_NULL); class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_g, gensym("g"), A_FLOAT, A_NULL); class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_b, gensym("b"), A_FLOAT, A_NULL); class_addmethod(pdp_3d_color_class, (t_method)pdp_3d_color_set_a, gensym("a"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_context.c000066400000000000000000000071501266045153600223160ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_base.h" #include "pdp_opengl.h" typedef struct pdp_3d_context_struct { t_pdp_base x_base; t_outlet *x_outlet0; int x_packet0; t_symbol *x_type; unsigned int x_width; unsigned int x_height; void *x_constant; } t_pdp_3d_context; static void pdp_3d_context_preproc(t_pdp_3d_context *x) { int p; int i; /* create new packet */ p = pdp_packet_new_pbuf(x->x_width, x->x_height, 0); x->x_packet0 = p; if (-1 == p) return; pdp_pbuf_set_rendering_context(p); pdp_pbuf_setup_3d_context(p); /* clear buffer */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); /* disable everything that is enabled in other modules */ glDisable(GL_LIGHTING); for (i=0; i<8; i++) glDisable(GL_LIGHT0 + i); glDisable(GL_COLOR_MATERIAL); } static void pdp_3d_context_process(t_pdp_3d_context *x) { } static void pdp_3d_context_postproc(t_pdp_3d_context *x) { pdp_pass_if_valid(x->x_outlet0, &x->x_packet0); } static void pdp_3d_context_bang(t_pdp_3d_context *x) { pdp_base_bang(x); } static void pdp_3d_context_dim(t_pdp_3d_context *x, t_floatarg w, t_floatarg h) { x->x_width = pdp_imageproc_legalwidth((int)w); x->x_height = pdp_imageproc_legalheight((int)h); //post("dims %d %d", x->x_width, x->x_height); } static void pdp_3d_context_free(t_pdp_3d_context *x) { pdp_base_free(x); pdp_packet_mark_unused(x->x_packet0); } t_class *pdp_3d_context_class; void *pdp_3d_context_new(void) { int i; t_pdp_3d_context *x = (t_pdp_3d_context *)pd_new(pdp_3d_context_class); /* super init */ pdp_base_init(x); /* in/out*/ x->x_outlet0 = pdp_base_add_pdp_outlet(x); /* base callbacks */ pdp_base_disable_active_inlet(x); pdp_base_set_process_method(x, (t_pdp_method)pdp_3d_context_process); pdp_base_set_preproc_method(x, (t_pdp_method)pdp_3d_context_preproc); pdp_base_set_postproc_method(x, (t_pdp_method)pdp_3d_context_postproc); /* data init */ x->x_packet0 = -1; pdp_3d_context_dim(x, 320, 240); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_context_setup(void) { pdp_3d_context_class = class_new(gensym("pdp_3d_context"), (t_newmethod)pdp_3d_context_new, (t_method)pdp_3d_context_free, sizeof(t_pdp_3d_context), 0, A_NULL); class_addcreator((t_newmethod)pdp_3d_context_new, gensym("3dp_context"), A_NULL); pdp_base_setup(pdp_3d_context_class); class_addmethod(pdp_3d_context_class, (t_method)pdp_3d_context_dim, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_3d_context_class, (t_method)pdp_3d_context_bang, gensym("bang"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_dlist.c000066400000000000000000000075511266045153600217560ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" /* gl display list compilation & execution */ typedef struct pdp_3d_dlist_struct { t_pdp_3dp_base x_base; GLuint x_dlist; int x_compile; } t_pdp_3d_dlist; static void pdp_3d_dlist_complete_notify(t_pdp_3d_dlist *x) { /* disable the second outlet */ pdp_3dp_base_enable_outlet(x, 0, 0); } static void pdp_3d_dlist_compile(t_pdp_3d_dlist *x) { //x->x_compile = 1; /* enable the second outlet */ pdp_3dp_base_enable_outlet(x, 0, 1); } static void pdp_3d_dlist_process_start(t_pdp_3d_dlist *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* check if pbuf */ if (pdp_packet_3Dcontext_isvalid(p)){ /* set context */ //pdp_pbuf_set_rendering_context(p); /* display list needs to be created in the correct context if we don't have one yet, create it */ if (!x->x_dlist) x->x_dlist = glGenLists(1); /* start the list */ /* $$$TODO: error checking for recursion */ x->x_compile = 1; glNewList(x->x_dlist, GL_COMPILE_AND_EXECUTE); //glNewList(x->x_dlist, GL_COMPILE); //post("compiling"); } } } static void pdp_3d_dlist_process_cleanup(t_pdp_3d_dlist *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* check if pbuf */ if (pdp_packet_3Dcontext_isvalid(p)){ /* end list if we're compiling */ if (x->x_compile){ /* end the list */ glEndList(); /* use the list next time */ x->x_compile = 0; //post("ending compile"); } /* or execute the old one */ else { if (x->x_dlist) { //post("calling dlist %d", x->x_dlist); glCallList(x->x_dlist); } } } } } t_class *pdp_3d_dlist_class; void pdp_3d_dlist_free(t_pdp_3d_dlist *x) { pdp_3dp_base_free(x); if (x->x_dlist) glDeleteLists(x->x_dlist, 1); } void *pdp_3d_dlist_new(t_symbol *s __attribute__((__unused__))) { t_pdp_3d_dlist *x = (t_pdp_3d_dlist *)pd_new(pdp_3d_dlist_class); /* super init */ pdp_3dp_base_init(x); /* io & callbacks */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_dlist_process_start, 0); pdp_3dp_base_add_cleanup(x, (t_pdp_method)pdp_3d_dlist_process_cleanup, 0); pdp_3dp_base_register_complete_notify(x, (t_pdp_method)pdp_3d_dlist_complete_notify); /* disable the second outlet */ pdp_3dp_base_enable_outlet(x, 1, 0); /* create dlist */ x->x_dlist = 0; x->x_compile = 0; /* compile the first packet */ pdp_3d_dlist_compile(x); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_dlist_setup(void) { pdp_3d_dlist_class = class_new(gensym("pdp_3d_dlist"), (t_newmethod)pdp_3d_dlist_new, (t_method)pdp_3d_dlist_free, sizeof(t_pdp_3d_dlist), 0, A_DEFSYMBOL, A_NULL); class_addcreator((t_newmethod)pdp_3d_dlist_new, gensym("3dp_dlist"), A_DEFSYMBOL, A_NULL); pdp_3dp_base_setup(pdp_3d_dlist_class); class_addmethod(pdp_3d_dlist_class, (t_method)pdp_3d_dlist_compile, gensym("compile"), A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_draw.c000066400000000000000000000332041266045153600215660ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ //#include "GL/gl.h" #include #include #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" typedef struct _drawcommand { t_pdp_dpd_command x_head; int x_context_packet; int x_texture_packet; float x_p0; float x_p1; float x_p2; float x_p3; t_pdp_method x_method; GLUquadric* x_quadric; int x_have_texture; /* is there a valid texture ? */ } t_drawcommand; typedef struct _pdp_3d_draw { t_pdp_3dp_base x_base; t_pdp_dpd_commandfactory x_clist; int x_inlets; float x_p0; float x_p1; float x_p2; float x_p3; t_pdp_method x_method; int x_tex_in; /* the number of texture inlets */ GLUquadric* x_quadric; } t_pdp_3d_draw; void pdp_3d_draw_delete_texture(t_pdp_3d_draw *x) { pdp_base_move_packet(x, 1); } /* return a new command object */ void *pdp_3d_draw_get_command_object(t_pdp_3d_draw *x) { t_drawcommand *c = (t_drawcommand *)pdp_dpd_commandfactory_get_new_command(&x->x_clist); c->x_p0 = x->x_p0; c->x_p1 = x->x_p1; c->x_p2 = x->x_p2; c->x_p3 = x->x_p3; c->x_context_packet = pdp_3dp_base_get_context_packet(x); c->x_texture_packet = pdp_packet_copy_ro(pdp_base_get_packet(x, 1)); c->x_quadric = x->x_quadric; /* $$$TODO: this assumes quadric doesn't change */ c->x_method = x->x_method; //post("o: %x, vc %x, n %d, u %d", x, c, x->x_clist.nb_commands, c->x_head.used); return c; } /* object drawing methods */ static void draw_clear(t_drawcommand *x __attribute__((__unused__))) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } static void draw_square(t_drawcommand *x) { float f = x->x_p0 * 0.5f; float z = x->x_p1 * 0.5f; /* draw a square */ glBegin(GL_QUADS); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(1, 0); glVertex3f(f,-f, z); glTexCoord2f(1, 1); glVertex3f(f, f, z); glTexCoord2f(0, 1); glVertex3f(-f, f, z); glTexCoord2f(0, 0); glVertex3f(-f,-f, z); glEnd(); } static void draw_wsquare(t_drawcommand *x) { float f = x->x_p0; float z = x->x_p1; /* draw a square */ glBegin(GL_LINE_LOOP); glVertex3f(f,-f, z); glVertex3f(f, f, z); glVertex3f(-f, f, z); glVertex3f(-f,-f, z); glEnd(); } static void draw_triangle(t_drawcommand *x) { float f = x->x_p0 * 0.5f; float f2 = f * 0.5f; float f3 = f * (sqrt(3.0f) / 2.0f); float z = x->x_p1 * 0.5f; /* draw a triangle */ glBegin(GL_TRIANGLES); glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0.5f, 1.0f); glVertex3f(0, f, z); glTexCoord2f(0.5f * (1.0f - sqrt(3.0f)/2.0f), 0.25f); glVertex3f(-f3, -f2, z); glTexCoord2f(0.5f * (1.0f + sqrt(3.0f)/2.0f), 0.25f); glVertex3f(f3, -f2, z); glEnd(); } static void draw_wtriangle(t_drawcommand *x) { float f = x->x_p0 * 0.5f; float f2 = f * 0.5f; float f3 = f * (sqrt(3.0f) / 2.0f); float z = x->x_p1 * 0.5f; /* draw a wire triangle */ glBegin(GL_LINE_LOOP); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(0, f, z); glVertex3f(-f3, -f2, z); glVertex3f(f3, -f2, z); glEnd(); } static void draw_wcube(t_drawcommand *x) { x->x_p1 = x->x_p0; // set square z coord; glPushMatrix(); draw_wsquare(x); glRotatef(90, 0,1,0); draw_wsquare(x); glRotatef(90, 0,1,0); draw_wsquare(x); glRotatef(90, 0,1,0); draw_wsquare(x); glPopMatrix(); } static void draw_cube(t_drawcommand *x) { x->x_p1 = x->x_p0; // set square z coord; glPushMatrix(); draw_square(x); glRotatef(90, 0,1,0); draw_square(x); glRotatef(90, 0,1,0); draw_square(x); glRotatef(90, 0,1,0); draw_square(x); glPopMatrix(); glPushMatrix(); glRotatef(90, 1, 0, 0); draw_square(x); glRotatef(180, 1, 0, 0); draw_square(x); glPopMatrix(); } static void draw_wtorus(t_drawcommand *x) { float ri = x->x_p0; float ro = x->x_p1; int n = (int)x->x_p2; int m = (int)x->x_p3; if (n < 1) n = 20; if (m < 1) m = n; glutWireTorus(ri, ro, n, m); } static void draw_torus(t_drawcommand *x) { float ri = x->x_p0; float ro = x->x_p1; int n = (int)x->x_p2; int m = (int)x->x_p3; if (n < 1) n = 20; if (m < 1) m = n; glutSolidTorus(ri, ro, n, m); } static void draw_cone(t_drawcommand *x) { float base = x->x_p0; float height = x->x_p1; int n = (int)x->x_p2; int m = (int)x->x_p3; if (n < 1) n = 20; if (m < 1) m = n; glutSolidCone(base, height, n, m); } static void draw_wcone(t_drawcommand *x) { float base = x->x_p0; float height = x->x_p1; int n = (int)x->x_p2; int m = (int)x->x_p3; if (n < 1) n = 20; if (m < 1) m = n; glutWireCone(base, height, n, m); } static void draw_wteapot(t_drawcommand *x) { float f = x->x_p0; glutWireTeapot(f); } static void draw_teapot(t_drawcommand *x) { float f = x->x_p0; glutSolidTeapot(f); } static void draw_wsphere(t_drawcommand *x) { float f = x->x_p0; int n = (int)x->x_p1; int m = (int)x->x_p2; if (n < 1) n = 20; if (m < 1) m = n; glutWireSphere(f, n, m); } static void draw_sphere(t_drawcommand *x) { float f = x->x_p0; int n = (int)x->x_p1; int m = (int)x->x_p2; if (n < 1) n = 20; if (m < 1) m = n; gluSphere(x->x_quadric, f, n, m); glutSolidSphere(f, n, m); } #define UNUSED __attribute__((__unused__)) static void draw_dodeca(t_drawcommand *x UNUSED){ glutSolidDodecahedron(); } static void draw_octa(t_drawcommand *x UNUSED) { glutSolidOctahedron(); } static void draw_tetra(t_drawcommand *x UNUSED) { glutSolidTetrahedron(); } static void draw_icosa(t_drawcommand *x UNUSED) { glutSolidIcosahedron(); } static void draw_wdodeca(t_drawcommand *x UNUSED){ glutWireDodecahedron(); } static void draw_wocta(t_drawcommand *x UNUSED) { glutWireOctahedron(); } static void draw_wtetra(t_drawcommand *x UNUSED) { glutWireTetrahedron(); } static void draw_wicosa(t_drawcommand *x UNUSED) { glutWireIcosahedron(); } /* the actual (registered) draw method */ /* when this is finished, the drawcommand object should commit suicide */ static void draw_process(t_drawcommand *x) { int p = x->x_context_packet; int pt = x->x_texture_packet; float fx=1; float fy=1; x->x_have_texture = pdp_packet_texture_isvalid(pt); //post("pdp_3d_draw: context = %d, texture = %d", p, pt); /* check if it's a valid buffer we can draw in */ if (pdp_packet_3Dcontext_isvalid(p)){ /* setup rendering context */ pdp_packet_3Dcontext_set_rendering_context(p); /* enable texture */ if (x->x_have_texture){ fx = pdp_packet_texture_fracx(pt); fy = pdp_packet_texture_fracy(pt); glEnable(GL_TEXTURE_2D); pdp_packet_texture_make_current(pt); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* scale texture matrix to reflect subtexture's coords */ glMatrixMode(GL_TEXTURE); //glLoadIdentity(); glPushMatrix(); glScalef(fx, fy, 1); glMatrixMode(GL_MODELVIEW); gluQuadricTexture(x->x_quadric, 1); } /* call the generating method */ if (x->x_method) (*x->x_method)(x); /* disable texture */ if (x->x_have_texture){ glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glDisable(GL_TEXTURE_2D); gluQuadricTexture(x->x_quadric, 0); } } /* you know the drill: command done, sword in belly. */ pdp_packet_mark_unused(x->x_texture_packet); pdp_dpd_command_suicide(x); } static void pdp_3d_draw_p0(t_pdp_3d_draw *x, t_floatarg f){x->x_p0 = f;} static void pdp_3d_draw_p1(t_pdp_3d_draw *x, t_floatarg f){x->x_p1 = f;} static void pdp_3d_draw_p2(t_pdp_3d_draw *x, t_floatarg f){x->x_p2 = f;} static void pdp_3d_draw_p3(t_pdp_3d_draw *x, t_floatarg f){x->x_p3 = f;} t_class *pdp_3d_draw_class; void pdp_3d_draw_free(t_pdp_3d_draw *x) { pdp_3dp_base_free(x); gluDeleteQuadric(x->x_quadric); pdp_dpd_commandfactory_free(&x->x_clist); } void pdp_3d_draw_object(t_pdp_3d_draw *x, t_symbol *s) { /* find out if it is a buffer operation */ if (s == gensym("clear")) {x->x_method = (t_pdp_method)draw_clear; x->x_inlets = 0;} /* if not, find out which object we need to draw */ else if (s == gensym("triangle")) {x->x_method = (t_pdp_method)draw_triangle; x->x_inlets = 1;} else if (s == gensym("wtriangle")) {x->x_method = (t_pdp_method)draw_wtriangle; x->x_inlets = 1;} else if (s == gensym("square")) {x->x_method = (t_pdp_method)draw_square; x->x_inlets = 1;} else if (s == gensym("wsquare")) {x->x_method = (t_pdp_method)draw_wsquare; x->x_inlets = 1;} else if (s == gensym("cube")) {x->x_method = (t_pdp_method)draw_cube; x->x_inlets = 1;} else if (s == gensym("wcube")) {x->x_method = (t_pdp_method)draw_wcube; x->x_inlets = 1;} else if (s == gensym("sphere")) {x->x_method = (t_pdp_method)draw_sphere; x->x_inlets = 3;} else if (s == gensym("wsphere")) {x->x_method = (t_pdp_method)draw_wsphere; x->x_inlets = 3;} else if (s == gensym("torus")) {x->x_method = (t_pdp_method)draw_torus; x->x_inlets = 4;} else if (s == gensym("wtorus")) {x->x_method = (t_pdp_method)draw_wtorus; x->x_inlets = 4;} else if (s == gensym("cone")) {x->x_method = (t_pdp_method)draw_cone; x->x_inlets = 4;} else if (s == gensym("wcone")) {x->x_method = (t_pdp_method)draw_wcone; x->x_inlets = 4;} else if (s == gensym("teapot")) {x->x_method = (t_pdp_method)draw_teapot; x->x_inlets = 1;} else if (s == gensym("wteapot")) {x->x_method = (t_pdp_method)draw_wteapot; x->x_inlets = 1;} else if (s == gensym("dodeca")) {x->x_method = (t_pdp_method)draw_dodeca; x->x_inlets = 0;} else if (s == gensym("icosa")) {x->x_method = (t_pdp_method)draw_icosa; x->x_inlets = 0;} else if (s == gensym("octa")) {x->x_method = (t_pdp_method)draw_octa; x->x_inlets = 0;} else if (s == gensym("tetra")) {x->x_method = (t_pdp_method)draw_tetra; x->x_inlets = 0;} else if (s == gensym("wdodeca")) {x->x_method = (t_pdp_method)draw_wdodeca; x->x_inlets = 0;} else if (s == gensym("wicosa")) {x->x_method = (t_pdp_method)draw_wicosa; x->x_inlets = 0;} else if (s == gensym("wocta")) {x->x_method = (t_pdp_method)draw_wocta; x->x_inlets = 0;} else if (s == gensym("wtetra")) {x->x_method = (t_pdp_method)draw_wtetra; x->x_inlets = 0;} else { post("pdp_3d_draw: object %s not found", s->s_name); x->x_method = 0; x->x_inlets = 0; } // the number of texture inlets x->x_tex_in = 1; } void *pdp_3d_draw_new(t_symbol *s, t_floatarg p0, t_floatarg p1, t_floatarg p2, t_floatarg p3) { t_pdp_3d_draw *x = (t_pdp_3d_draw *)pd_new(pdp_3d_draw_class); char param[] = "p0"; int i; /* super init */ pdp_3dp_base_init(x); x->x_p0 = p0; x->x_p1 = p1; x->x_p2 = p2; x->x_p3 = p3; /* set the object & number of inlets */ pdp_3d_draw_object(x, s); /* create texture inlets */ for(i=0; ix_tex_in; i++){ pdp_base_add_pdp_inlet(x); } /* create additional inlets */ for(i=0; ix_inlets; i++){ pdp_base_add_gen_inlet(x, gensym("float"), gensym(param)); param[1]++; } /* create dpd outlet */ pdp_3dp_base_add_outlet(x, (t_pdp_method)draw_process, 0); /* setup quadric */ x->x_quadric = gluNewQuadric(); /* init command list */ pdp_dpd_commandfactory_init(&x->x_clist, sizeof(t_drawcommand)); /* register command factory method */ pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_draw_get_command_object); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_draw_setup(void) { // FIXME: The GLUT dependency has been added in the revival of 3DP 2013-10 // It might be best to remove it again and just copy the drawing routines. int argc = 0; glutInit(&argc, NULL); pdp_3d_draw_class = class_new(gensym("3dp_draw"), (t_newmethod)pdp_3d_draw_new, (t_method)pdp_3d_draw_free, sizeof(t_pdp_3d_draw), 0, A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_draw_class); class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p0, gensym("p0"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p1, gensym("p1"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p2, gensym("p2"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_p3, gensym("p3"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_draw_class, (t_method)pdp_3d_draw_delete_texture, gensym("delete_texture"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_drawmesh.c000066400000000000000000000222661266045153600224510ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* a very naive approach to triangular meshes */ // $$TODO: some serious memory corruption in this file our the list implementation #include "GL/gl.h" #include //#include #include "pdp_opengl.h" #include "pdp_3dp_base.h" #include "pdp_mesh.h" /* PD OBJECT */ typedef struct _pdp_3d_drawmesh { t_pdp_3dp_base x_base; t_pdp_dpd_commandfactory x_clist; t_mesh *x_mesh; int x_wireframe; int x_flatshading; } t_pdp_3d_drawmesh; /* MESHCOMMAND OBJECT */ typedef struct _meshcommand { t_pdp_dpd_command x_head; int x_context_packet; int x_texture_packet; t_pdp_3d_drawmesh *x_mother; t_pdp_method x_method; int x_wireframe; int x_flatshading; float x_step; float x_d0; float x_r0; int x_normal_type; } t_meshcommand; /* MESHCOMMAND METHODS */ /* draw the mesh */ static void meshcommand_draw(t_meshcommand *x) { int i = 0; t_pdp_atom *it; t_pdp_list *tl = x->x_mother->x_mesh->triangles; t_triangle *t; GLenum mode = (x->x_wireframe) ? GL_LINE_LOOP : GL_TRIANGLES; //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); glLineWidth(5); glBegin(mode); if (x->x_flatshading){ PDP_POINTER_IN(tl, it, t){ glNormal3fv(t->n); for (i=0; i<3; i++){ glVertex3fv(t->v[i]->c); } } } else{ PDP_POINTER_IN(tl, it, t){ for (i=0; i<3; i++){ glNormal3fv(t->v[i]->n); glVertex3fv(t->v[i]->c); } } } glEnd(); } static void meshcommand_relax(t_meshcommand *x) { mesh_relax(x->x_mother->x_mesh, x->x_step, x->x_d0, x->x_r0); } /* the main subcommand dispatcher */ static void meshcommand_execute(t_meshcommand *x) { int p = x->x_context_packet; /* check if it's a valid buffer we can draw in */ if (pdp_packet_3Dcontext_isvalid(p)){ /* setup rendering context */ pdp_packet_3Dcontext_set_rendering_context(p); /* call the command method */ if (x->x_method) (x->x_method)(x); } /* you know the drill: command done, sword in belly. */ pdp_dpd_command_suicide(x); } static void meshcommand_split_all_four(t_meshcommand *x) { mesh_split_all_four(x->x_mother->x_mesh); } static void meshcommand_split_all_three(t_meshcommand *x){ mesh_split_all_three(x->x_mother->x_mesh); } static void meshcommand_split_random_three(t_meshcommand *x){ mesh_split_random_three(x->x_mother->x_mesh); } static void meshcommand_reset(t_meshcommand *x) { mesh_free(x->x_mother->x_mesh); x->x_mother->x_mesh = mesh_new_tetra(); } static void meshcommand_debug(t_meshcommand *x) { mesh_debug(x->x_mother->x_mesh); } static void meshcommand_calculate_normals(t_meshcommand *x) { x->x_mother->x_mesh->normal_type = x->x_normal_type; mesh_calculate_normals(x->x_mother->x_mesh); } /* PD OBJECT METHODS */ /* return a new command object */ void *pdp_3d_drawmesh_get_command_object(t_pdp_3d_drawmesh *x) { t_meshcommand *c = (t_meshcommand *)pdp_dpd_commandfactory_get_new_command(&x->x_clist); c->x_context_packet = pdp_3dp_base_get_context_packet(x); c->x_mother = x; c->x_method = (t_pdp_method)meshcommand_draw; //default command is draw c->x_wireframe = x->x_wireframe; c->x_flatshading = x->x_flatshading; return c; } /* schedule a command */ static void pdp_3d_drawmesh_queue_command(t_pdp_3d_drawmesh *x, t_meshcommand *c) { pdp_3dp_base_queue_command(x, c, (t_pdp_method)meshcommand_execute, 0, 0); } static void pdp_3d_drawmesh_queue_simple_command(t_pdp_3d_drawmesh *x, t_pdp_method method) { t_meshcommand *c = (t_meshcommand *)pdp_3d_drawmesh_get_command_object(x); c->x_method = method; pdp_3dp_base_queue_command(x, c, (t_pdp_method)meshcommand_execute, 0, 0); } //NOTE: only the meshcommands are entitled to use the mesh (thread issues) //therefore all mesh manipulations must be queued as a command static void pdp_3d_drawmesh_debug(t_pdp_3d_drawmesh *x) { pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_debug); } static void pdp_3d_drawmesh_relax(t_pdp_3d_drawmesh *x, t_floatarg step, t_floatarg d0, t_floatarg r0) { t_meshcommand *c = (t_meshcommand *)pdp_3d_drawmesh_get_command_object(x); c->x_step = step; c->x_d0 = d0; c->x_r0 = r0; c->x_method = (t_pdp_method)meshcommand_relax; pdp_3d_drawmesh_queue_command(x, c); } void pdp_3d_drawmesh_normal(t_pdp_3d_drawmesh *x, t_symbol *s) { t_meshcommand *c = (t_meshcommand *)pdp_3d_drawmesh_get_command_object(x); if (gensym("sphere") == s) c->x_normal_type = MESH_NORMAL_SPHERE; else if (gensym("prism") == s) c->x_normal_type = MESH_NORMAL_PRISM; else if (gensym("random") == s) c->x_normal_type = MESH_NORMAL_RANDOM; else if (gensym("average") == s) c->x_normal_type = MESH_NORMAL_AVERAGE; c->x_method = (t_pdp_method)meshcommand_calculate_normals; pdp_3d_drawmesh_queue_command(x, c); } /* this is used by the standard drawing routine, so doesn't need to be scheduled */ void pdp_3d_drawmesh_wireframe(t_pdp_3d_drawmesh *x, t_float f) { x->x_wireframe = (f != 0.0f); } void pdp_3d_drawmesh_flatshading(t_pdp_3d_drawmesh *x, t_float f) { x->x_flatshading = (f != 0.0f); } static void pdp_3d_drawmesh_split_all_four(t_pdp_3d_drawmesh *x) { pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_split_all_four); } static void pdp_3d_drawmesh_split_all_three(t_pdp_3d_drawmesh *x) { pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_split_all_three); } static void pdp_3d_drawmesh_split_random_three(t_pdp_3d_drawmesh *x) { pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_split_random_three); } static void pdp_3d_drawmesh_reset(t_pdp_3d_drawmesh *x) { pdp_3d_drawmesh_queue_simple_command(x, (t_pdp_method)meshcommand_reset); } t_class *pdp_3d_drawmesh_class; void pdp_3d_drawmesh_free(t_pdp_3d_drawmesh *x) { /* queue needs to finish before mesh is deleted */ pdp_3dp_base_queue_wait(x); mesh_free(x->x_mesh); pdp_3dp_base_free(x); pdp_dpd_commandfactory_free(&x->x_clist); } void *pdp_3d_drawmesh_new(t_symbol *s __attribute__((__unused__)), t_floatarg p0 __attribute__((__unused__)), t_floatarg p1 __attribute__((__unused__)), t_floatarg p2 __attribute__((__unused__)), t_floatarg p3 __attribute__((__unused__))) { t_pdp_3d_drawmesh *x = (t_pdp_3d_drawmesh *)pd_new(pdp_3d_drawmesh_class); /* super init */ pdp_3dp_base_init(x); /* create dpd outlet */ pdp_3dp_base_add_outlet(x, (t_pdp_method)meshcommand_execute, 0); /* init command list */ pdp_dpd_commandfactory_init(&x->x_clist, sizeof(t_meshcommand)); /* register command factory method */ pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_drawmesh_get_command_object); /* initialize triangular mesh with a simply connected manifold */ x->x_mesh = mesh_new_tetra(); x->x_wireframe = 0; x->x_flatshading = 0; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_drawmesh_setup(void) { pdp_3d_drawmesh_class = class_new(gensym("3dp_drawmesh"), (t_newmethod)pdp_3d_drawmesh_new, (t_method)pdp_3d_drawmesh_free, sizeof(t_pdp_3d_drawmesh), 0, A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_drawmesh_class); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_split_random_three, gensym("split3random"), A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_split_all_three, gensym("split3"), A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_split_all_four, gensym("split4"), A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_reset, gensym("reset"), A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_normal, gensym("normal"), A_SYMBOL, A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_relax, gensym("springrelax"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_debug, gensym("info"), A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_wireframe, gensym("wireframe"), A_FLOAT, A_NULL); class_addmethod(pdp_3d_drawmesh_class, (t_method)pdp_3d_drawmesh_flatshading, gensym("flatshading"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_for.c000066400000000000000000000047261266045153600214260ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* a for loop for 3dp packets this can later be adapted to a for loop for dpd packets. */ #include "pdp_opengl.h" #include "pdp_internals.h" typedef struct pdp_3d_for_struct { t_object x_obj; t_int x_count; t_outlet *x_outlet_dpd; t_outlet *x_outlet_float; } t_pdp_3d_for; static void pdp_3d_for_input_0(t_pdp_3d_for *x, t_symbol *s, t_floatarg f) { int i; /* trigger on "accumulate" */ if (s == gensym("accumulate")){ for (i=0; ix_count; i++){ outlet_float(x->x_outlet_float, (float)i); outlet_dpd(x->x_outlet_dpd, (int)f); } } } static void pdp_3d_for_count(t_pdp_3d_for *x, t_floatarg f) { int count = (int)f; if (count >= 0) x->x_count = count; } static void pdp_3d_for_free(t_pdp_3d_for *x __attribute__((__unused__))) { } t_class *pdp_3d_for_class; void *pdp_3d_for_new(t_floatarg f) { int count = (int)f; t_pdp_3d_for *x = (t_pdp_3d_for *)pd_new(pdp_3d_for_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("count")); x->x_outlet_dpd = outlet_new(&x->x_obj, &s_anything); x->x_outlet_float = outlet_new(&x->x_obj, &s_float); x->x_count = (count > 0) ? count : 1; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_for_setup(void) { pdp_3d_for_class = class_new(gensym("3dp_for"), (t_newmethod)pdp_3d_for_new, (t_method)pdp_3d_for_free, sizeof(t_pdp_3d_for), 0, A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_for_class, (t_method)pdp_3d_for_input_0, gensym("dpd"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_for_class, (t_method)pdp_3d_for_count, gensym("count"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_light.c000066400000000000000000000103731266045153600217420ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" typedef struct pdp_3d_light_struct { t_pdp_3dp_base x_base; //float x_centerx; //float x_centery; //float x_centerz; int x_index; } t_pdp_3d_light; static void pdp_3d_light_process(t_pdp_3d_light *x) { int p = pdp_3dp_base_get_context_packet(x); int i; GLfloat ambient[] = {.7,.7,.7,1}; GLfloat diffuse[] = {.6,.6,.6,1}; GLfloat specular[] = {1, 1, 1, 1}; GLfloat shininess[] = {50}; GLfloat position[] = {0,0,1,1}; GLfloat intensity[] = {1,1,1,0}; int light = GL_LIGHT0 + x->x_index; /* check if it's a valid buffer we can draw in */ if (pdp_packet_3Dcontext_isvalid(p)){ position[0] = 0; //x->x_centerx; position[1] = 0; //x->x_centery; position[2] = 0; //x->x_centerz; /* set rendering context */ //pdp_packet_3Dcontext_set_rendering_context(p); /* setup lighting */ glEnable(GL_LIGHTING); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); //glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT, GL_SPECULAR, specular); glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); glMaterialfv(GL_FRONT, GL_SHININESS, shininess); glLightfv(light, GL_POSITION, position); //glLightfv(light, GL_DIFFUSE, intensity); glEnable(light); /* ALPHA HACK */ //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glBlendFunc(GL_SRC_ALPHA, GL_ONE); //glEnable(GL_ALPHA_TEST); //glAlphaFunc(GL_GREATER, 0.f); } } //static void pdp_3d_light_centerx(t_pdp_3d_light *x, t_floatarg f){x->x_centerx = f;} //static void pdp_3d_light_centery(t_pdp_3d_light *x, t_floatarg f){x->x_centery = f;} //static void pdp_3d_light_centerz(t_pdp_3d_light *x, t_floatarg f){x->x_centerz = f;} t_class *pdp_3d_light_class; void pdp_3d_light_free(t_pdp_3d_light *x) { pdp_3dp_base_free(x); } #define UNUSED __attribute__((__unused__)) void *pdp_3d_light_new(t_floatarg fi, t_floatarg cx UNUSED, t_floatarg cy UNUSED, t_floatarg cz UNUSED) { t_pdp_3d_light *x = (t_pdp_3d_light *)pd_new(pdp_3d_light_class); /* super init */ pdp_3dp_base_init(x); if (fi < 0) fi = 0; x->x_index = (int)fi; //x->x_centerx = cx; //x->x_centery = cy; //x->x_centerz = cz; /* io */ //pdp_base_add_gen_inlet(x, gensym("float"), gensym("centerx")); //pdp_base_add_gen_inlet(x, gensym("float"), gensym("centery")); //pdp_base_add_gen_inlet(x, gensym("float"), gensym("centerz")); /* add dpd outlet */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_light_process, 0); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_light_setup(void) { pdp_3d_light_class = class_new(gensym("3dp_light"), (t_newmethod)pdp_3d_light_new, (t_method)pdp_3d_light_free, sizeof(t_pdp_3d_light), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_light_class); //class_addmethod(pdp_3d_light_class, (t_method)pdp_3d_light_centerx, gensym("centerx"), A_DEFFLOAT, A_NULL); //class_addmethod(pdp_3d_light_class, (t_method)pdp_3d_light_centery, gensym("centery"), A_DEFFLOAT, A_NULL); //class_addmethod(pdp_3d_light_class, (t_method)pdp_3d_light_centerz, gensym("centerz"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_push.c000066400000000000000000000074751266045153600216230ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" typedef struct pdp_3d_push_struct { t_pdp_3dp_base x_base; GLenum x_matrix; int x_change_mode; } t_pdp_3d_push; static void pdp_3d_push_process_right(t_pdp_3d_push *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* push one of the matrices */ glMatrixMode(x->x_matrix); glPushMatrix(); /* set default matrix to modelview */ if (!x->x_change_mode) glMatrixMode(GL_MODELVIEW); } } static void pdp_3d_push_process_left(t_pdp_3d_push *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* restore the saved matrix */ glMatrixMode(x->x_matrix); glPopMatrix(); /* set default matrix back to modelview */ glMatrixMode(GL_MODELVIEW); } } static void pdp_3d_mode_process_right(t_pdp_3d_push *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* change matrix mode */ glMatrixMode(x->x_matrix); } } static void pdp_3d_mode_process_left(t_pdp_3d_push *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* restore default matrix to modelview */ glMatrixMode(GL_MODELVIEW); } } static void pdp_3d_push_setmatrix(t_pdp_3d_push *x, t_symbol *s) { GLenum m; /* find out which matrix to push */ if (s == gensym("projection")) m = GL_PROJECTION; else if (s == gensym("modelview")) m = GL_MODELVIEW; else if (s == gensym("texture")) m = GL_TEXTURE; else if (s == gensym("color")) m = GL_COLOR; /* default is modelview */ else m = GL_MODELVIEW; x->x_matrix = m; } t_class *pdp_3d_push_class; void pdp_3d_push_free(t_pdp_3d_push *x) { pdp_3dp_base_free(x); } void *pdp_3d_push_mode_new(t_symbol *s) { t_pdp_3d_push *x = (t_pdp_3d_push *)pd_new(pdp_3d_push_class); /* super init */ pdp_3dp_base_init(x); /* setup which matrix we are talking about */ pdp_3d_push_setmatrix(x, s); x->x_change_mode = 0; return (void *)x; } void *pdp_3d_push_new(t_symbol *s, t_floatarg f) { t_pdp_3d_push *x = (t_pdp_3d_push *)pdp_3d_push_mode_new(s); /* create dpd outlets */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_push_process_left, 0); pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_push_process_right, 0); x->x_change_mode = (f != 0.0f); return (void *)x; } void *pdp_3d_mode_new(t_symbol *s) { t_pdp_3d_push *x = (t_pdp_3d_push *)pdp_3d_push_mode_new(s); /* create dpd outlets */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_mode_process_left, 0); pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_mode_process_right, 0); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_push_setup(void) { pdp_3d_push_class = class_new(gensym("3dp_push"), (t_newmethod)pdp_3d_push_new, (t_method)pdp_3d_push_free, sizeof(t_pdp_3d_push), 0, A_DEFSYMBOL, A_NULL); class_addcreator((t_newmethod)pdp_3d_mode_new, gensym("3dp_mode"), A_DEFSYMBOL, A_NULL); pdp_3dp_base_setup(pdp_3d_push_class); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_snap.c000066400000000000000000000126251266045153600215760ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp.h" #include "pdp_3dp_base.h" #include "pdp_opengl.h" typedef struct _pdp_3d_snap { t_pdp_3dp_base x_base; t_pdp_dpd_commandfactory x_cfact; t_outlet *x_result_outlet; t_pdp_symbol *x_dest_template; int x_is_texture; u32 x_width; u32 x_height; int x_auto_snap; int x_pending_snap; } t_pdp_3d_snap; typedef struct _snap_command { t_pdp_dpd_command x_base; t_pdp_3d_snap *x_mother; int x_context_packet; int x_result_packet; int x_active; } t_snap_command; /* COMAND METHODS */ static void snap_texture_process(t_snap_command *x) { int pt = -1; int p = x->x_context_packet; int i; u32 w,h; if (x->x_active && pdp_packet_3Dcontext_isvalid(p)){ /* get dest texture sub dims */ w = (x->x_mother->x_width) ? x->x_mother->x_width : pdp_packet_3Dcontext_subwidth(p); h = (x->x_mother->x_height) ? x->x_mother->x_height : pdp_packet_3Dcontext_subheight(p); /* texture is a special case */ if (x->x_mother->x_is_texture){ /* create a new texture packet */ pt = pdp_packet_new_texture(w,h,GL_RGB); if (-1 != pt) { /* set rendering context */ pdp_packet_3Dcontext_set_rendering_context(p); /* copy pbuf to new texture */ pdp_packet_texture_make_current(pt); //glReadBuffer(GL_FRONT); //this is for weird feedback stuff.. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h); x->x_result_packet = pt; } } /* other type: snap to bitmap first, then convert */ else{ //nvidia driver 4191 bug workaround (w -> multiple of 4) w &= -4; pt = pdp_packet_3Dcontext_snap_to_bitmap(p, w, h); //pt = pdp_packet_new_bitmap_rgb(w, h); //pdp_packet_print_debug(pt); x->x_result_packet = pdp_packet_convert_ro(pt, x->x_mother->x_dest_template); pdp_packet_mark_unused(pt); } } } static void snap_callback(t_snap_command *x) { /* send packet to outlet */ pdp_packet_pass_if_valid(x->x_mother->x_result_outlet, &x->x_result_packet); pdp_dpd_command_suicide(x); } /* PD OBJECT METHODS */ static void pdp_3d_snap_snap(t_pdp_3d_snap *x) { x->x_pending_snap = 1; } static void pdp_3d_snap_autosnap(t_pdp_3d_snap *x, t_floatarg f) { if (f){ x->x_auto_snap = 1; x->x_pending_snap = 1; } else{ x->x_auto_snap = 0; x->x_pending_snap = 0; } } static void *pdp_3d_snap_get_new_command(t_pdp_3d_snap *x) { t_snap_command *c = (t_snap_command *)pdp_dpd_commandfactory_get_new_command(&x->x_cfact); c->x_mother = x; c->x_context_packet = pdp_3dp_base_get_context_packet(x); c->x_result_packet = -1; c->x_active = x->x_pending_snap; if (!x->x_auto_snap) x->x_pending_snap = 0; return (void *)c; } t_class *pdp_3d_snap_class; void pdp_3d_snap_free(t_pdp_3d_snap *x) { //pdp_dpd_base_queue_wait(x); pdp_3dp_base_free(x); } void *pdp_3d_snap_new(t_symbol *s, t_floatarg w, t_floatarg h) { t_pdp_3d_snap *x = (t_pdp_3d_snap *)pd_new(pdp_3d_snap_class); /* super init */ pdp_3dp_base_init(x); /* get destination template */ x->x_dest_template = (s == gensym("")) ? pdp_gensym("texture/*/*") : pdp_gensym(s->s_name); x->x_is_texture = pdp_type_description_match(x->x_dest_template, pdp_gensym("texture/*/*")); w = (w < 0) ? 0 : w; h = (h < 0) ? 0 : h; x->x_width = w; x->x_height = h; x->x_auto_snap = 1; x->x_pending_snap = 1; /* issue warning */ if (!x->x_is_texture && !(x->x_width && x->x_height)){ //post("WARNING: 3dp_snap: target is not a texture and dimensions are not set."); //post("WARNING: using default image size 320x240."); //x->x_width = 320; //x->x_height = 240; } /* create outlets */ pdp_3dp_base_add_outlet(x, (t_pdp_method)snap_texture_process, (t_pdp_method)snap_callback); x->x_result_outlet = outlet_new((t_object *)x, &s_anything); /* init command list */ pdp_dpd_commandfactory_init(&x->x_cfact, sizeof(t_snap_command)); /* register command factory method */ pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_snap_get_new_command); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_snap_setup(void) { pdp_3d_snap_class = class_new(gensym("3dp_snap"), (t_newmethod)pdp_3d_snap_new, (t_method)pdp_3d_snap_free, sizeof(t_pdp_3d_snap), 0, A_DEFSYMBOL, A_DEFFLOAT, A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_snap_class); class_addmethod(pdp_3d_snap_class, (t_method)pdp_3d_snap_snap, gensym("bang"), A_NULL); class_addmethod(pdp_3d_snap_class, (t_method)pdp_3d_snap_autosnap, gensym("autosnap"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_state.c000066400000000000000000000073141266045153600217540ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* change binary opengl state variables. all defaults (flag = 0) should be set in the render context init. right outlet has the thing enabled (or disabled, depending on toggle) left outlet has the thing disabled (better: it should push it) simple version: does not permit reentry (yet) */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" typedef struct pdp_3d_state_struct { t_pdp_3dp_base x_base; GLboolean x_flag; GLboolean x_prev_flag; GLenum x_thing; void (*x_setup)(void); } t_pdp_3d_state; static void _setflag(GLenum thing, GLboolean flag) { if (flag) glEnable(thing); else glDisable(thing); } static void pdp_3d_state_process_right(t_pdp_3d_state *x) { int p; if (-1 != (p = pdp_3dp_base_get_context_packet(x))){ /* store previous flag */ pdp_packet_3Dcontext_set_rendering_context(p); glGetBooleanv(x->x_thing, &x->x_prev_flag); _setflag(x->x_thing, x->x_flag); if (x->x_setup) x->x_setup(); } } static void pdp_3d_state_process_left(t_pdp_3d_state *x) { int p; /* allways run left method (reset) */ if (-1 != (p = pdp_3dp_base_get_context_packet(x))){ pdp_packet_3Dcontext_set_rendering_context(p); _setflag(x->x_thing, x->x_prev_flag); } } static void pdp_3d_state_flag(t_pdp_3d_state *x, t_floatarg f) { x->x_flag = (f == 0.0f) ? GL_FALSE : GL_TRUE; } static void _blend(void) {glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);} static void _blend_add(void) {glBlendFunc(GL_SRC_ALPHA, GL_ONE);} t_class *pdp_3d_state_class; void pdp_3d_state_free(t_pdp_3d_state *x){pdp_3dp_base_free(x);} void *pdp_3d_state_new(t_symbol *s, t_floatarg f) { t_pdp_3d_state *x = (t_pdp_3d_state *)pd_new(pdp_3d_state_class); /* super init */ pdp_3dp_base_init(x); pdp_3d_state_flag(x,f); if (s == gensym("blend_mix")) {x->x_setup = _blend; x->x_thing = GL_BLEND;} else if (s == gensym("blend_add")) {x->x_setup = _blend_add; x->x_thing = GL_BLEND;} else if (s == gensym("depth_test")) {x->x_setup = 0; x->x_thing = GL_DEPTH_TEST;} /* unkown command: do nothing */ else { post ("3dp_state: unknown flag %s", s->s_name); pd_free((void *)x); return 0; } /* create additional inlet */ pdp_base_add_gen_inlet(x, gensym("float"), gensym("flag")); /* create dpd outlets */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_state_process_left, 0); pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_state_process_right, 0); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_state_setup(void) { pdp_3d_state_class = class_new(gensym("3dp_toggle"), (t_newmethod)pdp_3d_state_new, (t_method)pdp_3d_state_free, sizeof(t_pdp_3d_state), 0, A_SYMBOL, A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_state_class); class_addmethod(pdp_3d_state_class, (t_method)pdp_3d_state_flag, gensym("flag"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_subcontext.c000066400000000000000000000053651266045153600230360ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" typedef struct pdp_3d_subcontext_struct { t_pdp_3dp_base x_base; int x_width; int x_height; } t_pdp_3d_subcontext; static void pdp_3d_subcontext_process_right(t_pdp_3d_subcontext *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* set subdims */ pdp_packet_3Dcontext_set_subwidth(p, x->x_width); pdp_packet_3Dcontext_set_subheight(p, x->x_height); /* reinit everything */ pdp_packet_3Dcontext_set_rendering_context(p); pdp_packet_3Dcontext_setup_3d_context(p); } } static void pdp_3d_subcontext_process_left(t_pdp_3d_subcontext *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 != p){ /* restore subdims */ pdp_packet_3Dcontext_set_subwidth(p, pdp_packet_3Dcontext_width(p)); pdp_packet_3Dcontext_set_subheight(p, pdp_packet_3Dcontext_height(p)); /* re-init everything */ pdp_packet_3Dcontext_set_rendering_context(p); pdp_packet_3Dcontext_setup_3d_context(p); } } t_class *pdp_3d_subcontext_class; void pdp_3d_subcontext_free(t_pdp_3d_subcontext *x) { pdp_3dp_base_free(x); } void *pdp_3d_subcontext_new(t_floatarg w, t_floatarg h) { t_pdp_3d_subcontext *x = (t_pdp_3d_subcontext *)pd_new(pdp_3d_subcontext_class); /* super init */ pdp_3dp_base_init(x); /* create dpd outlets */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_subcontext_process_left, 0); pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_subcontext_process_right, 0); x->x_width = (w < 0) ? 64 : w; x->x_height = (h < 0) ? 64 : h; return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_subcontext_setup(void) { pdp_3d_subcontext_class = class_new(gensym("3dp_subcontext"), (t_newmethod)pdp_3d_subcontext_new, (t_method)pdp_3d_subcontext_free, sizeof(t_pdp_3d_subcontext), 0, A_FLOAT, A_FLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_subcontext_class); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_view.c000066400000000000000000000162471266045153600216130ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" /* PD OBJECT */ typedef struct _pdp_3d_view { t_pdp_3dp_base x_base; t_pdp_dpd_commandfactory x_clist; float x_p0; float x_p1; float x_p2; float x_p3; t_pdp_method x_method; int x_inlets; } t_pdp_3d_view; /* COMMAND OBJECT */ typedef struct _viewcommand { t_pdp_dpd_command x_head; // viewcommand base t_pdp_3d_view *x_x; // command owner int x_context_packet; float x_p0; float x_p1; float x_p2; float x_p3; } t_viewcommand; /* COMMAND OBJECT METHODS */ /* rotate about the negative z axis */ static void view_rot2d(t_viewcommand *x) {glRotatef(x->x_p0, 0, 0, -1);} /* rotate about the positive x,y,z axis */ static void view_rotx(t_viewcommand *x) {glRotatef(x->x_p0, 1, 0, 0);} static void view_roty(t_viewcommand *x) {glRotatef(x->x_p0, 0, 1, 0);} static void view_rotz(t_viewcommand *x) {glRotatef(x->x_p0, 0, 0, 1);} static void view_rota(t_viewcommand *x) {glRotatef(x->x_p3, x->x_p0, x->x_p1, x->x_p2);} /* translate along an axis */ static void view_transx(t_viewcommand *x) {glTranslatef(x->x_p0, 0, 0);} static void view_transy(t_viewcommand *x) {glTranslatef(0, x->x_p0, 0);} static void view_transz(t_viewcommand *x) {glTranslatef(0, 0, x->x_p0);} static void view_transxyz(t_viewcommand *x) {glTranslatef(x->x_p0, x->x_p1, x->x_p2);} /* rotate about the positive x,y,z axis */ static void view_scalex(t_viewcommand *x) {glScalef(x->x_p0, 1, 1);} static void view_scaley(t_viewcommand *x) {glScalef(1, x->x_p0, 1);} static void view_scalez(t_viewcommand *x) {glScalef(1, 1, x->x_p0);} static void view_scale(t_viewcommand *x) {glScalef(x->x_p0, x->x_p0, x->x_p0);} /* specials */ static void view_reset_3d(t_viewcommand *x) {pdp_packet_3Dcontext_setup_3d_context(x->x_context_packet);} static void view_scale_aspect(t_viewcommand *x) {glScalef(pdp_packet_3Dcontext_subaspect(x->x_context_packet),1,1);} /* process command */ static void view_process(t_viewcommand *x) { int p = x->x_context_packet; /* check if it's a valid context buffer we can draw in */ if (pdp_packet_3Dcontext_isvalid(p)){ /* setup rendering context */ pdp_packet_3Dcontext_set_rendering_context(p); /* call the generating method */ if (x->x_x->x_method) (*x->x_x->x_method)(x); } /* suicide */ pdp_dpd_command_suicide(x); } /* command object factory method */ void *pdp_3d_view_get_command_object(t_pdp_3d_view *x) { t_viewcommand *c = (t_viewcommand *)pdp_dpd_commandfactory_get_new_command(&x->x_clist); c->x_p0 = x->x_p0; c->x_p1 = x->x_p1; c->x_p2 = x->x_p2; c->x_p3 = x->x_p3; c->x_context_packet = pdp_3dp_base_get_context_packet(x); c->x_x = x; return c; } /* PD OBJECT METHODS */ static void pdp_3d_view_p0(t_pdp_3d_view *x, t_floatarg f){x->x_p0 = f;} static void pdp_3d_view_p1(t_pdp_3d_view *x, t_floatarg f){x->x_p1 = f;} static void pdp_3d_view_p2(t_pdp_3d_view *x, t_floatarg f){x->x_p2 = f;} static void pdp_3d_view_p3(t_pdp_3d_view *x, t_floatarg f){x->x_p3 = f;} t_class *pdp_3d_view_class; void pdp_3d_view_free(t_pdp_3d_view *x) { pdp_dpd_commandfactory_free(&x->x_clist); pdp_3dp_base_free(x); } void *pdp_3d_view_new(t_symbol *s, t_floatarg p0, t_floatarg p1, t_floatarg p2, t_floatarg p3) { t_pdp_3d_view *x = (t_pdp_3d_view *)pd_new(pdp_3d_view_class); char param[] = "p0"; int i; /* super init */ pdp_3dp_base_init(x); x->x_p0 = p0; x->x_p1 = p1; x->x_p2 = p2; x->x_p3 = p3; /* find out which transform we need to apply */ if (s == gensym("rot2d")) {x->x_method = (t_pdp_method)view_rot2d; x->x_inlets = 1;} else if (s == gensym("rotx")) {x->x_method = (t_pdp_method)view_rotx; x->x_inlets = 1;} else if (s == gensym("roty")) {x->x_method = (t_pdp_method)view_roty; x->x_inlets = 1;} else if (s == gensym("rotz")) {x->x_method = (t_pdp_method)view_rotz; x->x_inlets = 1;} else if (s == gensym("rota")) {x->x_method = (t_pdp_method)view_rota; x->x_inlets = 4;} else if (s == gensym("transx")) {x->x_method = (t_pdp_method)view_transx; x->x_inlets = 1;} else if (s == gensym("transy")) {x->x_method = (t_pdp_method)view_transy; x->x_inlets = 1;} else if (s == gensym("transz")) {x->x_method = (t_pdp_method)view_transz; x->x_inlets = 1;} else if (s == gensym("transxyz")) {x->x_method = (t_pdp_method)view_transxyz; x->x_inlets = 3;} else if (s == gensym("scalex")) {x->x_method = (t_pdp_method)view_scalex; x->x_inlets = 1;} else if (s == gensym("scaley")) {x->x_method = (t_pdp_method)view_scaley; x->x_inlets = 1;} else if (s == gensym("scalez")) {x->x_method = (t_pdp_method)view_scalez; x->x_inlets = 1;} else if (s == gensym("scale")) {x->x_method = (t_pdp_method)view_scale; x->x_inlets = 1;} else if (s == gensym("scale_aspect")) {x->x_method = (t_pdp_method)view_scale_aspect; x->x_inlets = 0;} else if (s == gensym("reset")) {x->x_method = (t_pdp_method)view_reset_3d; x->x_inlets = 0;} else { post("pdp_view: view transformation %s not found", s->s_name); x->x_method = 0; x->x_inlets = 0; } /* create additional inlets */ for(i=0; ix_inlets; i++){ pdp_base_add_gen_inlet(x, gensym("float"), gensym(param)); param[1]++; } /* create dpd outlet */ pdp_3dp_base_add_outlet(x, (t_pdp_method)view_process, 0); /* init command factory */ pdp_dpd_commandfactory_init(&x->x_clist, sizeof(t_viewcommand)); /* register command factory method */ pdp_dpd_base_register_command_factory_method(x, (t_pdp_newmethod)pdp_3d_view_get_command_object); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_view_setup(void) { pdp_3d_view_class = class_new(gensym("3dp_view"), (t_newmethod)pdp_3d_view_new, (t_method)pdp_3d_view_free, sizeof(t_pdp_3d_view), 0, A_SYMBOL, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT, A_NULL); pdp_3dp_base_setup(pdp_3d_view_class); class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p0, gensym("p0"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p1, gensym("p1"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p2, gensym("p2"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_3d_view_class, (t_method)pdp_3d_view_p3, gensym("p3"), A_DEFFLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/modules/pdp_3d_windowcontext.c000066400000000000000000000140561266045153600235510ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_opengl.h" #include "pdp_3dp_base.h" typedef struct pdp_3d_windowcontext_struct { t_pdp_3dp_base x_base; int x_width; int x_height; t_outlet *x_eventout; int x_finish_queue_id[2]; int x_finish_queue_id_current; } t_pdp_3d_windowcontext; static void pdp_3d_windowcontext_sendfinish(t_pdp_3d_windowcontext *x) { PDP_ASSERT(x); PDP_ASSERT(x->x_eventout); outlet_symbol(x->x_eventout, gensym("done")); } /* outlet methods */ /* called before the context is propagated */ static void pdp_3d_windowcontext_clearbuffer(t_pdp_3d_windowcontext *x) { int p = pdp_3dp_base_get_context_packet(x); //post("setting up render buffer"); // for multipass rendering //pdp_packet_3Dcontext_set_subwidth(p, 320); //pdp_packet_3Dcontext_set_subheight(p, 240); pdp_packet_3Dcontext_set_rendering_context(p); pdp_packet_3Dcontext_setup_3d_context(p); /* clear buffer */ //glScissor(0,0, // pdp_packet_3Dcontext_subwidth(p), // pdp_packet_3Dcontext_subheight(p)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } /* called after context is propagated */ static void pdp_3d_windowcontext_swapbuffer(t_pdp_3d_windowcontext *x) { int p = pdp_3dp_base_get_context_packet(x); //post("displaying render buffer"); //pdp_packet_3Dcontext_set_rendering_context(p); pdp_packet_3Dcontext_win_swapbuffers(p); //pdp_packet_3Dcontext_unset_rendering_context(p); } void pdp_3d_windowcontext_resize(t_pdp_3d_windowcontext *x, t_floatarg width, t_floatarg height) { int w = (int)width; int h = (int)height; int p = pdp_3dp_base_get_context_packet(x); if ((w>0) && (h>0)){ pdp_packet_3Dcontext_win_resize(p, w, h); x->x_width = w; x->x_height = h; } } void pdp_3d_windowcontext_open(t_pdp_3d_windowcontext *x) { int p = pdp_3dp_base_get_context_packet(x); if (-1 == p){ p = pdp_packet_new_3Dcontext_win(); pdp_3d_windowcontext_resize(x, x->x_width, x->x_height); pdp_3dp_base_set_context_packet(x, p); } } void pdp_3d_windowcontext_close(t_pdp_3d_windowcontext *x) { pdp_packet_delete(pdp_3dp_base_move_context_packet(x)); } void pdp_3d_windowcontext_cursor(t_pdp_3d_windowcontext *x, t_floatarg f) { int p = pdp_3dp_base_get_context_packet(x); bool toggle = (f != 0.0f); pdp_packet_3Dcontext_win_cursor(p, toggle); } static void pdp_3d_windowcontext_bang(t_pdp_3d_windowcontext *x) { int p; int cur = x->x_finish_queue_id_current; t_pdp_list *eventlist; /* check if at least recent processing chain is done (two chains busy = max pipeline depth) */ if (-1 != x->x_finish_queue_id[cur]){ //post("pdp_3d_windowcontext_bang: bang ignored (previous rendering not finished)"); return; } /* create a window context if needed */ pdp_3d_windowcontext_open(x); /* get events and send to outlet */ p = pdp_3dp_base_get_context_packet(x); pdp_packet_3Dcontext_event_out(p, x->x_eventout); /* bang base */ pdp_3dp_base_bang(x); /* add a dummy process to the queue for synchro */ pdp_procqueue_add(pdp_3dp_base_get_queue(x), x, 0, 0, &x->x_finish_queue_id[cur]); x->x_finish_queue_id_current = !cur; } static void pdp_3d_windowcontext_free(t_pdp_3d_windowcontext *x) { pdp_3d_windowcontext_close(x); pdp_3dp_base_free(x); } t_class *pdp_3d_windowcontext_class; void *pdp_3d_windowcontext_new(void) { /* allocate */ t_pdp_3d_windowcontext *x = (t_pdp_3d_windowcontext *)pd_new(pdp_3d_windowcontext_class); x->x_width = 320; x->x_height = 240; x->x_finish_queue_id[0] = -1; x->x_finish_queue_id[1] = -1; x->x_finish_queue_id_current =0; /* init super: this is mandatory */ pdp_3dp_base_init(x); pdp_3dp_base_disable_active_inlet(x); /* set the dpd processing methods & outlets */ pdp_3dp_base_add_outlet(x, (t_pdp_method)pdp_3d_windowcontext_clearbuffer, 0); pdp_3dp_base_add_cleanup(x, (t_pdp_method)pdp_3d_windowcontext_swapbuffer, (t_pdp_method)pdp_3d_windowcontext_sendfinish); /* add event outlet */ x->x_eventout = outlet_new((t_object *)x, &s_anything); return (void *)x; } #ifdef __cplusplus extern "C" { #endif void pdp_3d_windowcontext_setup(void) { /* create a standard pd class */ pdp_3d_windowcontext_class = class_new(gensym("3dp_windowcontext"), (t_newmethod)pdp_3d_windowcontext_new, (t_method)pdp_3d_windowcontext_free, sizeof(t_pdp_3d_windowcontext), 0, A_NULL); /* inherit pdp base class methods */ pdp_3dp_base_setup(pdp_3d_windowcontext_class); /* register methods */ class_addbang(pdp_3d_windowcontext_class, pdp_3d_windowcontext_bang); class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_open, gensym("open"), A_NULL); class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_close, gensym("close"), A_NULL); class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_3d_windowcontext_class, (t_method)pdp_3d_windowcontext_cursor, gensym("cursor"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/system/000077500000000000000000000000001266045153600171065ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/system/Makefile000066400000000000000000000002441266045153600205460ustar00rootroot00000000000000include ../Makefile.config all: pdp_texture.o pdp_3Dcontext_glx.o pdp_3Dcontext_common.o \ pdp_opengl.o pdp_3dp_base.o pdp_mesh.o setup.o clean: rm -rf *~ *.o pdp-0.14.1+darcs20180201/opengl/system/pdp_3Dcontext_common.c000066400000000000000000000140221266045153600233370ustar00rootroot00000000000000 /* * OpenGL Extension Module for pdp - pbuffer packet implementation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this code uses glx. i don't know if it is worth to take into account portabiliy. since it will take a while until pdp runs on anything else than linux. but in any case, providing a windows/osx implementation here should not be too difficult.. */ #include "pdp_3Dcontext.h" #include #include #define D if (0) /* constructor */ /* pbuf operators */ u32 pdp_packet_3Dcontext_width(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); return zl_3Dcontext_width(c); } u32 pdp_packet_3Dcontext_height(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); return zl_3Dcontext_height(c); } u32 pdp_packet_3Dcontext_subwidth(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); return zl_3Dcontext_subwidth(c); } u32 pdp_packet_3Dcontext_subheight(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); return zl_3Dcontext_subheight(c); } void pdp_packet_3Dcontext_set_subwidth(int packet, u32 w) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_set_subwidth(c, w); } void pdp_packet_3Dcontext_set_subheight(int packet, u32 h) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_set_subheight(c, h); } float pdp_packet_3Dcontext_subaspect(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); return zl_3Dcontext_subaspect(c); } int pdp_packet_3Dcontext_isvalid(int packet) { t_pdp *header = pdp_packet_header(packet); zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); if (!header) return 0; if (!c) return 0; if (PDP_3DCONTEXT != header->type) return 0; return 1; } zl_3Dcontext *pdp_packet_3Dcontext_info(int packet) { t_pdp *header = pdp_packet_header(packet); if (!header) return 0; if (PDP_3DCONTEXT != header->type) return 0; zl_3Dcontext_wrapper *cw = (void*)&header->info.raw; return cw->c; } void pdp_llconv_flip_top_bottom(char *data, int width, int height, int pixelsize); int pdp_packet_3Dcontext_snap_to_bitmap(int packet, int w, int h) { int x, y, new_p, i; char *data = 0; // char r; // int extra = 5; if (!pdp_packet_3Dcontext_isvalid(packet)) goto error; new_p = pdp_packet_new_bitmap_rgb(w, h); data = (char *)pdp_packet_data(new_p); if (-1 == new_p || !data) goto error; zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_snap_to_bitmap(c, w, h, data); /* inplace swap top to bottom (textures and buffers have another coordinate system than standard images) instead of fixing this by using a different texture coordinate system, a memory swap is performed. this is more expensive but eliminates hassle when converting between buffers, textures and bitmaps */ pdp_llconv_flip_top_bottom(data, w, h, 3); return new_p; error: return -1; } /* move these to the pdp_3d_context object: they're too specific */ /* setup for 2d operation from pbuf dimensions */ void pdp_packet_3Dcontext_setup_2d_context(int p) { u32 w; u32 h; float asp; if (!pdp_packet_3Dcontext_isvalid(p)) return; w = pdp_packet_3Dcontext_subwidth(p); h = pdp_packet_3Dcontext_subheight(p); asp = pdp_packet_3Dcontext_subaspect(p); /* set the viewport to the size of the sub frame */ glViewport(0, 0, w, h); /* set orthogonal projection, with a relative frame size of (2asp x 2) */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, 2*asp, 0, 2); /* set the center of view */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(asp, 1, 0); glScalef(1,-1,1); } /* setup for 3d operation from pbuf dimensions */ void pdp_packet_3Dcontext_setup_3d_context(int p) { u32 w; u32 h; int i; float asp; float m_perspect[] = {-1.f, /* left */ 1.f, /* right */ -1.f, /* bottom */ 1.f, /* top */ 1.f, /* front */ 20.f};/* back */ if (!pdp_packet_3Dcontext_isvalid(p)) return; w = pdp_packet_3Dcontext_subwidth(p); h = pdp_packet_3Dcontext_subheight(p); asp = pdp_packet_3Dcontext_subaspect(p); /* set the viewport to the size of the sub frame */ glViewport(0, 0, w, h); /* set orthogonal projection, with a relative frame size of (2asp x 2) */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(m_perspect[0] * asp, m_perspect[1] * asp, // left, right m_perspect[2], m_perspect[3], // bottom, top m_perspect[4], m_perspect[5]); // front, back /* reset texture matrix */ glMatrixMode(GL_TEXTURE); glLoadIdentity(); /* set the center of view */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0); //glTranslatef(asp, 1, 0); glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); //glShadeModel(GL_FLAT); /* disable everything that is enabled in other modules this resets the ogl state to its initial conditions */ glDisable(GL_LIGHTING); for (i=0; i<8; i++) glDisable(GL_LIGHT0 + i); glDisable(GL_COLOR_MATERIAL); } void pdp_3Dcontext_common_setup(void) { } pdp-0.14.1+darcs20180201/opengl/system/pdp_3Dcontext_glx.c000066400000000000000000000132501266045153600226430ustar00rootroot00000000000000 /* * OpenGL Extension Module for pdp - opengl system stuff * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains the platform dependent opengl setup routines (glx) and pdp_packet_3Dcontext methods */ #include "zl_pd/zl_pd.h" // outlet_zl_float_list() //#include "pdp_packet.h" #include "pdp_3Dcontext.h" #include "pdp_internals.h" #include #include #include /* all symbols are C-style */ #ifdef __cplusplus //extern "C" //{ #endif // this is buggy: disabled #define PRIVATE_CONTEXT 0 static t_pdp_class *context_class; /* PDP_3DCONTEXT packet methods */ /* set/unset ogl rendering context to pbuf */ void pdp_packet_3Dcontext_set_rendering_context(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_set_rendering_context(c); } void pdp_packet_3Dcontext_unset_rendering_context(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_unset_rendering_context(c); } /* cons/des */ static void _3Dcontext_clone(t_pdp *dst __attribute__((__unused__)), t_pdp *src __attribute__((__unused__))) { post("ERROR: clone not supported for 3Dcontext packets"); } static void _3Dcontext_copy(t_pdp *dst __attribute__((__unused__)), t_pdp *src __attribute__((__unused__))) { post("ERROR: copy not supported for 3Dcontext packets"); } static void _3Dcontext_reinit(t_pdp *dst __attribute__((__unused__))) { /* leave the packet as is */ } static void _3Dcontext_cleanup(t_pdp *dst) { zl_3Dcontext *c = (void *)(&dst->info.raw); zl_3Dcontext_free(c); } /* setup packet methods */ static void _3Dcontext_init_methods(t_pdp *header) { header->theclass = context_class; header->flags = PDP_FLAG_DONOTCOPY; } /* window specific methods */ /* resize the window */ void pdp_packet_3Dcontext_win_resize(int packet, int width, int height) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_win_resize(c, width, height); } static void outlet_event(void *context, int nb_double_args, zl_tag tag, va_list args) { t_outlet *outlet = context; outlet_zl_float_list(outlet, nb_double_args, tag, args); } void pdp_packet_3Dcontext_event_out(int packet, t_outlet *outlet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); if (!c) return; zl_3Dcontext_for_parsed_events(c, outlet_event, outlet); } void pdp_packet_3Dcontext_win_cursor(int packet, bool toggle) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_win_cursor(c, toggle); } void pdp_packet_3Dcontext_win_swapbuffers(int packet) { zl_3Dcontext *c = pdp_packet_3Dcontext_info(packet); zl_3Dcontext_win_swapbuffers(c); } /* constructors */ /* construct (or reuse) a window packet */ int pdp_packet_new_3Dcontext_win(void) { /* $$$FIXME: this assumes packet can't be reused */ int p = pdp_packet_new(PDP_3DCONTEXT, 0); t_pdp *header = pdp_packet_header(p); if (!header) return -1; /* pool full ? */ zl_3Dcontext *c = zl_3Dcontext_win_new(); zl_3Dcontext_wrapper *cw = (void*)&header->info.raw; cw->c = c; /* init packet methods */ _3Dcontext_init_methods(header); /* init header */ header->desc = pdp_gensym("3Dcontext/window"); header->flags = PDP_FLAG_DONOTCOPY; return p; } /* pbuf constructor */ int pdp_packet_new_3Dcontext_pbuf(u32 width __attribute__((__unused__)), u32 height __attribute__((__unused__)), u32 depth __attribute__((__unused__))) { post("ERROR: 3Dcontext/pbuffer packets not implemented"); return -1; } /* this is a notifier sent when the processing thread which executes gl commands is changed. we need to release the current context before another thread can take it. */ void pdp_3Dcontext_prepare_for_thread_switch(void) { zl_3Dcontext_unset_rendering_context(NULL); // unset current } static void pdp_3Dcontext_glx_setup_in_thread(void) { /* init xlib for thread usage */ if (!XInitThreads()){ post("pdp_3Dcontext_glx_setup_in_thread: can't init Xlib for thread usage."); return; } else { // post("pdp_3Dcontext_glx_setup_in_thread: OK"); } zl_3Dcontext_glx_setup(); } /* setup routine */ void pdp_3Dcontext_glx_setup(void) { /* run the setup routine in the procqueue thread, and wait for it to finish */ t_pdp_procqueue *q = pdp_opengl_get_queue(); pdp_procqueue_add(q, 0, pdp_3Dcontext_glx_setup_in_thread, 0, 0); pdp_procqueue_flush(q); // post("pdp_3Dcontext_glx_setup: pdp_procqueue_flush() OK"); /* setup class object */ context_class = pdp_class_new(pdp_gensym("3Dcontext/*"), 0); context_class->cleanup = _3Dcontext_cleanup; context_class->wakeup = _3Dcontext_reinit; //context_class->clone = _3Dcontext_clone; context_class->copy = _3Dcontext_copy; /* setup conversion programs: NOT IMPLEMENTED */ return; } #ifdef __cplusplus //} #endif pdp-0.14.1+darcs20180201/opengl/system/pdp_3dp_base.c000066400000000000000000000010311266045153600215700ustar00rootroot00000000000000#include "pdp_opengl.h" #include "pdp_3dp_base.h" #define THIS(b) t_pdp_3pd_base *b = (t_pdp_3pd_base *)x /* destructor */ void pdp_3dp_base_free(void *x) { // free super pdp_dpd_base_free(x); } /* init method */ void pdp_3dp_base_init(void *x) { // init super pdp_dpd_base_init(x); // set processing queue to pdp_opengl system queue pdp_dpd_base_set_queue(x, pdp_opengl_get_queue()); } /* class setup method */ void pdp_3dp_base_setup(t_class *class) { // setup super pdp_dpd_base_setup(class); } pdp-0.14.1+darcs20180201/opengl/system/pdp_mesh.c000066400000000000000000000324731266045153600210620ustar00rootroot00000000000000/* * Pure Data Packet module. mesh implementation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* a very naive approach to triangular meshes */ // $$TODO: some serious memory corruption in this file our the list implementation #include #include "pdp.h" #include "pdp_mesh.h" /* VERTEX methods */ void vertex_add_triangle(t_vertex *v, t_triangle *t) { pdp_list_add_pointer(v->trilist, t); } void vertex_remove_triangle(t_vertex *v, t_triangle *t) { pdp_list_remove_pointer(v->trilist, t); } void vertex_add_neighbour(t_vertex *v, t_vertex *neighbour) { pdp_list_add_pointer_to_set(v->vertlist, neighbour); }; /* constructor/destructors are "private" they may only be called by the mesh object to ensure the vector list stays sound (i.e. without duplicates) */ void _vertex_free(t_vertex *v) { if (!v->trilist) post("WARNING: vertex %x has empty trilist", v); else{ pdp_list_free(v->trilist); v->trilist = 0; } if (!v->vertlist) post("WARNING: vertex %x has empty vertlist", v); { pdp_list_free(v->vertlist); v->vertlist = 0; } pdp_dealloc(v); } t_vertex *_vertex_new(float *c, float *n) { int k; t_vertex *v = (t_vertex *) pdp_alloc(sizeof(t_vertex)); I3(k) v->c[k] = c[k]; I3(k) v->n[k] = n[k]; v->trilist = pdp_list_new(0); v->vertlist = pdp_list_new(0); return v; } void vertex_compute_normal_random(t_vertex *v){int k; I3(k) v->n[k] = _rand();} void vertex_compute_normal_sphere(t_vertex *v){int k; I3(k) v->n[k] = v->c[k];} void vertex_compute_normal_prism(t_vertex *v) { float scale = 0.0f; float sum[] = {0.0f, 0.0f, 0.0f}; int k; t_pdp_atom* i; t_pdp_list *vl = v->vertlist; t_vertex *vtx; PDP_POINTER_IN(vl, i, vtx) { I3(k) sum[k] += vtx->c[k]; scale = scale + 1.0f; } scale = 1.0f / scale; I3(k) sum[k] *= scale; I3(k) v->n[k] = v->c[k] - sum[k]; //post("computed normal (%f, %f, %f) of vertex (%f, %f, %f)", v->n[0], v->n[1], v->n[2], v->c[0], v->c[1], v->c[2]); }; void vertex_compute_normal_average(t_vertex *v) { int triangles = pdp_list_size(v->trilist); float scale = 1.0f / ((float)triangles); t_pdp_atom* i; int k; t_triangle *t; I3(k) v->n[k] = 0; //reset normal PDP_POINTER_IN(v->trilist, i, t){ I3(k) v->n[k] += t->n[k]; } _vector3_scale(v->n, scale); } float vertex_normalize(t_vertex *v) { return _vector3_normalize(v->c); } /* TRIANGLE methods */ /* create triangle (a connection between 3 vertices): counterclockwize with facing front this method is "private" you can only create triangles as part of a mesh */ t_triangle *_triangle_new(t_vertex *v0, t_vertex *v1, t_vertex *v2) { int k; t_triangle *t = (t_triangle *)pdp_alloc(sizeof(t_triangle)); /* store vertex references */ t->v[0] = v0; t->v[1] = v1; t->v[2] = v2; /* reset median vertices */ I3(k) t->m[k] = 0; /* connect triangle to vertices */ vertex_add_triangle(v0, t); vertex_add_triangle(v1, t); vertex_add_triangle(v2, t); /* connect vertices to vertices */ vertex_add_neighbour(v0, v1); vertex_add_neighbour(v0, v2); vertex_add_neighbour(v1, v0); vertex_add_neighbour(v1, v2); vertex_add_neighbour(v2, v0); vertex_add_neighbour(v2, v1); return t; } /* delete a triangle, disconnecting the vertices */ void _triangle_free(t_triangle *t) { int k; /* remove the triangle reference of the vertices */ I3(k) vertex_remove_triangle(t->v[k], t); /* set references to zero (bug catcher) */ I3(k) t->v[k] = 0; I3(k) t->m[k] = 0; /* free struct */ pdp_dealloc(t); } /* get triangle that shares the link between v0 and v1 */ t_triangle *triangle_neighbour(t_triangle *t, t_vertex *v0, t_vertex *v1) { t_pdp_atom* it; t_triangle *tri; PDP_POINTER_IN(v1->trilist, it, tri){ if (tri != t && pdp_list_contains_pointer(v0->trilist, tri)) return tri; } return 0; } /* add a median vector to a link in a triangle note: vertices must be in triangle, or behaviour is undefined */ void triangle_add_median(t_triangle *t, t_vertex *v0, t_vertex *v1, t_vertex *median) { /* link 0 1 */ if (!((v0 == t->v[2]) || (v1 == t->v[2]))) t->m[0] = median; /* link 1 2 */ else if (!((v0 == t->v[0]) || (v1 == t->v[0]))) t->m[1] = median; /* link 2 0 */ else t->m[2] = median; } void triangle_compute_normal(t_triangle *t) { int k; float v0[3]; float v1[3]; I3(k) v0[k] = t->v[1]->c[k] - t->v[0]->c[k]; I3(k) v1[k] = t->v[2]->c[k] - t->v[0]->c[k]; _vector3_cross(v0,v1,t->n); } void triangle_compute_unit_normal(t_triangle *t) { triangle_compute_normal(t); _vector3_normalize(t->n); } /* MESH methods */ /* add and remove methods for vertices and triangles */ t_vertex *mesh_vertex_add(t_mesh *m, float *c, float *n) { t_vertex *v = _vertex_new(c, n); pdp_list_add_pointer(m->vertices, v); return v; } void mesh_vertex_remove(t_mesh *m, t_vertex *v) { pdp_list_remove_pointer(m->vertices, v); _vertex_free(v); } t_triangle *mesh_triangle_add(t_mesh *m, t_vertex *v0, t_vertex *v1, t_vertex *v2) { t_triangle *t = _triangle_new(v0,v1,v2); pdp_list_add_pointer(m->triangles, t); return t; } void mesh_triangle_remove(t_mesh *m, t_triangle *t) { pdp_list_remove_pointer(m->triangles, t); _triangle_free(t); } /* calculate normals */ void mesh_calculate_normals(t_mesh *m) { t_pdp_atom* it; t_pdp_atom* it_tri; t_pdp_list *l = m->vertices; t_pdp_list *l_tri = m->triangles; t_vertex *v; t_triangle *t; //while (v = pdp_list_getnext_pointer(l, &it)) vertex_compute_normal_sphere(v); switch(m->normal_type){ default: case MESH_NORMAL_SPHERE: PDP_POINTER_IN(l, it, v) vertex_compute_normal_sphere(v); break; case MESH_NORMAL_PRISM: PDP_POINTER_IN(l, it, v) vertex_compute_normal_prism(v); break; case MESH_NORMAL_RANDOM: PDP_POINTER_IN(l, it, v) vertex_compute_normal_random(v); break; case MESH_NORMAL_AVERAGE: PDP_POINTER_IN(l_tri, it_tri, t) triangle_compute_unit_normal(t); PDP_POINTER_IN(l, it, v) vertex_compute_normal_average(v); break; } } /* split a triangle in 4, using the intermedia median vertex storage */ void mesh_split_four(t_mesh *m, t_triangle *old_t) { int k; t_vertex *v[6]; /* some intermediates */ t_triangle *neighbour; t_float newv[] = {0,0,0}; t_float nullvect[] = {0,0,0}; /* get main vertices */ I3(k) v[k] = old_t->v[k]; /* get median vertices inserted by neighbouring triangles */ I3(k) v[k+3] = old_t->m[k]; #define GET_MEDIAN(v, v0, v1) \ if (!v){ \ I3(k) newv[k] = 0.5f * (v0->c[k] + v1->c[k]); \ v = mesh_vertex_add(m, newv, nullvect); \ /*vertex_normalize(v);*/ \ if (neighbour = triangle_neighbour(old_t, v0, v1)){ \ triangle_add_median(neighbour, v0, v1, v); \ } \ } GET_MEDIAN(v[3], v[0], v[1]) GET_MEDIAN(v[4], v[1], v[2]) GET_MEDIAN(v[5], v[2], v[0]) #undef GET_MEDIAN /* remove the old triangle */ mesh_triangle_remove(m, old_t); /* create 4 new triangles */ mesh_triangle_add(m, v[0], v[3], v[5]); mesh_triangle_add(m, v[1], v[4], v[3]); mesh_triangle_add(m, v[2], v[5], v[4]); mesh_triangle_add(m, v[3], v[4], v[5]); } /* split a triangle in 3 */ void mesh_split_three(t_mesh *m, t_triangle *old_t) { int k, l; t_vertex *v[4]; t_float newv[] = {0,0,0}; t_float nullvect[] = {0,0,0}; /* get vertices */ I3(k) v[k] = old_t->v[k]; /* remove a triangle */ mesh_triangle_remove(m, old_t); /* compute new vertex coordinates */ I3(k) I3(l) newv[k] += 0.33333f * v[l]->c[k]; /* create new vertex */ v[3] = mesh_vertex_add(m, newv, nullvect); //vertex_normalize(v[3]); /* create 3 new triangles */ mesh_triangle_add(m, v[0], v[1], v[3]); mesh_triangle_add(m, v[1], v[2], v[3]); mesh_triangle_add(m, v[2], v[0], v[3]); } void mesh_split_all_four(t_mesh *m) { t_triangle *t; t_pdp_list *l = pdp_list_copy(m->triangles); //post("split_all_four: nb triangles %d", pdp_list_size(m->triangles)); while (l->elements){ t = pdp_list_pop(l).w_pointer; mesh_split_four(m, t); } mesh_calculate_normals(m); pdp_list_free(l); } void mesh_split_all_three(t_mesh *m) { t_triangle *t; t_pdp_list *l = pdp_list_copy(m->triangles); //post("split_all_three: nb triangles %d", pdp_list_size(m->triangles)); while (l->elements){ t = pdp_list_pop(l).w_pointer; mesh_split_three(m, t); } mesh_calculate_normals(m); pdp_list_free(l); } void mesh_split_random_three(t_mesh *m) { int size = pdp_list_size(m->triangles); t_triangle *t = pdp_list_index(m->triangles, (random() % size)).w_pointer; mesh_split_three(m, t); mesh_calculate_normals(m); } void mesh_free(t_mesh *m) { t_pdp_list *l; t_triangle *t; t_vertex *v; /* delete all triangles */ while (m->triangles->elements){ t = pdp_list_pop(m->triangles).w_pointer; //post("freeing triangle %x", t); _triangle_free(t); } pdp_list_free(m->triangles); m->triangles = 0; /* delete all vertices */ while (m->vertices->elements){ v = pdp_list_pop(m->vertices).w_pointer; //post("freeing vertex %x", v); _vertex_free(v); } pdp_list_free(m->vertices); m->vertices = 0; pdp_dealloc(m); } t_mesh *_mesh_new(void) { t_mesh *m = (t_mesh *)pdp_alloc(sizeof(t_mesh)); /* create main vertex and triangle lists */ m->triangles = pdp_list_new(0); m->vertices = pdp_list_new(0); /* set normal type */ m->normal_type = MESH_NORMAL_PRISM; return m; } /* init tetra */ t_mesh *mesh_new_tetra(void) { int k; t_triangle *t[4]; t_vertex *v[4]; t_pdp_atom* it; t_triangle *tri; t_mesh *m = _mesh_new(); float n[] = {0,0,0}; float fv[4][3] = {{2,0,0},{0,2,0},{0,0,2}, {-1,-1,-1}}; /* add vertices */ I4(k) v[k] = mesh_vertex_add(m, &fv[k][0], n); I4(k) vertex_normalize(v[k]); /* add triangles */ mesh_triangle_add(m, v[0], v[1], v[2]); mesh_triangle_add(m, v[1], v[0], v[3]); mesh_triangle_add(m, v[0], v[2], v[3]); mesh_triangle_add(m, v[1], v[3], v[2]); /* compute normals */ mesh_calculate_normals(m); return m; } void _mesh_relax_compute_resultant_spring(t_mesh *m, float *center, float d0, float r0) { int k; t_pdp_atom *i, *j; t_vertex *v, *w; PDP_POINTER_IN(m->vertices, i, v){ float scale = 0.0f; float r; /* compute contribution of origin link */ I3(k) v->n[k] = v->c[k] - center[k]; r = _vector3_normalize(v->n); I3(k) v->n[k] *= (r0 - r); PDP_POINTER_IN(v->vertlist, j, w){ int k; float f[3]; float d, l; /* compute force contribution of one link (model: spring with rest length == d0) */ I3(k) f[k] = w->c[k] - v->c[k]; // PC: f == distance vector d = _vector3_normalize(f); // PC: d == distance, vector == unit norm I3(k) v->n[k] += (d - d0) * f[k]; // PC: n == n_prev + fource resultant } } } void _mesh_relax_apply_force(t_mesh *m, float k) { t_pdp_atom* it; t_vertex *v; PDP_POINTER_IN(m->vertices, it, v){ int i; /* apply fource vector with step */ I3(i) v->c[i] += k * v->n[i]; } } void mesh_compute_center(t_mesh *m, float *c) { t_pdp_atom*(it); t_vertex *v; float scale; int k; I3(k) c[k] = 0; PDP_POINTER_IN(m->vertices, it, v){ I3(k) c[k] += v->c[k]; } scale = 1.0f / ((float)pdp_list_size(m->vertices)); I3(k) c[k] *= scale; } void mesh_translate(t_mesh *m, float *c) { t_pdp_atom *it; t_vertex *v; int k; PDP_POINTER_IN(m->vertices, it, v){ I3(k) v->c[k] += c[k]; } } /* relax a mesh (move toward equal link length) */ void mesh_relax(t_mesh *m, float step, float d0, float r0) { int k; float c[3]; mesh_compute_center(m, c); I3(k) c[k] = -c[k]; mesh_translate(m, c); I3(k) c[k] = 0; _mesh_relax_compute_resultant_spring(m, c, d0, r0); /* compute force resultant */ _mesh_relax_apply_force(m, step); /* apply "time step towards desired distance" */ mesh_calculate_normals(m); /* restore normals */ } /* print some debug information */ void mesh_debug(t_mesh *m) { int k; int boundary_edges = 0; t_pdp_atom* it; t_triangle *t; post("mesh info"); post("\tnumber of vertices = %d", pdp_list_size(m->vertices)); post("\tnumber of triangles = %d", pdp_list_size(m->triangles)); PDP_POINTER_IN(m->triangles, it, t){ I3(k) if (!triangle_neighbour(t, t->v[k], t->v[(k+1)%3])) boundary_edges++; } post("\tnumber of boundaray edges = %d", boundary_edges); } pdp-0.14.1+darcs20180201/opengl/system/pdp_opengl.c000066400000000000000000000045561266045153600214130ustar00rootroot00000000000000 /* * OpenGL Extension Module for pdp - opengl system stuff * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp.h" #include "pdp_control.h" #define PDP_3DP_QUEUE_LOGSIZE 16 #define PDP_3DP_QUEUE_DELTIME 1.0f void pdp_3Dcontext_prepare_for_thread_switch(void *); static t_pdp_procqueue _3dp_queue; t_pdp_procqueue* pdp_opengl_get_queue(void){return (&_3dp_queue);} static void pdp_control_thread(void *x __attribute__((__unused__)), t_symbol *s __attribute__((__unused__)), int argc, t_atom *argv) { int t = 0; float f; if (argc != 1) return; if (argv[0].a_type != A_FLOAT) return; f = argv[0].a_w.w_float; t = (f != 0.0f); post("3dp thread switched %s", t ? "on":"off"); /* when we switch threads, the glx system needs to be notified because it has to release the render context. this is done in a process method, so it is run in the correct thread. */ pdp_procqueue_add(&_3dp_queue, 0, pdp_3Dcontext_prepare_for_thread_switch, 0, 0); pdp_procqueue_wait(&_3dp_queue); /* fresh start: enable/disable the thread dispatching */ pdp_procqueue_use_thread(&_3dp_queue, t); } /* kernel setup */ void pdp_opengl_system_setup(void) { /* init the 3dp queue */ pdp_procqueue_init(&_3dp_queue, PDP_3DP_QUEUE_DELTIME, PDP_3DP_QUEUE_LOGSIZE); /* scheduler uses the thread */ pdp_procqueue_use_thread(&_3dp_queue, 1); //pdp_procqueue_use_thread(&_3dp_queue, 0); //DEBUG: disable 3dp thread /* add pdp_control method for thread */ pdp_control_addmethod((t_method)pdp_control_thread, gensym("3dthread")); } pdp-0.14.1+darcs20180201/opengl/system/pdp_texture.c000066400000000000000000000357211266045153600216250ustar00rootroot00000000000000/* * OpenGL Extension Module for pdp - texture packet implementation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this modules implemtents the opengl texture packet it contains only portable opengl code */ #include #include #include #include "pdp_opengl.h" #include "pdp_texture.h" #include "pdp_dpd_command.h" static t_pdp_class *texture_class; static t_pdp_dpd_commandfactory _tex_cf; typedef struct _texture_command { t_pdp_dpd_command base; int p_src; int p_dst; } t_texture_command; /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif /* returns a pointer to the packet subheader given the pdp header */ static t_texture *_pdp_tex_info(t_pdp *x) { return (t_texture *)&(x->info.raw); } /* create a pow of 2 texture dimension, ge than 8 */ static int _round_to_pow_2(int n){ int r = 8; while (n > r) r <<= 1; return r; } t_pdp_symbol *_pdp_get_tex_description_from_params(GLsizei width, GLsizei height, GLint format) { char description[1024]; char *c = description; c += sprintf(c, "texture"); switch(format){ case GL_LUMINANCE: c += sprintf(c, "/grey"); break; case GL_RGB: c += sprintf(c, "/rgb"); break; case GL_RGBA: c += sprintf(c, "/rgba"); break; default: c += sprintf(c, "/unknown"); goto exit; } c += sprintf(c, "/%dx%d", width, height); exit: return pdp_gensym(description); } t_pdp_symbol *_pdp_tex_get_description(t_pdp *header) { t_texture *texture = _pdp_tex_info(header); int encoding; if (!header) return pdp_gensym("invalid"); else if (!header->desc){ if (header->type == PDP_TEXTURE){ /* if description is not defined, try to construct it */ return _pdp_get_tex_description_from_params(texture->width, texture->height, texture->format); } else return pdp_gensym("unknown"); } else return header->desc; } static int _pdp_packet_texture_old_or_dummy(u32 width, u32 height, s32 format); static void _pdp_packet_gentexture(int packet); static void texture_command_convert_bitmap_to_texture(t_texture_command *c) { t_texture *t = (t_texture *)pdp_packet_subheader(c->p_dst); /* make sure packet contains a texture, since it is created with _pdp_packet_reuse_texture */ _pdp_packet_gentexture(c->p_dst); /* flip source image before uploading */ pdp_packet_bitmap_flip_top_bottom(c->p_src); /* fill texture */ pdp_packet_texture_make_current(c->p_dst); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, t->sub_width, t->sub_height, t->format, GL_UNSIGNED_BYTE, (char *)pdp_packet_data(c->p_src)); /* decrease refcount */ pdp_packet_mark_unused(c->p_src); pdp_packet_mark_unused(c->p_dst); //post("conversion done"); pdp_dpd_command_suicide(c); } /* converters to standard pdp types */ int _pdp_packet_texture_convert_image_to_texture( int packet, t_pdp_symbol *dest_template __attribute__((__unused__))) { int p_temp, p; //post ("converting to bitmap"); p_temp = pdp_packet_convert_rw(packet, pdp_gensym("bitmap/*/*")); if (p_temp == -1) return -1; //post ("converting to texture"); p = pdp_packet_convert_rw(p_temp, pdp_gensym("texture/*/*")); pdp_packet_mark_unused(p_temp); return p; } /* converters to standard pdp types */ int _pdp_packet_texture_convert_bitmap_to_texture( int packet, t_pdp_symbol *dest_template __attribute__((__unused__))) { t_pdp *header = pdp_packet_header(packet); void *data = pdp_packet_data (packet); int new_p; u32 w; u32 h; t_texture_command *c; if (!pdp_packet_bitmap_isvalid(packet)) return -1; w = header->info.image.width; h = header->info.image.height; switch (header->info.image.encoding){ case PDP_BITMAP_GREY: /* create greyscale texture */ new_p = _pdp_packet_texture_old_or_dummy(w,h, GL_LUMINANCE); break; case PDP_BITMAP_RGB: /* create rgb texture */ new_p = _pdp_packet_texture_old_or_dummy(w,h, GL_RGB); break; case PDP_BITMAP_RGBA: /* create greyscale texture */ new_p = _pdp_packet_texture_old_or_dummy(w,h, GL_RGBA); break; default: new_p = -1; break; } if (new_p != -1){ /* remark: this is a hack. a texture has to be created when a rendering context is active. this means it has to be created in the correct thread. therefore a dpd command is added to the 3dp queue. this seems to work, but without a dropping mechanism, this can overload the queue. the real solution would be to add a converter object to a 3dp chain, or to accept image or bitmap packets in 3dp objects */ /* dispatch command */ c = (t_texture_command *)pdp_dpd_commandfactory_get_new_command(&_tex_cf); c->p_src = pdp_packet_copy_rw(packet); c->p_dst = pdp_packet_copy_ro(new_p); pdp_procqueue_add(pdp_opengl_get_queue(), c, texture_command_convert_bitmap_to_texture, 0, 0); } return new_p; } int _pdp_packet_texture_convert_texture_to_bitmap( int packet __attribute__((__unused__)), t_pdp_symbol *dest_template __attribute__((__unused__))) { post("_pdp_packet_texture_convert_texture_to_bitmap not implemented."); return -1; } t_texture *pdp_packet_texture_info(int packet) { t_pdp *header = pdp_packet_header(packet); if (pdp_packet_texture_isvalid(packet)) return _pdp_tex_info(header); else return 0; } /* check if valid texture packet. all other methods assume packet is valid */ // FIXME: This doesn't work if there is no current gl context. int pdp_packet_texture_isvalid(int packet) { t_pdp *header; if (!(header = pdp_packet_header(packet))) return 0; if (PDP_TEXTURE != header->type) return 0; u32 tex_obj = _pdp_tex_info(header)->tex_obj; return glIsTexture(tex_obj); } static void _tex_init_obj(t_texture *t) { //u8 *dummydata; //int i; glBindTexture(GL_TEXTURE_2D, t->tex_obj); glTexImage2D(GL_TEXTURE_2D, 0, t->format, t->width, t->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); /* debug dummydata = (u8 *)malloc(t->width*t->height*4); for (i=0; iwidth*t->height*4; i++){dummydata[i] = random(); } glTexImage2D(GL_TEXTURE_2D, 0, t->format, t->width, t->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummydata); free(dummydata); */ } static void _pdp_tex_copy(t_pdp *dst, t_pdp *src); static void _pdp_tex_clone(t_pdp *dst, t_pdp *src); static void _pdp_tex_reinit(t_pdp *dst); static void _pdp_tex_cleanup(t_pdp *dst); static void _pdp_tex_init_methods(t_pdp *h) { h->theclass = texture_class; } static void _pdp_tex_reinit(t_pdp *dst __attribute__((__unused__))) { /* this does nothing. texture is assumed to be in a valid state */ } static void _pdp_tex_clone(t_pdp *dst, t_pdp *src) { t_texture *dst_t = _pdp_tex_info(dst); t_texture *src_t = _pdp_tex_info(src); //post("WARNING: _pdp_tex_clone: should not be called from outside 3d thread"); /* determine if destination texture is valid */ if (glIsTexture(dst_t->tex_obj)){ /* check format */ if ((dst_t->width >= src_t->width) && (dst_t->height >= src_t->height) && (dst_t->format == src_t->format)){ dst_t->sub_width = src_t->sub_width; dst_t->sub_height = src_t->sub_height; return; } } /* not initialized, so we need to create a new one */ else { glGenTextures(1, (GLuint*)&dst_t->tex_obj); } /* setup header */ dst_t->width = src_t->width; dst_t->height = src_t->height; dst_t->format = src_t->format; dst_t->sub_width = src_t->sub_width; dst_t->sub_height = src_t->sub_height; /* setup packet methods */ _pdp_tex_init_methods(dst); /* init description */ dst->desc = _pdp_tex_get_description(dst); } static void _pdp_tex_copy(t_pdp *dst, t_pdp *src) { /* texture copying is inefficient. for the tex extensions there is no analogy for "efficient in-place processing" this means the pdp_packet_register_rw() call should be avoided this inconsistency should be tucked away in a texture base class */ /* todo: use texture combining extensions for this */ post("WARNING: fanout is not yet implemented correctly for texture packets"); /* not implemented yet, just a call to the clone method */ _pdp_tex_clone(dst, src); } static void _pdp_tex_cleanup(t_pdp *dst) { t_texture *t = _pdp_tex_info(dst); glDeleteTextures(1, (GLuint*)&t->tex_obj); t->tex_obj = -1; /* is this value guaranteed to be invalid? */ } /* texture constructors */ /* reuse a texture, or create a "dummy" == packet with everything except a valid texture object */ static int _pdp_packet_texture_old_or_dummy(u32 width, u32 height, s32 format) { int p = -1; t_pdp *h; t_texture *t; int p2_w = _round_to_pow_2(width); int p2_h = _round_to_pow_2(height); /* try to reuse a texture packet or get a new one */ p = pdp_packet_reuse(_pdp_get_tex_description_from_params(p2_w, p2_h, format)); if (-1 == p) p = pdp_packet_create(PDP_TEXTURE, 0); if (-1 == p) return -1; h = pdp_packet_header(p); t = _pdp_tex_info(h); /* check if alloc succeded */ if (!h) return -1; /* check if tex is already initialized */ if (pdp_packet_texture_isvalid(p)){ /* check format */ if ((t->width >= width) && (t->height >= height) && (t->format == format)){ //post("pdp_packet_new_tex: reused"); t->sub_width = width; t->sub_height = height; return p; } post("ERROR: pdp_packet_new_texture: pdp_packet_reuse returned wrong type"); } /* determine the texture dims * setup rest of data struct */ t->width = 64; t->height = 64; while (t->width < width) t->width <<= 1; while (t->height < height) t->height <<= 1; t->format = format; t->sub_width = width; t->sub_height = height; _pdp_tex_init_methods(h); /* init the texture */ //_tex_init_obj(t); /* init description */ h->desc = _pdp_tex_get_description(h); return p; } /* don't call this method on a non-texture object! */ static void _pdp_packet_gentexture(int p) { t_texture *t; if (!pdp_packet_texture_isvalid(p)){ /* not initialized, so we need to create a new one */ // post("generating texture"); t = (t_texture *)pdp_packet_subheader(p); /* create the texture object */ glGenTextures(1, (GLuint *)&t->tex_obj); /* init the texture */ _tex_init_obj(t); } } int pdp_packet_new_texture(u32 width, u32 height, s32 format) { t_texture *t; int p = _pdp_packet_texture_old_or_dummy(width, height, format); //post("WARNING: pdp_packet_new_texture: this method should not be called outside the 3dp thread"); if (p == -1) return -1; _pdp_packet_gentexture(p); return p; } /* high level texture packet operators */ /* make a texture the current texture context */ void pdp_packet_texture_make_current(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return; glBindTexture(GL_TEXTURE_2D, t->tex_obj); } void pdp_packet_texture_make_current_enable(int packet) { glEnable(GL_TEXTURE_2D); pdp_packet_texture_make_current(packet); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } float pdp_packet_texture_fracx(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0.0; return (float)t->sub_width/t->width; } float pdp_packet_texture_fracy(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0.0; return (float)t->sub_height/t->height; } u32 pdp_packet_texture_total_width(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0; return t->width; } u32 pdp_packet_texture_total_height(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0; return t->height; } u32 pdp_packet_texture_sub_width(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0; return t->sub_width; } u32 pdp_packet_texture_sub_height(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0; return t->sub_height; } float pdp_packet_texture_sub_aspect(int packet) { t_texture *t = pdp_packet_texture_info(packet); if (!t) return 0; return (float)t->sub_width/t->sub_height; } /* setup for 2d operation from texture dimensions */ void pdp_packet_texture_setup_2d_context(int p) { u32 w; u32 h; float asp; if (!pdp_packet_texture_isvalid(p)) return; w = pdp_packet_texture_sub_width(p); h = pdp_packet_texture_sub_height(p); asp = pdp_packet_texture_sub_aspect(p); /* set the viewport to the size of the sub texture */ glViewport(0, 0, w, h); /* set orthogonal projection, with a relative frame size of (2asp x 2) */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 2*asp, 0, 2); /* set the center of view */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(asp, 1, 0); glScalef(1,-1,1); } void pdp_texture_setup(void) { t_pdp_conversion_program *program; /* setup packet class */ texture_class = pdp_class_new(pdp_gensym("texture/*/*"), 0); texture_class->cleanup = _pdp_tex_cleanup; texture_class->wakeup = _pdp_tex_reinit; //texture_class->clone = _pdp_tex_clone; texture_class->copy = _pdp_tex_copy; /* init command list */ pdp_dpd_commandfactory_init(&_tex_cf, sizeof(t_texture_command)); /* setup programs */ program = pdp_conversion_program_new(_pdp_packet_texture_convert_bitmap_to_texture, 0); pdp_type_register_conversion(pdp_gensym("bitmap/*/*"), pdp_gensym("texture/*/*"), program); /* this is a hack to use until the type conversion system has a proper search algo */ program = pdp_conversion_program_new(_pdp_packet_texture_convert_image_to_texture, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("texture/*/*"), program); program = pdp_conversion_program_new(_pdp_packet_texture_convert_texture_to_bitmap, 0); pdp_type_register_conversion(pdp_gensym("texture/*/*"), pdp_gensym("bitmap/*/*"), program); } /* all symbols are C-style */ #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/system/setup.c000066400000000000000000000037441266045153600204220ustar00rootroot00000000000000#include "pdp_opengl.h" /* 3dp overview: - texture packets (gl) - drawable packets (glX windows and pbufs) the 3dp system connects to a display server and creates a common context this can be a pbuf context (if supported, glx >= 1.3) or a normal glX context textures are standard opengl drawable packets are wrappers around glx drawables (windows or pbufs) they share the central display connection and rendering context */ #ifdef __cplusplus extern "C" { #endif /* opengl lib kernel setup */ void pdp_opengl_system_setup(void); /* packet type setup */ void pdp_3Dcontext_glx_setup(void); /* glx specific part of the 3D context packet */ void pdp_3Dcontext_common_setup(void); /* common part of the 3D context packet */ void pdp_texture_setup(void); /* texture packet */ /* module setup */ void pdp_3d_windowcontext_setup(void); void pdp_3d_draw_setup(void); void pdp_3d_view_setup(void); void pdp_3d_light_setup(void); void pdp_3d_color_setup(void); void pdp_3d_push_setup(void); void pdp_3d_snap_setup(void); void pdp_3d_dlist_setup(void); void pdp_3d_drawmesh_setup(void); void pdp_3d_for_setup(void); void pdp_3d_state_setup(void); void pdp_3d_subcontext_setup(void); //#define D(x) { pdp_post_n( #x ".." ); x; pdp_post("done"); } #define D(x) x void pdp_setup(void); void pdp_opengl_setup(void) { int i; pdp_setup(); post("PDP: opengl extensions version " PDP_VERSION); /* setup system */ D(pdp_opengl_system_setup()); /* setup packet types */ D(pdp_3Dcontext_glx_setup()); D(pdp_3Dcontext_common_setup()); D(pdp_texture_setup()); /* setup modules */ D(pdp_3d_windowcontext_setup()); D(pdp_3d_draw_setup()); D(pdp_3d_view_setup()); D(pdp_3d_push_setup()); D(pdp_3d_light_setup()); D(pdp_3d_dlist_setup()); D(pdp_3d_color_setup()); D(pdp_3d_snap_setup()); D(pdp_3d_drawmesh_setup()); D(pdp_3d_for_setup()); D(pdp_3d_state_setup()); D(pdp_3d_subcontext_setup()); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/opengl/test/000077500000000000000000000000001266045153600165415ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/opengl/test/arm.pd000066400000000000000000000016631266045153600176530ustar00rootroot00000000000000#N canvas 475 534 450 300 10; #X obj 51 14 inlet; #X obj 52 252 outlet; #X obj 76 133 3dp_push; #X obj 176 117 3dp_view transx 0.5; #X obj 71 81 3dp_view rotz; #X obj 211 52 inlet; #X obj 177 91 3dp_view scalex \$1; #X obj 51 194 3dp_view transx \$1; #X obj 360 105 r texture; #X obj 40 62 3dp_view roty; #X obj 159 22 r roty; #X obj 301 50 r scale; #X obj 43 37 3dp_draw cube 1; #X obj 123 5 r cubesize; #X obj 257 219 3dp_draw torus 0.25 0.5 6; #X obj 231 176 spigot; #X obj 264 148 r drawtorus; #X obj 322 191 r torusr1; #X obj 355 160 r torusr2; #X connect 0 0 12 0; #X connect 2 0 7 0; #X connect 2 1 6 0; #X connect 3 0 15 0; #X connect 4 0 2 0; #X connect 5 0 4 1; #X connect 6 0 3 0; #X connect 7 0 1 0; #X connect 8 0 14 1; #X connect 9 0 4 0; #X connect 10 0 9 1; #X connect 11 0 6 1; #X connect 11 0 7 1; #X connect 12 0 9 0; #X connect 13 0 12 2; #X connect 15 0 14 0; #X connect 16 0 15 1; #X connect 17 0 14 2; #X connect 18 0 14 3; pdp-0.14.1+darcs20180201/opengl/test/example01.gdb000066400000000000000000000000631266045153600210120ustar00rootroot00000000000000set breakpoint pending on break glXSwapBuffers run pdp-0.14.1+darcs20180201/opengl/test/example01.pd000066400000000000000000000147601266045153600206720ustar00rootroot00000000000000#N canvas 0 30 1438 868 10; #X floatatom 126 37 5 0 0 0 - - -, f 5; #X obj 56 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 83 19 stop; #X floatatom 360 431 5 0 0 0 - - -, f 5; #X obj 59 103 3dp_push; #X floatatom 672 189 5 0 0 0 - - -, f 5; #X obj 546 244 3dp_view transx 3; #X obj 546 270 3dp_light; #X obj 612 97 f; #X floatatom 641 98 5 0 0 0 - - -, f 5; #X floatatom 669 370 5 0 0 0 - - -, f 5; #X obj 182 491 arm 3; #X obj 182 514 arm 3; #X obj 182 537 arm 3; #X obj 182 467 arm 3; #X floatatom 360 455 5 0 0 0 - - -, f 5; #X floatatom 359 478 5 0 0 0 - - -, f 5; #X floatatom 358 501 5 0 0 0 - - -, f 5; #X floatatom 358 524 5 0 0 0 - - -, f 5; #X obj 182 584 arm 3; #X obj 182 607 arm 3; #X obj 182 630 arm 3; #X obj 182 560 arm 3; #X floatatom 358 548 5 0 0 0 - - -, f 5; #X floatatom 358 571 5 0 0 0 - - -, f 5; #X floatatom 358 594 5 0 0 0 - - -, f 5; #X obj 59 224 3dp_view roty; #X obj 284 449 * 1; #X obj 284 589 * -1; #X obj 182 653 arm 3; #X floatatom 358 617 5 0 0 0 - - -, f 5; #X obj 284 635 * -1.5; #X obj 663 686 s roty; #X floatatom 615 611 5 0 0 0 - - -, f 5; #X floatatom 671 585 5 0 0 0 - - -, f 5; #X obj 673 616 s scale; #X floatatom 359 388 5 0 0 0 - - -, f 5; #X obj 284 473 * -1.01; #X obj 284 496 * 0.99; #X obj 284 519 * -1.01; #X obj 284 542 * 2.1; #X obj 284 566 * -1.7; #X obj 182 425 3dp_draw cube 1.4; #X obj 182 809 3dp_draw cube 1.4; #X msg 597 536 4; #X obj 59 151 3dp_view transz -3; #X obj 546 216 3dp_view roty 54; #X obj 669 392 s cubesize; #X msg 360 345 3.15; #X msg 126 17 20; #X obj 284 612 * 0.11; #X floatatom 672 220 5 0 0 0 - - -, f 5; #X msg 612 72 0; #X obj 342 311 * 1; #X obj 59 201 3dp_view rotx; #X floatatom 164 187 5 0 0 0 - - -, f 5; #X floatatom 358 641 5 0 0 0 - - -, f 5; #X obj 182 700 arm 3; #X obj 182 724 arm 3; #X obj 182 748 arm 3; #X obj 182 677 arm 3; #X floatatom 359 664 5 0 0 0 - - -, f 5; #X floatatom 359 688 5 0 0 0 - - -, f 5; #X floatatom 360 712 5 0 0 0 - - -, f 5; #X obj 284 706 * -1; #X obj 182 771 arm 3; #X floatatom 360 735 5 0 0 0 - - -, f 5; #X obj 283 753 * -1.5; #X obj 284 659 * 2.1; #X obj 284 682 * -1.7; #X obj 283 730 * 0.11; #X obj 9 334 3dp_push; #X obj 182 399 3dp_view transz; #X floatatom 282 369 5 0 0 0 - - -, f 5; #X obj 131 371 3dp_view transz; #X obj 231 338 * -1; #X msg 282 341 2; #X obj 564 401 s drawtorus; #X obj 564 374 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 674 496 s torusr1; #X floatatom 672 473 5 0 0 0 - - -, f 5; #X floatatom 667 419 5 0 0 0 - - -, f 5; #X obj 669 442 s torusr2; #X msg 564 349 1; #X obj 597 645 *; #X obj 59 126 3dp_push; #X obj 9 364 3dp_push; #X obj 9 437 3dp_view rotx; #X floatatom 96 416 5 0 0 0 - - -, f 5; #X obj 9 471 3dp_draw sphere 30 40; #X obj 9 593 3dp_snap; #X obj 473 487 / 1000; #X floatatom 473 461 5 0 0 0 - - -, f 5; #X obj 430 8 loadbang; #X obj 430 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 59 77 3dp_windowcontext; #X obj 59 274 3dp_push; #X obj 110 303 pdp_t p b; #X obj 9 307 pdp_t p b; #X msg 349 252 400; #X msg 311 252 -400; #X obj 342 287 +; #X msg 473 434 3; #X text 544 189 light source; #X obj 59 248 3dp_view scale 0.4; #X obj 640 157 s counter; #X obj 245 169 r counter; #X text 694 98 speed; #X obj 59 54 metro 20; #X obj 238 207 * 0.05; #X obj 9 570 spigot; #X obj 76 546 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 612 122 + 1; #X text 28 521 texture feedback; #X text 486 751 "no-bots in no-sphere"; #X text 459 768 a double dance of 13 segments; #X text 549 734 ---; #X text 549 787 ---; #X obj 59 176 3dp_mouserotate; #X msg 188 47 close; #X obj 285 51 delay 5000; #X connect 0 0 108 1; #X connect 1 0 108 0; #X connect 2 0 108 0; #X connect 3 0 27 1; #X connect 4 0 85 0; #X connect 4 1 46 0; #X connect 5 0 46 1; #X connect 6 0 7 0; #X connect 8 0 112 0; #X connect 9 0 112 1; #X connect 10 0 47 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 13 0 22 0; #X connect 14 0 11 0; #X connect 15 0 37 1; #X connect 16 0 38 1; #X connect 17 0 39 1; #X connect 18 0 40 1; #X connect 19 0 20 0; #X connect 20 0 21 0; #X connect 21 0 29 0; #X connect 22 0 19 0; #X connect 23 0 41 1; #X connect 24 0 28 1; #X connect 25 0 50 1; #X connect 26 0 104 0; #X connect 27 0 37 0; #X connect 27 0 14 1; #X connect 28 0 50 0; #X connect 28 0 20 1; #X connect 29 0 60 0; #X connect 30 0 31 1; #X connect 31 0 29 1; #X connect 31 0 68 0; #X connect 33 0 84 1; #X connect 34 0 35 0; #X connect 36 0 42 2; #X connect 36 0 43 2; #X connect 37 0 38 0; #X connect 37 0 11 1; #X connect 38 0 39 0; #X connect 38 0 12 1; #X connect 39 0 40 0; #X connect 39 0 13 1; #X connect 40 0 41 0; #X connect 40 0 22 1; #X connect 41 0 28 0; #X connect 41 0 19 1; #X connect 42 0 14 0; #X connect 44 0 34 0; #X connect 45 0 118 0; #X connect 46 0 6 0; #X connect 48 0 36 0; #X connect 48 0 102 0; #X connect 48 0 76 0; #X connect 48 0 83 0; #X connect 49 0 0 0; #X connect 50 0 31 0; #X connect 50 0 21 1; #X connect 51 0 6 1; #X connect 52 0 8 0; #X connect 53 0 27 0; #X connect 54 0 26 0; #X connect 55 0 54 1; #X connect 56 0 68 1; #X connect 57 0 58 0; #X connect 58 0 59 0; #X connect 59 0 65 0; #X connect 60 0 57 0; #X connect 61 0 69 1; #X connect 62 0 64 1; #X connect 63 0 70 1; #X connect 64 0 70 0; #X connect 64 0 58 1; #X connect 65 0 43 0; #X connect 66 0 67 1; #X connect 67 0 65 1; #X connect 68 0 69 0; #X connect 68 0 60 1; #X connect 69 0 64 0; #X connect 69 0 57 1; #X connect 70 0 67 0; #X connect 70 0 59 1; #X connect 71 0 86 0; #X connect 71 1 74 0; #X connect 72 0 42 0; #X connect 73 0 72 1; #X connect 73 0 75 0; #X connect 74 0 42 0; #X connect 75 0 74 1; #X connect 76 0 73 0; #X connect 78 0 77 0; #X connect 80 0 79 0; #X connect 81 0 82 0; #X connect 83 0 78 0; #X connect 84 0 32 0; #X connect 85 0 45 0; #X connect 86 0 87 0; #X connect 87 0 89 0; #X connect 88 0 87 1; #X connect 89 0 110 0; #X connect 90 1 89 1; #X connect 91 0 33 0; #X connect 92 0 91 0; #X connect 93 0 94 0; #X connect 93 0 120 0; #X connect 94 0 1 0; #X connect 94 0 48 0; #X connect 95 0 4 0; #X connect 95 1 118 1; #X connect 96 0 98 0; #X connect 96 1 97 0; #X connect 97 0 72 0; #X connect 97 1 100 0; #X connect 98 0 71 0; #X connect 98 1 99 0; #X connect 99 0 101 0; #X connect 100 0 101 0; #X connect 101 0 53 0; #X connect 102 0 92 0; #X connect 102 0 44 0; #X connect 104 0 96 0; #X connect 106 0 109 0; #X connect 108 0 95 0; #X connect 108 0 8 0; #X connect 109 0 26 1; #X connect 110 0 90 0; #X connect 111 0 110 1; #X connect 112 0 8 1; #X connect 112 0 84 0; #X connect 112 0 101 1; #X connect 112 0 105 0; #X connect 118 0 54 0; #X connect 119 0 95 0; #X connect 120 0 119 0; pdp-0.14.1+darcs20180201/opengl/test/example01.sh000077500000000000000000000004161266045153600206750ustar00rootroot00000000000000#!/bin/bash cd $(dirname $0) PD=/usr/local/bin/pd PDP=/home/tom/pdp exec gdb -x example01.gdb -i=mi --args $PD \ -nogui -nrt -noprefs \ -path $PDP \ -path $PDP/abstractions \ -path $PDP/opengl \ -path $PDP/opengl/abstractions \ -lib pdp \ -lib pdp_opengl \ example01.pd pdp-0.14.1+darcs20180201/opengl/test/meshtest.pd000066400000000000000000000122771266045153600207330ustar00rootroot00000000000000#N canvas 561 0 657 860 10; #X obj 101 61 3dp_windowcontext; #X obj 101 27 metro 20; #X obj 101 122 3dp_push; #X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 253 32 cursor \$1; #X obj 253 12 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 90 222 3dp_mouserotate; #X text 14 250 use the mouse to rotate the model (but not the light source since it is rendered before the rotation is applied.); #X obj 67 516 3dp_drawmesh; #X obj 261 163 3dp_view transxyz 0 0 4; #X floatatom 412 128 5 0 0 0 - - -; #X floatatom 193 392 5 0 0 0 - - -; #X obj 312 293 spigot; #X obj 362 263 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 119 341 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 179 494 3dp_dlist; #X msg 188 467 compile; #X obj 110 466 pdp_route; #X obj 202 442 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 266 363 reset; #X obj 180 292 t b b b b b; #X msg 310 504 normal sphere; #X msg 309 458 normal prism; #X msg 310 481 normal random; #X obj 276 307 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 276 328 t b b b; #X obj 334 369 f; #X floatatom 382 317 5 0 0 0 - - -; #X floatatom 433 318 5 0 0 0 - - -; #X obj 81 297 pdp_t p b; #X obj 308 607 t b b; #X obj 390 612 t b b; #X obj 251 581 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 428 575 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 483 316 5 0 0 0 - - -; #X msg 451 288 5; #X msg 478 287 0; #X msg 507 290 5; #X obj 317 399 pack 0 0 0; #X msg 383 293 0.01; #X obj 68 420 3dp_view scale 0.5; #X obj 426 348 abs; #X obj 470 337 abs; #X msg 67 569 wireframe \$1; #X obj 84 545 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 10 322 spigot; #X obj 60 292 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 518 152 collectgarbage; #X obj 516 179 pdp_control; #X msg 317 537 info; #X msg 226 332 split4; #X msg 177 334 split3; #X msg 10 364 split3random; #X msg 317 421 springrelax \$1 \$2 \$3; #X obj 471 243 t b b b b; #X obj 486 219 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 273 199 3dp_light; #X floatatom 58 147 5 0 0 0 - - -; #X floatatom 103 146 5 0 0 0 - - -; #X floatatom 147 145 5 0 0 0 - - -; #X floatatom 191 143 5 0 0 0 - - -; #X msg 431 485 normal average; #X obj 85 590 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 68 614 flatshading \$1; #X obj 89 196 3dp_view roty; #X obj 387 54 f; #X obj 388 82 +; #X obj 98 78 pdp_t p b; #X floatatom 431 57 5 0 0 0 - - -; #X floatatom 181 9 5 0 0 0 - - -; #X obj 45 785 3dp_snap; #X floatatom 152 692 5 0 0 0 - - -; #X obj 221 736 print; #X obj 21 176 3dp_color 0.74 0.73 0.62 1; #X obj 32 726 3dp_draw sphere 9; #X obj 533 88 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 524 111 3dthread \$1; #X obj 256 672 pdp_v4l; #X obj 258 644 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 369 682 pdp_convert texture/*/*; #X obj 365 712 pdp_description; #X symbolatom 376 746 10 0 0 0 - - -; #X obj 191 654 metro 40; #X obj 191 631 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 314 760 pdp_xv; #X connect 0 0 68 0; #X connect 0 1 7 1; #X connect 1 0 0 0; #X connect 1 0 66 0; #X connect 2 0 74 0; #X connect 2 1 10 0; #X connect 3 0 1 0; #X connect 4 0 0 0; #X connect 5 0 0 0; #X connect 6 0 5 0; #X connect 7 0 30 0; #X connect 9 0 75 0; #X connect 10 0 57 0; #X connect 11 0 10 3; #X connect 12 0 41 1; #X connect 13 0 27 0; #X connect 14 0 13 1; #X connect 15 0 9 0; #X connect 16 0 9 0; #X connect 17 0 16 0; #X connect 18 0 9 0; #X connect 18 1 16 0; #X connect 19 0 18 1; #X connect 20 0 9 0; #X connect 21 0 52 0; #X connect 21 1 52 0; #X connect 21 2 51 0; #X connect 21 4 51 0; #X connect 22 0 9 0; #X connect 23 0 9 0; #X connect 24 0 9 0; #X connect 25 0 26 0; #X connect 26 0 62 0; #X connect 26 1 21 0; #X connect 26 2 20 0; #X connect 27 0 39 0; #X connect 28 0 27 1; #X connect 29 0 39 1; #X connect 30 0 41 0; #X connect 30 1 13 0; #X connect 30 1 46 0; #X connect 31 0 52 0; #X connect 31 1 50 0; #X connect 32 0 51 0; #X connect 32 1 50 0; #X connect 33 0 31 0; #X connect 34 0 32 0; #X connect 35 0 43 0; #X connect 36 0 29 0; #X connect 37 0 29 0; #X connect 38 0 35 0; #X connect 39 0 54 0; #X connect 40 0 28 0; #X connect 41 0 18 0; #X connect 42 0 39 1; #X connect 43 0 39 2; #X connect 44 0 9 0; #X connect 45 0 44 0; #X connect 46 0 53 0; #X connect 47 0 46 1; #X connect 48 0 49 0; #X connect 50 0 9 0; #X connect 51 0 9 0; #X connect 52 0 9 0; #X connect 53 0 9 0; #X connect 54 0 9 0; #X connect 55 0 14 0; #X connect 55 1 40 0; #X connect 55 2 37 0; #X connect 55 3 38 0; #X connect 56 0 55 0; #X connect 58 0 74 1; #X connect 59 0 74 2; #X connect 60 0 74 3; #X connect 61 0 74 4; #X connect 62 0 9 0; #X connect 63 0 64 0; #X connect 64 0 9 0; #X connect 65 0 7 0; #X connect 66 0 67 0; #X connect 67 0 66 1; #X connect 67 0 65 1; #X connect 68 0 2 0; #X connect 69 0 67 1; #X connect 70 0 1 1; #X connect 72 0 75 2; #X connect 74 1 65 0; #X connect 76 0 77 0; #X connect 77 0 49 0; #X connect 78 0 80 0; #X connect 79 0 78 0; #X connect 80 0 81 0; #X connect 80 0 75 1; #X connect 81 0 82 0; #X connect 83 0 78 0; #X connect 84 0 83 0; pdp-0.14.1+darcs20180201/opengl/test/pdp_ogl_draw_limb.pd000066400000000000000000000213011266045153600225270ustar00rootroot00000000000000#N canvas 408 287 799 654 10; #X floatatom 170 39 5 0 0; #X obj 82 46 metro 40; #X obj 82 19 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 125 17 10; #X msg 99 4 stop; #X floatatom 284 336 5 0 0; #X obj 83 128 3dp_push; #X floatatom 502 132 5 0 0; #X obj 413 193 3dp_view transx 3; #X obj 404 251 3dp_light; #X obj 317 23 f; #X floatatom 356 24 5 0 0; #X floatatom 155 114 5 0 0; #X floatatom 575 415 5 0 0; #X floatatom 405 344 5 0 0; #X obj 130 456 arm 3; #X obj 128 482 arm 3; #X obj 128 516 arm 3; #X obj 137 430 arm 3; #X floatatom 288 376 5 0 0; #X floatatom 286 414 5 0 0; #X floatatom 290 454 5 0 0; #X floatatom 285 509 5 0 0; #X obj 139 608 arm 3; #X obj 138 641 arm 3; #X obj 132 671 arm 3; #X obj 139 583 arm 3; #X floatatom 289 549 5 0 0; #X floatatom 287 587 5 0 0; #X floatatom 291 627 5 0 0; #X obj 78 226 3dp_view roty; #X obj 248 358 * 1; #X obj 251 610 * -1; #X obj 507 567 s texture; #X obj 790 506 pdp_v4l; #X obj 790 478 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 785 434 metro 10; #X obj 782 408 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 812 403 stop; #X obj 139 707 arm 3; #X floatatom 307 661 5 0 0; #X obj 256 684 * -1.5; #X obj 474 719 s roty; #X floatatom 436 644 5 0 0; #X floatatom 570 687 5 0 0; #X obj 572 718 s scale; #X floatatom 180 212 5 0 0; #X floatatom 285 108 5 0 0; #X floatatom 347 299 5 0 0; #X obj 252 398 * -1.01; #X obj 250 436 * 0.99; #X obj 254 476 * -1.01; #X obj 249 531 * 2.1; #X obj 253 571 * -1.7; #X obj 133 399 3dp_draw cube 1.4; #X obj 129 886 3dp_draw cube 1.4; #X obj 445 68 t b b; #X msg 615 633 4; #X msg 503 640 14; #X obj 323 57 + 3; #X obj 70 174 3dp_view transz -3; #X obj 411 164 3dp_view roty 54; #X obj 398 378 s cubesize; #X msg 351 255 3.15; #X obj 68 248 3dp_view scale 0.4; #X msg 173 15 20; #X obj 255 649 * 0.11; #X floatatom 544 163 5 0 0; #X msg 421 3 0; #X obj 269 283 * 1; #X obj 85 203 3dp_view rotx; #X floatatom 163 172 5 0 0; #X floatatom 309 690 5 0 0; #X obj 128 769 arm 3; #X obj 127 802 arm 3; #X obj 121 832 arm 3; #X obj 128 733 arm 3; #X floatatom 313 730 5 0 0; #X floatatom 311 768 5 0 0; #X floatatom 315 808 5 0 0; #X obj 275 791 * -1; #X obj 128 868 arm 3; #X floatatom 331 842 5 0 0; #X obj 280 865 * -1.5; #X obj 273 712 * 2.1; #X obj 277 752 * -1.7; #X obj 279 830 * 0.11; #X obj 8 344 3dp_push; #X obj 148 311 3dp_view transz; #X floatatom 212 262 5 0 0; #X obj 44 365 3dp_view transz; #X obj 88 326 * -1; #X msg 267 165 2; #X obj 222 118 * 0.05; #X obj 518 805 s drawtorus; #X obj 518 778 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 515 853 s torusr1; #X floatatom 513 830 5 0 0; #X floatatom 611 831 5 0 0; #X obj 613 854 s torusr2; #X msg 569 761 1; #X obj 418 678 *; #X obj 422 292 metro 100; #X obj 418 266 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 167 366 3dp_dlist; #X msg 174 335 compile; #X floatatom 27 142 5 0 0; #X obj 82 150 3dp_push; #X obj 449 801 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 400 772 metro 40; #X obj 375 780 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj -20 368 3dp_push; #X obj -23 453 3dp_view rotx; #X floatatom 64 432 5 0 0; #X msg -4 56 dim 640 480; #X obj -15 533 3dp_draw sphere 30 40; #X msg 635 291 dim 512 512; #X obj 445 424 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 637 360 pdp_t p p; #X msg 434 617; #X msg 478 613 0.001; #X obj -11 573 3dp_snap; #X obj 701 192 pdp_control; #X msg 731 157 thread 1; #X msg 731 126 thread 0; #X obj 438 580 / 1000; #X floatatom 432 545 5 0 0; #X obj 156 89 3dp_view roty; #X floatatom 264 67 5 0 0; #X obj 591 104 print een; #X obj 595 129 print twee; #X obj 380 866 pdp_tex; #X obj 389 836 pdp_noise; #X msg 376 806 dim 64 64; #X obj 376 748 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 476 880 dim 32 32; #X obj 341 894 print tex; #X obj 452 858 print noise; #X obj 505 16 loadbang; #X obj 460 13 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 440 821 pdp_v4l; #X obj 38 25 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 597 243 osc~ 400; #X obj 582 275 dac~; #X msg 601 50 \; pd dsp 1; #X obj 137 68 3dp_windowcontext; #X msg 575 188 stop; #X obj 569 211 metro 1000; #X floatatom 620 181 5 0 0; #X obj 551 188 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj -13 98 3dp_windowcontext; #X obj 82 66 t b b; #X floatatom 361 84 5 0 0; #X obj 14 281 3dp_push; #X obj 96 273 pdp_t p b; #X obj 9 307 pdp_t p b; #X obj 428 43 t b b; #X msg 510 42 open; #X msg 304 213 400; #X msg 241 209 -400; #X obj 274 254 +; #X obj 748 595 pdp_xv; #X obj 750 544 pdp_abs; #X obj 504 465 print; #X obj 504 441 route done; #X obj -17 170 3dp_color; #X obj 8 696 pdp_description; #X symbolatom -14 773 40 0 0; #X msg 695 82 collectgarbage; #X obj -9 738 symbol; #X obj -11 717 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 14 628 pdp_del 50; #X connect 0 0 1 1; #X connect 1 0 10 0; #X connect 1 0 151 0; #X connect 2 0 1 0; #X connect 3 0 1 1; #X connect 4 0 1 0; #X connect 5 0 31 1; #X connect 6 0 107 0; #X connect 6 1 61 0; #X connect 7 0 61 1; #X connect 8 0 9 0; #X connect 10 0 59 0; #X connect 11 0 59 1; #X connect 12 0 60 1; #X connect 14 0 62 0; #X connect 15 0 16 0; #X connect 16 0 17 0; #X connect 17 0 26 0; #X connect 18 0 15 0; #X connect 19 0 49 1; #X connect 20 0 50 1; #X connect 21 0 51 1; #X connect 22 0 52 1; #X connect 23 0 24 0; #X connect 24 0 25 0; #X connect 25 0 39 0; #X connect 26 0 23 0; #X connect 27 0 53 1; #X connect 28 0 32 1; #X connect 29 0 66 1; #X connect 30 0 64 0; #X connect 31 0 49 0; #X connect 31 0 18 1; #X connect 32 0 66 0; #X connect 32 0 24 1; #X connect 34 0 162 0; #X connect 35 0 34 0; #X connect 36 0 35 0; #X connect 37 0 36 0; #X connect 38 0 36 0; #X connect 39 0 76 0; #X connect 40 0 41 1; #X connect 41 0 39 1; #X connect 41 0 84 0; #X connect 43 0 101 1; #X connect 44 0 45 0; #X connect 46 0 64 1; #X connect 47 0 93 1; #X connect 48 0 54 2; #X connect 48 0 55 2; #X connect 49 0 50 0; #X connect 49 0 15 1; #X connect 50 0 51 0; #X connect 50 0 16 1; #X connect 51 0 52 0; #X connect 51 0 17 1; #X connect 52 0 53 0; #X connect 52 0 26 1; #X connect 53 0 32 0; #X connect 53 0 23 1; #X connect 54 0 18 0; #X connect 56 0 2 0; #X connect 56 0 63 0; #X connect 56 0 65 0; #X connect 56 0 92 0; #X connect 56 1 57 0; #X connect 56 1 144 0; #X connect 56 1 147 0; #X connect 57 0 44 0; #X connect 57 0 58 0; #X connect 57 0 100 0; #X connect 58 0 42 0; #X connect 59 0 10 1; #X connect 59 0 93 0; #X connect 59 0 101 0; #X connect 59 0 160 1; #X connect 60 0 70 0; #X connect 61 0 8 0; #X connect 63 0 48 0; #X connect 64 0 153 0; #X connect 65 0 0 0; #X connect 66 0 41 0; #X connect 66 0 25 1; #X connect 67 0 8 1; #X connect 68 0 10 0; #X connect 69 0 31 0; #X connect 70 0 30 0; #X connect 71 0 70 1; #X connect 72 0 84 1; #X connect 73 0 74 0; #X connect 74 0 75 0; #X connect 75 0 81 0; #X connect 76 0 73 0; #X connect 77 0 85 1; #X connect 78 0 80 1; #X connect 79 0 86 1; #X connect 80 0 86 0; #X connect 80 0 74 1; #X connect 81 0 55 0; #X connect 82 0 83 1; #X connect 83 0 81 1; #X connect 84 0 85 0; #X connect 85 0 80 0; #X connect 85 0 73 1; #X connect 86 0 83 0; #X connect 86 0 75 1; #X connect 87 0 111 0; #X connect 87 1 90 0; #X connect 88 0 54 0; #X connect 89 0 88 1; #X connect 89 0 91 0; #X connect 90 0 54 0; #X connect 91 0 90 1; #X connect 92 0 89 0; #X connect 93 0 30 1; #X connect 95 0 94 0; #X connect 97 0 96 0; #X connect 98 0 99 0; #X connect 100 0 95 0; #X connect 101 0 42 0; #X connect 103 0 102 0; #X connect 104 0 54 0; #X connect 105 0 104 0; #X connect 106 0 165 3; #X connect 107 0 60 0; #X connect 108 0 140 0; #X connect 110 0 132 0; #X connect 111 0 112 0; #X connect 112 0 115 0; #X connect 113 0 112 1; #X connect 114 0 150 0; #X connect 115 0 121 0; #X connect 117 0 134 0; #X connect 120 0 43 0; #X connect 121 1 171 0; #X connect 123 0 122 0; #X connect 124 0 122 0; #X connect 125 0 43 0; #X connect 126 0 125 0; #X connect 127 0 6 0; #X connect 128 0 127 1; #X connect 133 0 132 0; #X connect 134 0 108 0; #X connect 135 0 132 0; #X connect 138 0 139 0; #X connect 139 0 156 0; #X connect 141 0 151 0; #X connect 142 0 143 0; #X connect 142 0 143 1; #X connect 145 0 127 0; #X connect 145 1 130 0; #X connect 146 0 147 0; #X connect 148 0 147 1; #X connect 149 0 147 0; #X connect 150 0 165 0; #X connect 151 0 150 0; #X connect 153 0 155 0; #X connect 153 1 154 0; #X connect 154 0 88 0; #X connect 154 1 159 0; #X connect 155 0 87 0; #X connect 155 1 158 0; #X connect 156 1 56 0; #X connect 157 0 145 0; #X connect 158 0 160 0; #X connect 159 0 160 0; #X connect 160 0 69 0; #X connect 162 0 161 0; #X connect 164 0 163 0; #X connect 165 0 6 0; #X connect 166 0 169 1; #X connect 168 0 122 0; #X connect 169 0 167 0; #X connect 170 0 169 0; #X connect 171 0 115 1; pdp-0.14.1+darcs20180201/opengl/test/textest.pd000066400000000000000000000027251266045153600205740ustar00rootroot00000000000000#N canvas 561 0 657 860 10; #X obj 106 106 3dp_windowcontext; #X obj 101 27 metro 20; #X obj 102 11 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X obj 56 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 181 9 5 0 0 0 - - -; #X floatatom 106 663 5 0 0 0 - - -; #X obj 221 736 print; #X obj 229 541 pdp_v4l; #X obj 231 513 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 369 682 pdp_convert texture/*/*; #X obj 314 760 pdp_xv; #X obj 365 712 pdp_description; #X symbolatom 376 746 10 0 0 0 - - -; #X obj 369 657 pdp_convert bitmap/*/*; #X obj 164 523 metro 40; #X obj 164 500 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X floatatom 214 466 5 0 0 0 - - -; #X obj 363 235 pdp_control; #X msg 366 199 3dthread \$1; #X obj 374 167 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 109 135 3dp_mouserotate; #X obj 32 726 3dp_draw sphere 9; #X msg 167 417 open /dev/video1; #X obj 379 558 pdp_chrot; #X floatatom 429 519 5 0 0 0 - - -; #X connect 0 0 20 0; #X connect 0 1 20 1; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 0 0; #X connect 4 0 1 1; #X connect 5 0 21 2; #X connect 7 0 23 0; #X connect 8 0 7 0; #X connect 9 0 11 0; #X connect 9 0 21 1; #X connect 11 0 12 0; #X connect 13 0 9 0; #X connect 14 0 7 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 18 0 17 0; #X connect 19 0 18 0; #X connect 20 0 21 0; #X connect 22 0 7 0; #X connect 23 0 13 0; #X connect 23 0 10 0; #X connect 24 0 23 1; pdp-0.14.1+darcs20180201/project.mk000077500000000000000000000111141266045153600162760ustar00rootroot00000000000000#!/usr/bin/make -f include Makefile.config # Faster alternative makefile, for development only. C := \ modules/image_special/pdp_chrot.c \ modules/image_special/pdp_scanxy.c \ modules/image_special/pdp_array.c \ modules/image_special/pdp_grey2mask.c \ modules/image_special/pdp_scan.c \ modules/image_special/pdp_histo.c \ modules/image_special/pdp_scale.c \ modules/image_special/pdp_cog.c \ modules/image_special/pdp_scope.c \ modules/image_basic/pdp_cheby.c \ modules/image_basic/pdp_stateless.c \ modules/image_basic/pdp_bq.c \ modules/image_basic/pdp_mul.c \ modules/image_basic/pdp_gain.c \ modules/image_basic/pdp_logic.c \ modules/image_basic/pdp_mix.c \ modules/image_basic/pdp_add.c \ modules/image_basic/pdp_conv.c \ modules/image_basic/pdp_plasma.c \ modules/image_basic/pdp_constant.c \ modules/image_basic/pdp_randmix.c \ modules/image_basic/pdp_noise.c \ modules/image_basic/pdp_zoom.c \ modules/matrix_basic/pdp_mat_vec.c \ modules/matrix_basic/pdp_mat_lu.c \ modules/matrix_basic/pdp_mat_mul.c \ modules/generic/pdp_route.c \ modules/generic/pdp_convert.c \ modules/generic/pdp_udp_send.c \ modules/generic/pdp_del.c \ modules/generic/pdp_description.c \ modules/generic/pdp_inspect.c \ modules/generic/pdp_loop.c \ modules/generic/pdp_rawin.c \ modules/generic/pdp_snap.c \ modules/generic/pdp_rawout.c \ modules/generic/pdp_udp_receive.c \ modules/generic/pdp_metro.c \ modules/generic/pdp_trigger.c \ modules/generic/pdp_reg.c \ modules/image_io/pdp_glx.c \ modules/image_io/pdp_v4l.c \ modules/image_io/pdp_xv.c \ modules/image_io/pdp_qt.c \ modules/test/pdp_dpd_test.c \ puredata/pdp_comm.c \ puredata/pdp_imagebase.c \ puredata/pdp_control.c \ puredata/pdp_queue.c \ puredata/pdp_dpd_base.c \ puredata/pdp_ut.c \ puredata/pdp_base.c \ puredata/pdp_compat.c \ system/type/pdp_image.c \ system/type/pdp_matrix.c \ system/type/pdp_bitmap.c \ system/image/pdp_llconv_portable.c \ system/image/pdp_llconv.c \ system/image/pdp_resample.c \ system/image/pdp_imageproc_common.c \ system/image/pdp_imageproc_gcc_mmx.c \ system/pdp.c \ system/png/pdp_png.c \ system/kernel/pdp_mem.c \ system/kernel/pdp_packet.c \ system/kernel/pdp_debug.c \ system/kernel/pdp_dpd_command.c \ system/kernel/pdp_post.c \ system/kernel/pdp_symbol.c \ system/kernel/pdp_type.c \ system/kernel/pdp_list.c \ system/net/pdp_net.c \ system/zl/v4l.c \ system/zl/glx.c \ system/zl/xv.c \ system/zl/xwindow.c \ modules/image_io/pdp_sdl.c \ C_SCAF := \ scaf/pdp/pdp_ca_system.c \ scaf/pdp/pdp_ca.c \ # debug/teststuff.c \ # modules/matrix_basic/clusterstuff.c \ # system/kernel/pdp_packet2.c \ C_OPENGL := \ opengl/modules/pdp_3d_state.c \ opengl/modules/pdp_3d_view.c \ opengl/modules/pdp_3d_subcontext.c \ opengl/modules/pdp_3d_context.c \ opengl/modules/pdp_3d_push.c \ opengl/modules/pdp_3d_draw.c \ opengl/modules/pdp_3d_windowcontext.c \ opengl/modules/pdp_3d_dlist.c \ opengl/modules/pdp_3d_light.c \ opengl/modules/pdp_3d_for.c \ opengl/modules/pdp_3d_drawmesh.c \ opengl/modules/pdp_3d_color.c \ opengl/modules/pdp_3d_snap.c \ opengl/system/setup.c \ opengl/system/pdp_texture.c \ opengl/system/pdp_3Dcontext_common.c \ opengl/system/pdp_3dp_base.c \ opengl/system/pdp_opengl.c \ opengl/system/pdp_mesh.c \ opengl/system/pdp_3Dcontext_glx.c \ C_MMX := \ system/image/pdp_llconv_mmx.c \ system/image/pdp_imageproc_mmx.c \ system/mmx/pdp_mmx_test.c \ CC := gcc # CFLAGS := -Iinclude -Iopengl/include -Iscaf/include CFLAGS_MMX := -mmmx # Necessary on i32 CFLAGS := -I../ -I../system -Isystem -Iinclude -Iopengl/include -Iscaf/include -fPIC -O3 $(PDP_CFLAGS) $(CFLAGS_MMX) -g #-DHAVE_LIBV4L1_VIDEODEV_H BUILD := build ARCH := pd_linux LDFLAGS := -rdynamic -shared LIBS := $(PDP_LIBS) PDP := $(BUILD)/pdp.$(ARCH) # .SECONDARY: ## This is tricky stuff... .DELETE_ON_ERROR: .PHONY: all all: $(PDP) .PHONY: clean clean: rm -rf build O := $(patsubst %.c,$(BUILD)/%.o,$(C)) D := $(O:.o=.d) $(BUILD)/%.d: %.c @echo [d] $(notdir $@) @mkdir -p $(dir $@) @$(CC) -MT $(basename $@).o -MM $(CFLAGS) $< >$@ -include $(D) $(BUILD)/%.o: %.c $(BUILD)/%.d @echo [o] $(notdir $@) @mkdir -p $(dir $@) @$(CC) $(CFLAGS) -c $< -o $@ $(BUILD)/pdp.$(ARCH): $(O) @echo [pd_linux] $(notdir $@) @$(CC) $(LDFLAGS) -o $@ $(O) $(LIBS) %.dasm: %.o objdump -d $< >$@ .PHONY: test PD := pd.local test: $(PDP) $(BUILD)/system/image/pdp_imageproc_gcc_mmx.dasm cd test ; PDP_TEST=v4l $(PD) -nogui test-v4l.pd # Symlink pdp.$(ARCH): $(BUILD)/pdp.$(ARCH) rm -f $@ ln -s $< $@ cscope.files: find \ -regex '.*\.[ch][px]?[px]?' \ -print >$@ cscope: cscope.files # cscope -kbq cscope -kb pdp-0.14.1+darcs20180201/puredata/000077500000000000000000000000001266045153600161035ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/puredata/CONTENTS000066400000000000000000000005631266045153600172670ustar00rootroot00000000000000base pdp base pd object image_base image processing base pd object dpd_base bucket base pd object comm pdp communication protocol in pd compat legacy pdp stuff control control pdp from within pd fp object interface to the forth system forthconsole console interface to the forth system queue processing queue and synchro stuff ut some utility pd objects pdp-0.14.1+darcs20180201/puredata/Makefile000066400000000000000000000003151266045153600175420ustar00rootroot00000000000000 OBJECTS = pdp_base.o pdp_imagebase.o pdp_dpd_base.o pdp_ut.o pdp_queue.o pdp_comm.o \ pdp_control.o pdp_compat.o $(PDP_PDMOD) include ../Makefile.config all: $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/puredata/pdp_base.c000066400000000000000000000226421266045153600200320ustar00rootroot00000000000000/* * Pure Data Packet base class implementation. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains the pdp base class object. This is really nothing more than an attempt to stay away from c++ as far as possible, while having some kind of base class functionality for pdp (tucking away the communication & thread protocol). */ #include "pdp_base.h" #include static void pdp_base_debug(t_pdp_base *b, t_floatarg __attribute__((unused)) f) { int i; post("debug"); post("inlets: %d", b->b_inlets); post("\tpacket\tnext_packet"); for (i=0; ib_inlets; i++) post("\t%d\t%d", b->b_packet[i], b->b_packet_next[i]); //post("outlets: %d", b->b_inlets); } static void pdp_base_thread(t_pdp_base *b, t_floatarg f) { int i = (int)f; if ((i == 0) || (i == 1)) b->b_thread_enabled = i; } static void pdp_base_process(t_pdp_base *b) { if (b->b_process_method) (*b->b_process_method)(b); } /* this method is called after the thread has finished processing */ static void pdp_base_postprocess(t_pdp_base *b) { /* call the derived class postproc callback if there is any */ if (b->b_postproc_method) (*b->b_postproc_method)(b); /* unregister (mark unused) packet and propagate if packet is valid */ if (b->b_outlet[0]) pdp_pass_if_valid(b->b_outlet[0], &b->b_packet[0]); } /* move the passive packets in place */ void pdp_base_movepassive(void *x) { t_pdp_base *b = (t_pdp_base *)x; int i; /* if a cold packet was received in the meantime swap it in, else keep the old one */ for (i=1; ib_inlets; i++){ pdp_replace_if_valid(&b->b_packet[i], &b->b_packet_next[i]); } } /* the standard bang method */ void pdp_base_bang(void *x) { t_pdp_base *b = (t_pdp_base *)x; int i; /* if pdp thread is still processing, do nothing */ if (-1 != b->b_queue_id) return; /* move packets in place */ pdp_base_movepassive(x); /* if there is a preproc method defined, call it inside the pd thread. (mainly for allocations) */ if (b->b_preproc_method) (*b->b_preproc_method)(b); /* check if we need to use pdp queue */ if (b->b_thread_enabled){ /* add the process method and callback to the process queue */ pdp_procqueue_add(b->b_q, b, pdp_base_process, pdp_base_postprocess, &b->b_queue_id); } else{ /* call both methods directly */ pdp_base_process(b); pdp_base_postprocess(b); } } /* hot packet input handler */ void pdp_base_input_hot(t_pdp_base *b, t_symbol *s, t_floatarg f) { int p = (int)f; /* dont register if active inlet is disabled */ if (!b->b_active_inlet_enabled) return; /* register the packet (readonly or read/write) or drop it if we have an active packet if type template is not null, packet will be converted */ if (b->b_active_inlet_readonly){ if (s == S_REGISTER_RO){ if (b->b_type_template[0]){ pdp_packet_convert_ro_or_drop(&b->b_packet[0], p, b->b_type_template[0]); } else{ pdp_packet_copy_ro_or_drop(&b->b_packet[0], p); } } } else{ if (s == S_REGISTER_RW) { if (b->b_type_template[0]){ pdp_packet_convert_rw_or_drop(&b->b_packet[0], p, b->b_type_template[0]); } else{ pdp_packet_copy_rw_or_drop(&b->b_packet[0], p); } } } /* start processing if there is an active packet to process and the processing method is not active */ if ((s == S_PROCESS) && (-1 != b->b_packet[0]) && (-1 == b->b_queue_id)){ pdp_base_bang(b); } //if ((pdp_sym_prc() == s) && (-1 != b->b_packet[0]) && (!b->b_dropped)) pdp_base_bang(b); } /* cold packet input handlers */ void pdp_base_input_cold(t_pdp_base *b, t_symbol *s, int ac, t_atom *av) { int p; int i; char msg[] = "pdp1"; char *c; int inlet; //post("pdp_base_input_cold: got packet"); /* do cheap tests first */ if (ac != 2) return; if (av[0].a_type != A_SYMBOL) return; if (av[0].a_w.w_symbol != S_REGISTER_RO) return; if (av[1].a_type != A_FLOAT) return; p = (int)av[1].a_w.w_float; /* check if it's a pdp message and determine inlet */ for (i=1; ib_packet_next[inlet], p); } void pdp_base_set_process_method(void *x, t_pdp_method m) { t_pdp_base *b = (t_pdp_base *)x; b->b_process_method = m; } void pdp_base_set_preproc_method(void *x, t_pdp_method m) { t_pdp_base *b = (t_pdp_base *)x; b->b_preproc_method = m; } void pdp_base_set_postproc_method(void *x, t_pdp_method m) { t_pdp_base *b = (t_pdp_base *)x; b->b_postproc_method = m; } void pdp_base_queue_wait(void *x) { t_pdp_base *b = (t_pdp_base *)x; pdp_procqueue_wait(b->b_q); } void pdp_base_set_queue(void *x, t_pdp_procqueue *q) { t_pdp_base *b = (t_pdp_base *)x; pdp_base_queue_wait(x); b->b_q = q; } t_pdp_procqueue *pdp_base_get_queue(void *x) { t_pdp_base *b = (t_pdp_base *)x; return b->b_q; } void pdp_base_setup(t_class *c) { /* add pdp base class methods */ class_addmethod(c, (t_method)pdp_base_thread, gensym("thread"), A_FLOAT, A_NULL); class_addmethod(c, (t_method)pdp_base_debug, gensym("debug"), A_NULL); /* hot packet handler */ class_addmethod(c, (t_method)pdp_base_input_hot, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); /* cold packet handler */ class_addanything(c, (t_method)pdp_base_input_cold); } /* pdp base instance constructor */ void pdp_base_init(void *x) { int i; t_pdp_base *b = (t_pdp_base *)x; b->b_channel_mask = -1; for(i=0; ib_packet[i] = -1; b->b_packet_next[i] = -1; b->b_type_template[i] = 0; } b->b_queue_id = -1; //b->b_dropped = 0; b->b_process_method = 0; b->b_preproc_method = 0; b->b_inlets = 1; b->b_outlets = 0; b->b_active_inlet_enabled = 1; b->b_active_inlet_readonly = 0; b->b_thread_enabled = 1; // default queue is pdp queue b->b_q = pdp_queue_get_queue(); } /* base instance destructor */ void pdp_base_free(void *x) { int i; t_pdp_base *b = (t_pdp_base *)x; /* remove process method from queue before deleting data */ pdp_procqueue_finish(b->b_q, b->b_queue_id); /* delete stuff */ for(i=0; ib_packet[i]); pdp_packet_mark_unused(b->b_packet_next[i]); } } void pdp_base_readonly_active_inlet(void *x) { t_pdp_base *b = (t_pdp_base *)x; b->b_active_inlet_readonly = 1; } void pdp_base_disable_active_inlet(void *x) { t_pdp_base *b = (t_pdp_base *)x; b->b_active_inlet_enabled = 0; } /* add an inlet */ void pdp_base_add_pdp_inlet(void *x) { t_pdp_base *b = (t_pdp_base *)x; char s[] = "pdp0"; s[3] += b->b_inlets; if (b->b_inlets < MAX_NB_PDP_BASE_INLETS){ inlet_new(&b->x_obj, &b->x_obj.ob_pd, gensym("pdp"), gensym(s)); b->b_inlets++; } else { post("pdp_base_add_pdp_inlet: only %d pdp inlets allowed. ignoring.", MAX_NB_PDP_BASE_INLETS); } } /* add an outlet: only one allowed */ t_outlet *pdp_base_add_pdp_outlet(void *x) { t_pdp_base *b = (t_pdp_base *)x; t_outlet *outlet = outlet_new(&b->x_obj, &s_anything); if (b->b_outlets < MAX_NB_PDP_BASE_OUTLETS){ b->b_outlet[b->b_outlets] = outlet; b->b_outlets++; } return outlet; } void pdp_base_set_packet(void *x, int inlet, int packet) { t_pdp_base *b = (t_pdp_base *)x; if (inlet < b->b_inlets){ //post("%d %d", b->b_packet[inlet], b->b_packet_next[inlet]); pdp_packet_mark_unused(b->b_packet[inlet]); b->b_packet[inlet] = packet; } } int pdp_base_get_packet(void *x, int inlet) { t_pdp_base *b = (t_pdp_base *)x; if (inlet < b->b_inlets){ //post("%d %d", b->b_packet[inlet], b->b_packet_next[inlet]); return (b->b_packet[inlet]); } return -1; } int pdp_base_move_packet(void *x, int inlet) { t_pdp_base *b = (t_pdp_base *)x; int p; if (inlet < b->b_inlets){ p = b->b_packet[inlet]; b->b_packet[inlet] = -1; return (p); } return -1; } t_object *pdp_base_get_object(void *x) { return (t_object *)x; } void pdp_base_add_gen_inlet(void *x, t_symbol *from, t_symbol *to) { t_object *o = (t_object *)x; inlet_new(o, &o->ob_pd, from, to); } void pdp_base_disable_thread(void *x) { t_pdp_base *b = (t_pdp_base *)x; b->b_thread_enabled = 0; } void pdp_base_set_type_template(void *x, int inlet, t_pdp_symbol *type_template) { t_pdp_base *b = (t_pdp_base *)x; if (inlet < b->b_inlets){ b->b_type_template[inlet] = type_template; } } pdp-0.14.1+darcs20180201/puredata/pdp_comm.c000066400000000000000000000204561266045153600200540ustar00rootroot00000000000000/* * Pure Data Packet system implementation. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains misc communication (packet) methods for pd */ #include #include "pdp_pd.h" #include "pdp_internals.h" #include "pdp_packet.h" #include "pdp_comm.h" #include "pdp_type.h" #include "pdp_control.h" #include "pdp_mem.h" #include "pdp_queue.h" // for notify drop: fix this (should be from pdp_control.h) #include "pdp_debug.h" /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* interface to pd system: pdp/dpd communication protocol in pd pd <-> pdp atom and list conversion */ /* NOTE: when using the outlet_pdp methods, the packet is no longer read/write, but can be readonly */ /* NOTE: since 0.13 the passing packet is no more. in order to limit copying. processors should always register ro, and replace with writable when packet needs to be written in the process method */ /* send a packet to an outlet */ void outlet_pdp_register(t_outlet *out, int packetid) { t_atom atom[2]; SETFLOAT(atom+1, (float)packetid); /* during the following phase, objects can register a ro copy */ SETSYMBOL(atom+0, S_REGISTER_RO); outlet_anything(out, S_PDP, 2, atom); /* DEPRECIATED: objects can register a rw copy but this will always copy the packet. it is better to perform a pdp_packet_replace_with_writable operation during the process step */ SETSYMBOL(atom+0, S_REGISTER_RW); outlet_anything(out, S_PDP, 2, atom); } /* send a packet to an outlet */ void outlet_pdp_process(t_outlet *out) { t_atom atom[2]; /* set a dummy invalid packet. this is for uniform pdp messages in pd, for ease of routing. */ SETFLOAT(atom+1, (float)-1); /* during the process phase, objects can perform pdp_packet_replace_with_writable and process the packet data */ SETSYMBOL(atom+0, S_PROCESS); outlet_anything(out, S_PDP, 2, atom); } /* for compat */ void outlet_pdp(t_outlet *out, int packetid) { outlet_pdp_register(out, packetid); outlet_pdp_process(out); } /* send an accumulation packet to an outlet */ void outlet_dpd(t_outlet *out, int packetid) { t_atom atom[2]; SETFLOAT(atom+1, (float)packetid); SETSYMBOL(atom+0, S_INSPECT); outlet_anything(out, S_DPD, 2, atom); SETSYMBOL(atom+0, S_ACCUMULATE); outlet_anything(out, S_DPD, 2, atom); } /* unregister a packet and send it to an outlet */ void pdp_packet_pass_if_valid(t_outlet *outlet, int *packet_ptr) { t_pdp *header = pdp_packet_header(*packet_ptr); if (header){ /* send register phase */ outlet_pdp_register(outlet, *packet_ptr); /* unregister */ pdp_packet_mark_unused(*packet_ptr); *packet_ptr = -1; /* send process phase */ outlet_pdp_process(outlet); } } void pdp_packet_replace_if_valid(int *dpacket, int *spacket) { if (-1 != *spacket){ pdp_packet_mark_unused(*dpacket); *dpacket = *spacket; *spacket = -1; } } int pdp_packet_copy_ro_or_drop(int *dpacket, int spacket) { int drop = 0; if (*dpacket == -1) *dpacket = pdp_packet_copy_ro(spacket); else { /* send a notification there is a dropped packet */ pdp_control_notify_drop(spacket); drop = 1; } return drop; } int pdp_packet_copy_rw_or_drop(int *dpacket, int spacket) { int drop = 0; if (*dpacket == -1) *dpacket = pdp_packet_copy_rw(spacket); else { /* send a notification there is a dropped packet */ pdp_control_notify_drop(spacket); drop = 1; } return drop; } int pdp_packet_convert_ro_or_drop(int *dpacket, int spacket, t_pdp_symbol *template) { int drop = 0; if (!template) return pdp_packet_copy_ro_or_drop(dpacket, spacket); if (*dpacket == -1) *dpacket = pdp_packet_convert_ro(spacket, template); else { /* send a notification there is a dropped packet */ pdp_control_notify_drop(spacket); drop = 1; } return drop; } int pdp_packet_convert_rw_or_drop(int *dpacket, int spacket, t_pdp_symbol *template) { int drop = 0; if (!template) return pdp_packet_copy_rw_or_drop(dpacket, spacket); if (*dpacket == -1) *dpacket = pdp_packet_convert_rw(spacket, template); else { /* send a notification there is a dropped packet */ pdp_control_notify_drop(spacket); drop = 1; } return drop; } /* send a pdp list to a pd outlet. packets are not copied but passed! */ void outlet_pdp_atom(t_outlet *out, t_pdp_atom *a) { int packet = -1; if (!a) return; switch(a->t){ case a_float: outlet_float(out, a->w.w_float); return; case a_int: outlet_float(out, (float)a->w.w_int); return; case a_symbol: outlet_symbol(out, gensym(a->w.w_symbol->s_name)); return; case a_list: outlet_pdp_list(out, a->w.w_list); return; case a_packet: pdp_packet_pass_if_valid(out, &a->w.w_packet); return; default: return; } } void outlet_pdp_list(t_outlet *out, struct _pdp_list *l) { int elements; t_atom *atomlist; t_pdp_atom *pdp_a; t_atom *pd_a; t_symbol *pd_selector; if (!l) return; switch(l->elements){ case 0: /* bang */ outlet_bang(out); return; case 1: /* atom */ outlet_pdp_atom(out, l->first); return; default: /* proper list*/ elements = l->elements; /* allocate list */ atomlist = pdp_alloc(sizeof (t_atom) * l->elements); pd_a = atomlist; pdp_a = l->first; /* setup selector */ if (pdp_a->t != a_symbol){ pd_selector = gensym("list"); } else { pd_selector = gensym(pdp_a->w.w_symbol->s_name); elements--; pdp_a = pdp_a->next; } /* setup atoms */ while (pdp_a){ switch(pdp_a->t){ case a_float: SETFLOAT(pd_a, pdp_a->w.w_float); break; case a_int: SETFLOAT(pd_a, (float)pdp_a->w.w_int); break; case a_symbol: SETSYMBOL(pd_a, gensym(pdp_a->w.w_symbol->s_name)); break; default: SETSYMBOL(pd_a, gensym("invalid")); break; } pdp_a = pdp_a->next; pd_a++; } /* send out */ outlet_anything(out, pd_selector, elements, atomlist); /* clean up */ pdp_dealloc(atomlist); } } void pd_atom_to_pdp_atom(t_atom *pdatom, t_pdp_atom *pdpatom) { switch (pdatom->a_type){ case A_FLOAT: pdpatom->t = a_float; pdpatom->w.w_float = pdatom->a_w.w_float; break; case A_SYMBOL: pdpatom->t = a_symbol; pdpatom->w.w_symbol = pdp_gensym(pdatom->a_w.w_symbol->s_name); break; default: pdpatom->t = a_undef; break; } } #if PDP_SYMBOL_HACK /* some "accelerated" pd symbols */ t_symbol s_pdp = {"pdp", 0, 0}; t_symbol s_register_ro = {"register_ro", 0, 0}; t_symbol s_register_rw = {"register_rw", 0, 0}; t_symbol s_process = {"process", 0, 0}; t_symbol s_dpd = {"dpd", 0, 0}; t_symbol s_inspect = {"inspect", 0, 0}; t_symbol s_accumulate = {"accumulate", 0, 0}; t_symbol s_chanmask = {"chanmask", 0, 0}; // internal pd method t_symbol *dogensym(char *s, t_symbol *oldsym); static void _addsym(t_symbol *s) { /* don't kill me for this one.. if the symbol is already defined and used, .. well, that's a problem but right now it seems a reasonable hack */ t_symbol *sret = dogensym(s->s_name, s); if (s != sret){ post("PDP INIT ERROR: pd symbol clash adding symbol %s: new=%08x old=%08x", s->s_name, s, sret); post("try loading pdp before other libraries"); } } void pdp_pdsym_setup(void) { _addsym(&s_pdp); _addsym(&s_register_ro); _addsym(&s_register_rw); _addsym(&s_process); _addsym(&s_dpd); _addsym(&s_inspect); _addsym(&s_accumulate); _addsym(&s_chanmask); } #else void pdp_pdsym_setup(void){ } #endif #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/puredata/pdp_compat.c000066400000000000000000000024511266045153600203770ustar00rootroot00000000000000/* * Pure Data Packet system implementation. Compatibility routines. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains misc communication methods */ #include #include "pdp_pd.h" #include "pdp_comm.h" #include "pdp_internals.h" /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif void pdp_pass_if_valid(t_outlet *outlet, int *packet) { pdp_packet_pass_if_valid(outlet, packet); } void pdp_replace_if_valid(int *dpacket, int *spacket) { pdp_packet_replace_if_valid(dpacket, spacket); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/puredata/pdp_control.c000066400000000000000000000110331266045153600205700ustar00rootroot00000000000000/* * Pure Data Packet system implementation: control object * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this is an actual pd class that is used for communication with the pdp framework */ #include "pdp_internals.h" #include "pdp_control.h" #include "pdp_packet.h" #include /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif static long dropped_packets; static t_class* pdp_control_class; /* pdp control instance data */ struct _pdp_control; typedef struct _pdp_control { t_object x_obj; t_outlet *x_outlet0; struct _pdp_control *x_next; } t_pdp_control; static t_pdp_control *pdp_control_list; static void pdp_control_info(t_pdp_control __attribute__((unused)) *x) { } static void pdp_control_collectgarbage(t_pdp_control __attribute__((unused)) *x) { int nb_packets_freed = pdp_pool_collect_garbage(); post("pdp_control: freed %d packets", nb_packets_freed); } static void pdp_control_set_mem_limit(t_pdp_control __attribute__((unused)) *x, t_floatarg f) { int limit = (int)f; if (limit < 0) limit = 0; pdp_pool_set_max_mem_usage(limit); if (limit) post("pdp_control: set memory limit to %d bytes", limit); else post("pdp_control: disabled memory limit"); } static void pdp_control_thread(t_pdp_control __attribute__((unused)) *x, t_floatarg f) { int t = (int)f; if (t){ post("pdp_control: pdp is now using its own processing thread"); pdp_queue_use_thread(1); } else { post("pdp_control: pdp is now using the main pd thread"); pdp_queue_use_thread(0); } } static void pdp_control_send_drop_message(t_pdp_control *x) { t_atom atom[1]; t_symbol *s = gensym("pdp_drop"); SETFLOAT(atom+0, (float)dropped_packets); outlet_anything(x->x_outlet0, s, 1, atom); } static void pdp_control_free(t_pdp_control *x) { /* remove from linked list */ t_pdp_control *curr = pdp_control_list; if (pdp_control_list == x) pdp_control_list = x->x_next; else while (curr){ if (curr->x_next == x) { curr->x_next = x->x_next; break; } else { curr = curr->x_next; } } } static void *pdp_control_new(void) { t_pdp_control *x = (t_pdp_control *)pd_new(pdp_control_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); /* add to list */ x->x_next = pdp_control_list; pdp_control_list = x; return x; } /************************* class methods ***************************************/ void pdp_control_addmethod(t_method m, t_symbol *s) { class_addmethod(pdp_control_class, m, s, A_GIMME, A_NULL); } void pdp_control_setup(void) { pdp_control_list = 0; dropped_packets = 0; /* setup pd class data */ pdp_control_class = class_new(gensym("pdp_control"), (t_newmethod)pdp_control_new, (t_method)pdp_control_free, sizeof(t_pdp_control), 0, A_NULL); class_addmethod(pdp_control_class, (t_method)pdp_control_info, gensym("info"), A_NULL); class_addmethod(pdp_control_class, (t_method)pdp_control_thread, gensym("thread"), A_DEFFLOAT, A_NULL); class_addmethod(pdp_control_class, (t_method)pdp_control_collectgarbage, gensym("collectgarbage"), A_NULL); class_addmethod(pdp_control_class, (t_method)pdp_control_set_mem_limit, gensym("memlimit"), A_FLOAT, A_NULL); } void pdp_control_notify_broadcast(t_pdp_control_method_notify *notify) { t_pdp_control *curr = pdp_control_list; while (curr){ (*notify)(curr); curr = curr->x_next; } } /************************* notify class methods *************************/ void pdp_control_notify_drop(int __attribute__((unused)) packet) { dropped_packets++; /* send drop notify to controller class instances */ pdp_control_notify_broadcast(pdp_control_send_drop_message); //post("dropped packet"); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/puredata/pdp_dpd_base.c000066400000000000000000000144611266045153600206610ustar00rootroot00000000000000/* * Pure Data Packet module. DPD base class implementation. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp_dpd_base.h" #include "pdp_internals.h" #define THIS(b) t_pdp_dpd_base *b = (t_pdp_dpd_base *)x #ifdef __cplusplus extern "C" { #endif /* PRIVATE METHODS */ /* dpd packet context input handler */ static void _pdp_dpd_base_context_input(t_pdp_dpd_base *b, t_symbol *s, t_floatarg f) { int p = (int)f; int i; //post ("pdp_dpd_base_context_input: got %s %d", s->s_name, p); /* sources/sinks have active inlet disabled */ if (b->b_dpd_active_inlet_disabled) return; /* handle inspect message */ if (s == S_INSPECT){ /* store packet for inspector */ b->b_context_packet = p; /* add inspector to pdp queue this is special: it doesn't use a command object */ pdp_dpd_base_queue_command(b, b, b->b_inspector_method, b->b_inspector_callback, 0); } /* handle accumulate message */ if (s == S_ACCUMULATE){ /* store context for accumulator methods */ b->b_context_packet = p; /* call bang */ pdp_dpd_base_bang(b); } } /* default command object (returns self) */ void *_pdp_dpd_base_get_command_object(void *x){return x;} /* PUBLIC METHODS */ void pdp_dpd_base_queue_command(void *x, void *c, t_pdp_method process, t_pdp_method callback, int *id) { THIS(b); t_pdp_procqueue *q = pdp_base_get_queue(x); pdp_procqueue_add(q, c, process, callback, id); } /* bang method (propagate context to outlet) : it is not registered as a pd message by default ! */ void pdp_dpd_base_bang(void *x) { THIS(b); int i, id; void *cobj; /* move passive pdp packets in place */ pdp_base_movepassive(x); /* get command object (or use self) */ cobj = b->b_command_factory_method ? (b->b_command_factory_method)(b) : b; //post(" command object is %x. object is %x", cobj, b); /* queue acc method & propagate for all outlets */ for (i=b->b_nb_context_outlets; i--;){ /* propagate the context packet to the outlet */ if (b->b_outlet_enable[i]){ pdp_dpd_base_queue_command(x, cobj, b->b_accum_method[i], b->b_accum_callback[i], 0); outlet_dpd(b->b_context_outlet[i], b->b_context_packet); } else{ //post("outlet %d disabled", i); } } /* queue cleanup method */ if (b->b_cleanup_method) //pdp_procqueue_add(b->b_q, b, b->b_cleanup_method, 0, &b->b_cleanup_queue_id); pdp_dpd_base_queue_command(x, cobj, b->b_cleanup_method, b->b_cleanup_callback, 0); /* send communication complete notify */ if (b->b_complete_notify) (b->b_complete_notify)(x); } /* get/set context packet */ int pdp_dpd_base_get_context_packet(void *x){ THIS(b); return b->b_context_packet; } int pdp_dpd_base_move_context_packet(void *x){ THIS(b); int p = b->b_context_packet; b->b_context_packet = -1; return p; } void pdp_dpd_base_set_context_packet(void *x, int p){ THIS(b); pdp_packet_mark_unused(b->b_context_packet); b->b_context_packet = p; } /* add a cleanup callback (called after all propagation is finished) for sources/sinks */ void pdp_dpd_base_add_cleanup(void *x, t_pdp_method cleanup_method, t_pdp_method cleanup_callback) { THIS(b); b->b_cleanup_method = cleanup_method; b->b_cleanup_callback = cleanup_callback; //b->b_cleanup_queue_id = -1; } /* add a inspector callback */ void pdp_dpd_base_add_inspector(void *x, t_pdp_method inspector_method) { THIS(b); b->b_inspector_method = inspector_method; //b->b_inspector_queue_id = -1; } /* add a context outlet */ t_outlet *pdp_dpd_base_add_outlet(void *x, t_pdp_method accum_method, t_pdp_method accum_callback) { THIS(b); int i = b->b_nb_context_outlets; if (i < PDP_DPD_MAX_CONTEXT_OUTLETS){ b->b_context_outlet[i] = outlet_new((t_object *)b, &s_anything); b->b_outlet_enable[i] = 1; b->b_accum_method[i] = accum_method; b->b_accum_callback[i] = accum_callback; //b->b_accum_queue_id[i] = -1; b->b_nb_context_outlets++; return b->b_context_outlet[i]; } else{ post("pdp_dpd_base_add_outlet: no more free outlet slots"); return 0; } } /* destructor */ void pdp_dpd_base_free(void *x) { THIS(b); /* free base */ pdp_base_free(b); } void pdp_dpd_base_disable_active_inlet(void *x) { THIS(b); b->b_dpd_active_inlet_disabled = 1; } void pdp_dpd_base_enable_outlet(void *x, int outlet, int toggle) { THIS(b); if (outlet >=0 && outlet < PDP_DPD_MAX_CONTEXT_OUTLETS){ b->b_outlet_enable[outlet] = toggle; } } void pdp_dpd_base_register_complete_notify(void *x, t_pdp_method method) { THIS(b); b->b_complete_notify = method; } void pdp_dpd_base_register_command_factory_method(void *x, t_pdp_newmethod command_factory_method) { THIS(b); b->b_command_factory_method = command_factory_method; } /* init method */ void pdp_dpd_base_init(void *x) { THIS(b); /* super init */ pdp_base_init(b); /* disable pdp messages on active inlet (dpd messages are used as sync) */ pdp_base_disable_active_inlet(b); /* init data */ b->b_nb_context_outlets = 0; b->b_context_packet = -1; b->b_cleanup_method = 0; //b->b_cleanup_queue_id = -1; b->b_inspector_method = 0; //b->b_inspector_queue_id = -1; b->b_dpd_active_inlet_disabled = 0; // default notify == none b->b_complete_notify = 0; // default command object getter b->b_command_factory_method = 0; } void pdp_dpd_base_setup(t_class *class) { pdp_base_setup(class); class_addmethod(class, (t_method)_pdp_dpd_base_context_input, gensym("dpd"), A_SYMBOL, A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/puredata/pdp_imagebase.c000066400000000000000000000036241266045153600210340ustar00rootroot00000000000000/* * Pure Data Packet image processor base class implementation. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains the pdp image base class object. */ #include "pdp_imagebase.h" #include static void pdp_imagebase_chanmask(t_pdp_base *b, t_floatarg f) { int i = (int)f; if (i < 0) i = -1; b->b_channel_mask = i; } void pdp_imagebase_setup(t_class *c) { /* parent class setup */ pdp_base_setup(c); /* add pdp base class methods */ class_addmethod(c, (t_method)pdp_imagebase_chanmask, gensym("chanmask"), A_FLOAT, A_NULL); } /* pdp base instance constructor */ void pdp_imagebase_init(void *x) { int i; t_pdp_imagebase *b = (t_pdp_imagebase *)x; /* init super */ pdp_base_init(x); /* convert all active incoming packet types to image */ pdp_base_set_type_template(x, 0, pdp_gensym("image/*/*")); /* default chanmask == all */ b->b_channel_mask = -1; } /* base instance destructor */ void pdp_imagebase_free(void *x) { /* free super */ pdp_base_free(x); } /* chanmask getter */ u32 pdp_imagebase_get_chanmask(void *x) { t_pdp_base *b = (t_pdp_base *)x; return b->b_channel_mask; } pdp-0.14.1+darcs20180201/puredata/pdp_queue.c000066400000000000000000000231141266045153600202370ustar00rootroot00000000000000/* * Pure Data Packet - processor queue module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this is a the processor queue pdp system module it receives tasks from objects that are schedules to be computed in another thread. the object is signalled back when the task is completed, using a polling mechanism based on a pd clock. the queue object can be reused. the pdp system however only has one instance (one pdp queue. pdp remains a serial program, though it can run in a separate thread) */ #include #include "pdp_queue.h" #include "pdp_mem.h" #define D if (0) #ifdef __cplusplus extern "C" { #endif #define PDP_QUEUE_LOGSIZE 10 #define PDP_QUEUE_DELTIME 10.0f /* there are 3 synchro methods, which can be used i.e. to ensure all processing is done before shared resources are freed. all 3 wait for the processing thread to finish, and _wait: leaves callback queue untouched _finish: clears the queue_id item in the callback queue _flush: waits for thread and calls callbacks and loops until callback list is empty */ /********************* general purpose pd process queue class *********************/ void pdp_procqueue_wait(t_pdp_procqueue *q) { D post("pdp_procqueue_wait(%x): waiting for pdp_queue_thread to finish processing", q); pthread_mutex_lock(&q->mut); while(((q->curr - q->head) & q->mask) != 0){ pthread_cond_wait(&q->cond_processingdone, &q->mut); } pthread_mutex_unlock(&q->mut); D post("pdp_procqueue_wait(%x): pdp_procqueue_thread has finished processing", q); } void pdp_procqueue_finish(t_pdp_procqueue *q, int indx) { if (-1 == indx) { //post("pdp_pq_remove: index == -1"); return; } /* wait for processing thread to finish*/ pdp_procqueue_wait(q); /* invalidate callback at index */ q->q[indx & q->mask].x_callback = 0; q->q[indx & q->mask].x_queue_id = 0; } static void pdp_procqueue_callback (t_pdp_procqueue *q); void pdp_procqueue_flush(t_pdp_procqueue *q) { /* wait once */ pdp_procqueue_wait(q); do { /* process callbacks and wait again in case the callbacks introduced new tasks */ pdp_procqueue_callback(q); pdp_procqueue_wait(q); } /* repeat if callback list is not empty */ while ((q->curr - q->head) & q->mask); D post("pdp_procqueue_flush: done"); } static void pdp_procqueue_signal_processor(t_pdp_procqueue *q) { //NOTE: uncommenting these post statements causes a libc crash //in mutex lock in putc //D post("pdp_procqueue_signal_processor(%x): signalling process thread", q); pthread_mutex_lock(&q->mut); pthread_cond_signal(&q->cond_dataready); pthread_mutex_unlock(&q->mut); //D post("pdp_procqueue_signal_processor(%x): signalling done", q); } static void pdp_procqueue_wait_for_feeder(t_pdp_procqueue *q) { /* only use locking when there is no data */ if(((q->curr - q->head) & q->mask) == 0){ /* signal processing done */ D post("pdp_procqueue_wait_for_feeder(%x): signalling processing is done", q); pthread_mutex_lock(&q->mut); pthread_cond_signal(&q->cond_processingdone); /* wait until there is an item in the queue */ while(((q->curr - q->head) & q->mask) == 0){ pthread_cond_wait(&q->cond_dataready, &q->mut); } pthread_mutex_unlock(&q->mut); D post("pdp_procqueue_wait_for_feeder(%x): waiting done", q); } } int pdp_procqueue_full(t_pdp_procqueue *q) { return (1 == ((q->tail - q->head) & q->mask)); } void pdp_procqueue_add(t_pdp_procqueue *q, void *owner, void *process, void *callback, int *queue_id) { int i; /* if processing is in not in thread, just call the funcs */ if (!q->use_thread){ D post("pdp_procqueue_add(%q): calling processing routine directly", q); if (queue_id) *queue_id = -1; if (process) ((t_pdpmethod) process)(owner); if (callback) ((t_pdpmethod) callback)(owner); return; } /* if queue is full, print an error message and return */ if (pdp_procqueue_full(q)) { post("pdp_procqueue_add: WARNING: processing queue (%x) is full.\n", q); post("pdp_procqueue_add: WARNING: tail %08x, head %08x (%08x), mask %08x.\n", q->tail, q->head, q->head & q->mask, q->mask); post("pdp_procqueue_add: WARNING: skipping process method, calling callback directly.\n"); if (queue_id) *queue_id = -1; if (callback) ((t_pdpmethod) callback)(owner); return; //exit(1); } /* schedule method in thread queue */ i = q->head & q->mask; q->q[i].x_owner = owner; q->q[i].x_process = process; q->q[i].x_callback = callback; q->q[i].x_queue_id = queue_id; if (queue_id) *queue_id = i; //post("pdp_queue_add: added method to queue, index %d", i); // increase the packet count q->packets++; // move head forward q->head++; pdp_procqueue_signal_processor(q); } /* processing thread */ static void *pdp_procqueue_thread(void *vq) { t_pdp_procqueue *q = (t_pdp_procqueue *)vq; D post("pdp_procqueue_thread(%x): thread started", q); while(1){ t_process_queue_item *p; D post("pdp_procqueue_thread(%x): waiting for feeder", q); /* wait until there is data available */ pdp_procqueue_wait_for_feeder(q); D post("pdp_procqueue_thread(%x): processing %d", q, q->curr & q->mask); /* call the process routine */ p = &q->q[q->curr & q->mask]; if (p->x_process) (p->x_process)(p->x_owner); /* advance */ q->curr++; } return 0; } /* call back all the callbacks */ static void pdp_procqueue_callback (t_pdp_procqueue *q) { /* call callbacks for finished packets */ while(0 != ((q->curr - q->tail) & q->mask)) { int i = q->tail & q->mask; /* invalidate queue id */ if(q->q[i].x_queue_id) *q->q[i].x_queue_id = -1; /* call callback */ if(q->q[i].x_callback) (q->q[i].x_callback)(q->q[i].x_owner); //else post("pdp_pq_tick: callback %d is disabled",i ); q->tail++; } } /* the clock method */ static void pdp_procqueue_tick (t_pdp_procqueue *q) { /* do work */ //if (!(ticks % 1000)) post("pdp tick %d", ticks); if (!q->use_thread) return; /* call callbacks */ pdp_procqueue_callback(q); /* increase counter */ q->ticks++; /* set clock for next update */ clock_delay(q->pdp_clock, q->deltime); } void pdp_procqueue_use_thread(t_pdp_procqueue* q, int t) { /* if thread usage is being disabled, wait for thread to finish processing first */ if (t == 0) { pdp_procqueue_wait(q); q->use_thread = 0; pdp_procqueue_callback(q); clock_unset(q->pdp_clock); } else { clock_unset(q->pdp_clock); clock_delay(q->pdp_clock, q->deltime); q->use_thread = 1; } } void pdp_procqueue_init(t_pdp_procqueue *q, double milliseconds, int logsize) { pthread_attr_t attr; int size = 1 << logsize; /* setup pdp queue processor object */ q->ticks = 0; q->deltime = milliseconds; /* setup queue data */ q->mask = size - 1; q->head = 0; q->tail = 0; q->curr = 0; q->q = pdp_alloc(size * sizeof(t_process_queue_item)); memset(q->q, 0, size * sizeof(t_process_queue_item)); /* enable threads */ q->use_thread = 1; /* setup synchro stuff */ pthread_mutex_init(&q->mut, NULL); pthread_cond_init(&q->cond_dataready, NULL); pthread_cond_init(&q->cond_processingdone, NULL); /* allocate the clock */ q->pdp_clock = clock_new(q, (t_method)pdp_procqueue_tick); /* set the clock */ clock_delay(q->pdp_clock, 0); /* start processing thread */ /* glibc doc says SCHED_OTHER is default, but it seems not to be when initiated from a RT thread so we explicitly set it here */ pthread_attr_init (&attr); //pthread_attr_setschedpolicy(&attr, SCHED_FIFO); pthread_attr_setschedpolicy(&attr, SCHED_OTHER); D post("pdp_procqueue_init(%x): starting thread", q); pthread_create(&q->thread_id, &attr, pdp_procqueue_thread, (void *)q); D post("pdp_procqueue_init(%x): back in pd thread", q); /* wait for processing thread to finish */ //pdp_procqueue_wait(q); /* set default disable/enable thread here */ //post("pdp_queue: THREAD PROCESSING ON BY DEFAULT!!"); pdp_procqueue_use_thread(q,0); } /* the (static) pdp queue object */ static t_pdp_procqueue pdp_queue; /* get the default queue */ t_pdp_procqueue *pdp_queue_get_queue(void){return &pdp_queue;} #if 1 /* default pdp queue shortcut methods */ void pdp_queue_wait() {pdp_procqueue_wait(&pdp_queue);} void pdp_queue_finish(int indx) { pdp_procqueue_finish(&pdp_queue, indx);} void pdp_queue_add(void *owner, void *process, void *callback, int *queue_id) { pdp_procqueue_add(&pdp_queue, owner, process, callback, queue_id); } void pdp_queue_use_thread(int t) {pdp_procqueue_use_thread(&pdp_queue, t);} void pdp_queue_setup(void){ pdp_procqueue_init(&pdp_queue, PDP_QUEUE_DELTIME, PDP_QUEUE_LOGSIZE); pdp_procqueue_use_thread(&pdp_queue,0); } #endif #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/puredata/pdp_ut.c000066400000000000000000000167161266045153600175550ustar00rootroot00000000000000/* * Pure Data Packet - Utility toolkit objects. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains some small utility pd objects that make working with pdp objects a lot easier. Mainly as glue to be used in the abstractions in the distro. */ #include "pdp_pd.h" #include /* this object does an add, scale, clip operation */ t_class *pdp_ut_addscaleclip_class; typedef struct pdp_ut_addscaleclip_struct { t_object x_obj; t_outlet *x_outlet0; t_float x_min; t_float x_max; t_float x_offset; t_float x_scale; } t_pdp_ut_addscaleclip; static void pdp_ut_addscaleclip_float(t_pdp_ut_addscaleclip *x, t_floatarg f) { f += x->x_offset; f *= x->x_scale; f = (f < x->x_min) ? x->x_min : f; f = (f > x->x_max) ? x->x_max : f; outlet_float(x->x_outlet0, f); } static void pdp_ut_addscaleclip_free(t_pdp_ut_addscaleclip __attribute__((unused)) *x){} void *pdp_ut_addscaleclip_new(t_floatarg offset, t_floatarg scale, t_floatarg min, t_floatarg max) { t_pdp_ut_addscaleclip *x = (t_pdp_ut_addscaleclip *)pd_new(pdp_ut_addscaleclip_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_float); x->x_offset = offset; x->x_scale = scale; x->x_min = min; x->x_max = max; return (void *)x; } void pdp_ut_addscaleclip_setup(void) { pdp_ut_addscaleclip_class = class_new(gensym("pdp_ut_addscaleclip"), (t_newmethod)pdp_ut_addscaleclip_new, (t_method)pdp_ut_addscaleclip_free, sizeof(t_pdp_ut_addscaleclip), 0, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); class_addfloat(pdp_ut_addscaleclip_class, pdp_ut_addscaleclip_float); } /* pdp_ut_logmap does a logarithmic parameter mapping [0->1] x -> min(max/min)^x max an add, scale, clip operation */ /* pdp_ut_logmap_comp does x -> min(max/min)^(1-x) */ /* pdp_ut_linmap dos x -> min + (max - min * x */ t_class *pdp_ut_linmap_class; t_class *pdp_ut_logmap_class; t_class *pdp_ut_logmap_comp_class; typedef struct pdp_ut_map_struct { t_object x_obj; t_outlet *x_outlet0; t_float x_min; t_float x_max; } t_pdp_ut_map; static void pdp_ut_logmap_float(t_pdp_ut_map *x, t_floatarg f) { f = (f < 0.0f) ? 0.0f : f; f = (f > 1.0f) ? 1.0f : f; f = x->x_min * pow((x->x_max / x->x_min), f); outlet_float(x->x_outlet0, f); } static void pdp_ut_linmap_float(t_pdp_ut_map *x, t_floatarg f) { f = (f < 0.0f) ? 0.0f : f; f = (f > 1.0f) ? 1.0f : f; f = x->x_min + ((x->x_max - x->x_min) * f); outlet_float(x->x_outlet0, f); } static void pdp_ut_logmap_comp_float(t_pdp_ut_map *x, t_floatarg f) { f = (f < 0.0f) ? 0.0f : f; f = (f > 1.0f) ? 1.0f : f; f = x->x_min * pow((x->x_max / x->x_min), (1.0f - f)); outlet_float(x->x_outlet0, f); } static void pdp_ut_map_free(t_pdp_ut_map __attribute__((unused)) *x){} void pdp_ut_map_init(t_pdp_ut_map *x, t_floatarg min, t_floatarg max) { x->x_outlet0 = outlet_new(&x->x_obj, &s_float); x->x_min = min; x->x_max = max; } void *pdp_ut_logmap_new(t_floatarg min, t_floatarg max) { t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_logmap_class); pdp_ut_map_init(x, min, max); return (void *)x; } void *pdp_ut_linmap_new(t_floatarg min, t_floatarg max) { t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_linmap_class); pdp_ut_map_init(x, min, max); return (void *)x; } void *pdp_ut_logmap_comp_new(t_floatarg min, t_floatarg max) { t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_logmap_comp_class); pdp_ut_map_init(x, min, max); return (void *)x; } void pdp_ut_logmap_setup(void) { pdp_ut_logmap_class = class_new(gensym("pdp_ut_logmap"), (t_newmethod)pdp_ut_logmap_new, (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0, A_FLOAT, A_FLOAT, A_NULL); class_addfloat(pdp_ut_logmap_class, pdp_ut_logmap_float); } void pdp_ut_logmap_comp_setup(void) { pdp_ut_logmap_comp_class = class_new(gensym("pdp_ut_logmap_comp"), (t_newmethod)pdp_ut_logmap_comp_new, (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0, A_FLOAT, A_FLOAT, A_NULL); class_addfloat(pdp_ut_logmap_comp_class, pdp_ut_logmap_comp_float); } void pdp_ut_linmap_setup(void) { pdp_ut_linmap_class = class_new(gensym("pdp_ut_linmap"), (t_newmethod)pdp_ut_linmap_new, (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0, A_FLOAT, A_FLOAT, A_NULL); class_addfloat(pdp_ut_linmap_class, pdp_ut_linmap_float); } t_class *pdp_ut_rgb2ycrcb_class; typedef struct pdp_ut_rgb2ycrcb { t_object x_obj; t_outlet *x_outlet_luma; t_outlet *x_outlet_chroma_red; t_outlet *x_outlet_chroma_blue; t_float x_red, x_green, x_blue; } t_pdp_ut_rgb2ycrcb; static void pdp_ut_rgb2ycrcb_bang (t_pdp_ut_rgb2ycrcb* x) { float luma = 0.299f * x->x_red + 0.587f * x->x_green + 0.114f * x->x_blue; float chroma_red = (x->x_red - luma) * 0.713f; float chroma_blue = (x->x_blue - luma) * 0.565f; outlet_float(x->x_outlet_chroma_blue, chroma_blue); outlet_float(x->x_outlet_chroma_red, chroma_red); outlet_float(x->x_outlet_luma, luma); } static void pdp_ut_rgb2ycrcb_red (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_red = f; pdp_ut_rgb2ycrcb_bang(x);} static void pdp_ut_rgb2ycrcb_green (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_green = f; pdp_ut_rgb2ycrcb_bang(x);} static void pdp_ut_rgb2ycrcb_blue (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_blue = f; pdp_ut_rgb2ycrcb_bang(x);} static void pdp_ut_rgb2ycrcb_free (t_pdp_ut_rgb2ycrcb __attribute__((unused)) *x) {} static void* pdp_ut_rgb2ycrcb_new(void) { t_pdp_ut_rgb2ycrcb *x = (t_pdp_ut_rgb2ycrcb *)pd_new(pdp_ut_rgb2ycrcb_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("green")); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("blue")); x->x_outlet_luma = outlet_new(&x->x_obj, &s_float); x->x_outlet_chroma_red = outlet_new(&x->x_obj, &s_float); x->x_outlet_chroma_blue = outlet_new(&x->x_obj, &s_float); x->x_red = 0.0f; x->x_green = 0.0f; x->x_blue = 0.0f; return (void *)x; } void pdp_ut_rgb2ycrcb_setup(void) { pdp_ut_rgb2ycrcb_class = class_new(gensym("pdp_ut_rgb2ycrcb"), (t_newmethod)pdp_ut_rgb2ycrcb_new, (t_method)pdp_ut_rgb2ycrcb_free, sizeof(t_pdp_ut_rgb2ycrcb), 0, A_NULL); class_addfloat(pdp_ut_rgb2ycrcb_class, pdp_ut_rgb2ycrcb_red); class_addmethod(pdp_ut_rgb2ycrcb_class, (t_method)pdp_ut_rgb2ycrcb_green, gensym("green"), A_FLOAT, A_NULL); class_addmethod(pdp_ut_rgb2ycrcb_class, (t_method)pdp_ut_rgb2ycrcb_blue, gensym("blue"), A_FLOAT, A_NULL); } #ifdef __cplusplus extern "C" { #endif void pdp_ut_setup(void) { pdp_ut_addscaleclip_setup(); pdp_ut_logmap_setup(); pdp_ut_logmap_comp_setup(); pdp_ut_linmap_setup(); pdp_ut_rgb2ycrcb_setup(); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/scaf/000077500000000000000000000000001266045153600152125ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/COPYING000066400000000000000000000431031266045153600162460ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, 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 PDP.LICENSE, 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 Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pdp-0.14.1+darcs20180201/scaf/Makefile000066400000000000000000000023511266045153600166530ustar00rootroot00000000000000include Makefile.config all: pdp_scaf.pd_linux pdp_scaf_all: make -C include make -C compiler make -C rules make -C pdp clean: rm -f *~ rm -f pdp_scaf.pd_linux make -C include clean make -C compiler clean make -C rules clean make -C pdp clean mrproper: clean rm -rf configure rm -rf config.status rm -rf config.log rm -rf autom4te.cache #this needs to stay in #rm -rf Makefile.config pdp_scaf.pd_linux: pdp_scaf_all rm -f pdp_scaf.pd_linux gcc -rdynamic -shared -o pdp_scaf.pd_linux pdp/*.o $(PDP_CA_LIBS) install: all install -d $(prefix)/lib/scaf install -m 755 compiler/scafc $(prefix)/bin || echo failed install -m 755 compiler/scafc.pl $(prefix)/lib/scaf || echo failed install -m 644 compiler/kernel.scaf $(prefix)/lib/scaf || echo failed install -m 644 compiler/scafmacro.s $(prefix)/lib/scaf || echo failed install -m 644 compiler/optim.rules $(prefix)/lib/scaf || echo failed install -m 755 rules/carules.scafo $(prefix)/lib/scaf/default.scafo || echo failed #Check if pd is installed in $(prefix)/lib/pd. #If this fails the pdp_scaf lib and the docs won't be installed. test -d $(prefix)/lib/pd install -m 755 pdp_scaf.pd_linux $(prefix)/lib/pd/extra install -m 644 doc/*.pd $(prefix)/lib/pd/doc/5.reference pdp-0.14.1+darcs20180201/scaf/Makefile.config.in000066400000000000000000000014221266045153600205220ustar00rootroot00000000000000# build flags # define the include paths here if configure can't find them # PDP_CFLAGS=-I/somehere/pdp/include # PD_CFLAGS=-I/somewhere/pd/src prefix=@prefix@ PDP_CA_INCLUDE = @CPPFLAGS@ PDP_CA_LIBS = @LIBS@ DEFAULT_RULES_LIB = @DEFAULT_RULES_LIB@ PDP_CA_AFLAGS = #--gstabs PDP_CA_CFLAGS = -DPD -fPIC -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ -Wall -W -Wstrict-prototypes -I../include -I../../include \ -Wno-unused -Wno-parentheses -Wno-switch -g $(PDP_CFLAGS) $(PD_CFLAGS) \ -DPDP_CA_RULES_LIB=\"$(DEFAULT_RULES_LIB)\" # -Wshadow # compiler and assembler #CC = gcc-3.2 #CC = gcc #AS = as # build rules .c.o: $(CC) $(PDP_CA_CFLAGS) $(PDP_CA_INCLUDE) $(PDP_CA_DEFS) -o $*.o -c $*.c .s.o: $(CC) -x assembler-with-cpp -o $*.o -c $*.s $(PDP_CA_AFLAGS) pdp-0.14.1+darcs20180201/scaf/README000066400000000000000000000051641266045153600161000ustar00rootroot00000000000000PDP_SCAF for pdp v0.7 Cellular Automata modules for PDP Copyright (c) by Tom Schouten 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., 675 Mass Ave, Cambridge, MA 02139, USA. The GNU Public Licence can be found in the file COPYING ------------------------------------------------------------------ This is a pdp extension lib that contains modules for cellular automata built on a (very) minimal forth-like virtual system (scaf - simple cellular automaton forth) to define update rules. a compiler is included to produce scafo object code that can be dynamically loaded into the pdp_ca module. so it is possible to add/change rules without restarting pd (note however you need to close all lib files before the dynamic loader reloads the lib). see scaf/README for details. pdp_ca2image and pdp_image2ca are included for conversion between CA packets and image packets. (pdp_ca2image produces greyscale images) Have a look at the patches in test/ for some crude docs. The file README.scaf contains some more info on the internals. Requirements: * pd * pdp * linux * perl for the forth compiler * an intel/amd processor that supports MMX Building: ./configure make make install If you don't have both libraries in the same dir and want to keep it that way, hardcode the paths in Makefile.config.in and run configure. You need to do "make install" to install the scaf compiler "scafc" and the default ruleset. This is to be able to load plain (text) rule files and have the default rules loaded when you create a pdp_ca object. Using: add "-lib /pdp_scaf" to the pd command line after the "-lib /pdp" part. launch pd with the options -lib $PDP_DIR/pdp -path $PDP_DIR/abstractions Directory structure: include/ header files pdp/ pdp external code compiler/ forth system code test/ some test patches (cryptic doc) rules/ ca rule libraries Please let me know if you discover a bug or think something doesn't work right. Code, documentation or example patches are more than welcome of course. Have Fun, Tom last modified: 2003/01/12 pdp-0.14.1+darcs20180201/scaf/README.scaf000066400000000000000000000072121266045153600170070ustar00rootroot00000000000000SCAF - simple cellular automaton forth scaf is a virtual machine / forth environment for binary arithmic tailored to 2D 1 cell neighbourhood cellular automata. scaf is a compiled language. programs run inside a "feeder" (sort of operating system if you want) the feeder is responsable for loading/storing CA cells from/to memory. data in memory is organized as a scanline encoded toroidial bitplane (lsb = left). to simplify the feeder and the stack machine, the top left corner of the rectangular grid of pixels will shift down every processing step. this enables to keep a cell neighbourhood in a couple of registers. the stack machine has the following architecture: CA stack: (%esi), TOS: %mm0 (32x2 cells. lsb = top left) CA horizon: (%edi) (64x4 cells. (%edi) = top row. lsb = left) scratch register: %mm1, %mm2 bitmask register: %mm3 = 0xffffffffffffffff 4 bit counter: %mm4-%mm7 the stack size / organization is not known to the stack machine. it can be thought of as operating on a 3x3 cell neightbourhood. the only purpose of the forth program is to determine the CA local update rule. the machine is supposed to be very minimal. no looping control. no adressing modes. no conditional code. so recursion is not allowed (no way to stop it) there are 9 words to load the cell neigbourhood on the stack. the rest is just logic and stack manips. the counter can be used for counting neighbourhood cells, like in the game of life. the zero test and sign bit can be used for comparisons. there are kernel words for loading constants into the counter register, and for communication between stack and register. the horizon is limited to 3x3, however it can be easily extended to 32x3. extending it further than that would require a redesign of the forth + feeder. HOW TO CREATE NEW CA RULES edit scaf/modules/carules.scaf or create your own source lib and add the name to the scaf/modules/Makefile. type make in scaf/modules to compile. if you get error messages from the assembler saying things like Error: no such instruction: `xxx' or Error: invalid character '_' in mnemonic this means there are undefined words in your source file. since not all characters are allowed in an asm file, the offending characters are converted to _SOMETHINGELSE_ if you are stuck somewhere, just look at the output of scaf.pl on your .scaf file to determine where the problem is. words that can be accessed from inside pdp_ca have to start with the prefix rule_ and have to leave a single item on the data stack (the return value) other rules can have all the stack effect you want, but for safety reasons they can't be accessed from within pdp_ca. FORTH SYSTEM CODE the forth system is made up of the following files: kernel.scaf: a collection of forth kernel words scafmacro.s: a set of asm macro definitions used in kernel.scaf optim.rules: some substitution rules to eliminate redundant stack manipulations scaf.pl: the compiler scaf.pl is run like this: scaf.pl -Isystemdir source.scaf if the -I switch is left out, the current directory is searched for the system files. the compiler produces an assembler source that includes scafmacro.s on standard output. the code it produces is relatively fast. it only uses and/or/xor and shift mmx instructions. it's not optimal use of silicon but it's pretty fast given what's possible. the feeder routine could be improved though. porting to another platform would require a rewrite of scafmacro.s the rest can be reused. if the target machine has 64 bit registers (or if you can emulate this one using more registers) porting is relatively easy. for larger registers a small change needs to be made to the feeder routine in pdp_ca.c pdp-0.14.1+darcs20180201/scaf/TODO000066400000000000000000000002071266045153600157010ustar00rootroot00000000000000* add decimating to pdp_ca2image * clean up library * add translation option to pdp_ca (modify so horizontal shifts by 1 are possible) pdp-0.14.1+darcs20180201/scaf/compiler/000077500000000000000000000000001266045153600170245ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/compiler/Makefile000066400000000000000000000000431266045153600204610ustar00rootroot00000000000000all: clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/scaf/compiler/kernel.scaf000066400000000000000000000052371266045153600211510ustar00rootroot00000000000000( Pure Data Packet - scaforth kernel. ) ( Copyright (c) by Tom Schouten ) ( ) ( 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., 675 Mass Ave, Cambridge, MA 02139, USA. ) ( this file contains the inline words in the scaforth kernel. ) ( when a file is compiled to asm, it will consist of word ) ( definition asm routines, macros and jmp call ret instructions. ) ( ) ( all words in this file are defined in terms of asm macros ) ( defined in scafmacros.s ) ( stack manip words ) : over dup dropover ; ( neighbourhood cell fetch words ) : @-+ dup dropldTL ; : @0+ dup dropldTM ; : @++ dup dropldTR ; : @-0 dup dropldML ; : @00 dup dropldMM ; : @+0 dup dropldMR ; : @-- dup dropldBL ; : @0- dup dropldBM ; : @+- dup dropldBR ; ( boolean logic ) : or overor nip ; : xor overxor nip ; : and overand nip ; ( binary constant loading ) : 1 dup dropone ; : 0 dup dropzero ; ( 4,3,2,1 bit add stack to register, leave carry on stack ) : ++++ adb0 adb1 adb2 adb3 ; : +++ adb0 adb1 adb2 ; : ++ adb0 adb1 ; : + adb0 ; ( 4,3,2 bit shifted 1 add ) : ++++<<1 adb1 adb2 adb3 ; : +++<<1 adb1 adb2 ; : ++<<1 adb1 ; ( 4,3 bit shifted 2 add ) : ++++<<2 adb2 adb3 ; : +++<<2 adb2 ; ( 4 bit shifted 3 add ) : ++++<<3 adb3 ; ( 4 bit accumulator access ) : !a0 dupsta0 drop ; : !a1 dupsta1 drop ; : !a2 dupsta2 drop ; : !a3 dupsta3 drop ; : @a0 dup droplda0 ; : @a1 dup droplda1 ; : @a2 dup droplda2 ; : @a3 dup droplda3 ; ( 4,3,2,1 bit accumulator zero tests ) : ?anz dup dropisnonzero4 ; : ?anz4 dup dropisnonzero4 ; : ?anz3 dup dropisnonzero3 ; : ?anz2 dup dropisnonzero2 ; : ?anz1 dup dropisnonzero1 ; ( load constants into accumulator ) : a0 a0000 ; : a-0 a0000 ; : a+0 a0000 ; : a+1 a0001 ; : a+2 a0010 ; : a+3 a0011 ; : a+4 a0100 ; : a+5 a0101 ; : a+6 a0110 ; : a+7 a0111 ; : a+8 a1000 ; : a+9 a1001 ; : a+10 a1010 ; : a+11 a1011 ; : a+12 a1100 ; : a+13 a1101 ; : a+14 a1110 ; : a+15 a1111 ; : a-8 a1000 ; : a-7 a1001 ; : a-6 a1010 ; : a-5 a1011 ; : a-4 a1100 ; : a-3 a1101 ; : a-2 a1110 ; : a-1 a1111 ; pdp-0.14.1+darcs20180201/scaf/compiler/optim.rules000066400000000000000000000041521266045153600212320ustar00rootroot00000000000000# Pure Data Packet - scaf optimization rules. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # this file contains scaf source optimization rules for scaf compiler # applied after kernel word inlining and before compilation to asm # one rule that's not in here, and is the responsability for the # final compilation step: "word ;" is "jmp word" instead of "call word ret" # TODO: think about order! # no discrimination between pre inline and post inline optimization ops yet # pre inline optimizations "over xor" -> "overxor" "over and" -> "overand" "over or" -> "overor" "drop 1" -> "dropone" "drop 0" -> "dropzero" "over add" -> "overadd" "over addc" -> "overaddc" "dup !a0" -> "dupsta0" "dup !a1" -> "dupsta1" "dup !a2" -> "dupsta2" "dup !a3" -> "dupsta3" "drop @a0" -> "droplda0" "drop @a1" -> "droplda1" "drop @a2" -> "droplda2" "drop @a3" -> "droplda3" "drop ?anz" -> "dropisnonzero4" "drop ?anz4" -> "dropisnonzero4" "drop ?anz3" -> "dropisnonzero3" "drop ?anz2" -> "dropisnonzero2" "drop ?anz1" -> "dropisnonzero1" "drop @-+" -> "dropldTL" "drop @0+" -> "dropldTM" "drop @++" -> "dropldTR" "drop @-0" -> "dropldML" "drop @00" -> "dropldMM" "drop @+0" -> "dropldMR" "drop @--" -> "dropldBL" "drop @0-" -> "dropldBM" "drop @+-" -> "dropldBR" # post inline optimizations "dup drop" -> "" "swap drop" -> "nip" "dup swap" -> "dup" "drop dup" -> "dropdup" "drop over" -> "dropover" "nip dup" -> "nipdup" pdp-0.14.1+darcs20180201/scaf/compiler/scafc000077500000000000000000000012641266045153600200340ustar00rootroot00000000000000#!/bin/sh #scaf->scafo compiler if [ -z "$1" ]; then echo echo "scaf rules compiler" echo "usage:" echo " scafc source [dest]" echo exit 0 fi if [ -z "$2" ]; then DEST=$1o else DEST=$2 fi if ! test -f $1 then echo "source module $1 not found." exit 1 fi SCAFDIR=`dirname $0` if ! test -f $SCAFDIR/scafc.pl; then SCAFDIR=`dirname $SCAFDIR` SCAFDIR="$SCAFDIR/lib/scaf" if ! test -f $SCAFDIR/scafc.pl then echo "scaf library not found in $SCAFDIR" exit 1 fi fi TMP_S=`tempfile -s .S` $SCAFDIR/scafc.pl -I$SCAFDIR $1 > $TMP_S \ && cat $TMP_S \ && gcc -x assembler-with-cpp -I$SCAFDIR -shared -o $DEST $TMP_S \ && strip --strip-unneeded $DEST \ && rm $TMP_S \ || exit 1 pdp-0.14.1+darcs20180201/scaf/compiler/scafc.pl000077500000000000000000000125411266045153600204460ustar00rootroot00000000000000#!/usr/bin/perl # Pure Data Packet - scafc: scaf compiler. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # set this if you want to enable/disable optimizing $optimize = 1; # this parses a single scaf line # it is not very intelligent. only looks for 1 def on a line # todo: change later so it can read multiple lines sub remove_illegal_characters { my $line = shift; $$line =~ s/\+/_PLUS_/g; $$line =~ s/-/_MINUS_/g; $$line =~ s/\@/_AT_/g; $$line =~ s/:/_COLON_/g; $$line =~ s/\?/_QMARK_/g; $$line =~ s/</_GT_/g; $$line =~ s/=/_EQ_/g; $$line =~ s/\(/_OPEN_/g; $$line =~ s/\)/_CLOSE_/g; } sub parse_scaf_line { my $word, $def, $sub; shift; # this transforms the source into a parsed assembly like form # a word label: ":" # a word definition line "" # last def = # dont process if line doesn't have a def # first remove comments s/\(\s+(\S+\s+)*?\)//g; if (m/:\s+/){ # separate word and definition m/:\s+(\S+)\s+(.*)/; $word = $1; $def = $2; # remove illegal characters; remove_illegal_characters \$word; remove_illegal_characters \$def; # format definition in asm style $def =~ s/(\S+)(\s*)/\t$1\n/g; # replace ; by r $def =~ s/\s+;\s*/\n\tr\n/; # put word: def into one string $sub = "$word:\n$def\n"; # debug #$sub =~ s/\t//g; #$sub =~ s/\n/\n/g; #print "$sub"; return $sub; } }; # load and parse scaf source file sub load_source { my $filename = shift; open(SOURCE, $filename) or die "Can't locate source module $filename\n"; my @parsedsource; while (){ my $sub = parse_scaf_line $_; if ($sub) { push @parsedsource, ($sub); } } close(SOURCE); return @parsedsource; } # this routine parses the optimization rules sub load_optim { my $filename = shift; open(OPTIM, $filename) or die "Can't locate optimization rule file $filename\n"; my @parsedoptim; while (){ unless (m/\A\#/){ if (m/\"\s*(.*?)\s*\".*?\"\s*(.*?)\s*\"/) { my $source = $1; my $dest = $2; $source =~ s/\s+/\n\t/; $dest =~ s/\s+/\n\t/; $source = "\t$source\n"; $dest = "\t$dest\n"; remove_illegal_characters \$source; remove_illegal_characters \$dest; push @parsedoptim, ("$source:$dest"); } } } close(OPTIM); return @parsedoptim; } # inline one parsed source's definitions into another parsed source's sub inline_defs { my $dest = shift; my $source = shift; #print @$dest; #print @$source; # loop over file with inline defs foreach (@$source) { #print "$_\n"; m/(\S+):\n(.*)\tr\n/s; my $def = "\t$1\n"; my $body = $2; #print "$def\n"; #print "$body\n"; foreach (@$dest) { s/$def/$body/g; } } } # this changes to c or j all defined words # the undefined words are supposed to be asm macros sub call_defs { my $dest = shift; foreach (@$dest){ m/(\S+):\n/s; my $word = $1; foreach (@$dest){ s/\t$word\n\tr\n/\tj $word\n/sg; s/\t$word\n/\tc $word\n/sg; } } } # substitue word sequences in dest using optim table sub subst_optim { my $dest = shift; my $optim = shift; foreach (@$optim){ m/(.*?):(.*)/s; my $key = $1; my $subst = $2; foreach (@$dest){ s/$key/$subst/sg; } } } # add directives to produce global symbols # global symbols need to start with carule_ sub global_syms { my $source = shift; foreach (@$source){ s/rule_(\S+):\n/.globl\trule_$1\n.type\trule_$1,\@function\nrule_$1:\n/sg; } } # create an array with names for bookkeeping sub name_array { my @namearray; my $source = shift; push @namearray, (".globl rulenames\nrulenames:\n"); foreach (@$source){ if (m/rule_(\S+):/s){ push @namearray, (".asciz\t\"$1\"\n"); } } push @namearray, (".byte\t0\n"); return @namearray; } # main program body $dir="."; $source = "-"; # parse command line foreach (@ARGV){ if (m/-I(.*)/) { $dir = $1; } else { $source = $_; } } $kernel = "$dir/kernel.scaf"; $macro = "$dir/scafmacro.s"; $rules = "$dir/optim.rules"; # load files @psource = load_source $source; @pkernel = load_source $kernel; @poptim = load_optim $rules; # substitute kernel defs in source if ($optimize) {subst_optim \@psource, \@poptim;} inline_defs \@psource, \@pkernel; if ($optimize) {subst_optim \@psource, \@poptim;} call_defs \@psource; global_syms \@psource; @pnames = name_array \@psource; # print out asm file print "#include \"$macro\"\n\n"; print @psource; print @pnames; pdp-0.14.1+darcs20180201/scaf/compiler/scafmacro.s000066400000000000000000000170071266045153600211530ustar00rootroot00000000000000 # Pure Data Packet - scaf assembler macros. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # #if defined(__i386__) #define SI %esi #define DI %edi #else #if defined(__x86_64__) #define SI %rsi #define DI %rdi #else #error Needs __i386__ or __x84_64__ #endif #endif # this file contains pure asm macros. it is to be included before assembly # after scaforth.pl has processed the .scaf file # *************************** JMP CALL RET ************************************** # j c r .macro j address jmp \address .endm .macro c address call \address .endm .macro r ret .endm # *************************** CA CELL ACCESS MACROS ***************************** # dropldTL - dropldBR # shift / load rectangle macros: # shift rectangle horizontal # result is in reg1 .macro shift reg1 reg2 count psllq $(16-\count), \reg1 psrlq $(16+\count), \reg2 psrlq $32, \reg1 psllq $32, \reg2 por \reg2, \reg1 .endm .macro ldtop reg1 reg2 movq (DI), \reg1 movq 8(DI), \reg2 .endm .macro ldcenter reg1 reg2 movq 8(DI), \reg1 movq 16(DI), \reg2 .endm .macro ldbottom reg1 reg2 movq 16(DI), \reg1 movq 24(DI), \reg2 .endm # dropld from top row # dropld the top left square .macro dropldTL ldtop %mm0, %mm1 shift %mm0, %mm1, -1 .endm # dropld the top mid square .macro dropldTM ldtop %mm0, %mm1 shift %mm0, %mm1, 0 .endm # dropld the top right square .macro dropldTR ldtop %mm0, %mm1 shift %mm0, %mm1, 1 .endm # dropld from center row # dropld the mid left square .macro dropldML ldcenter %mm0, %mm1 shift %mm0, %mm1, -1 .endm # dropld the mid mid square .macro dropldMM ldcenter %mm0, %mm1 shift %mm0, %mm1, 0 .endm # dropld the mid right square .macro dropldMR ldcenter %mm0, %mm1 shift %mm0, %mm1, 1 .endm # dropld from bottom row # dropld the bottom left square .macro dropldBL ldbottom %mm0, %mm1 shift %mm0, %mm1, -1 .endm # dropld the bottom mid square .macro dropldBM ldbottom %mm0, %mm1 shift %mm0, %mm1, 0 .endm # dropld the bottom right square .macro dropldBR ldbottom %mm0, %mm1 shift %mm0, %mm1, 1 .endm # *************************** CA STACK MANIP MACROS ***************************** # these are the only asm macros that have a stack effect other than # just replacing the TOS # # dup drop dropdup swap nip dropover .macro dup lea -8(SI), SI movq %mm0, (SI) .endm .macro drop movq (SI), %mm0 lea 8(SI), SI .endm .macro dropdup movq (SI), %mm0 .endm .macro nipdup movq %mm0, (SI) .endm .macro swap movq (SI), %mm1 movq %mm0, (SI) movq %mm1, %mm0 .endm .macro nip lea 8(SI), SI .endm .macro dropover movq 8(SI), %mm0 .endm # *************************** CA BOOLEAN LOGIC MACROS ***************************** # overxor overand overor not .macro overxor pxor (SI), %mm0 .endm .macro overand pand (SI), %mm0 .endm .macro overor por (SI), %mm0 .endm .macro not pxor %mm3, %mm0 .endm # *************************** CONSTANTS ***************************** # dropzero dropone .macro dropzero pxor %mm0, %mm0 .endm .macro dropone pcmpeqw %mm0, %mm0 .endm # *************************** 4 BIT REG ACCESS ****************************** # dupsta0 - dupsta4 droplda0 - droplda4 # store bit in accumulator # bit store .macro dupsta0 movq %mm0, %mm4 .endm .macro dupsta1 movq %mm0, %mm5 .endm .macro dupsta2 movq %mm0, %mm6 .endm .macro dupsta3 movq %mm0, %mm7 .endm # load bit from accumulator .macro droplda0 movq %mm4, %mm0 .endm .macro droplda1 movq %mm5, %mm0 .endm .macro droplda2 movq %mm6, %mm0 .endm .macro droplda3 movq %mm7, %mm0 .endm # *************************** LOAD 4 BIT CONSTANT IN REG ****************************** # a0000 - a1111 .macro ldbit0 value .ifeq \value movq %mm1, %mm4 .else movq %mm3, %mm4 .endif .endm .macro ldbit1 value .ifeq \value movq %mm1, %mm5 .else movq %mm3, %mm5 .endif .endm .macro ldbit2 value .ifeq \value movq %mm1, %mm6 .else movq %mm3, %mm6 .endif .endm .macro ldbit3 value .ifeq \value movq %mm1, %mm7 .else movq %mm3, %mm7 .endif .endm .macro ldbin b3 b2 b1 b0 pxor %mm1, %mm1 ldbit0 \b0 ldbit1 \b1 ldbit2 \b2 ldbit3 \b3 .endm .macro a0000 ldbin 0 0 0 0 .endm .macro a0001 ldbin 0 0 0 1 .endm .macro a0010 ldbin 0 0 1 0 .endm .macro a0011 ldbin 0 0 1 1 .endm .macro a0100 ldbin 0 1 0 0 .endm .macro a0101 ldbin 0 1 0 1 .endm .macro a0110 ldbin 0 1 1 0 .endm .macro a0111 ldbin 0 1 1 1 .endm .macro a1000 ldbin 1 0 0 0 .endm .macro a1001 ldbin 1 0 0 1 .endm .macro a1010 ldbin 1 0 1 0 .endm .macro a1011 ldbin 1 0 1 1 .endm .macro a1100 ldbin 1 1 0 0 .endm .macro a1101 ldbin 1 1 0 1 .endm .macro a1110 ldbin 1 1 1 0 .endm .macro a1111 ldbin 1 1 1 1 .endm # *************************** 4 BIT COUNTER ****************************** # adds TOS to bit of counter and returns carry in TOS # # adb0 - adb3 .macro adb0 movq %mm4, %mm2 pxor %mm0, %mm4 pand %mm2, %mm0 .endm .macro adb1 movq %mm5, %mm2 pxor %mm0, %mm5 pand %mm2, %mm0 .endm .macro adb2 movq %mm6, %mm2 pxor %mm0, %mm6 pand %mm2, %mm0 .endm .macro adb3 movq %mm7, %mm2 pxor %mm0, %mm7 pand %mm2, %mm0 .endm # *************************** ACCUMULATOR TESTS *************************** # dropisnonzero4 - dropisnonzero1 .macro dropisnonzero4 movq %mm4, %mm0 por %mm5, %mm0 por %mm6, %mm0 por %mm7, %mm0 .endm .macro dropisnonzero3 movq %mm4, %mm0 por %mm5, %mm0 por %mm6, %mm0 .endm .macro dropisnonzero2 movq %mm4, %mm0 por %mm5, %mm0 .endm .macro dropisnonzero1 movq %mm4, %mm0 .endm # *************************** REGISTER SHIFT OPERATIONS ********************** # shift and leave shifted out byte on stack # rotate trough top of stack .macro dropshiftright movq %mm4, %mm0 movq %mm5, %mm4 movq %mm6, %mm5 movq %mm7, %mm6 pxor %mm7, %mm7 .endm .macro dropshiftleft movq %mm7, %mm0 movq %mm6, %mm7 movq %mm5, %mm6 movq %mm4, %mm5 pxor %mm4, %mm4 .endm .macro dropshiftrighta movq %mm4, %mm0 movq %mm5, %mm4 movq %mm6, %mm5 movq %mm7, %mm6 .endm .macro rotateright movq %mm4, %mm1 movq %mm5, %mm4 movq %mm6, %mm5 movq %mm7, %mm6 movq %mm1, %mm7 .endm .macro rotateleft movq %mm7, %mm1 movq %mm6, %mm7 movq %mm5, %mm6 movq %mm4, %mm5 movq %mm1, %mm4 .endm .macro rotaterightstack movq %mm0, %mm1 movq %mm4, %mm0 movq %mm5, %mm4 movq %mm6, %mm5 movq %mm7, %mm6 movq %mm1, %mm7 .endm .macro rotateleftstack movq %mm0, %mm1 movq %mm7, %mm0 movq %mm6, %mm7 movq %mm5, %mm6 movq %mm4, %mm5 movq %mm1, %mm4 .endm # *************************** OTHER REGISTER OPERATIONS ********************** # anot : complement reg (can be used to implement subtraction) .macro anot pxor %mm3, %mm4 pxor %mm3, %mm5 pxor %mm3, %mm6 pxor %mm3, %mm7 .endm pdp-0.14.1+darcs20180201/scaf/configure.ac000066400000000000000000000024011266045153600174750ustar00rootroot00000000000000AC_INIT(pdp/pdp_ca_system.c) AC_PROG_CC AC_HEADER_STDC dnl default install prefix is /usr/local if test $prefix == "NONE"; then prefix=/usr/local fi AC_PATH_PROG(PDP_CONFIG,pdp-config,"no", $PATH) AC_CHECK_LIB(m,sin) AC_CHECK_LIB(dl,dlopen,, echo libdl not found. sorry... || exit 1) TOPSRC=`pwd` PARENT=`dirname $TOPSRC` dnl if pdp-config is found use it to get the cflags if ! test $PDP_CONFIG == "no" then PDP_CPPFLAGS=`$PDP_CONFIG --cflags` dnl if not, check in the parent dir (in case we are distributed with the pdp package) elif test -f $PARENT/include/pdp.h then PDP_CPPFLAGS="-I$PARENT/include" fi CPPFLAGS="$CPPFLAGS $PDP_CPPFLAGS" AC_CHECK_HEADER(m_pd.h,,PD_OK=no) AC_CHECK_HEADER(pdp.h,,PDP_OK=no) if test PD_OK == "no"; then echo "WARNING: m_pd.h not found. Is PD installed? echo "WARNING: You can ignore this warning if you have set the PD_CFLAGS manually in Makefile.config.in fi if test PDP_OK == "no"; then echo "WARNING: pdp.h not found. Is PDP installed? echo "WARNING: You can ignore this warning if you have set the PDP_CFLAGS manually in Makefile.config.in fi CPPFLAGS="$CPPFLAGS $PDFLAGS $PDPFLAGS -I$TOPSRC/include" DEFAULT_RULES_LIB=$prefix/lib/scaf/default.scafo; AC_SUBST(DEFAULT_RULES_LIB) AC_CONFIG_FILES(Makefile.config) AC_OUTPUT pdp-0.14.1+darcs20180201/scaf/doc/000077500000000000000000000000001266045153600157575ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/doc/pdp_ca-help.pd000066400000000000000000000045351266045153600204670ustar00rootroot00000000000000#N canvas 62 0 753 664 10; #X obj 46 613 pdp_ca; #X obj 45 254 metro 40; #X msg 45 206 bang; #X msg 84 206 stop; #X msg 184 340 random; #X msg 181 137 rule gameoflife; #X floatatom 185 586 5 0 0 0 - - -; #X obj 185 558 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 46 638 pdp_ca2image; #X msg 181 215 rules; #X msg 185 434 close; #X floatatom 96 228 5 0 0 0 - - -; #X obj 46 662 pdp_xv; #X floatatom 183 285 5 0 0 0 - - -; #X msg 183 314 vshift \$1; #X msg 185 486 2D; #X msg 185 535 fullscreen1D \$1; #X obj 185 513 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X text 197 606 1st inlet: active input (bang or ca); #X text 197 621 2nd inlet: passive input (ca); #X text 196 638 3rd inlet: nb of iterations; #X text 307 137 set a rule by name; #X text 308 206 print rules in library; #X msg 181 187 ruleindex \$1; #X text 307 183 set a rule by index; #X floatatom 181 165 5 0 0 0 - - -; #X text 313 534 off: compute one line at a time; #X text 313 548 on: update entire image (all lines); #X text 313 520 specify how to compute a 1D ca; #X text 313 464 interpret rules as a 1D ca with (space+time); #X text 313 493 interpret rules as a 2D ca with (space); #X msg 185 465 1D; #X text 314 436 close current library; #X obj 179 43 openpanel; #X msg 179 66 open \$1; #X msg 184 370 dim 64 64; #X text 314 371 set ca dimensions; #X obj 179 24 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 306 22 open a source rule file or compiled rule library; #X text 306 38 (when it's a source file \, make sure the "scafc" compiler is in the system path); #X msg 340 70 opensrc \$1; #X msg 446 70 openlib \$1; #X text 306 72 use; #X text 419 71 and; #X text 306 89 to explicitly open source or library; #X text 314 342 init ca with random noise; #X text 314 312 vertical shift compensation; #X text 181 257 bang computes next iteration(s); #X msg 185 397 dim 512 512; #X connect 0 0 8 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 4 0 0 0; #X connect 5 0 0 0; #X connect 6 0 0 2; #X connect 7 0 6 0; #X connect 8 0 12 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 1 1; #X connect 13 0 14 0; #X connect 14 0 0 0; #X connect 15 0 0 0; #X connect 16 0 0 0; #X connect 17 0 16 0; #X connect 23 0 0 0; #X connect 25 0 23 0; #X connect 33 0 34 0; #X connect 34 0 0 0; #X connect 35 0 0 0; #X connect 37 0 33 0; #X connect 48 0 0 0; pdp-0.14.1+darcs20180201/scaf/include/000077500000000000000000000000001266045153600166355ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/include/Makefile000066400000000000000000000000351266045153600202730ustar00rootroot00000000000000current: clean: rm -f *~ pdp-0.14.1+darcs20180201/scaf/include/pdp_ca.h000066400000000000000000000036061266045153600202410ustar00rootroot00000000000000/* * Cellular Automata Extension Module for pdp - Main header file * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PDP_CA_H #define PDP_CA_H #include "pdp.h" /* 2D CA DATA PACKET */ typedef struct { unsigned int encoding; /* CA data format */ unsigned int width; /* CA width (in 1 bit cells) */ unsigned int height; /* CA height (in 1 bit cells) */ unsigned int offset; /* bit offset of upper left corner */ unsigned int currow; /* current row to compute for 1D CA */ } t_ca; /* CA encodings */ #define PDP_CA_STANDARD 1 /* rectangular CA */ /* pdp data packet types */ #define PDP_CA 2 /* 1bit toroidial shifted scanline encoded cellular automaton */ /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif /* constructor */ int pdp_packet_new_ca(int encoding, int width, int height); /* some utility methods for CA */ int pdp_packet_ca_isvalid(int packet); int pdp_type_ca2grey(int packet); int pdp_type_grey2ca(int packet, short int threshold); /* returns a pointer to the ca subheader given the pdp header */ t_ca *pdp_type_ca_info(t_pdp *x); #ifdef __cplusplus } #endif #endif //PDP_CA_H pdp-0.14.1+darcs20180201/scaf/pdp/000077500000000000000000000000001266045153600157755ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/pdp/Makefile000066400000000000000000000002341266045153600174340ustar00rootroot00000000000000current: all_modules include ../Makefile.config OBJECTS = pdp_ca.o pdp_ca_system.o scaf_feeder.o all_modules: $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/scaf/pdp/pdp_ca.c000066400000000000000000000566311266045153600174020ustar00rootroot00000000000000/* * Pure Data Packet module for cellular automata * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp_ca.h" #include "pdp_internals.h" #include #include #include t_class *pdp_ca_class; // a cellular automaton processor: single input - single output //t_class *pdp_ca2_class; // double input - single output t_class *pdp_ca2image_class; // converter from ca -> grey/yv12 t_class *pdp_image2ca_class; // converter from grey/yv12 -> ca // *********************** CA CLASS STUFF ********************* // this is defined in the makefile // #define PDP_CA_RULES_LIB "/path/default.scafo" #define PDP_CA_STACKSIZE 256 #define PDP_CA_MODE_1D 1 #define PDP_CA_MODE_2D 2 typedef struct pdp_ca_data_struct { uint32_t env[2*4]; uint32_t reg[2*4]; uint32_t stack[2*PDP_CA_STACKSIZE]; short int random_seed[4]; } t_pdp_ca_data; typedef struct pdp_ca_struct { t_object x_obj; t_float x_f; t_outlet *x_outlet0; int x_queue_id; /* double buffering data packets */ int x_packet0; int x_packet1; /* some data on the ca_routine */ void (*x_ca_routine)(void); void *x_ca_libhandle; char *x_ca_rulenames; int x_ca_nbrules; char ** x_ca_rulename; t_symbol *x_lastrule; /* nb of iterations */ int x_iterations; /* shift ca on output */ int x_horshift; int x_vershift; /* operation mode */ int x_mode; int x_fullscreen1d; /* aligned vector data */ t_pdp_ca_data *x_data; /* output packet type */ t_symbol *x_packet_type; } t_pdp_ca; static inline void check_stack(t_pdp_ca *x, uint32_t *tos, uint32_t *env) { /* feeder saves stack pointer in env. */ uint32_t *tos_out = *((uint32_t **)env); if (tos_out != tos) { if (tos_out > tos) post("pdp_ca: ERROR: stack underflow detected in ca routine"); if (tos_out < tos) post("pdp_ca: ERROR: ca routine returned more than one item"); x->x_ca_routine = 0; post("pdp_ca: rule disabled"); } } /* mmx feeder routine */ unsigned long long scaf_feeder(void *tos, void *reg, void (*ca_rule)(void), void *env); /* 1D: process from packet0 -> packet0 */ static void pdp_ca_process_ca_1D(t_pdp_ca *x) { t_pdp *header = pdp_packet_header(x->x_packet0); uint32_t *data = (uint32_t *)pdp_packet_data (x->x_packet0); int width = pdp_type_ca_info(header)->width; int height = pdp_type_ca_info(header)->height; int i; uint32_t saved; /* load TOS in middle of buffer to limit the effect of stack errors */ uint32_t *tos = &x->x_data->stack[2*(PDP_CA_STACKSIZE/2)]; uint32_t *env = &x->x_data->env[0]; uint32_t *reg = &x->x_data->reg[0]; void *ca_routine = x->x_ca_routine; uint32_t rtos; /* double word width: number of uint32_ts per row */ int dwwidth = width >> 5; int currow = pdp_type_ca_info(header)->currow; unsigned long long result = 0; unsigned short temp; unsigned short *usdata; /* set destination row to 4th row from top (ca time horizon is 3 deep) */ int dwrow0 = (((currow + height - 3) % height) * width) >> 5; int dwrow1 = (((currow + height - 2) % height) * width) >> 5; int dwrow2 = (((currow + height - 1) % height) * width) >> 5; int dwrow3 = (currow * width) >> 5; /* exit if there isn't a valid routine */ if(!ca_routine) return; /* compute new row */ for(i=0; i < (dwwidth-1) ; i+=1){ env[0] = data[dwrow0 + i]; env[1] = data[dwrow0 + i + 1]; env[2] = data[dwrow1 + i]; env[3] = data[dwrow1 + i + 1]; env[4] = data[dwrow2 + i]; env[5] = data[dwrow2 + i + 1]; result = scaf_feeder(tos, reg, ca_routine, env); data[dwrow3 + i] = result & 0xffffffff; } // i == dwwidth-1 /* compute last column in row */ env[0] = data[dwrow0 + i]; env[1] = data[dwrow0]; env[2] = data[dwrow1 + i]; env[3] = data[dwrow1]; env[4] = data[dwrow2 + i]; env[5] = data[dwrow2]; result = scaf_feeder(tos, reg, ca_routine, env); data[dwrow3 + i] = result & 0xffffffff; /* undo the shift */ usdata = (unsigned short *)(&data[dwrow3]); temp = usdata[(dwwidth*2)-1]; for (i = (dwwidth*2 - 1); i > 0; i--){ usdata[i] = usdata[i-1]; } usdata[0] = temp; check_stack(x, tos, env); /* save current row */ pdp_type_ca_info(header)->currow = (currow + 1) % height; } /* 2D: process from packet0 -> packet1 */ static void pdp_ca_process_ca_2D(t_pdp_ca *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); t_pdp *header1 = pdp_packet_header(x->x_packet1); uint32_t *data0 = (uint32_t *)pdp_packet_data (x->x_packet0); uint32_t *data1 = (uint32_t *)pdp_packet_data (x->x_packet1); int width = pdp_type_ca_info(header0)->width; int height = pdp_type_ca_info(header0)->height; int i,j; /* load TOS in middle of buffer to limit the effect of stack errors */ uint32_t *tos = &x->x_data->stack[2*(PDP_CA_STACKSIZE/2)]; uint32_t *env = &x->x_data->env[0]; uint32_t *reg = &x->x_data->reg[0]; void *ca_routine = x->x_ca_routine; uint32_t rtos; int offset = pdp_type_ca_info(header0)->offset; int xoffset = offset % width; int yoffset = offset / width; /* double word width: number of uint32_ts per row */ int dwwidth = width >> 5; unsigned long long result = 0; /* exit if there isn't a valid routine */ if(!ca_routine) return; if(!header0) return; if(!header1) return; //post("pdp_ca: PRE offset: %d, xoffset: %d, yoffset: %d", offset, xoffset, yoffset); /* calculate new offset: lines shift up, rows shift left by 16 cells */ xoffset = (xoffset + width - 16) % width; yoffset = (yoffset + height - 1) % height; offset = yoffset * width + xoffset; //post("pdp_ca: PST offset: %d, xoffset: %d, yoffset: %d", offset, xoffset, yoffset); pdp_type_ca_info(header1)->offset = offset; for(j=0; j> 32; } // i == dwwidth-1 env[0] = data0[i + j]; env[1] = data0[j]; env[2] = data0[i + j + dwwidth]; env[3] = data0[j + dwwidth]; env[4] = data0[i + j + (dwwidth<<1)]; env[5] = data0[j + (dwwidth<<1)]; env[6] = data0[i + j + (dwwidth<<1) + dwwidth]; env[7] = data0[j + (dwwidth<<1) + dwwidth]; result = scaf_feeder(tos, reg, ca_routine, env); data1[i + j] = result & 0xffffffff; data1[i + j + dwwidth] = result >> 32; } // j == dwwidth*(height - 2) for(i=0; i < (dwwidth-1) ; i+=1){ env[0] = data0[i + j]; env[1] = data0[i + j + 1]; env[2] = data0[i + j + dwwidth]; env[3] = data0[i + j + dwwidth + 1]; env[4] = data0[i]; env[5] = data0[i + 1]; env[6] = data0[i + dwwidth]; env[7] = data0[i + dwwidth + 1]; result = scaf_feeder(tos, reg, ca_routine, env); data1[i + j] = result & 0xffffffff; data1[i + j + dwwidth] = result >> 32; } // j == dwwidth*(height - 2) // i == dwwidth-1 env[0] = data0[i + j]; env[1] = data0[j]; env[2] = data0[i + j + dwwidth]; env[3] = data0[j + dwwidth]; env[4] = data0[i]; env[5] = data0[0]; env[6] = data0[i + dwwidth]; env[7] = data0[dwwidth]; result = scaf_feeder(tos, reg, ca_routine, env); data1[i + j] = result & 0xffffffff; data1[i + j + dwwidth] = result >> 32; check_stack(x, tos, env); return; } static void pdp_ca_swappackets(t_pdp_ca *x) { /* swap packets */ int packet = x->x_packet1; x->x_packet1 = x->x_packet0; x->x_packet0 = packet; } /* tick advance CA one timestep */ static void pdp_ca_bang_thread(t_pdp_ca *x) { int encoding; int packet; int i; int iterations = x->x_iterations; /* invariant: the two packets are allways valid and compatible so a bang is allways possible. this means that in the pdp an invalid packet needs to be converted to a valid one */ if (-1 == x->x_packet0) pdp_post("warning: packet 0 invalid"); if (-1 == x->x_packet1) pdp_post("warning: packet 1 invalid"); if (PDP_CA_MODE_2D == x->x_mode){ for(i=0; i < iterations; i++){ /* process form packet0 -> packet1 */ pdp_ca_process_ca_2D(x); /* swap */ pdp_ca_swappackets(x); } } else if (PDP_CA_MODE_1D == x->x_mode){ if (x->x_fullscreen1d){ t_pdp *header0 = pdp_packet_header(x->x_packet0); pdp_type_ca_info(header0)->currow = 0; pdp_type_ca_info(header0)->offset = 0; iterations = pdp_type_ca_info(header0)->height; } for(i=0; i < iterations; i++){ pdp_ca_process_ca_1D(x); } } } static void pdp_ca_sendpacket(t_pdp_ca *x) { /* adjust offset before sending */ t_pdp *header0 = pdp_packet_header(x->x_packet0); int offset, width, height, xoffset, yoffset, horshift, vershift; if (!header0) return; offset = pdp_type_ca_info(header0)->offset; width = pdp_type_ca_info(header0)->width; height = pdp_type_ca_info(header0)->height; xoffset = offset % width; yoffset = offset / width; horshift = x->x_horshift; vershift = x->x_vershift; horshift %= width; if (horshift < 0) horshift += width; vershift %= height; if (vershift < 0) vershift += height; xoffset = (xoffset + horshift) % width; yoffset = (yoffset + vershift) % height; offset = yoffset * width + xoffset; pdp_type_ca_info(header0)->offset = offset; /* output the packet */ outlet_pdp(x->x_outlet0, x->x_packet0); } static void pdp_ca_bang(t_pdp_ca *x) { /* we don't use input packets for testing dropping here but check the queue_id to see if processing is still going on */ if (-1 == x->x_queue_id){ pdp_queue_add(x, pdp_ca_bang_thread, pdp_ca_sendpacket, &x->x_queue_id); } else{ pdp_control_notify_drop(-1); } } /* this method stores the packet into x->x_packet0 (the packet to be processed) if it is valid. x->x_packet1 is not compatible it is regenerated so that it is in short, when this routine returns both packets are valid and compatible. */ static void pdp_ca_copy_rw_if_valid(t_pdp_ca *x, int packet) { t_pdp *header = pdp_packet_header(packet); t_pdp *header1 = pdp_packet_header(x->x_packet1); int grabpacket; int convertedpacket; /* check if header is valid */ if (!header) return; if (PDP_CA != header->type) return; if (PDP_CA_STANDARD != pdp_type_ca_info(header)->encoding) return; /* packet is a ca, register it */ pdp_packet_mark_unused(x->x_packet0); x->x_packet0 = pdp_packet_copy_rw(packet); /* make sure we have the right header */ header = pdp_packet_header(x->x_packet0); /* make sure that the other packet is compatible */ if ((pdp_type_ca_info(header1)->width != pdp_type_ca_info(header)->width) || (pdp_type_ca_info(header1)->height != pdp_type_ca_info(header)->height)) { /* if not, throw away and clone the new one */ pdp_packet_mark_unused(x->x_packet1); x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); } if (-1 == x->x_packet0) pdp_post("warning: packet 0 invalid"); if (-1 == x->x_packet1) pdp_post("warning: packet 1 invalid"); }; /* hot packet inlet */ static void pdp_ca_input_0(t_pdp_ca *x, t_symbol *s, t_floatarg f) { if (s == gensym("register_rw")){ pdp_ca_copy_rw_if_valid(x, (int)f); } else if (s == gensym("process")){ pdp_ca_bang(x); } } /* cold packet inlet */ static void pdp_ca_input_1(t_pdp_ca *x, t_symbol *s, t_floatarg f) { if (s == gensym("register_rw")) { pdp_ca_copy_rw_if_valid(x, (int)f); } } static void pdp_ca_rule_string(t_pdp_ca *x, char *c) { char tmp[256]; void (*ca_routine)(void); /* check if we can find string */ sprintf(tmp, "rule_%s", c); if (!(ca_routine = dlsym(x->x_ca_libhandle, tmp))){ post("pdp_ca: can't fine ca rule %s (symbol: %s)", c, tmp); return; } /* ok, so store routine address */ else{ x->x_ca_routine = ca_routine; x->x_lastrule = gensym(c); } } static void pdp_ca_rule(t_pdp_ca *x, t_symbol *s) { /* make sure lib is loaded */ if (!x->x_ca_libhandle) return; /* set rule by name */ pdp_ca_rule_string(x, s->s_name); } static void pdp_ca_rule_index(t_pdp_ca *x, t_float f) { int i = (int)f; /* make sure lib is loaded */ if (!x->x_ca_libhandle) return; /* check index */ if (i<0) return; if (i>=x->x_ca_nbrules) return; /* set rule by index */ pdp_ca_rule_string(x, x->x_ca_rulename[i]); } static void pdp_ca_close(t_pdp_ca *x) { if (x->x_ca_libhandle){ dlclose(x->x_ca_libhandle); x->x_ca_libhandle = 0; x->x_ca_routine = 0; if (x->x_ca_rulename){ free (x->x_ca_rulename); x->x_ca_rulename = 0; } } } static void pdp_ca_printrules(t_pdp_ca *x) { int i; if (!(x->x_ca_libhandle)) return; post("pdp_ca: found %d rules: ", x->x_ca_nbrules); for(i=0;ix_ca_nbrules; i++) post("%3d: %s ", i, x->x_ca_rulename[i]); } /* open code library */ static void pdp_ca_openlib(t_pdp_ca *x, t_symbol *s) { char *c; int words; /* close current lib, if one */ pdp_ca_close(x); /* try to open new lib */ if (!(x->x_ca_libhandle = dlopen(s->s_name, RTLD_NOW))){ post("pdp_ca: can't open ca library %s\n%s", s->s_name, dlerror()); x->x_ca_libhandle = 0; return; } /* scan for valid rules */ if (!(x->x_ca_rulenames = (char *)dlsym(x->x_ca_libhandle, "rulenames"))){ post("pdp_ca: ERROR: %s does not contain a name table. closing.", s->s_name); pdp_ca_close(x); return; } /* count rules */ words = 0; for(c = (char *)x->x_ca_rulenames; *c;){ words++; while(*c++); } x->x_ca_nbrules = words; x->x_ca_rulename = (char **)malloc(sizeof(char *) * words); /* build name array */ words = 0; for(c = (char *)x->x_ca_rulenames; *c;){ x->x_ca_rulename[words] = c; words++; while(*c++); } /* ok, we're done */ post("pdp_ca: opened rule library %s", s->s_name ,x->x_ca_nbrules); /* print rule names */ //pdp_ca_printrules(x); /* set last selected rule */ pdp_ca_rule(x, x->x_lastrule); } /* compile source file and open resulting code library */ static void pdp_ca_opensrc(t_pdp_ca *x, t_symbol *s) { #define TMPSIZE 1024 char commandline[TMPSIZE]; char library[TMPSIZE]; int status; /* setup compiler args */ snprintf(library, TMPSIZE, "%so", s->s_name); snprintf(commandline, TMPSIZE, "scafc %s %s", s->s_name, library); /* call compiler */ if (system(commandline)) { post ("pdp_ca: error compiling %s", s->s_name); } else { post("pdp_ca: compiled %s", s->s_name); pdp_ca_openlib(x, gensym(library)); } } /* open a source file or a library, depending on extension */ static void pdp_ca_open(t_pdp_ca *x, t_symbol *s) { char *name = s->s_name; char *end = name; while(*end) end++; if (end == name){ post("pdp_ca: invalid file name"); return; } /* if the name ends with 'o' assume it is a library */ if (end[-1] == 'o'){ pdp_ca_openlib(x, s); } /* otherwize, assume it is a source file */ else{ pdp_ca_opensrc(x, s); } } /* init the current packet with random noise */ static void pdp_ca_rand(t_pdp_ca *x){ t_pdp *header = pdp_packet_header(x->x_packet0); short int *data = (short int *) pdp_packet_data(x->x_packet0); int i; int nbshortints = (pdp_type_ca_info(header)->width >> 4) * pdp_type_ca_info(header)->height; for(i=0; ix_packet0); pdp_packet_mark_unused(x->x_packet1); /* create new packets */ x->x_packet0 = pdp_packet_new_ca(PDP_CA, width, height); x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); } static void pdp_ca_iterations(t_pdp_ca *x, t_float f) { int i = (int)f; if (i < 0) i = 0; x->x_iterations = i; } static void pdp_ca_horshift16(t_pdp_ca *x, t_float f) { x->x_horshift = 16 * (int)f; } static void pdp_ca_vershift(t_pdp_ca *x, t_float f) { x->x_vershift = (int)f; } static void pdp_ca_set1d(t_pdp_ca *x) { x->x_mode = PDP_CA_MODE_1D; } static void pdp_ca_set2d(t_pdp_ca *x) { x->x_mode = PDP_CA_MODE_2D; } static void pdp_ca_fullscreen1d(t_pdp_ca *x, t_floatarg f) { if (f == 0.0f) x->x_fullscreen1d = 0; if (f == 1.0f) x->x_fullscreen1d = 1; } static void pdp_ca_free(t_pdp_ca *x) { pdp_packet_mark_unused(x->x_packet0); pdp_packet_mark_unused(x->x_packet1); pdp_ca_close(x); free(x->x_data); } void *pdp_ca_new(void) { t_pdp_ca *x = (t_pdp_ca *)pd_new(pdp_ca_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1")); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("iterations")); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet0 = -1; x->x_packet1 = -1; x->x_queue_id = -1; x->x_data = (t_pdp_ca_data *)malloc(sizeof(t_pdp_ca_data)); x->x_ca_routine = 0; x->x_ca_libhandle = 0; x->x_ca_rulename = 0; x->x_horshift = 0; x->x_vershift = 0; pdp_ca_newca(x, 64, 64); pdp_ca_iterations(x, 1); pdp_ca_set2d(x); pdp_ca_fullscreen1d(x, 0); x->x_packet_type = gensym("grey"); x->x_lastrule = gensym("gameoflife"); pdp_ca_openlib(x, gensym(PDP_CA_RULES_LIB)); return (void *)x; } // *********************** CA CONVERTER CLASSES STUFF ********************* // TODO: move this to a separate file later together with other converters (part of system?) #define PDP_CA2IMAGE 1 #define PDP_IMAGE2CA 2 typedef struct pdp_ca_conv_struct { t_object x_obj; t_float x_f; int x_threshold; int x_packet; t_outlet *x_outlet0; /* solve identity crisis */ int x_whoami; /* output packet type */ /* only greyscale for now */ t_symbol *x_packet_type; } t_pdp_ca_conv; /* hot packet inlet */ static void pdp_ca_conv_input_0(t_pdp_ca_conv *x, t_symbol *s, t_floatarg f) { int packet = -1; if (s == gensym("register_ro")){ pdp_packet_mark_unused(x->x_packet); x->x_packet = pdp_packet_copy_ro((int)f); return; } else if (s == gensym("process")){ switch(x->x_whoami){ case PDP_CA2IMAGE: packet = pdp_type_ca2grey(x->x_packet); break; case PDP_IMAGE2CA: packet = pdp_type_grey2ca(x->x_packet, x->x_threshold); break; } /* throw away the original packet */ pdp_packet_mark_unused(x->x_packet); x->x_packet = -1; /* pass the fresh packet */ pdp_packet_pass_if_valid(x->x_outlet0, &packet); /* unregister the freshly created packet */ //pdp_packet_mark_unused(packet); /* output if valid */ //if (-1 != packet) outlet_pdp(x->x_outlet0, packet); } } void pdp_ca_conv_free(t_pdp_ca_conv *x) { pdp_packet_mark_unused(x->x_packet); } void pdp_image2ca_threshold(t_pdp_ca_conv *x, t_float f) { f *= 0x8000; if (f < -0x7fff) f = -0x7fff; if (f > 0x7fff) f = 0x7fff; x->x_threshold = (short int)f; } void *pdp_ca2image_new(void) { t_pdp_ca_conv *x = (t_pdp_ca_conv *)pd_new(pdp_ca2image_class); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet_type = gensym("grey"); x->x_packet = -1; x->x_whoami = PDP_CA2IMAGE; return (void *)x; } void *pdp_image2ca_new(void) { t_pdp_ca_conv *x = (t_pdp_ca_conv *)pd_new(pdp_image2ca_class); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("threshold")); x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); x->x_packet_type = gensym("grey"); x->x_packet = -1; x->x_whoami = PDP_IMAGE2CA; x->x_threshold = 0x4000; return (void *)x; } // *********************** CLASS SETUP FUNCTIONS ********************* #ifdef __cplusplus extern "C" { #endif void pdp_ca2image_setup(void) { pdp_ca2image_class = class_new(gensym("pdp_ca2image"), (t_newmethod)pdp_ca2image_new, (t_method)pdp_ca_conv_free, sizeof(t_pdp_ca), 0, A_NULL); class_addmethod(pdp_ca2image_class, (t_method)pdp_ca_conv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); } void pdp_image2ca_setup(void) { pdp_image2ca_class = class_new(gensym("pdp_image2ca"), (t_newmethod)pdp_image2ca_new, (t_method)pdp_ca_conv_free, sizeof(t_pdp_ca), 0, A_NULL); class_addmethod(pdp_image2ca_class, (t_method)pdp_ca_conv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_image2ca_class, (t_method)pdp_image2ca_threshold, gensym("threshold"), A_FLOAT, A_NULL); } void pdp_ca_setup(void) { pdp_ca_class = class_new(gensym("pdp_ca"), (t_newmethod)pdp_ca_new, (t_method)pdp_ca_free, sizeof(t_pdp_ca), 0, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_iterations, gensym("iterations"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_bang, gensym("bang"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_printrules, gensym("rules"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rand, gensym("random"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("ca"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_horshift16, gensym("hshift16"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_vershift, gensym("vshift"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_close, gensym("close"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_openlib, gensym("openlib"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_opensrc, gensym("opensrc"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_open, gensym("open"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule, gensym("rule"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule_index, gensym("ruleindex"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_input_1, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_set1d, gensym("1D"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_set2d, gensym("2D"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_fullscreen1d, gensym("fullscreen1D"), A_FLOAT, A_NULL); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/scaf/pdp/pdp_ca_system.c000066400000000000000000000201321266045153600207710ustar00rootroot00000000000000/* * Cellular Automata Extension Module for pdp - Main system code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp_ca.h" #include "pdp_internals.h" /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif /* check if packet is a valid ca packet */ int pdp_packet_ca_isvalid(int packet) { t_pdp *header = pdp_packet_header(packet); if (!header) return 0; if (PDP_CA != header->type) return 0; if (PDP_CA_STANDARD != pdp_type_ca_info(header)->encoding) return 0; return 1; } static t_pdp_symbol *pdp_packet_ca_get_description(int packet) { t_pdp *header = pdp_packet_header(packet); char description[1024]; char *c = description; int encoding; if (!header) return pdp_gensym("invalid"); if (header->type == PDP_CA){ c += sprintf(c, "ca"); switch(pdp_type_ca_info(header)->encoding){ case PDP_CA_STANDARD: c += sprintf(c, "/1bit2D"); break; default: c += sprintf(c, "/unknown"); goto exit; } c += sprintf(c, "/%dx%d", pdp_type_ca_info(header)->width, pdp_type_ca_info(header)->height); exit: return pdp_gensym(description); } else return pdp_gensym("unknown"); } /* create a new ca packet */ int pdp_packet_new_ca(int __attribute__((unused)) encoding, int width, int height) { int p; int w = (int)width; int h = (int)height; int bytesize; t_pdp *header; /* ensure with = multiple of 64 */ w &= 0xffffffc0; /* ensure height = multiple of 4 */ w &= 0xfffffffc; w = (w<64) ? 64 : w; h = (h<4) ? 4 : h; bytesize = (w>>3) * h; /* create new packets */ p = pdp_packet_new(PDP_CA, bytesize); header = pdp_packet_header(p); if (!header) { pdp_post("error: can't create CA packet"); return -1; } pdp_type_ca_info(header)->encoding = PDP_CA_STANDARD; pdp_type_ca_info(header)->width = w; pdp_type_ca_info(header)->height = h; pdp_type_ca_info(header)->offset = 0; pdp_type_ca_info(header)->currow = 0; /* only used for 1D ca */ pdp_type_ca_info(header)->currow = 0; header->desc = 0; header->desc = pdp_packet_ca_get_description(p); //post("creating %s", header->desc->s_name); return p; } /* convert a CA packet to greyscale */ inline void _pdp_type_ca2grey_convert_word(unsigned short int source, short int *dest) { int i; for (i = 15; i>=0; i--){ dest[i] = ((unsigned short)(((short int)(source & 0x8000)) >> 14)) >> 1; source <<= 1; } } int pdp_type_ca2grey(int packet) { int w, h, s, x, y, srcindex; long long offset, xoffset, yoffset; short int *dest; unsigned short int *source; t_pdp *header; t_pdp *newheader; int newpacket; if (!(pdp_packet_ca_isvalid(packet))) return -1; header = pdp_packet_header(packet); w = pdp_type_ca_info(header)->width; h = pdp_type_ca_info(header)->height; s = w*h; source = (unsigned short int *)pdp_packet_data(packet); offset = pdp_type_ca_info(header)->offset; yoffset = (offset / w) * w; xoffset = offset % w; //post("pdp_type_ca2grey: offset: %d, xoffset: %d, yoffset: %d", offset, xoffset, yoffset); newpacket = pdp_packet_new_image_grey(w, h); newheader = pdp_packet_header(newpacket); if (!newheader) return -1; //newheader->info.image.width = w; //newheader->info.image.height = h; //newheader->info.image.encoding = PDP_IMAGE_GREY; dest = (short int *)pdp_packet_data(newpacket); #define check_srcindex \ if (srcindex >= (s >> 4)) post ("pdp_type_ca2grey: srcindex out of bound"); #define check_dstindex \ if ((x+y) >= s) post ("pdp_type_ca2grey: dstindex out of bound"); /* debug : dont' shift offset if (0){ for(y=0; y< (h*w); y+=w){ for(x=0; x>4], &dest[x+y]); } } return newpacket; } */ /* create top left */ for (y=0; y < (h*w) - yoffset; y+=w) { for (x=0; x< (w - xoffset); x+=16) { srcindex = (x+xoffset + y+yoffset) >> 4; //check_srcindex; //check_dstindex; _pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]); } } /* create top right */ for (y=0; y < (h*w) - yoffset; y+=w) { for (x = (w - xoffset); x < w; x+=16) { srcindex = (x+xoffset-w + y+yoffset) >> 4; //check_srcindex; //check_dstindex; _pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]); } } /* create bottom left */ for (y=(h*w) - yoffset; y < h*w; y+=w) { for (x=0; x< (w - xoffset); x+=16) { srcindex = (x+xoffset + y+yoffset-(w*h)) >> 4; //check_srcindex; //check_dstindex; _pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]); } } /* create bottom right */ for (y=(h*w) - yoffset; y < h*w; y+=w) { for (x = (w - xoffset); x < w; x+=16) { srcindex = (x+xoffset-w + y+yoffset-(w*h)) >> 4; //check_srcindex; //check_dstindex; _pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]); } } return newpacket; } inline unsigned short int _pdp_type_grey2ca_convert_word(short int *src, short int threshold) { short int tmp; short int dest = 0; int i; for (i = 15; i >= 0; i--){ dest <<= 1; dest |= (src[i] > threshold); } return dest; } int pdp_type_grey2ca(int packet, short int threshold) { int w, h, s, x, y, srcindex; long long offset, xoffset, yoffset; short int *dest; short int *source; t_pdp *header; t_pdp *newheader; int newpacket; if (!(pdp_packet_image_isvalid(packet))) return -1; header = pdp_packet_header(packet); w = header->info.image.width; h = header->info.image.height; s = w*h; source = (short int *)pdp_packet_data(packet); if ( (PDP_IMAGE_GREY != header->info.image.encoding) && (PDP_IMAGE_YV12 != header->info.image.encoding)) return -1; newpacket = pdp_packet_new_ca(PDP_CA_STANDARD, w, h); newheader = pdp_packet_header(newpacket); if (!newheader) return -1; dest = (short int *)pdp_packet_data(newpacket); for(y=0; y< (h*w); y+=w){ for(x=0; x>4] = _pdp_type_grey2ca_convert_word (&source[x+y], threshold); } } return newpacket; } /* returns a pointer to the ca subheader given the pdp header */ t_ca *pdp_type_ca_info(t_pdp *x){return (t_ca *)(&x->info.raw);} void pdp_ca_setup(void); void pdp_ca2image_setup(void); void pdp_image2ca_setup(void); static int _ca_to_image(int packet, t_pdp_symbol __attribute__((unused)) *template) { return pdp_type_ca2grey(packet); } static int _image_to_ca(int packet, t_pdp_symbol __attribute__((unused)) *template) { // convert with default threshold == 0.5 return pdp_type_grey2ca(packet, 0.5f); } void pdp_scaf_setup(void) { t_pdp_conversion_program *program; /* babble */ post ("PDP: cellular automata extension library"); /* setup modules */ pdp_ca_setup(); pdp_ca2image_setup(); pdp_image2ca_setup(); /* setup type conversion */ program = pdp_conversion_program_new(_ca_to_image, 0); pdp_type_register_conversion(pdp_gensym("ca/*/*"), pdp_gensym("image/*/*"), program); pdp_type_register_conversion(pdp_gensym("ca/*/*"), pdp_gensym("image/grey/*"), program); program = pdp_conversion_program_new(_image_to_ca, 0); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("ca/*/*"), program); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/scaf/pdp/scaf_feeder.s000066400000000000000000000040151266045153600204070ustar00rootroot00000000000000# Pure Data Packet - scaf feeder routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # for dup #include "../compiler/scafmacro.s" # *rg is only used for returning the stack pointer # the 4 bit counter is using registers mm4-mm7 now # long long scaf_feeder(void *tos, void *rg, *void() ca_rule, void *env) .globl scaf_feeder .type scaf_feeder, @function #if defined(__i386__) scaf_feeder: pushl %ebp movl %esp, %ebp push %esi push %edi movl 20(%ebp), %edi # load env ptr movl 8(%ebp), %esi # load TOS2 ptr movl 16(%ebp), %eax # address of ca routine pcmpeqw %mm3, %mm3 # load 1 reg call *%eax # TOS = 32x2 cell result dup # push %mm0 to memory movl (%esi), %eax movl 4(%esi), %edx lea 16(%esi), %esi # discard stack movl %esi, (%edi) # store for stack underflow check emms pop %edi pop %esi leave ret #else #if defined(__x86_64__) scaf_feeder: movq %rdi, %rsi # arg0: tos (arg1 is ignoreD) movq %rdx, %rax # arg2: ca_rule movq %rcx, %rdi # arg3: pcmpeqw %mm3, %mm3 # load 1 reg call *%rax # TOS = 32x2 cell result dup # push %mm0 to memory movq (%rsi), %rax # | pop lea 16(%rsi), %rsi # | movq %rsi, (%rdi) # store for stack underflow check emms ret #else #error Needs __i386__ or __x84_64__ #endif #endif pdp-0.14.1+darcs20180201/scaf/rules/000077500000000000000000000000001266045153600163445ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/rules/Makefile000066400000000000000000000002321266045153600200010ustar00rootroot00000000000000OBJ = carules.scafo .SUFFIXES: .scaf .SUFFIXES: .scafo .scaf.scafo: ../compiler/scafc $*.scaf all: $(OBJ) clean: rm -f *.scafo rm -f *.s rm -f *~ pdp-0.14.1+darcs20180201/scaf/rules/carules.scaf000066400000000000000000000101611266045153600206370ustar00rootroot00000000000000( Pure Data Packet - ca rules library. ) ( Copyright (c) by Tom Schouten ) ( ) ( 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., 675 Mass Ave, Cambridge, MA 02139, USA. ) ( this is the standard ca rules library ) ( a rule that is accessible from the ouside should start with "rule_" ) ( and has to return exactly one item on the stack (this is checked in pdp_ca) ) ( a word is a sequence of non whitespace characters (\S+) ) ( words are separated by whitespace (\s+) ) ( so "word ;" is not the same as "word;" ) ( all words between the "(" word and the ")" word are ignored ) ( ":" starts a definition, the next word is the name of the new word ) ( newline ends a definition ) ( no more than one definition per line ) ( no more than one line per definition ) ( ";" returns to calling word ) ( if no ";" is encountered the next defined word is executed ) ( this is to have multiple entry points ) ( multiple exit points don't make sense since there are no conditional words ) : +(4) ++++ ; ( 4 bit add TOS - carry on TOS ) : +(3) +++ ; ( 3 bit add TOS - carry on TOS ) : +(2) ++ ; ( 2 bit add TOS - carry on TOS ) : +top @-+ +(4) drop @0+ +(4) drop @++ +(4) ; ( add top row to reg - carry on TOS ) : +mid @-0 +(4) drop @00 +(4) drop @+0 +(4) ; ( add mid row to reg - carry on TOS ) : +bot @-- +(4) drop @0- +(4) drop @+- +(4) ; ( add bot row to reg - carry on TOS ) : +all +top drop +mid drop +bot ; ( add all cells to reg - carry on TOS ) : +mid-1 @-0 +(4) drop @+0 +(4) ; ( add mid row except center element to reg - carry on TOS ) : +all-1 +top drop +mid-1 drop +bot ; ( add all cells expet middle one to reg - carry on TOS ) : countall a-0 +all drop ; ( count all cells - no stack effect ) : countall-1 a-0 +all-1 drop ; ( count all cells except middle one - no stack effect ) : +topbot @0+ +(3) drop @0- +(3) ; : +leftright @+0 +(3) drop @-0 +(3) ; : +star +topbot drop +leftright ; : countstar a-0 +star drop ; : =2or3? @a2 not @a1 and ; ( sum equal to 2 or 3? only checks 3 bits ) : =3? =2or3? @a0 and ; ( sum equal to 3 ? ) : =2? =2or3? @a0 not and ; ( sum equal to 2 ? ) : =4? @a2 @a1 not and @a0 not and ; ( sum equal to 4 ? ) ( some test rules ) ( : rule_one 1 ; ) ( : rule_zero 0 ; ) ( : rule_id @00 ; ) : rule_shiftleft @+0 ; : rule_shifttop @0- ; : rule_shiftbot @0+ ; : rule_shifttopright @-- ; : rule_strobe @00 not ; ( game of life ) : rule_gameoflife countall-1 =2? @00 and =3? or ; ( wolfram's rule 110) : rule_w110 @00 @+0 and not @-0 @00 @+0 or or and ; ( some other rules ) : rule_w110mod @0+ @+0 and not @-+ @0+ @++ or or and ; : rule_w110mod2 @0+ @+0 and not @-+ @0+ @+0 or or and ; : rule_w110mod3 @0+ @++ and not @-+ @0+ @++ or or and @-0 @00 @+0 or or and ; : rule_golmod countall-1 =3? @00 and =2? or ; : rule_golmod2 countall-1 =2? @0+ and =3? or ; : rule_golmod3 countall-1 =2? @++ and =3? or ; : rule_golmod4 countall-1 =2? @++ @-- or and =3? or ; : rule_golmod5 countall-1 =2? @++ @-- or and =3? @+- and or ; : rule_golmod6 countall-1 =2? @++ @-- or and =3? @+- and or @0+ or ; : rule_golmod7 countall-1 =2? @++ @-- or and =3? @+- and or @0+ or @00 and ; ( ca's with a short settling time ) : rule_block countstar =4? not =2? and @00 or ; : rule_noiseedges countstar =4? =3? or not =2? and @00 or @++ xor ; : rule_noiseplanes countstar =4? =3? or not =2? and @00 or @++ xor @-- xor ; ( : rule_noiseplanes countstar =4? =3? or not =2? and @00 or @++ xor @-- xor ; ) : rule_fire countall-1 =2? @0+ and =3? or ; pdp-0.14.1+darcs20180201/scaf/test/000077500000000000000000000000001266045153600161715ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/scaf/test/test_pdp_ca.pd000066400000000000000000000062171266045153600210110ustar00rootroot00000000000000#N canvas 650 350 625 557 10; #X obj 287 82 openpanel; #X msg 287 56 bang; #X msg 288 110 open \$1; #X obj 230 191 pdp_ca; #X obj 193 76 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 223 80 metro 40; #X msg 211 56 bang; #X msg 247 56 stop; #X obj 146 235 pdp_xv; #X obj 28 31 t b b b; #X obj 11 7 loadbang; #X msg 99 80 rule id; #X msg 328 155 ca 256 256; #X msg 256 296 rule shifttopright; #X msg 331 134 ca 64 64; #X msg 262 270 rule shiftleft; #X msg 298 216 random; #X msg 251 321 rule gameoflife; #X floatatom 344 52 5 0 0; #X msg 331 184 ca 1024 1024; #X floatatom 279 154 5 0 0; #X msg 357 106 ca 512 512; #X msg 363 80 ca 320 240; #X obj 211 120 pdp_v4l; #X obj 179 99 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 138 53 metro 40; #X msg 126 29 bang; #X msg 162 29 stop; #X floatatom 205 28 5 0 0; #X msg 243 348 rule w110; #X msg 245 371 rule w110mod; #X msg 54 371 rule w110mod2; #X msg 387 47 ca 640 394; #X obj 481 289 count; #X obj 397 248 route 0 1 2 3; #X floatatom 517 254 5 0 0; #X msg 466 184 bang; #X msg 502 184 stop; #X floatatom 552 171 5 0 0; #X obj 478 208 metro 1000; #X msg 258 403 rule golmod; #X floatatom 34 129 5 0 0; #X obj 90 207 pdp_bqt; #X msg 62 107 dim 64 64; #X msg 44 167 hpf \$1 0.5; #X msg 272 430 rule golmod2; #X msg 273 467 rule golmod3; #X msg 277 494 rule golmod4; #X msg 280 515 rule golmod5; #X msg 283 537 rule golmod6; #X msg 380 403 rule golmod7; #X obj 46 267 pdp_mix; #X floatatom 120 297 5 0 0; #X msg 61 462 type grey; #X msg 112 407 rule w110mod3; #X msg 64 490 type yv12; #X msg 438 471 dim 512 512; #X obj 270 134 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 463 111 ca 1024 512; #X msg 105 4 open /home/tom/pd/pdp/scaf/rules/carules.scafo; #X msg 163 468 rule toomuch; #X msg 165 500 rule underflow; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 3 0 8 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 5 0; #X connect 7 0 5 0; #X connect 9 1 11 0; #X connect 9 2 59 0; #X connect 10 0 9 0; #X connect 11 0 3 0; #X connect 12 0 3 0; #X connect 13 0 3 0; #X connect 14 0 3 0; #X connect 15 0 3 0; #X connect 16 0 3 0; #X connect 17 0 3 0; #X connect 18 0 5 1; #X connect 19 0 3 0; #X connect 20 0 3 2; #X connect 21 0 3 0; #X connect 22 0 3 0; #X connect 23 0 51 1; #X connect 23 0 3 1; #X connect 24 0 23 0; #X connect 25 0 24 0; #X connect 26 0 25 0; #X connect 27 0 25 0; #X connect 28 0 25 1; #X connect 29 0 3 0; #X connect 30 0 3 0; #X connect 31 0 3 0; #X connect 32 0 3 0; #X connect 33 0 34 0; #X connect 34 0 30 0; #X connect 34 1 17 0; #X connect 34 2 40 0; #X connect 34 3 17 0; #X connect 35 0 33 1; #X connect 36 0 39 0; #X connect 37 0 39 0; #X connect 38 0 39 1; #X connect 39 0 33 0; #X connect 40 0 3 0; #X connect 41 0 44 0; #X connect 42 0 8 0; #X connect 43 0 23 0; #X connect 44 0 42 0; #X connect 45 0 3 0; #X connect 46 0 3 0; #X connect 47 0 3 0; #X connect 48 0 3 0; #X connect 49 0 3 0; #X connect 50 0 3 0; #X connect 51 0 8 0; #X connect 52 0 51 2; #X connect 53 0 23 0; #X connect 54 0 3 0; #X connect 55 0 23 0; #X connect 56 0 8 0; #X connect 57 0 20 0; #X connect 58 0 3 0; #X connect 59 0 3 0; #X connect 60 0 3 0; #X connect 61 0 3 0; pdp-0.14.1+darcs20180201/scaf/test/test_pdp_ca2.pd000066400000000000000000000075031266045153600210720ustar00rootroot00000000000000#N canvas 454 152 625 557 10; #X obj 325 83 openpanel; #X msg 325 57 bang; #X msg 326 111 open \$1; #X obj 428 234 pdp_ca; #X obj 256 149 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 223 80 metro 40; #X msg 211 56 bang; #X msg 247 56 stop; #X obj 402 407 pdp_xv; #X obj 28 31 t b b b; #X obj 11 7 loadbang; #X msg 391 99 ca 256 256; #X msg 394 78 ca 64 64; #X msg 298 216 random; #X msg 251 321 rule gameoflife; #X floatatom 490 187 5 0 0; #X msg 420 50 ca 512 512; #X obj 107 188 pdp_v4l; #X obj 97 127 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 243 348 rule w110; #X msg 245 371 rule w110mod; #X msg 258 403 rule golmod; #X msg 272 430 rule golmod2; #X msg 273 467 rule golmod3; #X msg 277 494 rule golmod4; #X msg 280 515 rule golmod5; #X msg 283 537 rule golmod6; #X obj 481 167 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 526 55 ca 1024 512; #X obj 426 294 pdp_ca2image; #X obj 104 228 pdp_image2ca; #X obj 136 155 metro 40; #X msg 124 131 bang; #X msg 160 131 stop; #X floatatom 510 273 5 0 0; #X obj 501 253 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 468 416 rule gameoflife; #X msg 450 455 rule golmod6; #X msg 380 440 rule golmod3; #X msg 159 287 rules; #X floatatom 27 213 5 0 0; #X msg 40 319 ruleindex \$1; #X obj 31 254 t b f; #X msg 52 78 rule gameoflife; #X floatatom 193 198 5 0 0; #X msg 504 143 close; #X msg 149 448 rule test1; #X obj 181 178 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X msg 5 129 dim 640 480; #X obj 156 51 pdp_qt; #X msg 174 23 open /home/ben/MOV/test1.mov; #X floatatom 93 31 5 0 0; #X msg 65 56 autoplay 1; #X obj 144 25 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 22 94 loop 1; #X obj 439 483 osc~ 150; #X obj 439 508 *~ 0.1; #X obj 437 536 dac~; #X floatatom 282 57 5 0 0; #X msg 503 113 ca 32 32; #X obj 428 322 pdp_motion_blur; #X obj 488 349 pdp_gradient; #X obj 425 382 pdp_mix; #X floatatom 508 380 5 0 0; #X floatatom 204 128 5 0 0; #X obj 39 399 pdp_control; #X obj 83 476 pdp_control; #X obj 84 519 print two; #X obj 39 438 print one; #X obj 275 149 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 265 128 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 38 374 thread \$1; #X obj 32 349 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 105 4 open /home/tom/pd/pdp/scaf/rules/carules.scafo; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 3 0 29 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 5 0; #X connect 7 0 5 0; #X connect 9 1 43 0; #X connect 9 2 73 0; #X connect 10 0 9 0; #X connect 11 0 3 0; #X connect 12 0 3 0; #X connect 13 0 3 0; #X connect 14 0 3 0; #X connect 15 0 3 2; #X connect 16 0 3 0; #X connect 17 0 30 0; #X connect 17 0 62 1; #X connect 18 0 17 0; #X connect 19 0 3 0; #X connect 20 0 3 0; #X connect 21 0 3 0; #X connect 22 0 3 0; #X connect 23 0 3 0; #X connect 24 0 3 0; #X connect 25 0 3 0; #X connect 26 0 3 0; #X connect 27 0 15 0; #X connect 28 0 3 0; #X connect 29 0 61 0; #X connect 30 0 3 0; #X connect 31 0 17 0; #X connect 32 0 31 0; #X connect 33 0 31 0; #X connect 35 0 34 0; #X connect 39 0 3 0; #X connect 40 0 42 0; #X connect 41 0 3 0; #X connect 42 0 13 0; #X connect 42 1 41 0; #X connect 43 0 3 0; #X connect 44 0 30 1; #X connect 45 0 3 0; #X connect 46 0 3 0; #X connect 47 0 44 0; #X connect 48 0 17 0; #X connect 49 0 30 0; #X connect 50 0 49 0; #X connect 51 0 49 0; #X connect 52 0 49 0; #X connect 53 0 49 0; #X connect 54 0 49 0; #X connect 55 0 56 0; #X connect 56 0 57 0; #X connect 56 0 57 1; #X connect 58 0 5 1; #X connect 59 0 3 0; #X connect 61 0 62 0; #X connect 62 0 8 0; #X connect 63 0 62 2; #X connect 64 0 31 1; #X connect 65 0 68 0; #X connect 66 0 67 0; #X connect 69 0 3 0; #X connect 70 0 4 0; #X connect 70 0 69 0; #X connect 71 0 65 0; #X connect 72 0 71 0; #X connect 73 0 3 0; pdp-0.14.1+darcs20180201/scaf/test/test_pdp_ca3.pd000066400000000000000000000075731266045153600211020ustar00rootroot00000000000000#N canvas 540 210 625 557 10; #X obj 325 83 openpanel; #X msg 325 57 bang; #X msg 326 111 open \$1; #X obj 427 212 pdp_ca; #X obj 202 87 metro 40; #X msg 211 56 bang; #X msg 247 56 stop; #X obj 391 414 pdp_xv; #X obj 28 31 t b b b; #X obj 11 7 loadbang; #X msg 391 99 ca 256 256; #X msg 394 78 ca 64 64; #X msg 229 230 random; #X msg 251 321 rule gameoflife; #X floatatom 490 187 5 0 0; #X msg 420 50 ca 512 512; #X obj 97 127 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 243 348 rule w110; #X msg 245 371 rule w110mod; #X msg 258 403 rule golmod; #X msg 272 430 rule golmod2; #X msg 273 467 rule golmod3; #X msg 277 494 rule golmod4; #X msg 280 515 rule golmod5; #X msg 283 537 rule golmod6; #X obj 481 167 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 526 55 ca 1024 512; #X obj 427 236 pdp_ca2image; #X floatatom 530 253 5 0 0; #X msg 468 416 rule gameoflife; #X msg 450 455 rule golmod6; #X msg 380 440 rule golmod3; #X msg 159 287 rules; #X floatatom 27 213 5 0 0; #X msg 40 319 ruleindex \$1; #X obj 31 254 t b f; #X msg 52 78 rule gameoflife; #X msg 504 143 close; #X msg 149 448 rule test1; #X obj 156 51 pdp_qt; #X msg 174 23 open /home/ben/MOV/test1.mov; #X floatatom 93 31 5 0 0; #X msg 65 56 autoplay 1; #X obj 144 25 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 282 57 5 0 0; #X msg 503 113 ca 32 32; #X obj 39 399 pdp_control; #X obj 83 476 pdp_control; #X obj 84 519 print two; #X obj 39 438 print one; #X msg 38 374 thread \$1; #X obj 32 349 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 428 352 pdp_zrot; #X obj 428 324 pdp_mix; #X floatatom 523 305 5 0 0; #X floatatom 523 327 5 0 0; #X floatatom 523 349 5 0 0; #X obj 427 264 pdp_blur; #X obj 428 289 pdp_gain; #X floatatom 530 277 5 0 0; #X floatatom 260 120 5 0 0; #X obj 433 159 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 375 364 pdp_xv; #X floatatom 144 162 5 0 0; #X msg 144 191 vshift \$1; #X msg 549 160 1D; #X msg 579 160 2D; #X msg 253 183 fullscreen1D \$1; #X obj 253 164 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 583 272 3; #X msg 586 324 1.05; #X msg 586 351 2; #X msg 588 297 0.97; #X msg 581 243 0.1; #X msg 444 25 ca 512 256; #X obj 434 385 pdp_gain; #X floatatom 507 380 5 0 0; #X msg 105 4 open /home/tom/pd/pdp/scaf/rules/carules.scafo; #X msg 248 295 rule fire; #X msg 140 141 0; #X msg 175 140; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 3 0 27 0; #X connect 4 0 3 0; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 8 1 36 0; #X connect 8 2 77 0; #X connect 9 0 8 0; #X connect 10 0 3 0; #X connect 11 0 3 0; #X connect 12 0 3 0; #X connect 13 0 3 0; #X connect 14 0 3 2; #X connect 15 0 3 0; #X connect 17 0 3 0; #X connect 18 0 3 0; #X connect 19 0 3 0; #X connect 20 0 3 0; #X connect 21 0 3 0; #X connect 22 0 3 0; #X connect 23 0 3 0; #X connect 24 0 3 0; #X connect 25 0 14 0; #X connect 26 0 3 0; #X connect 27 0 57 0; #X connect 27 0 62 0; #X connect 28 0 57 1; #X connect 32 0 3 0; #X connect 33 0 35 0; #X connect 34 0 3 0; #X connect 35 0 12 0; #X connect 35 1 34 0; #X connect 36 0 3 0; #X connect 37 0 3 0; #X connect 38 0 3 0; #X connect 40 0 39 0; #X connect 41 0 39 0; #X connect 42 0 39 0; #X connect 43 0 39 0; #X connect 44 0 4 1; #X connect 45 0 3 0; #X connect 50 0 46 0; #X connect 51 0 50 0; #X connect 52 0 53 1; #X connect 52 0 75 0; #X connect 53 0 52 0; #X connect 54 0 53 2; #X connect 55 0 52 1; #X connect 56 0 52 2; #X connect 57 0 58 0; #X connect 58 0 53 0; #X connect 59 0 58 1; #X connect 61 0 3 0; #X connect 63 0 64 0; #X connect 64 0 3 0; #X connect 65 0 3 0; #X connect 66 0 3 0; #X connect 67 0 3 0; #X connect 68 0 67 0; #X connect 69 0 59 0; #X connect 70 0 55 0; #X connect 71 0 56 0; #X connect 72 0 54 0; #X connect 73 0 28 0; #X connect 74 0 3 0; #X connect 75 0 7 0; #X connect 76 0 75 1; #X connect 77 0 3 0; #X connect 78 0 3 0; #X connect 79 0 63 0; #X connect 80 0 63 0; pdp-0.14.1+darcs20180201/system/000077500000000000000000000000001266045153600156225ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/CONTENTS000066400000000000000000000003331266045153600170010ustar00rootroot00000000000000X11 x window specific code forth packet forth code image image processing code kernel the core pdp system mmx mmx assembly code net networking support png png support type different packet type implementations pdp-0.14.1+darcs20180201/system/Makefile000066400000000000000000000006361266045153600172670ustar00rootroot00000000000000 include ../Makefile.config all: $(PDP_TARGET) pdp.o common: make -C net make -C png make -C type make -C kernel make -C image $(PDP_TARGET) make -C zl linux_mmx: common make -C mmx linux_gcc_mmx: common linux: common darwin: common clean: rm -f *~ rm -f *.o make -C mmx clean make -C net clean make -C png clean make -C image clean make -C type clean make -C kernel clean make -C zl clean pdp-0.14.1+darcs20180201/system/image/000077500000000000000000000000001266045153600167045ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/image/Makefile000066400000000000000000000007471266045153600203540ustar00rootroot00000000000000include ../../Makefile.config all: $(PDP_TARGET) OBJECTS = pdp_llconv.o pdp_resample.o pdp_imageproc_common.o OBJECTS_MMX = pdp_imageproc_mmx.o pdp_llconv_mmx.o OBJECTS_PORTABLE = pdp_imageproc_portable.o pdp_llconv_portable.o OBJECTS_GCC_MMX = pdp_imageproc_gcc_mmx.o pdp_llconv_portable.o linux_mmx: $(OBJECTS_MMX) $(OBJECTS) linux_gcc_mmx: $(OBJECTS_GCC_MMX) $(OBJECTS) linux: $(OBJECTS_PORTABLE) $(OBJECTS) darwin: $(OBJECTS_PORTABLE) $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/system/image/pdp_imageproc_common.c000066400000000000000000000411321266045153600232320ustar00rootroot00000000000000/* * Pure Data Packet. common image processing routines. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains common code for (portable) low level image processing objects pdp_imageproc_* methods The rest is int pdp_imageproc_.c There are also highlevel dispatcher methods that operate on packets: pdp_imageproc_dispatch_* methods */ #include #include #include #include "pdp_imageproc.h" #include "pdp_image.h" #include "pdp_mem.h" #include "pdp_packet.h" #define CLAMP16(x) (((x) > 0x7fff) ? 0x7fff : (((x) < -0x7fff) ? -0x7fff : (x))) u32 pdp_imageproc_legalwidth(int i) { // sevy : we don't see no need for that limitation // has been tested on linux with 1280x1024 without problems // if (i>1024) return 1024; if (i>0) return ((((i-1)>>3)+1)<<3); return 8; } u32 pdp_imageproc_legalheight(int i) { // if (i>1024) return 1024; if (i>0) return ((((i-1)>>3)+1)<<3); return 8; } u32 pdp_imageproc_legalwidth_round_down(int i) { // if (i>1024) return 1024; if (i>8) return ((i>>3)<<3); return 8; } u32 pdp_imageproc_legalheight_round_down(int i) { // if (i>1024) return 1024; if (i>8) return ((i>>3)<<3); return 8; } /* check if two packets are allocated and of the same type */ int pdp_packet_compat(int packet0, int packet1) { t_pdp *header0 = pdp_packet_header(packet0); t_pdp *header1 = pdp_packet_header(packet1); if (!(header1)) return 0; if (!(header0)) return 0; if (header0->type != header1->type) return 0; return 1; } /* some operations */ /* logic operators */ void pdp_imageproc_xor_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image, s16 *image2) { u32 *plane = (u32 *)image; u32 *plane2 = (u32 *)image2; int count = (width * height) >> 1; int i; for (i=0; i> 1; int i; for (i=0; i> 1; int i; for (i=0; i> 1; int i; for (i=0; i> 1; int i; mask = (mask & 0xffff) | (mask << 16); for (i=0; i> 1) + (two >> 1) + ((scale * _rand_s16()) >> 16)); //return (one >> 1) + (two >> 1); } void *pdp_imageproc_plasma_new(void){return pdp_alloc(sizeof(t_plasma));} void pdp_imageproc_plasma_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_plasma_setseed(void *x, float seed) { *((float *)x) = seed; } void pdp_imageproc_plasma_setturbulence(void *x, float f) { ((t_plasma *)x)->scale = CLAMP16(f * ((float)0x7fff)); } static void _plasma_subdiv(u32 w, u32 h, u32 s, s16 *image, int calc_left, int calc_top, s32 scale) { int w0 = ((w-1)>>1); // width of left segments int h0 = ((h-1)>>1); // heigth of top segments int w1 = w - w0; int h1 = h - h0; /* conditions: w0 <= w1, h0 <= h1 */ /* original coordinates */ int topleft = 0; int topright = w-1; int bottomleft = s * (h-1); int bottomright = bottomleft + topright; /* new subdivision coordinates */ int top = w0; int left = s * h0; int bottom = bottomleft + w0; int right = topright + left; int center = left + top; if (w0 && h0){ /* left-right and top-bottom subdivide */ /* calculate corner pixel colours */ if (calc_top) image[top] = _new_color(image[topleft], image[topright], scale); if (calc_left) image[left] = _new_color(image[topleft], image[bottomleft], scale); image[right] = _new_color(image[topright], image[bottomright], scale); image[bottom] = _new_color(image[bottomleft], image[bottomright], scale); image[center] = (_new_color(image[top], image[bottom], scale) >> 1) +(_new_color(image[left], image[right], scale) >> 1); /* subdivide (with overlap) */ _plasma_subdiv(w0+1, h0+1, s, &image[topleft], 1, 1, scale); _plasma_subdiv(w1, h0+1, s, &image[top], 0, 1, scale); _plasma_subdiv(w0+1, h1, s, &image[left], 1, 0, scale); _plasma_subdiv(w1, h1, s, &image[center], 0, 0, scale); } else if(h0) { /* top-bottom subdivide */ //post("h:%d", h); /* calculate corner pixel colours */ if(calc_left) image[left] = _new_color(image[topleft], image[bottomleft], scale); image[right] = _new_color(image[topright], image[bottomright], scale); /* subdivide (without overlap) */ _plasma_subdiv(w, h0+1, s, &image[topleft], 1, 0, scale); _plasma_subdiv(w, h1, s, &image[left], 1, 0, scale); } else if (w0){ /* left-right subdivide */ /* calculate corner pixel colours */ if (calc_top) image[top] = _new_color(image[topleft], image[topright], scale); image[bottom] = _new_color(image[bottomleft], image[bottomright],scale); /* subdivide with overlap */ _plasma_subdiv(w0+1, h, s, &image[topleft], 0, 1, scale); _plasma_subdiv(w1, h, s, &image[top], 0, 1, scale); } } void pdp_imageproc_plasma_process(void *x, u32 width, u32 height, s16 *image) { s32 scale = (((t_plasma *)x)->scale); srandom (((t_plasma *)x)->seed); /* set initial border colours */ image[0] = _rand_s16(); image[width-1] = _rand_s16(); image[width * (height-1)] = _rand_s16(); image[width * height - 1] = _rand_s16(); /* subdivide */ _plasma_subdiv(width, height, width, image, 1, 1, scale); ((t_plasma *)x)->seed = random(); } void pdp_imageproc_zero_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image) { int bytesize = (width * height) << 1; memset(image, 0, bytesize); } void pdp_imageproc_constant_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image) { int i; uptr value = (uptr)x; u32 *plane = (u32 *)image; int wordsize = (width * height) >> 1; value = (value & 0xffff) | (value << 16); for (i=0; i>= 15; /* shift sign bit into top word */ mask_bot >>= 15; mask_bot = (s32)(((u32)mask_bot) >> 16); /* shift top word into bottom word */ return mask_top |mask_bot; } /* clear the least significant bit of the top word to ensure a decoupled vector add */ static inline void _decouple(s32 *invec) { *invec &= 0xfffeffff; } void pdp_imageproc_abs_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image) { int i; s32 *wimage = (s32 *)image; int wsize = (width * height) >> 1; for (i=0; i= 0) ? (c) : (~c) */ /* not is used instead of neg to prevent overflow on 0x8000 */ /* this maps both 0 and -1 to 0 */ wimage[i] ^= _sign(wimage[i]); } } void pdp_imageproc_zthresh_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image) { int i; s32 *wimage = (s32 *)image; int wsize = (width * height) >> 1; for (i=0; i= 0) ? (c) : (0) */ wimage[i] &= ~_sign(wimage[i]); } } /* hard thresholding: x contains a positive unsigned short int */ void pdp_imageproc_hardthresh_process(void *x, u32 width, u32 height, s16 *image) { int i; uptr thresh = (uptr)x; s32 sign1, isign2, a; s32 *wimage = (s32 *)image; int wsize = (width * height) >> 1; thresh |= (thresh << 16); for (i=0; i> 1; thresh |= thresh << 16; for (i=0; i> 1; for (i=0; i> 1; for (i=0; i right */ void pdp_imageproc_flip_lr_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image) { u32 y; s16 tmp, *l, *r; for (y=0; ywidth; h = image0->height; d = image0->depth; plane_size = w*h; if (image0->chanmask) chanmask = image0->chanmask; image0->chanmask = 0; switch(image0->encoding){ case PDP_IMAGE_GREY: if (chanmask & 1) (*process_routine)(x, w, h, idata0); break; case PDP_IMAGE_YV12: if (chanmask & 1) (*process_routine)(x, w, h, idata0); idata0 += plane_size; plane_size >>= 2; w >>= 1; h >>= 1; if (chanmask & 2) (*process_routine)(x, w, h, idata0); idata0 += plane_size; if (chanmask & 4) (*process_routine)(x, w, h, idata0); break; case PDP_IMAGE_MCHP: mask = 1; while (d--){ if (chanmask & mask) (*process_routine)(x, w, h, idata0); idata0 += plane_size; mask <<= 1; } break; default: break; } } void pdp_imageproc_dispatch_2buf(void (*process_routine)(void*, u32, u32, s16*, s16 *), void *x, u32 chanmask, int packet0, int packet1) { t_pdp *header0; t_image *image0; s16 *idata0, *idata1; unsigned int w,h,d,plane_size,mask; /* if packets are not compatible images, return without doing anything */ if (!(pdp_packet_image_compat(packet0, packet1))) return; header0 = pdp_packet_header(packet0); image0 = pdp_packet_image_info(packet0); idata0 = pdp_packet_data (packet0); idata1 = pdp_packet_data (packet1); w = image0->width; h = image0->height; d = image0->depth; plane_size = w*h; if (image0->chanmask) chanmask = image0->chanmask; image0->chanmask = 0; switch(image0->encoding){ case PDP_IMAGE_GREY: if (chanmask & 1) (*process_routine)(x, w, h, idata0, idata1); break; case PDP_IMAGE_YV12: if (chanmask & 1) (*process_routine)(x, w, h, idata0, idata1); idata0 += plane_size; idata1 += plane_size; plane_size >>= 2; w >>= 1; h >>= 1; if (chanmask & 2) (*process_routine)(x, w, h, idata0, idata1); idata0 += plane_size; idata1 += plane_size; if (chanmask & 4) (*process_routine)(x, w, h, idata0, idata1); break; case PDP_IMAGE_MCHP: mask = 1; while (d--){ if (chanmask & mask) (*process_routine)(x, w, h, idata0, idata1); idata0 += plane_size; idata1 += plane_size; mask <<= 1; } break; default: break; } } void pdp_imageproc_dispatch_3buf(void (*process_routine)(void*, u32, u32, s16*, s16 *, s16 *), void *x, u32 chanmask, int packet0, int packet1, int packet2) { t_pdp *header0; t_image *image0; s16 *idata0, *idata1, *idata2; unsigned int w,h,d,plane_size, mask; /* if packets are not compatible images, return without doing anything */ if (!((pdp_packet_image_compat(packet0, packet1)) &&(pdp_packet_image_compat(packet0, packet1)))) return; header0 = pdp_packet_header(packet0); image0 = pdp_packet_image_info(packet0); idata0 = pdp_packet_data (packet0); idata1 = pdp_packet_data (packet1); idata2 = pdp_packet_data (packet2); w = image0->width; h = image0->height; d = image0->depth; plane_size = w*h; if (image0->chanmask) chanmask = image0->chanmask; image0->chanmask = 0; switch(image0->encoding){ case PDP_IMAGE_GREY: if (chanmask & 1)(*process_routine)(x, w, h, idata0, idata1, idata2); break; case PDP_IMAGE_YV12: if (chanmask & 1)(*process_routine)(x, w, h, idata0, idata1, idata2); idata0 += plane_size; idata1 += plane_size; idata2 += plane_size; plane_size >>= 2; w >>= 1; h >>= 1; if (chanmask & 2)(*process_routine)(x, w, h, idata0, idata1, idata2); idata0 += plane_size; idata1 += plane_size; idata2 += plane_size; if (chanmask & 4)(*process_routine)(x, w, h, idata0, idata1, idata2); break; case PDP_IMAGE_MCHP: mask = 1; while (d--){ if (chanmask & mask) (*process_routine)(x, w, h, idata0, idata1, idata2); idata0 += plane_size; idata1 += plane_size; idata2 += plane_size; mask <<= 1; } break; default: break; } } pdp-0.14.1+darcs20180201/system/image/pdp_imageproc_gcc_mmx.c000066400000000000000000001230371266045153600233640ustar00rootroot00000000000000/* * Pure Data Packet. portable image processing routines. * Copyright (c) 2003-2012 by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include /* Check this file for the relation between the more generic names and the direct wrappers for the MMX instructions. For GCC 4.6 on Debian this is in: /usr/lib/gcc/x86_64-linux-gnu/4.6/include/mmintrin.h */ #include /* General remarks on MMX code. PMUL ---- There is only one kind of multiplication implemented by 2 instructions, both operating on signed 16 bit values grouped in 4 element vectors (4 x s16, 4 x s16) -> 4 x s16 (hi) | 4 x u16 (lo) _mm_mullo_pi16() -> returns low 16 bits _mm_mulhi_pi16() -> returns high 16 bits Most code below uses _mm_mulhi_pi16() If you _interpret_ the data as fixed point s.15, meaing 1 sign bit, 15 fractional bits, the _interpretation_ of _mm_mulhi_pi16(a,b) is (a x b) / 2 PACK / PUNPCK ------------- In general: PACK: Reduce the word size by throwing away the upper bits PUNPCK: Increase the word size by appending upper bits. PACK comes in two variants: signed and unsigned saturation. This is fairly straightforward. If you want to throw away lower bits, do a shift first. PACK does not interleave vectors. PUNPCK is the only one that interleaves vectors. It comes in two variants, taking data from the low or high words of the operand vectors. http://www.tommesani.com/MMXPrimer.html */ #include "pdp_imageproc.h" #ifdef DEBUG #define INLINE #else #define INLINE inline //#define INLINE __attribute__((always_inline)) #endif /* pdp memory alloc/dealloc prototype */ void *pdp_alloc(int size); void pdp_dealloc(void *); /* This should be the native signed machine word, i.e. 64 bit on 64 bit arch, 32 bit on 32 bit arch. */ typedef int word_t; typedef union { __m64 v; s16 s[4]; // short u16 us[4]; // short word_t w; // only low 32 bits are used } v4_t; typedef union { __m64 v; u32 l[2]; // long } v2_t; #define CLAMP16(x) (((x) > 0x7fff) ? 0x7fff : (((x) < -0x7fff) ? -0x7fff : (x))) // utility stuff inline static s16 float2fixed(float f) { if (f > 1) f = 1; if (f < -1) f = -1; f *= 0x7fff; return (s16)f; } inline static void setvec(s16 *v, float f) { s16 a = float2fixed(f); v[0] = a; v[1] = a; v[2] = a; v[3] = a; } // GCC what? 4.7 ?? #define __builtin_assume_aligned(x,a) x // add two images void pdp_imageproc_add_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image, s16 *image2) { __m64 *im = __builtin_assume_aligned((void*)image, 16); __m64 *im2 = __builtin_assume_aligned((void*)image2, 16); int a, b; unsigned int v, v_max = width * height / 4; for (v = 0; v < v_max; v++) { im[v] = _mm_adds_pi16(im[v], im2[v]); } _mm_empty(); } // mul two images void pdp_imageproc_mul_process(void __attribute__((unused)) *x, u32 width, u32 height, s16 *image, s16 *image2) { __m64 *im = (void*)image; __m64 *im2 = (void*)image2; int a, b; unsigned int v, v_max = width * height / 4; for (v = 0; v < v_max; v++) { im[v] = _mm_mulhi_pi16(im[v], im2[v]); } _mm_empty(); } // mix 2 images #define MIX_SIZE 8*sizeof(s16) void *pdp_imageproc_mix_new(void){return pdp_alloc(MIX_SIZE);} int pdp_imageproc_mix_nb_stackwords(void){return PDP_IMAGEPROC_NB_STACKWORDS(MIX_SIZE);} void pdp_imageproc_mix_delete(void *x) {pdp_dealloc (x);} void pdp_imageproc_mix_setleftgain(void *x, float gain){setvec((s16 *)x, gain);} void pdp_imageproc_mix_setrightgain(void *x, float gain){setvec((s16 *)x + 4, gain);} void pdp_imageproc_mix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { __m64 *g = x; __m64 g_left = g[0]; __m64 g_right = g[1]; /* Do not multiply; copy image to allow for perfect feedback. Do not copy if pointers are the same (same packet). */ if (0 == *((s16*)x)) { if (image != image2) { memcpy(image, image2, width * height * 2); } return; } __m64 *im_left = (void*)image; __m64 *im_right = (void*)image2; int a, b; unsigned int v, v_max = width * height / 4; for (v = 0; v < v_max; v++) { __m64 left = _mm_mulhi_pi16(g_left, im_left[v]); __m64 right = _mm_mulhi_pi16(g_right, im_right[v]); __m64 sum = _mm_adds_pi16(left, right); __m64 sum2 = _mm_adds_pi16(sum, sum); im_left[v] = sum2; } _mm_empty(); } // random mix 2 images void *pdp_imageproc_randmix_new(void){return pdp_alloc(2*sizeof(s32));;} int pdp_imageproc_randmix_nb_stackwords(void) {return PDP_IMAGEPROC_NB_STACKWORDS(2*sizeof(s32));} void pdp_imageproc_randmix_delete(void *x) {pdp_dealloc(x);} void pdp_imageproc_randmix_setthreshold(void *x, float threshold) { s32 *d = (s32 *)x; if (threshold > 1.0f) threshold = 1.0f; if (threshold < 0.0f) threshold = 0.0f; d[0] = float2fixed(threshold); } void pdp_imageproc_randmix_setseed(void *x, float seed) { s32 *d = (s32 *)x; d[1] = float2fixed(seed); } void pdp_imageproc_randmix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { s32 *d = (s32 *)x; u32 i; s16 r; srandom((u32)d[1]); for(i=0; i>15); data += stride; } r = a*d[0] + b*d[1] + c*d[2]; a = data[0]; b = data[stride]; c = d[3]; //border data[0] = (s16)CLAMP16(r>>15); r = a*d[0] + b*d[1] + c*d[2]; data[stride] = (s16)CLAMP16(r>>15); } void pdp_imageproc_conv_process(void *x, u32 width, u32 height, s16 *image) { s32 *d = (s32 *)x; u32 i, j; u32 orientation = d[4]; u32 nbp = d[5]; if (orientation == PDP_IMAGEPROC_CONV_HORIZONTAL){ for(i=0; i>= 15; a2 >>= 15; image[i] = (s16)CLAMP16(a1); image[j] = (s16)CLAMP16(a2); } } // biquad and biquad time typedef struct { s16 ma1[4]; s16 ma2[4]; s16 b0[4]; s16 b1[4]; s16 b2[4]; s16 u0[4]; s16 u1[4]; s16 u0_save[4]; s16 u1_save[4]; u32 nbpasses; u32 direction; } t_bq; void *pdp_imageproc_bq_new(void){return pdp_alloc(sizeof(t_bq));} void pdp_imageproc_bq_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_bq_setcoef(void *x, float *coef) // a0,-a1,-a2,b0,b1,b2,u0,u1 { t_bq *d = (t_bq *)x; float ia0 = 1.0f / coef[0]; /* all coefs are s1.14 fixed point */ /* representing values -2 < x < 2 */ /* so scale down before using the ordinary s0.15 float->fixed routine */ ia0 *= 0.5f; // coef setvec(d->ma1, ia0*coef[1]); setvec(d->ma2, ia0*coef[2]); setvec(d->b0, ia0*coef[3]); setvec(d->b1, ia0*coef[4]); setvec(d->b2, ia0*coef[5]); // state to reset too setvec(d->u0_save, coef[6]); setvec(d->u1_save, coef[7]); } void pdp_imageproc_bq_setnbpasses(void *x, u32 nbpasses){((t_bq *)x)->nbpasses = nbpasses;} void pdp_imageproc_bq_setdirection(void *x, u32 direction){((t_bq *)x)->direction = direction;} void pdp_imageproc_bq_process(void *x, u32 width, u32 height, s16* image); /* DIRECT FORM II BIQUAD y[k] = b0 * x[k] + u1[k-1] u1[k] = b1 * x[k] + u2[k-1] - a1 * y[k] u2[k] = b2 * x[k] - a2 * y[k] MACRO: df2 computes a direct form 2 biquad does not use {mm0-mm3}\ input: == input %mm4 == state 1 %mm5 == state 2 (%esi) == biquad coefs (-a1 -a2 b0 b1 b2) in s1.14 output: == output %mm4 == state 1 %mm5 == state 2 */ struct __attribute__((__packed__)) biquad_coef { __m64 ma1; // -a1 __m64 ma2; // -a2 __m64 b0; __m64 b1; __m64 b2; }; static INLINE void biquad_df2(__m64 *ry, /* output */ __m64 x, /* input */ __m64 *ru1, /* biquad state */ __m64 *ru2, struct biquad_coef *c) { __m64 xb0 = _mm_mulhi_pi16(c->b0, x); __m64 xb1 = _mm_mulhi_pi16(c->b1, x); __m64 u1 = *ru1; __m64 u2 = *ru2; __m64 b0x_plus_u1 = _mm_add_pi16(xb0, u1); // (1) __m64 b1x_plus_u2 = _mm_add_pi16(xb1, u2); // (1) /* 2x saturated add to compensate for mul = x*y/4; coefs are s1.14 fixed point */ __m64 y_div_2 = _mm_adds_pi16(b0x_plus_u1, b0x_plus_u1); __m64 y = _mm_adds_pi16(y_div_2, y_div_2); __m64 ma1y = _mm_mulhi_pi16(c->ma1, y); __m64 ma2y = _mm_mulhi_pi16(c->ma2, y); __m64 b2x = _mm_mulhi_pi16(c->b2, x); __m64 next_u1 = _mm_add_pi16(b1x_plus_u2, ma1y); // (1) __m64 next_u2 = _mm_add_pi16(b2x, ma2y); // (1) *ru1 = next_u1; *ru2 = next_u2; *ry = y; /* (1) This uses non-saturated add for the internal filter nodes. Leaving it in, but this makes sense only in direct form I, so is probably a bug from old MMX code switch from DFI->DFII */ } /* From the old MMX code (edited for clarity). In order to use the 4 line parallel biquad routine on horizontal lines, we need to reorder (rotate or transpose) the matrix, since images are scanline encoded, and we want to work in parallell on 4 lines. Since the 4 lines are independent, it doesnt matter in which order the the vector elements are present. This allows to pick either rotation or transpose to go from horizontal->vertical. Rotations, transposes and flips are part of the 8-element non-abelean group of square isometries consisting of (I) identity (H) horizontal axis mirror (V) vertical axis mirror (T) transpose (diagonal axis mirror) (A) antitranspose (antidiagonal axis mirror) (R1) 90deg anticlockwize rotation (R2) 180deg rotation (R3) 90deg clockwize rotation We basicly have two options: (R1,R3) or (T,A) The choice seems arbitrary.. I opt for flips because they are self-inverting. Only one of T,A needs to be implemented with MMX unpack instructions. The other one can be derived by flips and both input and output. A = V T V = H T H */ /* The routines below use the low=0 to high=3 naming scheme that is used in MMX, i.e. the low word corresponds to the lowest 16 bits in the 64 bit register. Note however that wrt to memory, MMX is little endian, so what looks like a transpose for the above naming scheme, looks like an antitranspose for pixels in memory! Since this is so confusing, to actually implement this it's best to realize that the transform needs to be performed twice, and the L->R and R->L need the opposite transforms. Then if it doesn't look right, flip the signs. */ static INLINE void transpose(__m64 *v0, __m64 *v1, __m64 *v2, __m64 *v3) { __m64 a0_a1_a2_a3 = *v0; __m64 b0_b1_b2_b3 = *v1; __m64 c0_c1_c2_c3 = *v2; __m64 d0_d1_d2_d3 = *v3; __m64 a0_c0_a1_c1 = _mm_unpacklo_pi16(a0_a1_a2_a3, c0_c1_c2_c3); __m64 a2_c2_a3_c3 = _mm_unpackhi_pi16(a0_a1_a2_a3, c0_c1_c2_c3); __m64 b0_d0_b1_d1 = _mm_unpacklo_pi16(b0_b1_b2_b3, d0_d1_d2_d3); __m64 b2_d2_b3_d3 = _mm_unpackhi_pi16(b0_b1_b2_b3, d0_d1_d2_d3); __m64 a0_b0_c0_d0 = _mm_unpacklo_pi16(a0_c0_a1_c1, b0_d0_b1_d1); __m64 a1_b1_c1_d1 = _mm_unpackhi_pi16(a0_c0_a1_c1, b0_d0_b1_d1); __m64 a2_b2_c2_d2 = _mm_unpacklo_pi16(a2_c2_a3_c3, b2_d2_b3_d3); __m64 a3_b3_c3_d3 = _mm_unpackhi_pi16(a2_c2_a3_c3, b2_d2_b3_d3); *v0 = a0_b0_c0_d0; *v1 = a1_b1_c1_d1; *v2 = a2_b2_c2_d2; *v3 = a3_b3_c3_d3; } static INLINE void antitranspose(__m64 *v0, __m64 *v1, __m64 *v2, __m64 *v3) { /* Vertical flip input and output. */ transpose(v3,v2,v1,v0); } static INLINE void biquad_4x4(__m64 *v0, __m64 *v1, __m64 *v2, __m64 *v3, __m64 *ru1, /* biquad state */ __m64 *ru2, struct biquad_coef *c) { biquad_df2(v0, *v0, ru1, ru2, c); biquad_df2(v1, *v1, ru1, ru2, c); biquad_df2(v2, *v2, ru1, ru2, c); biquad_df2(v3, *v3, ru1, ru2, c); } static INLINE void biquad_4x4_t(__m64 *v0, __m64 *v1, __m64 *v2, __m64 *v3, __m64 *ru1, /* biquad state */ __m64 *ru2, struct biquad_coef *c) { transpose(v0, v1, v2, v3); biquad_4x4(v0, v1, v2, v3, ru1, ru2, c); transpose(v0, v1, v2, v3); } static INLINE void biquad_4x4_a(__m64 *v0, __m64 *v1, __m64 *v2, __m64 *v3, __m64 *ru1, /* biquad state */ __m64 *ru2, struct biquad_coef *c) { antitranspose(v0, v1, v2, v3); biquad_4x4(v0, v1, v2, v3, ru1, ru2, c); antitranspose(v0, v1, v2, v3); } static void pixel_biquad_time_s16(s16 *image, // imput plane s16 *state0, // state planes s16 *state1, s16 *coef, int v_max) { __m64 *im = (void*)image; __m64 *pu1 = (void*)state0; __m64 *pu2 = (void*)state1; struct biquad_coef *c = (void*)coef; int v; for (v = 0; v < v_max; v++) { __m64 x = im[v]; __m64 u1 = pu1[v]; __m64 u2 = pu2[v]; __m64 y; biquad_df2(&y, x, &u1, &u2, c); im[v] = y; pu1[v] = u1; pu2[v] = u2; } _mm_empty(); } /* This code performs 4x4 strips in 4 directions: T->B, B->T, L->R, R->L. The loop iteration can probably be simplified a bit; this has a lot of duplication. */ static void pixel_biquad_vertb_s16(s16 *image, int nb_4x4_blocks /* height>>2 */, int stride, s16 *coefs, s16 *state) { stride /= 4; // vector stride __m64 *im = (void*)image; __m64 *s = (void*)state; __m64 u1 = s[0]; __m64 u2 = s[1]; struct biquad_coef *c = (void*)coefs; int block; int stride2 = 2 * stride; int stride3 = 3 * stride; int stride4 = 4 * stride; for (block = 0; block < nb_4x4_blocks; block++) { __m64 v0 = im[0]; __m64 v1 = im[stride]; __m64 v2 = im[stride2]; __m64 v3 = im[stride3]; biquad_4x4(&v0, &v1, &v2, &v3, &u1, &u2, c); im[0] = v0; im[stride] = v1; im[stride2] = v2; im[stride3] = v3; im += stride4; } s[0] = u1; s[1] = u2; _mm_empty(); } static void pixel_biquad_verbt_s16(s16 *image, int nb_4x4_blocks /* height>>2 */, int stride, s16 *coefs, s16 *state) { stride /= 4; // vector stride __m64 *im = (void*)image; __m64 *s = (void*)state; __m64 u1 = s[0]; __m64 u2 = s[1]; struct biquad_coef *c = (void*)coefs; int block; int stride2 = 2 * stride; int stride3 = 3 * stride; int stride4 = 4 * stride; im += (nb_4x4_blocks - 1) * stride4; for (block = 0; block < nb_4x4_blocks; block++) { __m64 v3 = im[0]; __m64 v2 = im[stride]; __m64 v1 = im[stride2]; __m64 v0 = im[stride3]; biquad_4x4(&v0, &v1, &v2, &v3, &u1, &u2, c); im[0] = v3; im[stride] = v2; im[stride2] = v1; im[stride3] = v0; im -= stride4; } s[0] = u1; s[1] = u2; _mm_empty(); } static void pixel_biquad_horlr_s16(s16 *image, int nb_4x4_blocks /* width>>2 */, int stride, s16 *coefs, s16 *state) { stride /= 4; // vector stride __m64 *im = (void*)image; __m64 *s = (void*)state; __m64 u1 = s[0]; __m64 u2 = s[1]; struct biquad_coef *c = (void*)coefs; int block; int stride2 = 2 * stride; int stride3 = 3 * stride; int stride4 = 4 * stride; for (block = 0; block < nb_4x4_blocks; block++) { __m64 v0 = im[0]; __m64 v1 = im[stride]; __m64 v2 = im[stride2]; __m64 v3 = im[stride3]; biquad_4x4_t(&v0, &v1, &v2, &v3, &u1, &u2, c); im[0] = v0; im[stride] = v1; im[stride2] = v2; im[stride3] = v3; im ++; } s[0] = u1; s[1] = u2; _mm_empty(); } static void pixel_biquad_horrl_s16(s16 *image, int nb_4x4_blocks /* width>>2 */, int stride, s16 *coefs, s16 *state) { stride /= 4; // vector stride __m64 *im = (void*)image; __m64 *s = (void*)state; __m64 u1 = s[0]; __m64 u2 = s[1]; struct biquad_coef *c = (void*)coefs; int block; int stride2 = 2 * stride; int stride3 = 3 * stride; int stride4 = 4 * stride; im += nb_4x4_blocks - 1; for (block = 0; block < nb_4x4_blocks; block++) { __m64 v3 = im[0]; __m64 v2 = im[stride]; __m64 v1 = im[stride2]; __m64 v0 = im[stride3]; biquad_4x4_a(&v0, &v1, &v2, &v3, &u1, &u2, c); im[0] = v3; im[stride] = v2; im[stride2] = v1; im[stride3] = v0; im--; } s[0] = u1; s[1] = u2; _mm_empty(); } void pdp_imageproc_bqt_process(void *x, u32 width, u32 height, s16 *image, s16 *state0, s16 *state1) { s16 *d = (s16 *)x; pixel_biquad_time_s16(image, state0, state1, d, (width*height)>>2); } void pdp_imageproc_bq_process(void *x, u32 width, u32 height, s16 *image) { t_bq *d = (t_bq *)x; s16 *c = d->ma1; /* coefs */ s16 *s = d->u0; /* state */ u32 direction = d->direction; u32 nbp = d->nbpasses; unsigned int i,j; /* VERTICAL */ if ((direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM) && (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP)){ for(i=0; i>2, width, c, s); pixel_biquad_verbt_s16(image+i, height>>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM){ for(i=0; i>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP){ for(i=0; i>2, width, c, s); } } } /* HORIZONTAL */ if ((direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT) && (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT)){ for(i=0; i<(width*height); i +=(width<<2)){ for (j=0; j>2, width, c, s); pixel_biquad_horrl_s16(image+i, width>>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT){ for(i=0; i<(width*height); i +=(width<<2)){ for (j=0; j>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT){ for(i=0; i<(width*height); i +=(width<<2)){ for (j=0; j>2, width, c, s); } } } } // produce a random image // note: random number generator can be platform specific // however, it should be seeded. (same seed produces the same result) void *pdp_imageproc_random_new(void){return pdp_alloc(4*sizeof(s16));} void pdp_imageproc_random_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_random_setseed(void *x, float seed) { s16 *d = (s16 *)x; srandom((u32)seed); d[0] = (s16)random(); d[1] = (s16)random(); d[2] = (s16)random(); d[3] = (s16)random(); } void pdp_imageproc_random_process(void *x, u32 width, u32 height, s16 *image) { v4_t one = {.s = {1,1,1,1}}; __m64 lsb_mask = one.v; __m64 *im = (void*)image; __m64 *seed = (void*)x; __m64 state = *seed; unsigned int v, nb_vec = (width * height)>>2; for (v=0; v dst image (src can be == dst) */ typedef struct { t_resample_cid csrc; //cooked src image meta data for bilinear interpolator t_resample_id src; //src image meta t_resample_id dst; //dst image meta } t_resample_cbrd; //Bilinear Resampler Data /* this struct contains high level zoom parameters, all image relative */ typedef struct { float centerx; float centery; float zoomx; float zoomy; float angle; } t_resample_zrd; /* This struct contains all data for the zoom object. Note that this is a flat struct to allow a single pointer register to be used for getting __m64 data. */ typedef struct { t_resample_cbrd cbrd; // Bilinear Resampler Data t_resample_clmd clmd; // Cooked Linear Mapping data t_resample_zrd zrd; // Zoom / Rotate Data } t_resample_zoom_rotate; /* initialize image meta data (dimensions + location) */ static void pdp_imageproc_resample_init_id(t_resample_id *x, u32 offset, s16* image, u32 w, u32 h) { x->lineoffset = offset; x->image = image; x->width = w; x->height = h; } static INLINE void bilin_pixel(t_resample_zoom_rotate *p, word_t *out, __m64 xy_32) { /* Input is in 0.32 image-relative coordinates: xy_32 == [ y(32) : x(32) ] */ /* This routine uses MMX for as long as it is practical, and switches to scalar integer math once data shuffling would get too complicated (Yes, I tried, it's horrible..) */ /* MMX only does signed 16 x 16 -> 16hi | 16lo so we convert here. This means we use a bit of precision which is practice is quite acceptable. I.e. even for 1920x1080, the x sub-pixel resolution is still 32 levels. */ __m64 xy_32_s = _mm_srli_pi32(xy_32, 16 + 1); // reduce precision + convert to signed __m64 xy_16 = _mm_packs_pi32(xy_32_s, xy_32_s); // 2nd arg is dummy: upper 32 bits ignored below /* Split coordinate into integer and factional part. Integer: used for indexing Fractional: used for interpolation. xy_16_index == [ 0 | 0 | y_index | x_index ] xy_16_frac == [ 0 | 0 | y_frac | x_frac ] */ __m64 xy_16_index = _mm_mulhi_pi16(xy_16, p->cbrd.csrc.coord_scale.v); v4_t xy_16_frac = {.v = _mm_mullo_pi16(xy_16, p->cbrd.csrc.coord_scale.v)}; word_t frac_x = xy_16_frac.us[0]; word_t frac_y = xy_16_frac.us[1]; /* The x and y integer pixel coordinates in xy_16_index need to be converted into pixel offsets for image array indexing. Uses 32bit result because 16bit is not enough. */ __m64 offset_16_lo = _mm_mullo_pi16(xy_16_index, p->cbrd.csrc.row_stride_scale.v); __m64 offset_16_hi = _mm_mulhi_pi16(xy_16_index, p->cbrd.csrc.row_stride_scale.v); /* offset_x0_y0 == [ offset_y | x-offset ] */ __m64 offset_x0_y0 = _mm_unpacklo_pi16(offset_16_lo, offset_16_hi); /* Next is to find the offsets of the neighbouring pixels in both x and y directions. First just add the appropriate offsets from config. This leads to offsets that might be past image borders. */ __m64 offset_x1_y0 = _mm_add_pi32(offset_x0_y0, p->cbrd.csrc.inc_x.v); __m64 offset_x0_y1 = _mm_add_pi32(offset_x0_y0, p->cbrd.csrc.inc_y.v); __m64 offset_x1_y1 = _mm_add_pi32(offset_x1_y0, p->cbrd.csrc.inc_y.v); /* Before fetch, set coords to 0 if they are out-of-bounds, effecitively implementing wrap-around addressing. */ s16 *im = p->cbrd.csrc.image; INLINE __m64 wrap_0(__m64 val, __m64 max) { /* Set components to zero when >= max */ __m64 mask = _mm_cmpgt_pi32(max, val); // 0xFFFFFFFF when true __m64 val_out = _mm_and_si64(val, mask); return val_out; } INLINE word_t fetch_pixel(__m64 xy_offset, bool do_wrap) { __m64 wrapped = do_wrap ? wrap_0(xy_offset, p->cbrd.csrc.offset_max.v) : xy_offset; v2_t flat = {.v = _mm_add_pi32(wrapped, _mm_srli_si64(wrapped, 32))}; word_t pixel = im[flat.l[0]]; return pixel; } /* Fetch 2x2 pixel grid to interpolate. */ word_t w_x0_y0 = fetch_pixel(offset_x0_y0, false); word_t w_x1_y0 = fetch_pixel(offset_x1_y0, true); word_t w_x0_y1 = fetch_pixel(offset_x0_y1, true); word_t w_x1_y1 = fetch_pixel(offset_x1_y1, true); /* Perform bilinear interpolation using fractional coordinates. */ word_t w_y0 = w_x0_y0 + (((w_x1_y0 - w_x0_y0) * frac_x) >> 16); word_t w_y1 = w_x0_y1 + (((w_x1_y1 - w_x0_y1) * frac_x) >> 16); word_t w = w_y0 + (((w_y1 - w_y0) * frac_y) >> 16); *out = w; } void pixel_resample_linmap_s16(t_resample_zoom_rotate *z) { int hor,ver; int vector = 0; int hor_max = z->cbrd.dst.width / 4; // vector count int ver_max = z->cbrd.dst.height; // row count /* Vertical increment loop. */ __m64 ver_co_x = z->clmd.origin_x.v; __m64 ver_co_y = z->clmd.origin_y.v; int v = 0; for (ver = 0; ver < ver_max; ver++) { /* Horizontal increment loop */ __m64 co_x = ver_co_x; __m64 co_y = ver_co_y; for (hor = 0; hor < hor_max; hor++) { /* Get coords of 2nd pixel pair. */ __m64 co1_x = _mm_add_pi32(co_x, z->clmd.hor_dx.v); __m64 co1_y = _mm_add_pi32(co_y, z->clmd.hor_dy.v); /* Now we have 4 sets of input coordinates for the 4 pixels in the output data. The format is 0.32 representing a number between 0 and 1. (0 == top/left, 1 = right/bottom) The interpolator however does only one pixel at a time, so these need to be packed to x/y format. */ __m64 xy_0 = _mm_unpacklo_pi32(co_x, co_y); __m64 xy_1 = _mm_unpackhi_pi32(co_x, co_y); __m64 xy_2 = _mm_unpacklo_pi32(co1_x, co1_y); __m64 xy_3 = _mm_unpackhi_pi32(co1_x, co1_y); /* Resample */ v4_t p0; bilin_pixel(z, &p0.w, xy_0); v4_t p1; bilin_pixel(z, &p1.w, xy_1); v4_t p2; bilin_pixel(z, &p2.w, xy_2); v4_t p3; bilin_pixel(z, &p3.w, xy_3); /* Pack & store */ __m64 p02 = _mm_unpacklo_pi16(p0.v, p2.v); __m64 p13 = _mm_unpacklo_pi16(p1.v, p3.v); __m64 p0123 = _mm_unpacklo_pi16(p02, p13); __m64 *im = (void*)z->cbrd.dst.image; im[v++] = p0123; /* Next coord pair. */ co_x = _mm_add_pi32(co1_x, z->clmd.hor_dx.v); co_y = _mm_add_pi32(co1_y, z->clmd.hor_dy.v); } /* Next coord */ ver_co_x = _mm_add_pi32(ver_co_x, z->clmd.ver_dx.v); ver_co_y = _mm_add_pi32(ver_co_y, z->clmd.ver_dy.v); } _mm_empty(); } /* convert image meta data into a cooked format used by the resampler routine */ static void pdp_imageproc_resample_init_cid(t_resample_cid *r, t_resample_id *i) { /* Factor 2 compensates for sign bit shift in s.15 fixed point. */ v4_t coord_scale = {.s = { 2 * (i->width-1), 2 * (i->height-1), 0, 0 }}; /* No scaling factor here since this is proper integer math. */ v4_t row_stride_scale = {.s = { 1, // x coord to offset i->width, // y coord to offset 0, 0}}; /* 32bit maximum offsets. */ v2_t offset_max = {.l = { i->width, i->width * i->height }}; /* 32 bit +1 offsets in x and y directions. */ v2_t inc_x = {.l = { 1, 0}}; v2_t inc_y = {.l = { 0, i->width }}; r->image = i->image; r->coord_scale = coord_scale; r->row_stride_scale = row_stride_scale; r->offset_max = offset_max; r->inc_x = inc_x; r->inc_y = inc_y; } /* convert incremental linear remapping vectors to internal cooked format. Coordinates and increments are 16.16 fixed point. We'll process 2 pixel coords in parallel. */ static void pdp_imageproc_resample_cookedlinmap_init(t_resample_clmd *l, s32 origin_x, s32 origin_y, s32 hor_dx, s32 hor_dy, s32 ver_dx, s32 ver_dy) { typeof(*l) config = { /* 2 Coordinate sets are computed in parallel. */ .origin_x = {.l = {origin_x, origin_x + hor_dx}}, .origin_y = {.l = {origin_y, origin_y + hor_dy}}, .hor_dx = {.l = {hor_dx * 2, hor_dx * 2}}, .hor_dy = {.l = {hor_dy * 2, hor_dy * 2}}, .ver_dx = {.l = {ver_dx, ver_dx}}, .ver_dy = {.l = {ver_dy, ver_dy}}, }; *l = config; } /* convert floating point center and zoom data to incremental linear remapping vectors */ static void pdp_imageproc_resample_clmd_init_from_id_zrd(t_resample_clmd *l, t_resample_id *i, t_resample_zrd *z) { double izx = 1.0f / (z->zoomx); double izy = 1.0f / (z->zoomy); double scale = (double)0xffffffff; double scalew = scale / ((double)(i->width - 1)); double scaleh = scale / ((double)(i->height - 1)); double cx = ((double)z->centerx) * ((double)(i->width - 1)); double cy = ((double)z->centery) * ((double)(i->height - 1)); double angle = z->angle * (-M_PI / 180.0); double c = cos(angle); double s = sin(angle); /* affine x, y mappings in screen coordinates */ double mapx(double x, double y){return cx + izx * ( c * (x-cx) + s * (y-cy));} double mapy(double x, double y){return cy + izy * (-s * (x-cx) + c * (y-cy));} u32 tl_x = (u32)(scalew * mapx(0,0)); u32 tl_y = (u32)(scaleh * mapy(0,0)); u32 row_inc_x = (u32)(scalew * (mapx(1,0)-mapx(0,0))); u32 row_inc_y = (u32)(scaleh * (mapy(1,0)-mapy(0,0))); u32 col_inc_x = (u32)(scalew * (mapx(0,1)-mapx(0,0))); u32 col_inc_y = (u32)(scaleh * (mapy(0,1)-mapy(0,0))); pdp_imageproc_resample_cookedlinmap_init(l, tl_x, tl_y, row_inc_x, row_inc_y, col_inc_x, col_inc_y); } // zoom + rotate void *pdp_imageproc_resample_affinemap_new(void) { t_resample_zoom_rotate *z = (t_resample_zoom_rotate *)pdp_alloc(sizeof(t_resample_zoom_rotate)); z->zrd.centerx = 0.5; z->zrd.centery = 0.5; z->zrd.zoomx = 1.0; z->zrd.zoomy = 1.0; z->zrd.angle = 0.0f; return (void *)z; } void pdp_imageproc_resample_affinemap_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_resample_affinemap_setcenterx(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.centerx = f;} void pdp_imageproc_resample_affinemap_setcentery(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.centery = f;} void pdp_imageproc_resample_affinemap_setzoomx(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.zoomx = f;} void pdp_imageproc_resample_affinemap_setzoomy(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.zoomy = f;} void pdp_imageproc_resample_affinemap_setangle(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.angle = f;} void pdp_imageproc_resample_affinemap_process(void *x, u32 width, u32 height, s16 *srcimage, s16 *dstimage) { t_resample_zoom_rotate *z = (t_resample_zoom_rotate *)x; /* setup resampler image meta data */ pdp_imageproc_resample_init_id(&(z->cbrd.src), width, srcimage, width, height); pdp_imageproc_resample_init_id(&(z->cbrd.dst), width, dstimage, width, height); pdp_imageproc_resample_init_cid(&(z->cbrd.csrc),&(z->cbrd.src)); /* setup linmap data from zoom_rotate parameters */ pdp_imageproc_resample_clmd_init_from_id_zrd(&(z->clmd), &(z->cbrd.src), &(z->zrd)); /* call assembler routine */ pixel_resample_linmap_s16(z); } // polynomials typedef struct { u32 order; u32 nbpasses; s16 coefs[0]; } t_cheby; void *pdp_imageproc_cheby_new(int order) { t_cheby *z; int i; if (order < 2) order = 2; z = (t_cheby *)pdp_alloc(sizeof(t_cheby) + (order + 1) * sizeof(s16[4])); z->order = order; setvec(z->coefs + 0*4, 0); setvec(z->coefs + 1*4, 0.25); for (i=2; i<=order; i++) setvec(z->coefs + i*4, 0); return z; } void pdp_imageproc_cheby_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_cheby_setcoef(void *x, u32 n, float f) { t_cheby *z = (t_cheby *)x; if (n <= z->order){ setvec(z->coefs + n*4, f * 0.25); // coefs are in s2.13 format } } void pdp_imageproc_cheby_setnbpasses(void *x, u32 n){((t_cheby *)x)->nbpasses = n;} static INLINE void pixel_cheby_s16_3plus(s16 *image, int nb_vec, int order_plus_one, s16 *coefs) { /* Coefs are s2.13 fixed point [-4,4] */ __m64 *a = (void*)coefs; __m64 *im = (void*)image; __m64 a0 = a[0]; __m64 FFFF = _mm_cmpeq_pi16(a0, a0); // independent of a0 __m64 one = _mm_srli_pi16(FFFF, 1); // logic shift -> 7FFF __m64 a0_div_2 = _mm_srai_pi16(a0, 1); int n,v; for (v = 0; v < nb_vec; v++) { __m64 x = im[v]; __m64 T1 = x; __m64 T2 = one; __m64 a1x_div_2 = _mm_mulhi_pi16(a[1], x); __m64 acc = _mm_adds_pi16(a1x_div_2, a0_div_2); for (n = 2; n < order_plus_one; n++) { /* Chebyshev recursion: T = 2x T1 - T2 */ __m64 xT1_div_2 = _mm_mulhi_pi16(x, T1); __m64 T2_div_4 = _mm_srai_pi16(T2, 2); __m64 T_div_4 = _mm_subs_pi16(xT1_div_2, T2_div_4); __m64 T_div_2 = _mm_adds_pi16(T_div_4, T_div_4); __m64 T = _mm_adds_pi16(T_div_2, T_div_2); /* Polynomial evaluation */ __m64 aT_div_2 = _mm_mulhi_pi16(a[n], T); acc = _mm_adds_pi16(acc, aT_div_2); /* Recursion state update */ T2 = T1; T1 = T; } /* Compensate for overall 1/8 factor. */ __m64 acc_2 = _mm_adds_pi16(acc, acc); __m64 acc_4 = _mm_adds_pi16(acc_2, acc_2); __m64 acc_8 = _mm_adds_pi16(acc_4, acc_4); im[v] = acc_8; } _mm_empty(); } void pdp_imageproc_cheby_process(void *x, u32 width, u32 height, s16 *image) { t_cheby *z = (t_cheby *)x; u32 iterations = z->nbpasses; u32 i,j; for (j=0; j < (height*width); j += width) { for (i=0; i>2, z->order+1, z->coefs); } } //pixel_cheby_s16_3plus(image, (width*height)>>2, z->order+1, z->coefs); } pdp-0.14.1+darcs20180201/system/image/pdp_imageproc_mmx.c000066400000000000000000000432271266045153600225520ustar00rootroot00000000000000/* * Pure Data Packet. c wrapper for mmx image processing routines. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this is a c wrapper around platform specific (mmx) code */ #include #include #include "pdp_mmx.h" #include "pdp_imageproc.h" /* pdp memory alloc/dealloc prototype */ void *pdp_alloc(int size); void pdp_dealloc(void *); // utility stuff inline static s16 float2fixed(float f) { if (f > 1) f = 1; if (f < -1) f = -1; f *= 0x7fff; return (s16)f; } inline static void setvec(s16 *v, float f) { s16 a = float2fixed(f); v[0] = a; v[1] = a; v[2] = a; v[3] = a; } // add two images void pdp_imageproc_add_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { unsigned int totalnbpixels = width * height; pixel_add_s16(image, image2, totalnbpixels>>2); } // mul two images void pdp_imageproc_mul_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { unsigned int totalnbpixels = width * height; pixel_mul_s16(image, image2, totalnbpixels>>2); } // mix 2 images #define MIX_SIZE 8*sizeof(s16) void *pdp_imageproc_mix_new(void){return pdp_alloc(MIX_SIZE);} int pdp_imageproc_mix_nb_stackwords(void){return PDP_IMAGEPROC_NB_STACKWORDS(MIX_SIZE);} void pdp_imageproc_mix_delete(void *x) {pdp_dealloc (x);} void pdp_imageproc_mix_setleftgain(void *x, float gain){setvec((s16 *)x, gain);} void pdp_imageproc_mix_setrightgain(void *x, float gain){setvec((s16 *)x + 4, gain);} void pdp_imageproc_mix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { s16 *d = (s16 *)x; u32 i; if (*d == 0) for(i=0; i>2, d, d+4); } } // random mix 2 images #define RANDMIX_SIZE 8*sizeof(s16) void *pdp_imageproc_randmix_new(void){return pdp_alloc(RANDMIX_SIZE);} int pdp_imageproc_randmix_nb_stackwords(void) {return PDP_IMAGEPROC_NB_STACKWORDS(RANDMIX_SIZE);} void pdp_imageproc_randmix_delete(void *x) {pdp_dealloc (x);} void pdp_imageproc_randmix_setthreshold(void *x, float threshold){setvec((s16 *)x, 2*threshold-1);} void pdp_imageproc_randmix_setseed(void *x, float seed) { s16 *d = (s16 *)x; srandom((u32)seed); d[4] = (s16)random(); d[5] = (s16)random(); d[6] = (s16)random(); d[7] = (s16)random(); } void pdp_imageproc_randmix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { s16 *d = (s16 *)x; unsigned int totalnbpixels = width * height; pixel_randmix_s16(image, image2, totalnbpixels>>2, d+4, d); } // 3x1 or 1x3 in place convolution // orientation typedef struct { s16 min1[4]; s16 zero[4]; s16 plus1[4]; s16 border[4]; u32 orientation; u32 nbpasses; } t_conv; void *pdp_imageproc_conv_new(void){return(pdp_alloc(sizeof(t_conv)));} void pdp_imageproc_conv_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_conv_setmin1(void *x, float val){setvec(((t_conv *)x)->min1, val);} void pdp_imageproc_conv_setzero(void *x, float val){setvec(((t_conv *)x)->zero, val);} void pdp_imageproc_conv_setplus1(void *x, float val){setvec(((t_conv *)x)->plus1, val);} void pdp_imageproc_conv_setbordercolor(void *x, float val){setvec(((t_conv *)x)->border, val);} void pdp_imageproc_conv_setorientation(void *x, u32 val){((t_conv *)x)->orientation = val;} void pdp_imageproc_conv_setnbpasses(void *x, u32 val){((t_conv *)x)->nbpasses = val;} void pdp_imageproc_conv_process(void *x, u32 width, u32 height, s16 *image) { t_conv *d = (t_conv *)x; u32 orientation = d->orientation; u32 nbp = d->nbpasses; u32 i,j; if (orientation == PDP_IMAGEPROC_CONV_HORIZONTAL) { for(i=0; i>2, d->border, d->min1); } else { for (j=0; jborder, d->min1); } } // apply a gain to an image void *pdp_imageproc_gain_new(void){return(pdp_alloc(8*sizeof(s16)));} void pdp_imageproc_gain_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_gain_setgain(void *x, float gain) { /* convert float to s16 + shift */ s16 *d = (s16 *)x; s16 g; int i; float sign; int shift = 0; sign = (gain < 0) ? -1 : 1; gain *= sign; /* max shift = 16 */ for(i=0; i<=16; i++){ if (gain < 0x4000){ gain *= 2; shift++; } else break; } gain *= sign; g = (s16) gain; //g = 0x4000; //shift = 14; d[0]=g; d[1]=g; d[2]=g; d[3]=g; d[4]=(s16)shift; d[5]=0; d[6]=0; d[7]=0; } void pdp_imageproc_gain_process(void *x, u32 width, u32 height, s16 *image) { s16 *d = (s16 *)x; pixel_gain_s16(image, (width*height)>>2, d, (u64 *)(d+4)); } // colour rotation for 2 colour planes void *pdp_imageproc_crot2d_new(void){return pdp_alloc(16*sizeof(s16));} void pdp_imageproc_crot2d_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_crot2d_setmatrix(void *x, float *matrix) { s16 *d = (s16 *)x; setvec(d, matrix[0]); setvec(d+4, matrix[1]); setvec(d+8, matrix[2]); setvec(d+12, matrix[3]); } void pdp_imageproc_crot2d_process(void *x, s16 *image, u32 width, u32 height) { s16 *d = (s16 *)x; pixel_crot2d_s16(image, width*height >> 2, d); } // biquad and biquad time typedef struct { s16 ma1[4]; s16 ma2[4]; s16 b0[4]; s16 b1[4]; s16 b2[4]; s16 u0[4]; s16 u1[4]; s16 u0_save[4]; s16 u1_save[4]; u32 nbpasses; u32 direction; } t_bq; void *pdp_imageproc_bq_new(void){return pdp_alloc(sizeof(t_bq));} void pdp_imageproc_bq_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_bq_setcoef(void *x, float *coef) // a0,-a1,-a2,b0,b1,b2,u0,u1 { t_bq *d = (t_bq *)x; float ia0 = 1.0f / coef[0]; /* all coefs are s1.14 fixed point */ /* representing values -2 < x < 2 */ /* so scale down before using the ordinary s0.15 float->fixed routine */ ia0 *= 0.5f; // coef setvec(d->ma1, ia0*coef[1]); setvec(d->ma2, ia0*coef[2]); setvec(d->b0, ia0*coef[3]); setvec(d->b1, ia0*coef[4]); setvec(d->b2, ia0*coef[5]); // state to reset too setvec(d->u0_save, coef[6]); setvec(d->u1_save, coef[7]); } void pdp_imageproc_bq_setnbpasses(void *x, u32 nbpasses){((t_bq *)x)->nbpasses = nbpasses;} void pdp_imageproc_bq_setdirection(void *x, u32 direction){((t_bq *)x)->direction = direction;} void pdp_imageproc_bq_process(void *x, u32 width, u32 height, s16* image); void pdp_imageproc_bqt_process(void *x, u32 width, u32 height, s16 *image, s16 *state0, s16 *state1) { s16 *d = (s16 *)x; pixel_biquad_time_s16(image, state0, state1, d, (width*height)>>2); } void pdp_imageproc_bq_process(void *x, u32 width, u32 height, s16 *image) { t_bq *d = (t_bq *)x; s16 *c = d->ma1; /* coefs */ s16 *s = d->u0; /* state */ u32 direction = d->direction; u32 nbp = d->nbpasses; unsigned int i,j; /* VERTICAL */ if ((direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM) && (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP)){ for(i=0; i>2, width, c, s); pixel_biquad_verbt_s16(image+i, height>>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM){ for(i=0; i>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP){ for(i=0; i>2, width, c, s); } } } /* HORIZONTAL */ if ((direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT) && (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT)){ for(i=0; i<(width*height); i +=(width<<2)){ for (j=0; j>2, width, c, s); pixel_biquad_horrl_s16(image+i, width>>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT){ for(i=0; i<(width*height); i +=(width<<2)){ for (j=0; j>2, width, c, s); } } } else if (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT){ for(i=0; i<(width*height); i +=(width<<2)){ for (j=0; j>2, width, c, s); } } } } // produce a random image // note: random number generator can be platform specific // however, it should be seeded. (same seed produces the same result) void *pdp_imageproc_random_new(void){return pdp_alloc(4*sizeof(s16));} void pdp_imageproc_random_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_random_setseed(void *x, float seed) { s16 *d = (s16 *)x; srandom((u32)seed); d[0] = (s16)random(); d[1] = (s16)random(); d[2] = (s16)random(); d[3] = (s16)random(); } void pdp_imageproc_random_process(void *x, u32 width, u32 height, s16 *image) { s16 *d = (s16 *)x; unsigned int totalnbpixels = width * height; pixel_rand_s16(image, totalnbpixels>>2, d); } /* resampling stuff this is quite a zoo of data structures the major point is this: the resampler mmx code is shared for all resampling code it uses data specified in t_resample_cbrd (Cooked Bilinear Resampler Data) then the there are several feeder algorithms. one is the linear mapper. it's data is specified in t_resample_clrd (Cooked Linear Remapper Data) for each feeder algorithm, there are several high level algorithms. like zoom, rotate, ... */ typedef struct { u32 lineoffset; s16 *image; u32 width; u32 height; } t_resample_id; // Image Data /* initialize image meta data (dimensions + location) */ static void pdp_imageproc_resample_init_id(t_resample_id *x, u32 offset, s16* image, u32 w, u32 h) { x->lineoffset = offset; x->image = image; x->width = w; x->height = h; } // mmx resampling source image resampling data + coefs typedef struct { // vector data for resampling routine (resampling computation) u8 reserved[0x60]; //internal data s16 *address[2]; //64 bit splatted offset address s16 twowidthm1[4]; //64 bit splatted 2*(width-1) s16 twoheightm1[4]; //64 bit splatted 2*(height-1) s16 lineoffset[4]; //64 bit splatted line offset in pixels } t_resample_cid; // Cooked Image Data /* convert image meta data into a cooked format used by the resampler routine */ static void pdp_imageproc_resample_init_cid(t_resample_cid *r, t_resample_id *i) { u32 twowm1 = (i->width-1)<<1; u32 twohm1 = (i->height-1)<<1; r->address[0] = i->image; r->address[1] = i->image; r->twowidthm1[0] = twowm1; r->twowidthm1[1] = twowm1; r->twowidthm1[2] = twowm1; r->twowidthm1[3] = twowm1; r->twoheightm1[0] = twohm1; r->twoheightm1[1] = twohm1; r->twoheightm1[2] = twohm1; r->twoheightm1[3] = twohm1; r->lineoffset[0] = i->lineoffset; r->lineoffset[1] = i->lineoffset; r->lineoffset[2] = i->lineoffset; r->lineoffset[3] = i->lineoffset; } // linear mapping data struct (zoom, scale, rotate, shear, ...) typedef struct { s32 rowstatex[2]; // row state x coord s32 rowstatey[2]; // row state y coord s32 colstatex[2]; // column state x coord s32 colstatey[2]; // column state y coord s32 rowincx[2]; // row inc vector x coord s32 rowincy[2]; // row inc vector y coord s32 colincx[2]; // column inc vector x coord s32 colincy[2]; // column inc vector y coord } t_resample_clmd; // Cooked Linear Mapping Data /* convert incremental linear remapping vectors to internal cooked format */ static void pdp_imageproc_resample_cookedlinmap_init(t_resample_clmd *l, s32 sx, s32 sy, s32 rix, s32 riy, s32 cix, s32 ciy) { l->colstatex[0] = l->rowstatex[0] = sx; l->colstatex[1] = l->rowstatex[1] = sx + rix; l->colstatey[0] = l->rowstatey[0] = sy; l->colstatey[1] = l->rowstatey[1] = sy + riy; l->rowincx[0] = rix << 1; l->rowincx[1] = rix << 1; l->rowincy[0] = riy << 1; l->rowincy[1] = riy << 1; l->colincx[0] = cix; l->colincx[1] = cix; l->colincy[0] = ciy; l->colincy[1] = ciy; } /* this struct contains all the data necessary for bilin interpolation from src -> dst image (src can be == dst) */ typedef struct { t_resample_cid csrc; //cooked src image meta data for bilinear interpolator t_resample_id src; //src image meta t_resample_id dst; //dst image meta } t_resample_cbrd; //Bilinear Resampler Data /* this struct contains high level zoom parameters, all image relative */ typedef struct { float centerx; float centery; float zoomx; float zoomy; float angle; } t_resample_zrd; /* convert floating point center and zoom data to incremental linear remapping vectors */ static void pdp_imageproc_resample_clmd_init_from_id_zrd(t_resample_clmd *l, t_resample_id *i, t_resample_zrd *z) { double izx = 1.0f / (z->zoomx); double izy = 1.0f / (z->zoomy); double scale = (double)0xffffffff; double scalew = scale / ((double)(i->width - 1)); double scaleh = scale / ((double)(i->height - 1)); double cx = ((double)z->centerx) * ((double)(i->width - 1)); double cy = ((double)z->centery) * ((double)(i->height - 1)); double angle = z->angle * (-M_PI / 180.0); double c = cos(angle); double s = sin(angle); /* affine x, y mappings in screen coordinates */ double mapx(double x, double y){return cx + izx * ( c * (x-cx) + s * (y-cy));} double mapy(double x, double y){return cy + izy * (-s * (x-cx) + c * (y-cy));} u32 tl_x = (u32)(scalew * mapx(0,0)); u32 tl_y = (u32)(scaleh * mapy(0,0)); u32 row_inc_x = (u32)(scalew * (mapx(1,0)-mapx(0,0))); u32 row_inc_y = (u32)(scaleh * (mapy(1,0)-mapy(0,0))); u32 col_inc_x = (u32)(scalew * (mapx(0,1)-mapx(0,0))); u32 col_inc_y = (u32)(scaleh * (mapy(0,1)-mapy(0,0))); pdp_imageproc_resample_cookedlinmap_init(l, tl_x, tl_y, row_inc_x, row_inc_y, col_inc_x, col_inc_y); } /* this struct contains all data for the zoom object */ typedef struct { t_resample_cbrd cbrd; // Bilinear Resampler Data t_resample_clmd clmd; // Cooked Linear Mapping data t_resample_zrd zrd; // Zoom / Rotate Data } t_resample_zoom_rotate; // zoom + rotate void *pdp_imageproc_resample_affinemap_new(void) { t_resample_zoom_rotate *z = (t_resample_zoom_rotate *)pdp_alloc(sizeof(t_resample_zoom_rotate)); z->zrd.centerx = 0.5; z->zrd.centery = 0.5; z->zrd.zoomx = 1.0; z->zrd.zoomy = 1.0; z->zrd.angle = 0.0f; return (void *)z; } void pdp_imageproc_resample_affinemap_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_resample_affinemap_setcenterx(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.centerx = f;} void pdp_imageproc_resample_affinemap_setcentery(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.centery = f;} void pdp_imageproc_resample_affinemap_setzoomx(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.zoomx = f;} void pdp_imageproc_resample_affinemap_setzoomy(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.zoomy = f;} void pdp_imageproc_resample_affinemap_setangle(void *x, float f){((t_resample_zoom_rotate *)x)->zrd.angle = f;} void pdp_imageproc_resample_affinemap_process(void *x, u32 width, u32 height, s16 *srcimage, s16 *dstimage) { t_resample_zoom_rotate *z = (t_resample_zoom_rotate *)x; /* setup resampler image meta data */ pdp_imageproc_resample_init_id(&(z->cbrd.src), width, srcimage, width, height); pdp_imageproc_resample_init_id(&(z->cbrd.dst), width, dstimage, width, height); pdp_imageproc_resample_init_cid(&(z->cbrd.csrc),&(z->cbrd.src)); /* setup linmap data from zoom_rotate parameters */ pdp_imageproc_resample_clmd_init_from_id_zrd(&(z->clmd), &(z->cbrd.src), &(z->zrd)); /* call assembler routine */ pixel_resample_linmap_s16(z); } // polynomials typedef struct { u32 order; u32 nbpasses; s16 coefs[0]; } t_cheby; void *pdp_imageproc_cheby_new(int order) { t_cheby *z; int i; if (order < 2) order = 2; z = (t_cheby *)pdp_alloc(sizeof(t_cheby) + (order + 1) * sizeof(s16[4])); z->order = order; setvec(z->coefs + 0*4, 0); setvec(z->coefs + 1*4, 0.25); for (i=2; i<=order; i++) setvec(z->coefs + i*4, 0); return z; } void pdp_imageproc_cheby_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_cheby_setcoef(void *x, u32 n, float f) { t_cheby *z = (t_cheby *)x; if (n <= z->order){ setvec(z->coefs + n*4, f * 0.25); // coefs are in s2.13 format } } void pdp_imageproc_cheby_setnbpasses(void *x, u32 n){((t_cheby *)x)->nbpasses = n;} void pdp_imageproc_cheby_process(void *x, u32 width, u32 height, s16 *image) { t_cheby *z = (t_cheby *)x; u32 iterations = z->nbpasses; u32 i,j; for (j=0; j < (height*width); j += width) for (i=0; i>2, z->order+1, z->coefs); //pixel_cheby_s16_3plus(image, (width*height)>>2, z->order+1, z->coefs); } pdp-0.14.1+darcs20180201/system/image/pdp_imageproc_portable.c000066400000000000000000000401461266045153600235560ustar00rootroot00000000000000/* * Pure Data Packet. portable image processing routines. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include "pdp_imageproc.h" /* pdp memory alloc/dealloc prototype */ void *pdp_alloc(int size); void pdp_dealloc(void *); // utility stuff inline static s32 float2fixed(float f) { if (f > 1) f = 1; if (f < -1) f = -1; f *= 0x7fff; return (s32)f; } #define CLAMP16(x) (((x) > 0x7fff) ? 0x7fff : (((x) < -0x7fff) ? -0x7fff : (x))) // add two images void pdp_imageproc_add_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { int a, b; unsigned int i; for (i=0; i>15); } } // mix 2 images void *pdp_imageproc_mix_new(void){return pdp_alloc(2*sizeof(s32));} int pdp_imageproc_mix_nb_stackwords(void) {return PDP_IMAGEPROC_NB_STACKWORDS(2*sizeof(s32));} void pdp_imageproc_mix_delete(void *x) {pdp_dealloc (x);} void pdp_imageproc_mix_setleftgain(void *x, float gain) { s32 *d = (s32 *)x; d[0] = float2fixed(gain); } void pdp_imageproc_mix_setrightgain(void *x, float gain) { s32 *d = (s32 *)x; d[1] = float2fixed(gain); } void pdp_imageproc_mix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { s32 *d = (s32 *)x; u32 i; s32 a,b; if (*d == 0) for(i=0; i> 15; image[i] = (s16)CLAMP16(a); } } // random mix 2 images void *pdp_imageproc_randmix_new(void){return pdp_alloc(2*sizeof(s32));;} int pdp_imageproc_randmix_nb_stackwords(void) {return PDP_IMAGEPROC_NB_STACKWORDS(2*sizeof(s32));} void pdp_imageproc_randmix_delete(void *x) {pdp_dealloc(x);} void pdp_imageproc_randmix_setthreshold(void *x, float threshold) { s32 *d = (s32 *)x; if (threshold > 1.0f) threshold = 1.0f; if (threshold < 0.0f) threshold = 0.0f; d[0] = float2fixed(threshold); } void pdp_imageproc_randmix_setseed(void *x, float seed) { s32 *d = (s32 *)x; d[1] = float2fixed(seed); } void pdp_imageproc_randmix_process(void *x, u32 width, u32 height, s16 *image, s16 *image2) { s32 *d = (s32 *)x; u32 i; s16 r; srandom((u32)d[1]); for(i=0; i>15); data += stride; } r = a*d[0] + b*d[1] + c*d[2]; a = data[0]; b = data[stride]; c = d[3]; //border data[0] = (s16)CLAMP16(r>>15); r = a*d[0] + b*d[1] + c*d[2]; data[stride] = (s16)CLAMP16(r>>15); } void pdp_imageproc_conv_process(void *x, u32 width, u32 height, s16 *image) { s32 *d = (s32 *)x; u32 i, j; u32 orientation = d[4]; u32 nbp = d[5]; if (orientation == PDP_IMAGEPROC_CONV_HORIZONTAL){ for(i=0; i> d[1])); } } // colour rotation for 2 colour planes void *pdp_imageproc_crot2d_new(void){return pdp_alloc(4*sizeof(s32));} void pdp_imageproc_crot2d_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_crot2d_setmatrix(void *x, float *matrix) { s32 *d = (s32 *)x; d[0] = float2fixed(matrix[0]); d[1] = float2fixed(matrix[1]); d[2] = float2fixed(matrix[2]); d[3] = float2fixed(matrix[3]); } void pdp_imageproc_crot2d_process(void *x, s16 *image, u32 width, u32 height) { s32 *d = (s32 *)x; u32 i,j; s32 a1,a2,c1,c2; for(i=0, j=width*height; i>= 15; a2 >>= 15; image[i] = (s16)CLAMP16(a1); image[j] = (s16)CLAMP16(a2); } } // biquad and biquad time typedef struct { s32 ma1; s32 ma2; s32 b0; s32 b1; s32 b2; s32 u0; s32 u1; s32 u0_save; s32 u1_save; u32 nbpasses; u32 direction; } t_bq; void *pdp_imageproc_bq_new(void){return pdp_alloc(sizeof(t_bq));} void pdp_imageproc_bq_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_bq_setnbpasses(void *x, u32 i){((t_bq *)x)->nbpasses = i;} void pdp_imageproc_bq_setdirection(void *x, u32 i){((t_bq *)x)->direction = i;} void pdp_imageproc_bq_setcoef(void *x, float *coef) // a0,-a1,-a2,b0,b1,b2,u0,u1 { s32 *d = (s32 *)x; float ia0 = 1.0f / coef[0]; /* all coefs are s1.14 fixed point */ /* representing values -2 < x < 2 */ /* so scale down before using the ordinary s0.15 float->fixed routine */ ia0 *= 0.5f; // coef d[0] = float2fixed(ia0*coef[1]); // -a1 d[1] = float2fixed(ia0*coef[2]); // -a2 d[2] = float2fixed(ia0*coef[3]); // b0 d[3] = float2fixed(ia0*coef[4]); // b1 d[4] = float2fixed(ia0*coef[5]); // b2 // state to reset too d[5] = float2fixed(coef[6]); d[6] = float2fixed(coef[7]); } #define A1 d[0] #define A2 d[1] #define B0 d[2] #define B1 d[3] #define B2 d[4] /* # DIRECT FORM II BIQUAD (from pixel_biquad_s16.s) # # y[k] = b0 * x[k] + u1[k-1] # u1[k] = b1 * x[k] + u2[k-1] - a1 * y[k] # u2[k] = b2 * x[k] - a2 * y[k] */ /* remark A1 and A2 are already negated) */ static inline void pdp_imageproc_bq_scanline(void *x, s16 *data, u32 count, s32 stride) { s32 *d = (s32 *)x; s32 u1,u2, xx, yy; u32 i; u1 = d[7]; u2 = d[8]; for(i = 0; i < count; i++){ xx = (s32)data[0]; yy = ((B0 * xx)>>14) + u1; u1 = ((B1 * xx)>>14) + u2 + ((A1 * yy)>>14); u2 = ((B2 * xx)>>14) + ((A2 * yy)>>14); data[0] = (s16)CLAMP16(yy); data += stride; } d[7] = u1; d[8] = u2; } void pdp_imageproc_bqt_process(void *x, u32 width, u32 height, s16 *image, s16 *state1, s16 *state2) { s32 *d = (s32 *)x; u32 i; s32 u1, u2, xx, yy; for (i=0; i>14) + u1; u1 = ((B1 * xx)>>14) + u2 + ((A1 * yy)>>14); u2 = ((B2 * xx)>>14) + ((A2 * yy)>>14); image[i] = (s16)CLAMP16(yy); state1[i] = (s16)CLAMP16(u1); state2[i] = (s16)CLAMP16(u2); } } void pdp_imageproc_bq_process(void *x, u32 width, u32 height, s16 *data) { s32 *d = (s32 *)x; u32 nbp = d[9]; u32 direction = d[10]; unsigned int i,j, offset; /* VERTICAL */ offset = (height-1)*width; if ((direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM) && (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP)){ for(i=0; iB pdp_imageproc_bq_scanline(x, data+offset+i, height, -width); //B->T } } } else if (direction & PDP_IMAGEPROC_BIQUAD_TOP2BOTTOM){ for(i=0; iB } } } else if (direction & PDP_IMAGEPROC_BIQUAD_BOTTOM2TOP){ for(i=0; iT } } } /* HORIZONTAL */ offset = width-1; if ((direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT) && (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT)){ for(i=0; i<(width*height); i += width){ for (j=0; jR pdp_imageproc_bq_scanline(x, data+offset+i, width, -1); //R->L } } } else if (direction & PDP_IMAGEPROC_BIQUAD_LEFT2RIGHT){ for(i=0; i<(width*height); i += width){ for (j=0; jR } } } else if (direction & PDP_IMAGEPROC_BIQUAD_RIGHT2LEFT){ for(i=0; i<(width*height); i += width){ for (j=0; jL } } } } // produce a random image // note: random number generator can be platform specific // however, it should be seeded. (same seed produces the same result) void *pdp_imageproc_random_new(void){return pdp_alloc(sizeof(s32));} void pdp_imageproc_random_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_random_setseed(void *x, float seed) { float *f = (float *)x; u32 *d = (u32 *)x; f[0] = seed; srandom(d[0]); } void pdp_imageproc_random_process(void *x, u32 width, u32 height, short int *image) { u32 *d = (u32 *)x; u32 i; s32 r; srandom(d[0]); for (i=0; i<(width*height); i++) { r = random(); image[i] = r; } d[0] = random(); } /* resampling code */ // zoom + rotate /* bilinear resampling core routine */ /* virtual coordinates are the lowest 16 bits in virt_x and virt_y*/ static inline s32 pdp_resample_bilin(s16 *image, s32 width, s32 height, s32 virt_x, s32 virt_y) { s32 fp_x, fp_y, frac_x, frac_y, f, offset, r_1, r_2; //virt_x &= 0xffff; //virt_y &= 0xffff; fp_x = virt_x * (width - 1); fp_y = virt_y * (height - 1); frac_x = fp_x & (0xffff); frac_y = fp_y & (0xffff); offset = (fp_x >> 16) + (fp_y >> 16) * width; image += offset; f = 0x10000 - frac_x; r_1 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16; image += width; r_2 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16; f = 0x10000 - frac_y; return ((f * r_1 + frac_y * r_2)>>16); } typedef struct { float centerx; float centery; float zoomx; float zoomy; float angle; } t_affine_map; void *pdp_imageproc_resample_affinemap_new(void) { t_affine_map *a = (t_affine_map *)pdp_alloc(sizeof(t_affine_map)); a->centerx = 0.5; a->centery = 0.5; a->zoomx = 1.0; a->zoomy = 1.0; a->angle = 0.0f; return (void *)a; } void pdp_imageproc_resample_affinemap_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_resample_affinemap_setcenterx(void *x, float f){((t_affine_map *)x)->centerx = f;} void pdp_imageproc_resample_affinemap_setcentery(void *x, float f){((t_affine_map *)x)->centery = f;} void pdp_imageproc_resample_affinemap_setzoomx(void *x, float f){((t_affine_map *)x)->zoomx = f;} void pdp_imageproc_resample_affinemap_setzoomy(void *x, float f){((t_affine_map *)x)->zoomy = f;} void pdp_imageproc_resample_affinemap_setangle(void *x, float f){((t_affine_map *)x)->angle = f;} void pdp_imageproc_resample_affinemap_process(void *x, u32 width, u32 height, s16 *srcimage, s16 *dstimage) { t_affine_map *a = (t_affine_map *)x; double izx = 1.0f / (a->zoomx); double izy = 1.0f / (a->zoomy); double scale = (double)0xffffffff; double scalew = scale / ((double)(width - 1)); double scaleh = scale / ((double)(height - 1)); double cx = ((double)a->centerx) * ((double)(width - 1)); double cy = ((double)a->centery) * ((double)(height - 1)); double angle = a->angle * (-M_PI / 180.0); double c = cos(angle); double s = sin(angle); /* affine x, y mappings in screen coordinates */ double mapx(double _x, double _y){return cx + izx * ( c * (_x-cx) + s * (_y-cy));} double mapy(double _x, double _y){return cy + izy * (-s * (_x-cx) + c * (_y-cy));} u32 colstate_x = (u32)(scalew * mapx(0,0)); u32 colstate_y = (u32)(scaleh * mapy(0,0)); u32 rowstate_x = colstate_x; u32 rowstate_y = colstate_y; u32 row_inc_x = (u32)(scalew * (mapx(1,0)-mapx(0,0))); u32 row_inc_y = (u32)(scaleh * (mapy(1,0)-mapy(0,0))); u32 col_inc_x = (u32)(scalew * (mapx(0,1)-mapx(0,0))); u32 col_inc_y = (u32)(scaleh * (mapy(0,1)-mapy(0,0))); u32 i,j; for (j=0; j>16, rowstate_y>>16); rowstate_x += row_inc_x; rowstate_y += row_inc_y; } colstate_x += col_inc_x; colstate_y += col_inc_y; rowstate_x = colstate_x; rowstate_y = colstate_y; } } // polynomials typedef struct { u32 order; u32 nbpasses; s32 coefs[0]; } t_cheby; void *pdp_imageproc_cheby_new(int order) { t_cheby *z; int i; if (order < 2) order = 2; z = (t_cheby *)pdp_alloc(sizeof(t_cheby) + (order + 1) * sizeof(s32)); z->order = order; z->coefs[0] = 0; z->coefs[1] = 0x7fff; for (i=2; i<=order; i++) z->coefs[i] = 0; return z; } void pdp_imageproc_cheby_delete(void *x){pdp_dealloc(x);} void pdp_imageproc_cheby_setnbpasses(void *x, u32 n){((t_cheby *)x)->nbpasses = n;} void pdp_imageproc_cheby_setcoef(void *x, u32 n, float f) { t_cheby *z = (t_cheby *)x; if (n <= z->order){ z->coefs[n] = (s32)(f * 32767.0f); // coefs are in s16.15 format } } void pdp_imageproc_cheby_process(void *x, u32 width, u32 height, s16 *image) { t_cheby *z = (t_cheby *)x; u32 iterations = z->nbpasses; u32 i,j,k; s32 *c = z->coefs; for (j=0; j < (height*width); j++){ s32 acc = (s32)image[j]; for (i=0; i>15); for (k=2; k<=z->order; k++){ t = ((T1*in)>>14) - T2; /* T_n = 2 x T_n-1 - T_n-2 */ T2 = T1; T1 = t; acc += ((c[k] * t)>>15); } } image[j] = (s16)(CLAMP16(acc)); } } pdp-0.14.1+darcs20180201/system/image/pdp_llconv.c000066400000000000000000000400371266045153600212140ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : low level format conversion code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains low level image conversion code nominated as "the ugliest part of pdp" some code is mmx, most is not. */ /* seem's there's some confusion between rgb and bgr formats. not that it matters much which is supposed to be the "real" rgb or bgr, but opengl and v4l seem to disagree on endianness grounds.. */ #include "pdp_llconv.h" #include "pdp_mmx.h" #include "pdp_post.h" /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif #define CLAMP8(x) (((x)<0) ? 0 : ((x>255)? 255 : (x))) #define CLAMP16(x) (((x)<-0x7fff) ? -0x7fff : ((x>0x7fff) ? 0x7fff : (x))) #define FP(x) ((int)(((float)(x)) * 256.0f)) #define CLAMP CLAMP8 /* some prototypes for functions defined elsewhere */ void llconv_yvu_planar_s16u8(short int *src, unsigned char *dst, unsigned int nbpixels); void llconv_yuv_planar_u8s16(unsigned char* source, short int *dest, int nbpixels); void llconv_grey_s16u8(short int *src, unsigned char *dst, unsigned int nbpixels); void llconv_yvu_planar_u8s16(unsigned char* source, short int *dest, int nbpixels); static inline int rgb2y(int r, int g, int b) { return (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); } static inline int rgb2v(int r, int g, int b) { return (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b) + FP(128); } static inline int rgb2u(int r, int g, int b) { return -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b) + FP(128); } /* swap top to bottom */ static inline void _exchange_row(char *row1, char *row2, int size) { int mask = ~((unsigned int)sizeof(int)-1); int *irow1 = (int *)row1; int *irow2 = (int *)row2; /* transfer words */ while (size & mask){ int tmp = *irow1; *irow1++ = *irow2; *irow2++ = tmp; size -= sizeof(int); } row1 = (char *)irow1; row2 = (char *)irow2; /* transfer rest bytes */ while (size){ int tmp = *row1; *row1++ = *row2; *row2++ = tmp; size--; } } void pdp_llconv_flip_top_bottom(char *data, int width, int height, int pixelsize) { int linesize = width * pixelsize; int i; char *row1 = data; char *row2 = data + linesize * (height-1); if (height <= 1) return; if (width <= 0) return; while (row1 < row2){ _exchange_row(row1, row2, linesize); row1 += linesize; row2 -= linesize; } } /* "standard" 8 bit conversion routine */ static void llconv_rgb2yvu(unsigned char* src, unsigned char* dst, int nbpixels) { int r,g,b,y,v,u,i; for (i=0; i>8); dst[1] = CLAMP(v>>8); dst[2] = CLAMP(u>>8); src += 3; dst += 3; } } static void llconv_yvu16planar2rgbpacked(short int *src, unsigned char *dst, int w, int h) { /* B = 1.164(Y - 16) + 2.018(U - 128) G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) R = 1.164(Y - 16) + 1.596(V - 128)} */ int r,g,b,y,u,v,b1,g1,r1,y1,xoff,yoff; int size = w*h; int voffset = size; int uoffset = size + (size>>2); int rgboff; int rgbw = w*3; int lumoff = 0; int chromoff = 0; for(yoff=0; yoff> 1) + (yoff >> 2); /* get uv values */ v = src[voffset + chromoff]; u = src[uoffset + chromoff]; /* calculate chroma contrib for 2x2 pixblock */ b1 = FP(2.018) * u; g1 = FP(-0.813) * v + FP(-0.391) * u; r1 = FP(1.596) * v; /* TOP LEFT */ /* top left luma contrib */ y = src[lumoff] << 1; y1 = FP(1.164) * y; y1 -= FP(16*256); b = (b1 + y1)>>16; g = (g1 + y1)>>16; r = (r1 + y1)>>16; /* store top left rgb pixel */ dst[rgboff+0] = CLAMP8(r); dst[rgboff+1] = CLAMP8(g); dst[rgboff+2] = CLAMP8(b); /* TOP RIGHT */ /* top right luma contrib */ y = src[lumoff + 1] << 1; y1 = FP(1.164) * y; y1 -= FP(16*256); b = (b1 + y1)>>16; g = (g1 + y1)>>16; r = (r1 + y1)>>16; /* store top right rgb pixel */ dst[rgboff+3] = CLAMP8(r); dst[rgboff+4] = CLAMP8(g); dst[rgboff+5] = CLAMP8(b); /* BOTTOM LEFT */ /* bottom left luma contrib */ y = src[lumoff+w] << 1; y1 = FP(1.164) * y; y1 -= FP(16*256); b = (b1 + y1)>>16; g = (g1 + y1)>>16; r = (r1 + y1)>>16; /* store bottom left rgb pixel */ dst[rgboff+rgbw+0] = CLAMP8(r); dst[rgboff+rgbw+1] = CLAMP8(g); dst[rgboff+rgbw+2] = CLAMP8(b); /* BOTTOM RIGHT */ /* bottom right luma contrib */ y = src[lumoff + w + 1] << 1; y1 = FP(1.164) * y; y1 -= FP(16*256); b = (b1 + y1)>>16; g = (g1 + y1)>>16; r = (r1 + y1)>>16; /* store bottom right rgb pixel */ dst[rgboff+rgbw+3] = CLAMP8(r); dst[rgboff+rgbw+4] = CLAMP8(g); dst[rgboff+rgbw+5] = CLAMP8(b); } } } /* common 8 bit rgb -> 16 bit yvu */ inline static void llconv_rgb2yvu_planar16sub_indexed(unsigned char* src, short int* dst, int w, int h, int ir, int ig, int ib, int stride) { int r,g,b,y,v,u,i,j,k; int size = w*h; int voffset = size; int uoffset = size + (size>>2); int loffset = w * stride; k=0; for (j=0; j> 1); r = src[k+stride+ir]; g = src[k+stride+ig]; b = src[k+stride+ib]; y = (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); v += (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b); u += -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b); dst[i+j+1] = CLAMP16(y >> 1); r = src[loffset + k+ir]; g = src[loffset + k+ig]; b = src[loffset + k+ib]; y = (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); v = (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b); u = -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b); dst[w+i+j] = CLAMP16(y >> 1); r = src[loffset + k+stride+ir]; g = src[loffset + k+stride+ig]; b = src[loffset + k+stride+ib]; k += 2 * stride; y = (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); v += (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b); u += -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b); dst[w+i+j+1] = CLAMP16(y >> 1); dst[uoffset+ (i>>1) + (j>>2)] = (CLAMP16(u >> 1)); dst[voffset+ (i>>1) + (j>>2)] = (CLAMP16(v >> 1)); } } } /* 8 bit rgb to 16 bit planar subsampled yvu */ static void llconv_rgb2yvu_planar16sub(unsigned char* src, short int* dst, int w, int h) { llconv_rgb2yvu_planar16sub_indexed(src,dst,w,h,0,1,2,3); } /* 8 bit rgba to 16 bit planar subsampled yvu */ static void llconv_rgba2yvu_planar16sub(unsigned char* src, short int* dst, int w, int h) { llconv_rgb2yvu_planar16sub_indexed(src,dst,w,h,0,1,2,4); } /* 8 bit bgr to 16 bit planar subsampled yvu */ static void llconv_bgr2yvu_planar16sub(unsigned char* src, short int* dst, int w, int h) { llconv_rgb2yvu_planar16sub_indexed(src,dst,w,h,2,1,0,3); } /* 8 bit bgra to 16 bit planar subsampled yvu */ static void llconv_bgra2yvu_planar16sub(unsigned char* src, short int* dst, int w, int h) { llconv_rgb2yvu_planar16sub_indexed(src,dst,w,h,2,1,0,4); } /* 8 bit rgb to 8 bit planar subsampled yvu */ static void llconv_rgb2yvu_planar8sub(unsigned char* src, unsigned char *dst, int w, int h) { int r,g,b,y,v,u,i,j,k; int size = w*h; int voffset = size; int uoffset = size + (size>>2); int loffset = w * 3; k=0; for (j=0; j> 8); r = src[k+3]; g = src[k+4]; b = src[k+5]; y = (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); v += (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b); u += -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b); dst[i+j+1] = CLAMP8(y >> 8); r = src[loffset + k]; g = src[loffset + k+1]; b = src[loffset + k+2]; y = (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); v = (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b); u = -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b); dst[w+i+j] = CLAMP8(y >> 8); r = src[loffset + k+3]; g = src[loffset + k+4]; b = src[loffset + k+5]; k += 6; y = (FP(0.257) * r) + (FP(0.504) * g) + (FP(0.098) * b) + FP(16); v += (FP(0.439) * r) - (FP(0.368) * g) - (FP(0.071) * b); u += -(FP(0.148) * r) - (FP(0.291) * g) + (FP(0.439) * b); dst[w+i+j+1] = CLAMP8(y >> 8); dst[uoffset+ (i>>1) + (j>>2)] = (CLAMP8((u >> 9)+128)); dst[voffset+ (i>>1) + (j>>2)] = (CLAMP8((v >> 9)+128)); } } } /* these seem to be pretty slow */ static void llconv_yvu2rgb(unsigned char* src, unsigned char* dst, int nbpixels) { int r,g,b,y,v,u,i; for (i=0; i>8); dst[1] = CLAMP(g>>8); dst[2] = CLAMP(b>>8); src += 3; dst += 3; } } /* convert yvu to yuyv */ static void llconv_yvu2yuyv(unsigned char *src, unsigned char *dst, unsigned int nbpixels) { unsigned int y1, y2, u, v, i; for (i = 0; i < nbpixels/2; i++){ y1 = src[0]; y2 = src[3]; v = (src[1] + src[4]) >> 1; u = (src[2] + src[5]) >> 1; dst[0] = y1; dst[1] = u; dst[2] = y2; dst[3] = v; src += 6; dst += 4; } } /* convert yuvu packed 8 bit unsigned to yv12 planar 16bit signed */ static void llconv_yuyv_packed_u8s16(unsigned char* ucsource, short int *sidest, unsigned int w, unsigned int h) { unsigned int i, j; unsigned int *source = (unsigned int *)ucsource; unsigned int *dest = (unsigned int *)sidest; unsigned int uoffset = (w*h)>>1; unsigned int voffset = (w*h + ((w*h) >> 2)) >> 1; for(j=0; j < (h*w)>>1; j +=(w)){ for(i=0; i< (w>>1); i+=2){ unsigned int y,u,v; unsigned int v00, v01, v10, v11; v00 = source[i+j]; v01 = source[i+j+1]; v10 = source[i+j+(w>>1)]; v11 = source[i+j+(w>>1)+1]; // save luma dest[i+j] = ((v00 & 0x00ff00ff) << 7); dest[i+j+1] = ((v01 & 0x00ff00ff) << 7); dest[i+j+(w>>1)] = ((v10 & 0x00ff00ff) << 7); dest[i+j+(w>>1)+1] = ((v11 & 0x00ff00ff) << 7); // compute chroma // mask out luma & shift right v00 = (v00 & 0xff00ff00)>>1; v01 = (v01 & 0xff00ff00)>>1; v10 = (v10 & 0xff00ff00)>>1; v11 = (v11 & 0xff00ff00)>>1; // average 2 scan lines v00 += v10; v01 += v11; // combine v = (v01 << 16) | (v00 & 0x0000ffff); u = (v01 & 0xffff0000) | (v00 >> 16); // flip sign bits for u,v u ^= 0x80008000; v ^= 0x80008000; // save chroma dest[uoffset + (i>>1) + (j>>2)] = u; dest[voffset + (i>>1) + (j>>2)] = v; } } } /* convert yuvu packed 8 bit unsigned to yv12 planar 16bit signed */ /* search for bithacks */ static void llconv_uyvy_packed_u8s16(unsigned char* ucsource, short int *sidest, unsigned int w, unsigned int h) { unsigned int i, j; unsigned int *source = (unsigned int *)ucsource; unsigned int *dest = (unsigned int *)sidest; unsigned int uoffset = (w*h)>>1; unsigned int voffset = (w*h + ((w*h) >> 2)) >> 1; for(j=0; j < (h*w)>>1; j +=(w)){ for(i=0; i< (w>>1); i+=2){ unsigned int y,u,v; unsigned int v00, v01, v10, v11; v00 = source[i+j]; v01 = source[i+j+1]; v10 = source[i+j+(w>>1)]; v11 = source[i+j+(w>>1)+1]; // save luma dest[i+j] = ((v00 & 0xff00ff00)>>1); v11 = source[i+j+(w>>1)+1]; // save luma dest[i+j] = ((v00 & 0xff00ff00)>>1); dest[i+j+1] = ((v01 & 0xff00ff00)>>1); dest[i+j+(w>>1)] = ((v10 & 0xff00ff00)>>1); dest[i+j+(w>>1)+1] = ((v11 & 0xff00ff00)>>1); // compute chroma v00 = (v00 & 0x00ff00ff) << 7; v01 = (v01 & 0x00ff00ff) << 7; v10 = (v10 & 0x00ff00ff) << 7; v11 = (v11 & 0x00ff00ff) << 7; // average 2 scan lines v00 += v10; v01 += v11; // combine TWO VALUES IN ONE WORD (32bits) v = (v01 << 16) | (v00 & 0x0000ffff); u = (v01 & 0xffff0000) | (v00 >> 16); // flip sign bits for u,v FOR PDP FORMAT u ^= 0x80008000; v ^= 0x80008000; // save chroma dest[uoffset + (i>>1) + (j>>2)] = u; dest[voffset + (i>>1) + (j>>2)] = v; } } } #define CONVERT(x,y) ((x) + ((y)<<16)) void pdp_llconv(void *src, int stype, void *dst, int dtype, int w, int h) { int conversion = CONVERT(stype, dtype); void *tmpbuf; switch(CONVERT(stype, dtype)){ case CONVERT( RIF_YVU__P411_U8, RIF_YVU__P411_S16 ): llconv_yvu_planar_u8s16((unsigned char*)src, (short int *)dst, w*h); break; case CONVERT( RIF_YUV__P411_U8, RIF_YVU__P411_S16 ): llconv_yuv_planar_u8s16((unsigned char*)src, (short int *)dst, w*h); break; case CONVERT( RIF_YUYV_P____U8, RIF_YVU__P411_S16 ): llconv_yuyv_packed_u8s16((unsigned char*)src, (short int *)dst, w, h); break; case CONVERT( RIF_UYVY_P____U8, RIF_YVU__P411_S16 ): llconv_uyvy_packed_u8s16((unsigned char*)src, (short int *)dst, w, h); break; case CONVERT( RIF_RGB__P____U8, RIF_YVU__P411_U8 ): llconv_rgb2yvu_planar8sub((unsigned char*) src, (unsigned char*) dst, w, h); break; case CONVERT( RIF_RGB__P____U8, RIF_YVU__P411_S16 ): llconv_rgb2yvu_planar16sub((unsigned char*) src, (short int*) dst, w, h); break; case CONVERT( RIF_RGBA_P____U8, RIF_YVU__P411_S16 ): llconv_rgba2yvu_planar16sub((unsigned char*) src, (short int*) dst, w, h); break; case CONVERT( RIF_BGR__P____U8, RIF_YVU__P411_S16 ): llconv_bgr2yvu_planar16sub((unsigned char*) src, (short int*) dst, w, h); break; case CONVERT( RIF_BGRA_P____U8, RIF_YVU__P411_S16 ): llconv_bgra2yvu_planar16sub((unsigned char*) src, (short int*) dst, w, h); break; case CONVERT( RIF_YVU__P411_S16, RIF_RGB__P____U8 ): llconv_yvu16planar2rgbpacked((short int*) src, (unsigned char*) dst, w, h); break; case CONVERT( RIF_YVU__P411_S16, RIF_YVU__P411_U8 ): llconv_yvu_planar_s16u8((short int*)src, (unsigned char*)dst, w*h); break; case CONVERT( RIF_GREY______S16, RIF_GREY______U8 ): llconv_grey_s16u8((short int*)src, (unsigned char*)dst, w*h); break; default: pdp_post("pdp_llconv: WARNING: no conversion routine defined for (%d)->(%d)", stype, dtype); } } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/system/image/pdp_llconv_mmx.c000066400000000000000000000040051266045153600220700ustar00rootroot00000000000000 /* * Pure Data Packet system implementation. : wrapper for mmx low level format conversion code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp_mmx.h" /* convert greyscale 8 bit unsigned to 16bit signed */ void llconv_grey_s16u8(short int *src, unsigned char *dst, unsigned int nbpixels) { pixel_pack_s16u8_y(src, dst, nbpixels>>3); } /* convert yvu planar 411 16 bit signed to 8 bit unsigned */ void llconv_yvu_planar_s16u8(short int *src, unsigned char *dst, unsigned int nbpixels) { pixel_pack_s16u8_y(src, dst, nbpixels>>3); pixel_pack_s16u8_uv(src + nbpixels, dst + nbpixels, nbpixels>>4); } /* convert yvu planar 411 8 bit unsigned to yv12 planar 16bit signed */ void llconv_yvu_planar_u8s16(unsigned char* source, short int *dest, int nbpixels) { pixel_unpack_u8s16_y(source, dest, nbpixels>>3); pixel_unpack_u8s16_uv(&source[nbpixels], &dest[nbpixels], nbpixels>>4); } /* convert yuv planar 411 8 bit unsigned to yv12 planar 16bit signed */ void llconv_yuv_planar_u8s16(unsigned char* source, short int *dest, int nbpixels) { pixel_unpack_u8s16_y(source, dest, nbpixels>>3); pixel_unpack_u8s16_uv(&source[nbpixels], &dest[nbpixels + (nbpixels>>2)], nbpixels>>5); pixel_unpack_u8s16_uv(&source[nbpixels + (nbpixels>>2)], &dest[nbpixels], nbpixels>>5); } pdp-0.14.1+darcs20180201/system/image/pdp_llconv_portable.c000066400000000000000000000056621266045153600231110ustar00rootroot00000000000000 /* * Pure Data Packet system implementation. : portable low level format conversion code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define CLAMP(x) (((x)<0) ? 0 : ((x>255)? 255 : (x))) #define FP(x) ((int)(((float)(x)) * 256.0f)) void pixel_unpack_portable_u8s16_y(unsigned char *src ,short int *dst, unsigned int nbpixels) { unsigned int i; for (i=0; i>7)); } void pixel_pack_portable_s16u8_uv(short int *src, unsigned char *dst, unsigned int nbpixels) { unsigned int i; unsigned short *usrc = (unsigned short *)src; for (i=0; i>8); } /* convert greyscale 8 bit unsigned to 16bit signed */ void llconv_grey_s16u8(short int *src, unsigned char *dst, unsigned int nbpixels) { pixel_pack_portable_s16u8_y(src, dst, nbpixels); } /* convert yvu planar 411 16 bit signed to 8 bit unsigned */ void llconv_yvu_planar_s16u8(short int *src, unsigned char *dst, unsigned int nbpixels) { pixel_pack_portable_s16u8_y(src, dst, nbpixels); pixel_pack_portable_s16u8_uv(src + nbpixels, dst + nbpixels, nbpixels>>1); } /* convert yvu planar 411 8 bit unsigned to yv12 planar 16bit signed */ void llconv_yvu_planar_u8s16(unsigned char* source, short int *dest, int nbpixels) { pixel_unpack_portable_u8s16_y(source, dest, nbpixels); pixel_unpack_portable_u8s16_uv(&source[nbpixels], &dest[nbpixels], nbpixels>>1); } /* convert yuv planar 411 8 bit unsigned to yv12 planar 16bit signed */ void llconv_yuv_planar_u8s16(unsigned char* source, short int *dest, int nbpixels) { pixel_unpack_portable_u8s16_y(source, dest, nbpixels); pixel_unpack_portable_u8s16_uv(&source[nbpixels], &dest[nbpixels + (nbpixels>>2)], nbpixels>>2); pixel_unpack_portable_u8s16_uv(&source[nbpixels + (nbpixels>>2)], &dest[nbpixels], nbpixels>>2); } pdp-0.14.1+darcs20180201/system/image/pdp_resample.c000066400000000000000000000120701266045153600215230ustar00rootroot00000000000000/* * Pure Data Packet system file. - image resampling routines * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_resample.h" /* efficient bilinear resampling ?? performance: how to eliminate divides? -> virtual coordinates 2^k x 2^k (conf. opengl) i.e. 16 bit virtual coordinates: easy modular addressing */ /* code in this file should go out to be replaced by code in pdp_imageproc */ static s32 pdp_resample_bilin(s16 *image, s32 width, s32 height, s32 virt_x, s32 virt_y) { s32 fp_x, fp_y, frac_x, frac_y, f, offset, r_1, r_2; virt_x &= 0xffff; virt_y &= 0xffff; fp_x = virt_x * (width - 1); fp_y = virt_y * (height - 1); frac_x = fp_x & (0xffff); frac_y = fp_y & (0xffff); offset = (fp_x >> 16) + (fp_y >> 16) * width; image += offset; f = 0x10000 - frac_x; r_1 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16; image += width; r_2 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16; f = 0x10000 - frac_y; return ((f * r_1 + frac_y * r_2)>>16); } void pdp_resample_scale_bilin(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h) { s32 i,j; s32 virt_x=0; s32 virt_y=0; /* virtual coordinates in 30 bit */ s32 scale_x = 0x40000000 / dst_w; s32 scale_y = 0x40000000 / dst_h; for (j=0; j>14, virt_y>>14); virt_x += scale_x; } virt_x = 0; virt_y += scale_y; } } void pdp_resample_scale_nn(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h) { s32 i,j; s32 x=0; s32 y=0; s32 frac_x=0; s32 frac_y=0; s32 scale_x = (src_w << 20 ) / dst_w; s32 scale_y = (src_h << 20 ) / dst_h; for (j=0; j> 20; } x = 0; frac_x = 0; frac_y += scale_y; y = (frac_y >> 20) * src_w; } } /* USE pdp_resample_affinemap void pdp_resample_zoom_tiled_bilin(s16 *src_image, s16 *dst_image, s32 w, s32 h, float zoom_x, float zoom_y, float center_x_relative, float center_y_relative) { float izx = 1.0f / zoom_x; float izy = 1.0f / zoom_y; s32 scale_x = (s32)((float)0x100000 * izx / (float)w); s32 scale_y = (s32)((float)0x100000 * izy / (float)h); s32 top_virt_x = (s32)((1.0f - izx) * (float)0x100000 * center_x_relative); s32 top_virt_y = (s32)((1.0f - izy) * (float)0x100000 * center_y_relative); s32 virt_x = top_virt_x; s32 virt_y = top_virt_y; s32 i,j; for (j=0; j>4, virt_y>>4); virt_x += scale_x; } virt_x = top_virt_x; virt_y += scale_y; } } */ void pdp_resample_halve(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h) { int dst_x,dst_y; int src_x = 0; int src_y = 0; int dst_w = src_w >> 1; int dst_h = src_h >> 1; s32 tmp1,tmp2,tmp3,tmp4; //post("%x %x %d %d\n", src_image, dst_image, src_w, src_h); for(dst_y = 0; dst_y < dst_h * dst_w; dst_y += dst_w){ for (dst_x = 0; dst_x < dst_w; dst_x++){ tmp1 = (s32)src_image[src_y + src_x]; tmp2 = (s32)src_image[src_y + src_x + 1]; tmp3 = (s32)src_image[src_y + src_x + src_w]; tmp4 = (s32)src_image[src_y + src_x + src_w + 1]; tmp1 += tmp2; tmp3 += tmp4; src_x += 2; dst_image[dst_x+dst_y] = (s16)((tmp1 + tmp3)>>2); } src_y += src_w << 1; src_x = 0; } } void pdp_resample_double(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h) { int src_x = 0; int src_y = 0; int dst = 0; int dst_w = src_w << 1; s16 tmp; for(src_y = 0; src_y < src_h * src_w; src_y += src_w){ for (src_x = 0; src_x < src_w; src_x++){ tmp = *src_image++; dst = (src_y << 2) + (src_x << 1); dst_image[dst] = tmp; dst_image[dst+1] = tmp; dst+=dst_w; dst_image[dst] = tmp; dst_image[dst+1] = tmp; } } } /* $$$TODO: finish this */ void pdp_resample_padcrop(s16 __attribute__((unused)) *src_image, s16 __attribute__((unused)) *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h) { int shift_x = (dst_w - src_w) / 2; int shift_y = (dst_h - src_h) / 2; } pdp-0.14.1+darcs20180201/system/kernel/000077500000000000000000000000001266045153600171025ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/kernel/CONTENTS000066400000000000000000000004031266045153600202570ustar00rootroot00000000000000debug debug stuff forth the forth system list the list implementation mem memory allocation stuf packet the packet memory manager type the type handling and conversion system symbol symbol implementation, with namespaces for forth, types, classes, ... pdp-0.14.1+darcs20180201/system/kernel/Makefile000066400000000000000000000003571266045153600205470ustar00rootroot00000000000000 OBJECTS = pdp_packet.o pdp_type.o pdp_dpd_command.o \ pdp_list.o pdp_debug.o pdp_symbol.o \ pdp_mem.o pdp_post.o include ../../Makefile.config all: pdp_main_clean $(OBJECTS) pdp_main_clean: rm -f pdp.o clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/system/kernel/pdp_debug.c000066400000000000000000000007531266045153600212040ustar00rootroot00000000000000#include #include #include #include "pdp_post.h" int pdp_debug_sigtrap_on_assert; void pdp_assert_hook (char *condition, char *file, int line) { pdp_post("PDP_ASSERT (%s) failed in file %s, line %u. ", condition, file, line); pdp_post("%s.\n", pdp_debug_sigtrap_on_assert ? "sending SIGTRAP" : "continuing"); if (pdp_debug_sigtrap_on_assert) kill(getpid(), SIGTRAP); } void pdp_debug_setup(void) { pdp_debug_sigtrap_on_assert = 1; } pdp-0.14.1+darcs20180201/system/kernel/pdp_dpd_command.c000066400000000000000000000043431266045153600223620ustar00rootroot00000000000000 /* * Pure Data Packet header file. DPD command class * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this object implements a dpd command queue and command object */ #include "pdp_dpd_command.h" #include "pdp_mem.h" void pdp_dpd_commandfactory_init(t_pdp_dpd_commandfactory *x, u32 size) { x->nb_commands = 0; x->command_size = size; x->command = 0; } void _pdp_dpd_commandfactory_free(t_pdp_dpd_command *x) { if (x) _pdp_dpd_commandfactory_free(x->next); pdp_dealloc(x); } void pdp_dpd_commandfactory_free(t_pdp_dpd_commandfactory *x) { _pdp_dpd_commandfactory_free(x->command); x->command = 0; x->nb_commands = 0; } /* factory method */ t_pdp_dpd_command *pdp_dpd_commandfactory_get_new_command(t_pdp_dpd_commandfactory *x) { t_pdp_dpd_command *c = x->command; t_pdp_dpd_command *oldhead = c; /* check if we can reuse */ while (c){ if (!c->used){ c->used = 1; //post("reusing command %x", c, c->used); return c; } //post("command %x is used %d", c, c->used); c = c->next; } /* create a new command */ x->command = (t_pdp_dpd_command *)pdp_alloc(x->command_size); x->command->next = oldhead; x->command->used = 1; x->nb_commands++; //post("created command %x, nbcommands: %d", x->command, x->nb_commands); return x->command; } /* (self)destructor */ void pdp_dpd_command_suicide(void *x) { t_pdp_dpd_command *c = (t_pdp_dpd_command *)x; c->used = 0; //post("command %x committed suicide %d", c, c->used); } pdp-0.14.1+darcs20180201/system/kernel/pdp_list.c000066400000000000000000000500301266045153600210620ustar00rootroot00000000000000 /* * Pure Data Packet header file. List class * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* who can live without a list, hmm? this is sorth of a compromise between lists, queues, stacks, lisp and forth. list contain pdp atoms (floats, ints, symbols, pointers, packets or lists) */ #include #include #include #include #include "pdp_list.h" #include "pdp_symbol.h" #include "pdp_packet.h" #include "pdp_type.h" #include "pdp_types.h" #include "pdp_mem.h" #include "pdp_post.h" #include "pdp_debug.h" #define D if (0) t_pdp_fastalloc *_fast_atom_allocator; t_pdp_fastalloc *_fast_list_allocator; static void _pdp_list_dealloc(t_pdp_list *l) { pdp_fastalloc_save_atom(_fast_list_allocator, l); } // allocator macros #define PDP_ATOM_ALLOC() pdp_fastalloc_new_atom(_fast_atom_allocator) #define PDP_ATOM_DEALLOC(x) pdp_fastalloc_save_atom(_fast_atom_allocator, x) #define PDP_LIST_ALLOC() pdp_fastalloc_new_atom(_fast_list_allocator) #define PDP_LIST_DEALLOC(x) _pdp_list_dealloc(x) //#define PDP_LIST_DEALLOC(x) pdp_fastalloc_save_atom(_fast_list_allocator, x) /* some private helper methods */ /* list pool setup */ void pdp_list_setup(void) { /* create fast allocators */ _fast_atom_allocator = pdp_fastalloc_new(sizeof(t_pdp_atom)); _fast_list_allocator = pdp_fastalloc_new(sizeof(t_pdp_list)); /* testing code */ if (0){ char *next; t_pdp_list *l = pdp_tree_from_cstring("( een twee (3 vier ()) vijf (6.0)", &next); if (!l){ pdp_post("parse error:"); pdp_post(next); } else{ pdp_list_print(l); } exit(1); } } /* create a list */ t_pdp_list* pdp_list_new(int elements) { t_pdp_atom *a = 0; t_pdp_list *l = PDP_LIST_ALLOC(); l->elements = 0; if (elements){ a = PDP_ATOM_ALLOC(); l->elements++; a->t = a_undef; a->w.w_int = 0; a->next = 0; elements--; } l->first = a; l->last = a; while (elements--){ a = PDP_ATOM_ALLOC(); l->elements++; a->t = a_undef; a->w.w_int = 0; a->next = l->first; l->first = a; } return l; } /* clear a list */ void pdp_list_clear(t_pdp_list *l) { t_pdp_atom *a = l->first; t_pdp_atom *next_a; while(a){ next_a = a->next; PDP_ATOM_DEALLOC(a); a = next_a; } l->first = 0; l->last = 0; l->elements = 0; } /* destroy a list */ void pdp_list_free(t_pdp_list *l) { if (l){ pdp_list_clear(l); PDP_LIST_DEALLOC(l); } } /* destroy a (sub)tree */ void pdp_tree_free(t_pdp_list *l) { if (l) { pdp_tree_clear(l); PDP_LIST_DEALLOC(l); } } /* clear a tree */ void pdp_tree_clear(t_pdp_list *l) { t_pdp_atom *a = l->first; t_pdp_atom *next_a; while(a){ if (a->t == a_list){ pdp_tree_free(a->w.w_list); } next_a = a->next; PDP_ATOM_DEALLOC(a); a = next_a; } l->first = 0; l->last = 0; l->elements = 0; } /* BEGIN PARSER CODE */ /* real whitespace handling */ static inline int _is_whitespace(char c){return (c == ' ' || c == '\n' || c == '\t');} static inline void _skip_real_whitespace(char **c){while (_is_whitespace(**c)) (*c)++;} /* comment handling */ static inline int _is_left_comment(char c) {return (c == '#');} static inline int _is_right_comment(char c) {return (c == '\n');} static inline void _skip_comment(char **c) { if (!_is_left_comment(**c)) return; (*c)++; while (!_is_right_comment(**c)){ if (!**c) return; // no terminating newline (*c)++; } (*c)++; } /* comment + whitespace handling */ static inline void _skip_whitespace(char **c) { char *prev_c; /* skip comments and whitespace until the pointer stops moving */ do { prev_c = *c; _skip_real_whitespace(c); _skip_comment(c); } while (prev_c != *c); } static inline int _is_left_separator(char c) {return (c == '(');} static inline int _is_right_separator(char c) {return (c == ')');} static inline int _is_terminator(char c) {return (c == 0);} /* the end of an atom is marked by a separator */ static inline int _is_separator(char c) {return (_is_terminator(c) || _is_left_separator(c) || _is_right_separator(c) || _is_whitespace(c));} /* parse a single pure atom from a zero terminated string a pure atom is either a number (int or float) xor a symbol */ static inline void _parse_pure_atom(t_pdp_atom *a, char *c) { char *next; /* check if the string has a decimal point */ int has_decimal = 0; char *c2; for(c2 = c; *c2; c2++){ if (*c2 == '.') { has_decimal = 1; break; } } /* try parsing as a number (int or float) first */ if (has_decimal){ // try float float f = strtod(c, &next); if (next[0] == 0){ // got everything? D pdp_post("parsing float %f", f); a->t = a_float; a->w = (t_pdp_word)f; return; } } else { // try int int i = strtol(c, &next, 0); if (next[0] == 0){ // got everything? D pdp_post("parsing int %d", i); a->t = a_int; a->w = (t_pdp_word)i; return; } } /* number parsing failed: it's a symbol */ D pdp_post("parsing symbol %s", c); a->t = a_symbol; a->w = (t_pdp_word)pdp_gensym(c); } t_pdp_atom *pdp_atom_new(void){t_pdp_atom *a = PDP_ATOM_ALLOC(); a->next = 0; return a;} void pdp_atom_free(t_pdp_atom *a){PDP_ATOM_DEALLOC(a);} /* there are two parser methods: parse an atom and parse a list both can call each other recursively. the atoms and list are allocated with pdp_list_new and pdp_atom_new respectively */ t_pdp_atom *pdp_atom_from_cstring(char *chardef, char **next) { t_pdp_atom *a = 0; /* skip whitespace and check if there's anything left */ _skip_whitespace(&chardef); if (!chardef[0] || _is_right_separator(*chardef)) goto done; /* check if it's a list atom */ if(_is_left_separator(*chardef)){ t_pdp_list *l = pdp_tree_from_cstring(chardef, &chardef); if (l){ a = pdp_atom_new(); a->t = a_list; a->w.w_list = l; } } /* we have a pure atom, copy it to a temp buffer */ else{ int n = 0; while (!_is_separator(chardef[n])) n++; if (!n) goto done; else { char tmp[n+1]; strncpy(tmp, chardef, n); tmp[n] = 0; a = pdp_atom_new(); _parse_pure_atom(a, tmp); chardef += n; } } done: if (next) *next = chardef; return a; } /* check if a tree (list of lists) matches a certain type syntax types: symbol -> a_sym; int -> a_int; float -> a_float; packet -> a_packet; list -> a_list; ... -> zero or more times the preceeding elements in the list */ /* create a list from a character string */ t_pdp_list *pdp_tree_from_cstring(char *chardef, char **next) { t_pdp_list *l = pdp_list_new(0); t_pdp_atom *a = 0; D pdp_post ("creating list from char: %s", chardef); /* find opening parenthesis and skip it*/ _skip_whitespace(&chardef); if (!_is_left_separator(*chardef)) goto error; else chardef++; /* chardef now points at the first atom, start adding atoms */ while(1){ a = pdp_atom_from_cstring(chardef, &chardef); if (a)pdp_list_add_back_atom(l, a); else break; } /* skip whitespace and find closing parenthesis */ _skip_whitespace(&chardef); if (!_is_right_separator(*chardef)) goto error; else chardef++; if (next) *next = chardef; return l; error: /* end of string encountered: parse error */ D pdp_post("parse error: %s", chardef); if (next) *next = chardef; pdp_tree_free(l); //this will free all sublists too return 0; // parse error } /* END PARSER CODE */ // this assumes syntax's syntax is correct int pdp_tree_check_syntax(t_pdp_list *list, t_pdp_list *syntax) { t_pdp_atom *la = 0; t_pdp_atom *sa = 0; t_pdp_symbol *ellipsis = pdp_gensym("..."); t_pdp_symbol *wildcard = pdp_gensym("*"); /* handle empty lists */ if (list->elements == 0){ /* check if syntax list is empty */ if (syntax->elements == 0) goto match; /* check if syntax list has ellipsis */ if (syntax->last->t == a_symbol && syntax->last->w.w_symbol == ellipsis) goto match; /* default: no match */ goto nomatch; } /* loop over list and syntax list */ for (la = list->first, sa = syntax->first; la && sa; la = la->next, sa = sa->next){ D pdp_post("pdp_tree_check_syntax: starting check"); checkatom: /* what do we expect for this atom ? */ switch(sa->t){ case a_list: D pdp_post("expecting list"); /* we need to recurse down the tree */ /* exit if the current list to check does not have a sublist */ if (la->t != a_list) { D pdp_post("not a list"); goto nomatch; } /* recurse and exit if no match */ D pdp_post("checking sublist"); if (!pdp_tree_check_syntax(la->w.w_list, sa->w.w_list)){ D pdp_post("sublist does not match"); goto nomatch; } break; case a_symbol: /* if ellipsis, rewind */ if (ellipsis == sa->w.w_symbol){ D pdp_post("got ellipsis"); /* check if we're not looping */ if (sa == syntax->first){ D pdp_post("ellipsis at start of list"); goto nomatch; } /* try again */ sa = syntax->first; D pdp_post("ellipsis rewind"); goto checkatom; } else if (wildcard == sa->w.w_symbol){ D pdp_post("got wildcard"); } /* ordinary atom: check type */ else{ D pdp_post("expecting %s", sa->w.w_symbol->s_name); switch(la->t){ case a_int: if (sa->w.w_symbol != pdp_gensym("int")) goto nomatch; break; case a_float: if (sa->w.w_symbol != pdp_gensym("float")) goto nomatch; break; case a_symbol: if (sa->w.w_symbol != pdp_gensym("symbol")) goto nomatch; break; case a_packet: if (sa->w.w_symbol != pdp_gensym("packet")) goto nomatch; break; case a_list: if (sa->w.w_symbol != pdp_gensym("list")) goto nomatch; break; default: goto nomatch; } D pdp_post("OK"); } break; default: D pdp_post("syntax syntax error"); pdp_list_print(syntax); goto nomatch; // incorrect syntax description } } /* loop ended because one of the lists was finished */ /* only two cases can be valid: la == 0 and (sa == 0 or ellipsis) */ if (la != 0){ D pdp_post("not end of list -> no match"); goto nomatch; } if (sa == 0) goto match; if (!(sa->t == a_symbol && sa->w.w_symbol == ellipsis)){ D pdp_post("syntax list not in ellipsis position -> no match"); goto nomatch; } /* exits */ match: D pdp_post("pdp_tree_check_syntax: match"); return 1; nomatch: D pdp_post("pdp_tree_check_syntax: no match"); return 0; } /* traversal */ void pdp_list_apply(t_pdp_list *l, t_pdp_atom_method m) { t_pdp_atom *a; if (!l) return; for (a=l->first; a; a=a->next) m(a); } void pdp_tree_apply(t_pdp_list *l, t_pdp_atom_method m) { t_pdp_atom *a; if (!l) return; for (a=l->first; a; a=a->next){ if (a->t == a_list) pdp_tree_apply(a->w.w_list, m); else m(a); } } void pdp_list_apply_word_method(t_pdp_list *l, t_pdp_word_type type, t_pdp_word_method wm) { t_pdp_atom *a; if (!l) return; for (a=l->first; a; a=a->next){ if (a->t == type) wm(a->w); } } void pdp_list_apply_pword_method(t_pdp_list *l, t_pdp_word_type type, t_pdp_pword_method pwm) { t_pdp_atom *a; if (!l) return; for (a=l->first; a; a=a->next){ if (a->t == type) pwm(&a->w); } } void pdp_tree_apply_word_method(t_pdp_list *l, t_pdp_word_type type, t_pdp_word_method wm) { t_pdp_atom *a; if (!l) return; for (a=l->first; a; a=a->next){ if (a->t == a_list) pdp_tree_apply_word_method(a->w.w_list, type, wm); else if (a->t == type) wm(a->w); } } void pdp_tree_apply_pword_method(t_pdp_list *l, t_pdp_word_type type, t_pdp_pword_method pwm) { t_pdp_atom *a; if (!l) return; for (a=l->first; a; a=a->next){ if (a->t == a_list) pdp_tree_apply_pword_method(a->w.w_list, type ,pwm); else if (a->t == type) pwm(&a->w); } } static void _atom_packet_mark_unused(t_pdp_atom *a) { if (a->t == a_packet){ pdp_packet_mark_unused(a->w.w_packet); a->w.w_packet = -1; } } static void _atom_packet_copy_ro(t_pdp_atom *a) { int p; if (a->t == a_packet){ a->w.w_packet = pdp_packet_copy_ro(a->w.w_packet); } } void pdp_tree_strip_packets (t_pdp_list *l) { pdp_tree_apply(l, _atom_packet_mark_unused); } static void _pdp_tree_copy_ro_packets (t_pdp_list *l) { pdp_tree_apply(l, _atom_packet_copy_ro); } t_pdp_list *pdp_tree_copy_ro(t_pdp_list *l) { t_pdp_list *l2 = pdp_tree_copy(l); _pdp_tree_copy_ro_packets(l2); return l2; } static void _pdp_atomlist_fprint(FILE* f, t_pdp_atom *a); static void _pdp_atom_fprint(FILE* f, t_pdp_atom *a) { if (!a){ fprintf(f, ""); return; } switch(a->t){ /* generic atoms */ case a_symbol: fprintf(f, "%s",a->w.w_symbol->s_name); break; case a_float: fprintf(f, "%f",a->w.w_float); break; case a_int: fprintf(f, "%d",a->w.w_int); break; case a_packet: fprintf(f, "#",a->w.w_packet, pdp_packet_get_description(a->w.w_packet)->s_name); break; case a_pointer: fprintf(f, "#<0x%08x>", a->w.w_int); break; case a_list: _pdp_atomlist_fprint(f, a->w.w_list->first); break; case a_atom_pointer: fprintf(f, "->"); _pdp_atom_fprint(f, a->w.w_atom_pointer); break; case a_undef: fprintf(f, ""); break; /* forth atoms */ case a_forthword: fprintf(f, "#", a->w.w_int); break; case a_vmword: fprintf(f, "#", a->w.w_int); break; case a_vmmacro: fprintf(f, "#", a->w.w_int); break; default: fprintf(f, ""); break; } } /* debug */ static void _pdp_atomlist_fprint(FILE* f, t_pdp_atom *a) { fprintf(f, "("); while (a){ _pdp_atom_fprint(f,a); a = a->next; if (a) fprintf(f, " "); } fprintf(f, ")"); } void _pdp_list_fprint(FILE* f, t_pdp_list *l) { _pdp_atomlist_fprint(f, l->first); fprintf(f, "\n"); } void pdp_list_print(t_pdp_list *l) { _pdp_list_fprint(stderr, l); } void pdp_atom_print(t_pdp_atom *a) { _pdp_atom_fprint(stderr, a); } /* public list operations */ /* add a atom/word to the start of the list */ void pdp_list_add_atom(t_pdp_list *l, t_pdp_atom *a) { a->next = l->first; l->first = a; l->elements++; if (!l->last) l->last = a; } void pdp_list_add(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w) { t_pdp_atom *a = PDP_ATOM_ALLOC(); a->t = t; a->w = w; pdp_list_add_atom(l, a); } /* add a word to the end of the list */ void pdp_list_add_back_atom(t_pdp_list *l, t_pdp_atom *a) { l->elements++; a->next = 0; if (l->last){ l->last->next = a; } else{ l->first = a; } l->last = a; } void pdp_list_add_back(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w) { t_pdp_atom *a = PDP_ATOM_ALLOC(); a->w = w; a->t = t; pdp_list_add_back_atom(l, a); } /* get list size */ int pdp_list_size(t_pdp_list *l) { return l->elements; } /* pop: return first item and remove */ t_pdp_atom *pdp_list_pop_atom(t_pdp_list *l) { t_pdp_atom *a = l->first; if (!a) return a; l->first = a->next; l->elements--; if (!l->first) l->last = 0; a->next = 0; // detach return a; } /* pop: return first item and remove */ t_pdp_word pdp_list_pop(t_pdp_list *l) { t_pdp_atom *a = pdp_list_pop_atom(l); t_pdp_word w=a->w; PDP_ATOM_DEALLOC(a); return w; } /* pop from one list and push to other */ void pdp_list_pop_push(t_pdp_list *source, t_pdp_list *dest) { t_pdp_atom *a = source->first; /* pop atom */ if (--(source->elements)){source->last = 0;} source->first = a->next; /* push atom */ a->next = dest->first; if (dest->elements++) {dest->last = a;} dest->first = a; return; } /* return element at index */ t_pdp_word pdp_list_index(t_pdp_list *l, int indx) { t_pdp_atom *a; for (a = l->first; indx--; a = a->next); return a->w; } /* remove an element from a list */ void pdp_list_remove(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w) { t_pdp_atom head; t_pdp_atom *a; t_pdp_atom *kill_a; head.next = l->first; for(a = &head; a->next; a = a->next){ if (a->next->w.w_int == w.w_int && a->next->t == t){ kill_a = a->next; // element to be killed a->next = a->next->next; // remove link PDP_ATOM_DEALLOC(kill_a); l->elements--; l->first = head.next; // restore the start pointer if (l->last == kill_a) { // restore the end pointer l->last = (a != &head) ? a : 0; } break; } } } /* copy a list */ t_pdp_list* pdp_tree_copy_reverse(t_pdp_list *list) { t_pdp_list *newlist = pdp_list_new(0); t_pdp_atom *a; for (a = list->first; a; a = a->next) if (a->t == a_list){ pdp_list_add(newlist, a->t, (t_pdp_word)pdp_tree_copy_reverse(a->w.w_list)); } else{ pdp_list_add(newlist, a->t, a->w); } return newlist; } t_pdp_list* pdp_list_copy_reverse(t_pdp_list *list) { t_pdp_list *newlist = pdp_list_new(0); t_pdp_atom *a; for (a = list->first; a; a = a->next) pdp_list_add(newlist, a->t, a->w); return newlist; } t_pdp_list* pdp_tree_copy(t_pdp_list *list) { t_pdp_list *newlist = pdp_list_new(list->elements); t_pdp_atom *a_src = list->first; t_pdp_atom *a_dst = newlist->first; while(a_src){ a_dst->t = a_src->t; if (a_dst->t == a_list){ //recursively copy sublists (tree copy) a_dst->w.w_list = pdp_tree_copy(a_src->w.w_list); } else{ a_dst->w = a_src->w; } a_src = a_src->next; a_dst = a_dst->next; } return newlist; } t_pdp_list* pdp_list_copy(t_pdp_list *list) { t_pdp_list *newlist = pdp_list_new(list->elements); t_pdp_atom *a_src = list->first; t_pdp_atom *a_dst = newlist->first; while(a_src){ a_dst->t = a_src->t; a_dst->w = a_src->w; a_src = a_src->next; a_dst = a_dst->next; } return newlist; } void pdp_list_join (t_pdp_list *l, t_pdp_list *tail) { if (tail->elements){ l->elements += tail->elements; if (l->last){ l->last->next = tail->first; l->last = tail->last; } else { l->first = tail->first; l->last = tail->last; } } PDP_LIST_DEALLOC(tail); //delete the tail header } void pdp_list_cat (t_pdp_list *l, t_pdp_list *tail) { t_pdp_list *tmp = pdp_list_copy(tail); pdp_list_join(l, tmp); } /* in place reverse: atoms stay the same they are just relinked. so pointers will stay accurate */ void pdp_list_reverse(t_pdp_list *l) { t_pdp_list tmp; t_pdp_atom *a; tmp.first = l->first; tmp.last = l->last; tmp.elements = l->elements; l->first = 0; l->last = 0; l->elements = 0; while (a = pdp_list_pop_atom(&tmp)){ pdp_list_add_atom(l, a); } } void pdp_list_reverse_old(t_pdp_list *l) { t_pdp_list *l2 = pdp_list_copy_reverse(l); pdp_list_clear(l); l->first = l2->first; l->last = l2->last; l->elements = l2->elements; _pdp_list_dealloc(l2); } /* check if a list contains an element */ int pdp_list_contains(t_pdp_list *list, t_pdp_word_type t, t_pdp_word w) { t_pdp_atom *a; for(a = list->first; a; a=a->next){ if (a->w.w_int == w.w_int && a->t == t) return 1; } return 0; } /* add a thing to the start of the list if it's not in there already */ void pdp_list_add_to_set(t_pdp_list *list, t_pdp_word_type t, t_pdp_word w) { if (!pdp_list_contains(list, t, w)) pdp_list_add(list, t, w); } pdp-0.14.1+darcs20180201/system/kernel/pdp_mem.c000066400000000000000000000074221266045153600206740ustar00rootroot00000000000000/* * Pure Data Packet system file: memory allocation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include "pdp_mem.h" #include "pdp_debug.h" // defined here so we don't need to rebuild when changing it (deps for headers are broken) #define PDP_FASTALLOC_BLOCK_ELEMENTS 4096 //#define PDP_FASTALLOC_BLOCK_ELEMENTS 1 #define D if (0) /* malloc wrapper that calls garbage collector */ void *pdp_alloc(int size) { void *ptr = malloc(size); PDP_ASSERT(ptr); D fprintf(stderr, "alloc %p %d\n", ptr, size); return ptr; //TODO: REPAIR THIS //post ("malloc failed in a pdp module: running garbage collector."); //pdp_pool_collect_garbage(); //return malloc(size); } void pdp_dealloc(void *stuff) { D fprintf(stderr, "dealloc %p\n", stuff); free (stuff); } /* fast atom allocation object well, this is not too fast yet, but will be later when it suports linux futexes or atomic operations */ //#include /* private linked list struct */ typedef struct _fastalloc { struct _fastalloc * next; } t_fastalloc; static void _pdp_fastalloc_lock(t_pdp_fastalloc *x){pthread_mutex_lock(&x->mut);} static void _pdp_fastalloc_unlock(t_pdp_fastalloc *x){pthread_mutex_unlock(&x->mut);} static void _pdp_fastalloc_refill_freelist(t_pdp_fastalloc *x) { t_fastalloc *atom; unsigned int i; PDP_ASSERT(x->freelist == 0); /* get a new block there is no means of freeing the data afterwards, this is a fast implementation with the tradeoff of data fragmentation "memory leaks".. */ x->freelist = pdp_alloc(x->block_elements * x->atom_size); /* link all atoms together */ atom = x->freelist; for (i=0; iblock_elements-1; i++){ atom->next = (t_fastalloc *)(((char *)atom) + x->atom_size); atom = atom->next; } atom->next = 0; } #define USE_FASTALLOC 1 #if USE_FASTALLOC void *pdp_fastalloc_new_atom(t_pdp_fastalloc *x) { t_fastalloc *atom; _pdp_fastalloc_lock(x); /* get an atom from the freelist or refill it and try again */ while (!(atom = x->freelist)){ _pdp_fastalloc_refill_freelist(x); } /* delete the element from the freelist */ x->freelist = x->freelist->next; atom->next = 0; _pdp_fastalloc_unlock(x); return (void *)atom; } void pdp_fastalloc_save_atom(t_pdp_fastalloc *x, void *atom) { _pdp_fastalloc_lock(x); ((t_fastalloc *)atom)->next = x->freelist; x->freelist = (t_fastalloc *)atom; _pdp_fastalloc_unlock(x); } t_pdp_fastalloc *pdp_fastalloc_new(unsigned int size) { t_pdp_fastalloc *x = pdp_alloc(sizeof(*x)); if (size < sizeof(t_fastalloc)) size = sizeof(t_fastalloc); x->freelist = 0; x->atom_size = size; x->block_elements = PDP_FASTALLOC_BLOCK_ELEMENTS; pthread_mutex_init(&x->mut, NULL); return x; } #else void *pdp_fastalloc_new_atom(t_pdp_fastalloc *x) {return pdp_alloc(12);} void pdp_fastalloc_save_atom(t_pdp_fastalloc *x, void *atom) {pdp_dealloc(atom);} t_pdp_fastalloc *pdp_fastalloc_new(unsigned int size) {return 0;} #endif pdp-0.14.1+darcs20180201/system/kernel/pdp_packet.c000066400000000000000000000377171266045153600213770ustar00rootroot00000000000000/* * Pure Data Packet system implementation: Packet Manager * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include "pdp_post.h" #include "pdp_packet.h" #include "pdp_mem.h" #include "pdp_list.h" #include "pdp_type.h" #include "pdp_debug.h" #define D if(0) /* packet implementation. contains class and packet (instance) handling some notes on packet operations. copy ro/rw and unregister are relatively straightforward packet creation can be done in 2 ways in this interface: create + reuse however, these methods should only be called by specific factory methods, so the user should only create packets using pdp_factory_newpacket reuse or create is thus the responsability of the factory methods for each packet type (class) implementation */ /* NOTE: the packet pool methods are called within the pool locks. this probably needs to change, because it will cause deadlocks for container packets (fobs) */ /* new implementation: probably just a minor adjustment: add the reuse fifo attached to type desc symbol name need to check and possibly eliminate hacks for non-pure packets pdp_packet_new: LOCK 1. check reuse fifo 2. empty -> create packet+return (search array) 3. element -> check if type is correct, yes->pop+return, no->goto 1. UNLOCK 4. wakeup pdp_packet_mark_unused 1. check refcount. if > 1 dec + exit 2. if 1 put packet to sleep 3. dec refcount 4. add to reuse fifo (no fifo -> create) pdp_packet_delete: analogous to mark_unused pdp_packet_copy_ro/rw: analogous to new */ /* the pool */ #define PDP_INITIAL_POOL_SIZE 64 static int pdp_pool_size; static t_pdp** pdp_pool; /* mutex: protects the pool and reuse lists attached to symbols */ static pthread_mutex_t pdp_pool_mutex; #define LOCK pthread_mutex_lock (&pdp_pool_mutex) #define UNLOCK pthread_mutex_unlock (&pdp_pool_mutex) /* the list of classes */ static t_pdp_list *class_list; /* debug */ void pdp_packet_print_debug(int packet) { t_pdp *h = pdp_packet_header(packet); pdp_post("debug info for packet %d", packet); if (!h){ pdp_post("invalid packet"); } else{ pdp_post ("\ttype: %d", h->type); pdp_post ("\tdesc: %s", h->desc ? h->desc->s_name : "unknown"); pdp_post ("\tsize: %d", h->size); pdp_post ("\tflags: %x", h->flags); pdp_post ("\tusers: %d", h->users); pdp_post ("\tclass: %x", h->theclass); } } /* setup methods */ void pdp_packet_setup(void) { pdp_pool_size = PDP_INITIAL_POOL_SIZE; pdp_pool = (t_pdp **)pdp_alloc(PDP_INITIAL_POOL_SIZE * sizeof(t_pdp *)); bzero(pdp_pool, pdp_pool_size * sizeof(t_pdp *)); class_list = pdp_list_new(0); pthread_mutex_init(&pdp_pool_mutex, NULL); } /* class methods */ t_pdp_class *pdp_class_new(t_pdp_symbol *type, t_pdp_factory_method create){ t_pdp_class *c = (t_pdp_class *)pdp_alloc(sizeof(t_pdp_class)); memset(c, 0, sizeof(t_pdp_class)); c->create = create; c->type = type; // set type pdp_list_add(class_list, a_pointer, (t_pdp_word)((void *)c)); return c; } /* the packet factory */ int pdp_factory_newpacket(t_pdp_symbol *type) { int p; t_pdp_class *c; t_pdp_atom *a = class_list->first; /* try to reuse first THINK: should this be the responsability of the type specific constructors, or should a packet allways be reusable (solution: depends on what the cleanup method returns??) */ p = pdp_packet_reuse(type); if (-1 != p) return p; /* call class constructor */ while(a){ D pdp_post("new: %s", type->s_name); c = (t_pdp_class *)(a->w.w_pointer); if (c->type && pdp_type_description_match(type, c->type)){ //pdp_post("method %x, type %s", c->create, type->s_name); return (c->create) ? (*c->create)(type) : -1; } a = a->next; } return -1; } static void _pdp_pool_expand_nolock(void){ int i; /* double the size */ int new_pool_size = pdp_pool_size << 1; t_pdp **new_pool = (t_pdp **)pdp_alloc(new_pool_size * sizeof(t_pdp *)); bzero(new_pool, new_pool_size * sizeof(t_pdp *)); memcpy(new_pool, pdp_pool, pdp_pool_size * sizeof(t_pdp *)); pdp_dealloc(pdp_pool); pdp_pool = new_pool; pdp_pool_size = new_pool_size; } /* private _pdp_packet methods */ /* packets can only be created and destroyed using these 2 methods */ /* it updates the mem usage and total packet count */ static void _pdp_packet_dealloc_nolock(t_pdp *p) { /* free memory */ pdp_dealloc (p); } static t_pdp* _pdp_packet_alloc_nolock(unsigned int datatype, unsigned int datasize) { unsigned int totalsize = datasize + PDP_HEADER_SIZE; t_pdp *p = (t_pdp *)pdp_alloc(totalsize); if (p){ memset(p, 0, PDP_HEADER_SIZE); //initialize header to 0 p->type = datatype; p->size = totalsize; p->users = 1; } return p; } /* create a new packet and expand pool if necessary */ static int _pdp_packet_create_nolock(unsigned int datatype, unsigned int datasize) { int p = 0; while(1){ for (; p < pdp_pool_size; p++){ if (!pdp_pool[p]){ /* found slot to store packet*/ t_pdp *header = _pdp_packet_alloc_nolock(datatype, datasize); if (!header) return -1; // error allocating packet pdp_pool[p] = header; return p; } } /* no slot found, expand pool */ _pdp_pool_expand_nolock(); } } void pdp_packet_destroy(void) { int i = 0; /* dealloc all the data in object stack */ pdp_post("DEBUG: pdp_packet_destroy: clearing object pool."); while ((i < pdp_pool_size) && (pdp_pool[i])) _pdp_packet_dealloc_nolock(pdp_pool[i++]); } /* public pool operations: have to be thread safe so each entry point locks the mutex */ /* create a new packet. this should only be used by type specific factory methods, and only if the reuse method fails, since it will always create a new packet */ int pdp_packet_create(unsigned int datatype, unsigned int datasize /*without header*/) { int packet; LOCK; packet = _pdp_packet_create_nolock(datatype, datasize); UNLOCK; return packet; } /* return a new packet. it tries to reuse a packet based on 1. matching data size 2. abscence of destructor (which SHOULD mean there are no enclosed references) it obviously can't use the reuse fifo tagged to a symbolic type description ALWAYS USE pdp_packet_reuse BEFORE calling pdp_packet_new if possible use both ONLY IN CONSTRUCTORS !!! use pdp_packet_factory to create packets as a "user" this is a summary of all internal packet creation mechanisms: -> pdp_packet_reuse, which uses symbolic type descriptions, and should work for all packet types it returns an initialized container (meta = correct, data = garbage) -> pdp_packet_new, which only works for non-pure packets, and reuses packets based on data type it returns a pure packet (meta + data = garbage) -> pdp_packet_create, like pdp_packet_new, only it always creates a new packet */ /* NEW DOES NOT USE THE REUSE FIFO !!!! this is a true and genuine mess: the reuse fifo can grow indefinitely with garbage elements if it's never used, while it points to stale packets.. backdoor access = BAD. if i recall, this is mainly a compatibility issue.. */ int pdp_packet_new(unsigned int datatype, unsigned int datasize) { t_pdp *header; int packet; LOCK; for (packet = 0; packet < pdp_pool_size; packet++){ header = pdp_pool[packet]; /* check data size */ if (header && header->users == 0 // must be unused && header->size == datasize + PDP_HEADER_SIZE // must be same size && !(header->theclass && header->theclass->cleanup)){ // must be pure packet (no destructor) /* ok, got one. initialize */ memset(header, 0, PDP_HEADER_SIZE); header->users = 1; header->type = datatype; header->size = datasize + PDP_HEADER_SIZE; UNLOCK; //EXIT1 return packet; } } /* no usable non-pure packet found, create a new one */ UNLOCK; //EXIT2 return pdp_packet_create(datatype, datasize); } /* internal method to add a packet to a packet type description symbol's unused packet fifo */ void _pdp_packet_save_nolock(int packet) { t_pdp *header = pdp_packet_header(packet); t_pdp_symbol *s; PDP_ASSERT(header); PDP_ASSERT(header->users == 0); PDP_ASSERT(header->desc); s = header->desc; if (!s->s_reusefifo) s->s_reusefifo = pdp_list_new(0); /* big o hack: since pdp_packet_new can reap packets behind our back, we won't add a packet if it's already in here */ if (1) { t_pdp_atom *a = s->s_reusefifo->first; while (a){ if (a->w.w_packet == packet) goto found; a = a->next; } } pdp_list_add(s->s_reusefifo, a_packet, (t_pdp_word)packet); found: if (PDP_DEBUG){ int el = s->s_reusefifo->elements; int maxel = 100; if (el > maxel) pdp_post("WARNING: %s reuse fifo has %d elements.", s->s_name, el); } } /* this will revive a packet matching a certain type description no wildcards are allowed */ int pdp_packet_reuse(t_pdp_symbol *type_description) { int packet = -1; t_pdp *header = 0; t_pdp_list *l = 0; LOCK; if (!type_description || !(l = type_description->s_reusefifo)) goto exit; while(l->elements){ packet = pdp_list_pop(l).w_packet; header = pdp_packet_header(packet); /* check if reuse fifo is consistent (packet unused + correct type) packet could be deleted and replaced with another one, or revived without the index updated (it's a "hint cache") */ if (header->users == 0){ /* check if type matches */ if (pdp_type_description_match(header->desc, type_description)){ header->users++; // revive goto exit; } /* if not, add the packet to the correct reuse fifo */ else{ _pdp_packet_save_nolock(packet); } } /* remove dangling refs */ header = 0; packet = -1; } exit: UNLOCK; if (header && header->theclass && header->theclass->wakeup){ header->theclass->wakeup(header); // revive if necessary } return packet; } /* find all unused packets in pool, marked as used (to protect from other reapers) and return them as a list. non-pure packets are not revived */ /* this returns a copy of a packet for read only access. (increases refcount of the packet -> packet will become readonly if it was writable, i.e. had rc=1 */ int pdp_packet_copy_ro(int handle) { t_pdp* header; if (header = pdp_packet_header(handle)){ PDP_ASSERT(header->users); // consistency check LOCK; header->users++; // increment reference count UNLOCK; } else handle = -1; return handle; } /* clone a packet: create a new packet with the same type as the source packet */ int pdp_packet_clone_rw(int handle) { t_pdp* header; int new_handle = -1; if (header = pdp_packet_header(handle)){ /* consistency checks */ PDP_ASSERT(header->users); PDP_ASSERT(header->desc); /* first try to reuse old packet */ new_handle = pdp_packet_reuse(header->desc); /* if this failed, create a new one using the central packet factory method */ if (-1 == new_handle) new_handle = pdp_factory_newpacket(header->desc); /* if the factory method failed cline it manually */ if (-1 == new_handle) { t_pdp *new_header; //pdp_post("WARNING: pdp_clone_rw: working around non-implemented factory method."); new_handle = pdp_packet_new(header->type, header->size - PDP_HEADER_SIZE); new_header = pdp_packet_header(new_handle); if (new_header){ memcpy(new_header, header, PDP_HEADER_SIZE); } } } return new_handle; } /* return a copy of a packet (clone + copy data) */ int pdp_packet_copy_rw(int handle) { t_pdp *header, *new_header; int new_handle = -1; if (!(header = pdp_packet_header(handle))) return -1; /* check if we are allowed to copy */ if (header->flags & PDP_FLAG_DONOTCOPY) return -1; /* get target packet */ new_handle = pdp_packet_clone_rw(handle); if (-1 == new_handle) return -1; new_header = pdp_packet_header(new_handle); /* if there is a copy method, use that one */ if (header->theclass && header->theclass->copy){ header->theclass->copy(header, new_header); } /* otherwize copy the data verbatim */ else { memcpy(pdp_packet_data(new_handle), pdp_packet_data(handle), pdp_packet_data_size(handle)); } return new_handle; } /* decrement refcount */ void pdp_packet_mark_unused(int handle) { t_pdp *header; if (!(header = pdp_packet_header(handle))) return; PDP_ASSERT(header->users); // consistency check LOCK; /* just decrement refcount */ if (header->users > 1){ header->users--; } /* put packet to sleep if refcount 1->0 */ else { if (header->theclass && header->theclass->sleep){ /* call sleep method (if any) outside of lock while the packet is still alive, so it won't be acclaimed by another thread */ UNLOCK; header->theclass->sleep(header); LOCK; } /* clear refcount & save in fifo for later use */ header->users = 0; if (header->desc) // sleep could have destructed packet.. _pdp_packet_save_nolock(handle); } UNLOCK; } /* delete a packet. rc needs to be == 1 */ void pdp_packet_delete(int handle) { t_pdp *header; header = pdp_packet_header(handle); PDP_ASSERT(header); PDP_ASSERT(header->users == 1); // consistency check LOCK; if (header->theclass && header->theclass->cleanup){ /* call cleanup method (if any) outside of lock while the packet is still alive, so it won't be acclaimed by another thread */ UNLOCK; header->theclass->cleanup(header); LOCK; } /* delete the packet */ pdp_pool[handle] = 0; _pdp_packet_dealloc_nolock(header); UNLOCK; } /* public data access methods */ t_pdp* pdp_packet_header(int handle) { if ((handle >= 0) && (handle < pdp_pool_size)) return pdp_pool[handle]; else return 0; } void* pdp_packet_subheader(int handle) { t_pdp* header = pdp_packet_header(handle); if (!header) return 0; return (void *)(&header->info.raw); } void* pdp_packet_data(int handle) { t_pdp *h; if ((handle >= 0) && (handle < pdp_pool_size)) { h = pdp_pool[handle]; if (!h) return 0; return (char *)(h) + PDP_HEADER_SIZE; } else return 0; } int pdp_packet_data_size(int handle) { t_pdp *h; if ((handle >= 0) && (handle < pdp_pool_size)) { h = pdp_pool[handle]; if (!h) return 0; return h->size - PDP_HEADER_SIZE; } else return 0; } int pdp_packet_writable(int packet) /* returns true if packet is writable */ { t_pdp *h = pdp_packet_header(packet); if (!h) return 0; return (h->users == 1); } void pdp_packet_replace_with_writable(int *packet) /* replaces a packet with a writable copy */ { int new_p; if (!pdp_packet_writable(*packet)){ new_p = pdp_packet_copy_rw(*packet); pdp_packet_mark_unused(*packet); *packet = new_p; } } /* pool stuff */ int pdp_pool_collect_garbage(void) { pdp_post("ERROR: garbage collector not implemented"); return 0; } void pdp_pool_set_max_mem_usage(int __attribute__((unused)) max) { pdp_post("ERROR: mem limit not implemented"); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/system/kernel/pdp_packet2.c000066400000000000000000000352351266045153600214520ustar00rootroot00000000000000/* * Pure Data Packet system implementation: Packet Manager * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include "pdp_post.h" #include "pdp_packet.h" #include "pdp_mem.h" #include "pdp_list.h" #include "pdp_type.h" #include "pdp_debug.h" /* packet implementation. contains class and packet (instance) handling some notes on packet operations. copy ro/rw and unregister are relatively straightforward packet creation can be done in 2 ways in this interface: create + reuse however, these methods should only be called by specific factory methods, so the user should only create packets using pdp_factory_newpacket reuse or create is thus the responsability of the factory methods for each packet type (class) implementation */ /* NOTE: the packet pool methods are called within the pool locks. this probably needs to change, because it will cause deadlocks for container packets (fobs) */ /* new implementation: probably just a minor adjustment: add the reuse fifo attached to type desc symbol name need to check and possibly eliminate hacks for non-pure packets pdp_packet_new: LOCK 1. check reuse fifo 2. empty -> create packet+return (search array) 3. element -> check if type is correct, yes->pop+return, no->goto 1. UNLOCK 4. wakeup pdp_packet_mark_unused 1. check refcount. if > 1 dec + exit 2. if 1 put packet to sleep 3. dec refcount 4. add to reuse fifo (no fifo -> create) pdp_packet_delete: analogous to mark_unused pdp_packet_copy_ro/rw: analogous to new */ /* the pool */ #define PDP_INITIAL_POOL_SIZE 64 static int pdp_pool_size; static t_pdp** pdp_pool; /* mutex: protects the pool and reuse lists attached to symbols */ static pthread_mutex_t pdp_pool_mutex; #define LOCK pthread_mutex_lock (&pdp_pool_mutex) #define UNLOCK pthread_mutex_unlock (&pdp_pool_mutex) /* the list of classes */ static t_pdp_list *class_list; /* debug */ void pdp_packet_print_debug(int packet) { t_pdp *h = pdp_packet_header(packet); pdp_post("debug info for packet %d", packet); if (!h){ pdp_post("invalid packet"); } else{ pdp_post ("\ttype: %d", h->type); pdp_post ("\tdesc: %s", h->desc ? h->desc->s_name : "unknown"); pdp_post ("\tsize: %d", h->size); pdp_post ("\tflags: %x", h->flags); pdp_post ("\tusers: %d", h->users); pdp_post ("\tclass: %x", h->theclass); } } /* setup methods */ void pdp_packet_setup(void) { pdp_pool_size = PDP_INITIAL_POOL_SIZE; pdp_pool = (t_pdp **)pdp_alloc(PDP_INITIAL_POOL_SIZE * sizeof(t_pdp *)); bzero(pdp_pool, pdp_pool_size * sizeof(t_pdp *)); class_list = pdp_list_new(0); pthread_mutex_init(&pdp_pool_mutex, NULL); } /* class methods */ t_pdp_class *pdp_class_new(t_pdp_symbol *type, t_pdp_factory_method create){ t_pdp_class *c = (t_pdp_class *)pdp_alloc(sizeof(t_pdp_class)); memset(c, 0, sizeof(t_pdp_class)); c->create = create; c->type = type; // set type pdp_list_add(class_list, a_pointer, (t_pdp_word)((void *)c)); return c; } /* the packet factory */ int pdp_factory_newpacket(t_pdp_symbol *type) { int p; t_pdp_class *c; t_pdp_atom *a = class_list->first; /* try to reuse first THINK: should this be the responsability of the type specific constructors, or should a packet allways be reusable (solution: depends on what the cleanup method returns??) */ p = pdp_packet_reuse(type); if (-1 != p) return p; /* call class constructor */ while(a){ c = (t_pdp_class *)(a->w.w_pointer); if (c->type && pdp_type_description_match(type, c->type)){ //pdp_post("method %x, type %s", c->create, type->s_name); return (c->create) ? (*c->create)(type) : -1; } a = a->next; } return -1; } static void _pdp_pool_expand_nolock(void){ int i; /* double the size */ int new_pool_size = pdp_pool_size << 1; t_pdp **new_pool = (t_pdp **)pdp_alloc(new_pool_size * sizeof(t_pdp *)); bzero(new_pool, new_pool_size * sizeof(t_pdp *)); memcpy(new_pool, pdp_pool, pdp_pool_size * sizeof(t_pdp *)); pdp_dealloc(pdp_pool); pdp_pool = new_pool; pdp_pool_size = new_pool_size; } /* private _pdp_packet methods */ /* packets can only be created and destroyed using these 2 methods */ /* it updates the mem usage and total packet count */ static void _pdp_packet_dealloc_nolock(t_pdp *p) { /* free memory */ pdp_dealloc (p); } static t_pdp* _pdp_packet_alloc_nolock(unsigned int datatype, unsigned int datasize) { unsigned int totalsize = datasize + PDP_HEADER_SIZE; t_pdp *p = (t_pdp *)pdp_alloc(totalsize); if (p){ memset(p, 0, PDP_HEADER_SIZE); //initialize header to 0 p->type = datatype; p->size = totalsize; p->users = 1; } return p; } /* create a new packet and expand pool if necessary */ static int _pdp_packet_create_nolock(unsigned int datatype, unsigned int datasize) { int p = 0; while(1){ for (; p < pdp_pool_size; p++){ if (!pdp_pool[p]){ /* found slot to store packet*/ t_pdp *header = _pdp_packet_alloc_nolock(datatype, datasize); if (!header) return -1; // error allocating packet pdp_pool[p] = header; return p; } } /* no slot found, expand pool */ _pdp_pool_expand_nolock(); } } void pdp_packet_destroy(void) { int i = 0; /* dealloc all the data in object stack */ pdp_post("DEBUG: pdp_packet_destroy: clearing object pool."); while ((i < pdp_pool_size) && (pdp_pool[i])) _pdp_packet_dealloc_nolock(pdp_pool[i++]); } /* public pool operations: have to be thread safe so each entry point locks the mutex */ /* create a new packet. this should only be used by type specific factory methods, and only if the reuse method fails, since it will always create a new packet */ int pdp_packet_create(unsigned int datatype, unsigned int datasize /*without header*/) { int packet; LOCK; packet = _pdp_packet_create_nolock(datatype, datasize); UNLOCK; return packet; } /* return a new packet. it tries to reuse a packet based on 1. matching data size 2. abscence of destructor (which SHOULD mean there are no enclosed references) it obviously can't use the reuse fifo tagged to a symbolic type description ALWAYS USE pdp_packet_reuse BEFORE calling pdp_packet_new if possible use both ONLY IN CONSTRUCTORS !!! use pdp_packet_factory to create packets as a "user" this is a summary of all internal packet creation mechanisms: -> pdp_packet_reuse, which uses symbolic type descriptions, and should work for all packet types it returns an initialized container (meta = correct, data = garbage) -> pdp_packet_new, which only works for non-pure packets, and reuses packets based on data type it returns a pure packet (meta + data = garbage) -> pdp_packet_create, like pdp_packet_new, only it always creates a new packet */ int pdp_packet_new(unsigned int datatype, unsigned int datasize) { t_pdp *header; int packet; LOCK; for (packet = 0; packet < pdp_pool_size; packet++){ header = pdp_pool[packet]; /* check data size */ if (header && header->users == 0 && header->size == datasize + PDP_HEADER_SIZE && !(header->theclass && header->theclass->cleanup)){ /* ok, got one. initialize */ memset(header, 0, PDP_HEADER_SIZE); header->users = 1; header->type = datatype; header->size = datasize + PDP_HEADER_SIZE; UNLOCK; //EXIT1 return packet; } } /* no usable non-pure packet found, create a new one */ UNLOCK; //EXIT2 return pdp_packet_create(datatype, datasize); } /* internal method to add a packet to a packet type description symbol's unused packet fifo */ void _pdp_packet_save_nolock(int packet) { t_pdp *header = pdp_packet_header(packet); t_pdp_symbol *s; PDP_ASSERT(header); PDP_ASSERT(header->users == 0); PDP_ASSERT(header->desc); s = header->desc; if (!s->s_reusefifo) s->s_reusefifo = pdp_list_new(0); pdp_list_add(s->s_reusefifo, a_packet, (t_pdp_word)packet); } /* this will revive a packet matching a certain type description no wildcards are allowed */ int pdp_packet_reuse(t_pdp_symbol *type_description) { int packet = -1; t_pdp *header = 0; t_pdp_list *l = 0; LOCK; if (!type_description || !(l = type_description->s_reusefifo)) goto exit; while(l->elements){ packet = pdp_list_pop(l).w_packet; header = pdp_packet_header(packet); /* check if reuse fifo is consistent (packet unused + correct type) packet could be deleted and replaced with another one, or revived without the index updated (it's a "hint cache") */ if (header->users == 0){ /* check if type matches */ if (pdp_type_description_match(header->desc, type_description)){ header->users++; // revive goto exit; } /* if not, add the packet to the correct reuse fifo */ else{ _pdp_packet_save_nolock(packet); } } /* remove dangling refs */ header = 0; packet = -1; } exit: UNLOCK; if (header && header->theclass && header->theclass->wakeup){ header->theclass->wakeup(header); // revive if necessary } return packet; } /* find all unused packets in pool, marked as used (to protect from other reapers) and return them as a list. non-pure packets are not revived */ /* this returns a copy of a packet for read only access. (increases refcount of the packet -> packet will become readonly if it was writable, i.e. had rc=1 */ int pdp_packet_copy_ro(int handle) { t_pdp* header; if (header = pdp_packet_header(handle)){ PDP_ASSERT(header->users); // consistency check LOCK; header->users++; // increment reference count UNLOCK; } else handle = -1; return handle; } /* clone a packet: create a new packet with the same type as the source packet */ int pdp_packet_clone_rw(int handle) { t_pdp* header; int new_handle = -1; if (header = pdp_packet_header(handle)){ /* consistency checks */ PDP_ASSERT(header->users); PDP_ASSERT(header->desc); /* first try to reuse old packet */ new_handle = pdp_packet_reuse(header->desc); /* if this failed, create a new one using the central packet factory method */ if (-1 == new_handle) new_handle = pdp_factory_newpacket(header->desc); } return new_handle; } /* return a copy of a packet (clone + copy data) */ int pdp_packet_copy_rw(int handle) { t_pdp *header, *new_header; int new_handle = -1; if (!(header = pdp_packet_header(handle))) return -1; /* check if we are allowed to copy */ if (header->flags & PDP_FLAG_DONOTCOPY) return -1; /* get target packet */ new_handle = pdp_packet_clone_rw(handle); if (-1 == new_handle) return -1; new_header = pdp_packet_header(new_handle); /* if there is a copy method, use that one */ if (header->theclass && header->theclass->copy){ header->theclass->copy(header, new_header); } /* otherwize copy the data verbatim */ else { memcpy(pdp_packet_data(new_handle), pdp_packet_data(handle), pdp_packet_data_size(handle)); } return new_handle; } /* decrement refcount */ void pdp_packet_mark_unused(int handle) { t_pdp *header; if (!(header = pdp_packet_header(handle))) return; PDP_ASSERT(header->users); // consistency check LOCK; /* just decrement refcount */ if (header->users > 1){ header->users--; } /* put packet to sleep if refcount 1->0 */ else { if (header->theclass && header->theclass->sleep){ /* call sleep method (if any) outside of lock while the packet is still alive, so it won't be acclaimed by another thread */ UNLOCK; header->theclass->sleep(header); LOCK; } /* clear refcount & save in fifo for later use */ header->users = 0; if (header->desc) // sleep could have destructed packet.. _pdp_packet_save_nolock(handle); } UNLOCK; } /* delete a packet. rc needs to be == 1 */ void pdp_packet_delete(int handle) { t_pdp *header; header = pdp_packet_header(handle); PDP_ASSERT(header); PDP_ASSERT(header->users == 1); // consistency check LOCK; if (header->theclass && header->theclass->cleanup){ /* call cleanup method (if any) outside of lock while the packet is still alive, so it won't be acclaimed by another thread */ UNLOCK; header->theclass->cleanup(header); LOCK; } /* delete the packet */ pdp_pool[handle] = 0; _pdp_packet_dealloc_nolock(header); UNLOCK; } /* public data access methods */ t_pdp* pdp_packet_header(int handle) { if ((handle >= 0) && (handle < pdp_pool_size)) return pdp_pool[handle]; else return 0; } void* pdp_packet_subheader(int handle) { t_pdp* header = pdp_packet_header(handle); if (!header) return 0; return (void *)(&header->info.raw); } void* pdp_packet_data(int handle) { t_pdp *h; if ((handle >= 0) && (handle < pdp_pool_size)) { h = pdp_pool[handle]; if (!h) return 0; return (char *)(h) + PDP_HEADER_SIZE; } else return 0; } int pdp_packet_data_size(int handle) { t_pdp *h; if ((handle >= 0) && (handle < pdp_pool_size)) { h = pdp_pool[handle]; if (!h) return 0; return h->size - PDP_HEADER_SIZE; } else return 0; } int pdp_packet_writable(int packet) /* returns true if packet is writable */ { t_pdp *h = pdp_packet_header(packet); if (!h) return 0; return (h->users == 1); } void pdp_packet_replace_with_writable(int *packet) /* replaces a packet with a writable copy */ { int new_p; if (!pdp_packet_writable(*packet)){ new_p = pdp_packet_copy_rw(*packet); pdp_packet_mark_unused(*packet); *packet = new_p; } } /* pool stuff */ int pdp_pool_collect_garbage(void) { pdp_post("ERROR: garbage collector not implemented"); return 0; } void pdp_pool_set_max_mem_usage(int max) { pdp_post("ERROR: mem limit not implemented"); } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/system/kernel/pdp_post.c000066400000000000000000000024351266045153600211020ustar00rootroot00000000000000 /* * Pure Data Packet system file. pdp logging. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include "pdp_post.h" /* list printing should be moved here too */ /* write a message to log (console) */ void _pdp_post_n(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } void _pdp_post(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); putc('\n', stderr); } pdp-0.14.1+darcs20180201/system/kernel/pdp_symbol.c000066400000000000000000000116511266045153600214220ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : code implementing pdp's namespace (symbols) * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include "pdp_symbol.h" #include "pdp_list.h" #include "pdp_debug.h" // some extra prototypes void *pdp_alloc(int size); void pdp_dealloc(void *data); // the symbol hash mutex static pthread_mutex_t pdp_hash_mutex; #define HASHSIZE 1024 static t_pdp_symbol *pdp_symhash[HASHSIZE]; #define LOCK pthread_mutex_lock(&pdp_hash_mutex) #define UNLOCK pthread_mutex_unlock(&pdp_hash_mutex) static void _pdp_symbol_init(t_pdp_symbol *s) { memset(s, 0, sizeof(*s)); s->s_forth.t = a_undef; } /* shamelessly copied from pd src and made thread safe */ t_pdp_symbol *_pdp_dogensym(char *s, t_pdp_symbol *oldsym) { t_pdp_symbol **sym1, *sym2; unsigned int hash1 = 0, hash2 = 0; int length = 0; char *s2 = s; while (*s2) { hash1 += *s2; hash2 += hash1; length++; s2++; } sym1 = pdp_symhash + (hash2 & (HASHSIZE-1)); /* lock hash */ LOCK; while (sym2 = *sym1) { if (!strcmp(sym2->s_name, s)) goto gotit; sym1 = &sym2->s_next; } if (oldsym){ sym2 = oldsym; } else { sym2 = (t_pdp_symbol *)pdp_alloc(sizeof(*sym2)); _pdp_symbol_init(sym2); sym2->s_name = pdp_alloc(length+1); sym2->s_next = 0; strcpy(sym2->s_name, s); } *sym1 = sym2; gotit: /* unlock hash */ UNLOCK; return (sym2); } t_pdp_symbol *pdp_gensym(char *s) { return(_pdp_dogensym(s, 0)); } /* connect a parsed typelist to a symbol type name 1 = succes, 0 = error (symbol already connected) */ int pdp_symbol_set_typelist(t_pdp_symbol *s, t_pdp_list *typelist) { int status = 0; LOCK; if (!s->s_type){ s->s_type = typelist; status = 1; } UNLOCK; return status; } void pdp_symbol_apply_all(t_pdp_symbol_iterator it) { int i; for (i=0; is_next){ it(s); } } } t_pdp_symbol _pdp_sym_wildcard; t_pdp_symbol _pdp_sym_float; t_pdp_symbol _pdp_sym_int; t_pdp_symbol _pdp_sym_symbol; t_pdp_symbol _pdp_sym_packet; t_pdp_symbol _pdp_sym_pointer; t_pdp_symbol _pdp_sym_invalid; t_pdp_symbol _pdp_sym_list; t_pdp_symbol _pdp_sym_question_mark; t_pdp_symbol _pdp_sym_atom; t_pdp_symbol _pdp_sym_null; t_pdp_symbol _pdp_sym_quote_start; t_pdp_symbol _pdp_sym_quote_end; t_pdp_symbol _pdp_sym_return; t_pdp_symbol _pdp_sym_nreturn; t_pdp_symbol _pdp_sym_defstart; t_pdp_symbol _pdp_sym_defend; t_pdp_symbol _pdp_sym_if; t_pdp_symbol _pdp_sym_then; t_pdp_symbol _pdp_sym_local; t_pdp_symbol _pdp_sym_forth; t_pdp_symbol _pdp_sym_call; t_pdp_symbol _pdp_sym_push; t_pdp_symbol _pdp_sym_pop; static void _sym(char *name, t_pdp_symbol *s) { t_pdp_symbol *realsym; _pdp_symbol_init(s); s->s_name = name; realsym = _pdp_dogensym(name, s); PDP_ASSERT(realsym == s); // if this fails, the symbol was already defined } void pdp_symbol_setup(void) { // create mutexes pthread_mutex_init(&pdp_hash_mutex, NULL); // init symbol hash memset(pdp_symhash, 0, HASHSIZE * sizeof(t_pdp_symbol *)); // setup predefined symbols (those that have direct pointer access for speedup) _sym("*", &_pdp_sym_wildcard); _sym("float", &_pdp_sym_float); _sym("int", &_pdp_sym_int); _sym("symbol", &_pdp_sym_symbol); _sym("packet", &_pdp_sym_packet); _sym("pointer", &_pdp_sym_pointer); _sym("invalid", &_pdp_sym_invalid); _sym("list", &_pdp_sym_list); _sym("?", &_pdp_sym_question_mark); _sym("atom", &_pdp_sym_atom); _sym("null", &_pdp_sym_null); _sym("[", &_pdp_sym_quote_start); _sym("]", &_pdp_sym_quote_end); _sym("ret", &_pdp_sym_return); _sym("nret", &_pdp_sym_nreturn); _sym(":", &_pdp_sym_defstart); _sym(";", &_pdp_sym_defend); _sym("if", &_pdp_sym_if); _sym("then", &_pdp_sym_then); _sym("local", &_pdp_sym_local); _sym("forth", &_pdp_sym_forth); _sym("call", &_pdp_sym_call); _sym("push", &_pdp_sym_push); _sym("pop", &_pdp_sym_pop); } pdp-0.14.1+darcs20180201/system/kernel/pdp_type.c000066400000000000000000000325411266045153600210770ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : code for handling different packet types * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains type handling routines */ #include #include #include #include "pdp_list.h" #include "pdp_symbol.h" #include "pdp_packet.h" #include "pdp_post.h" #include "pdp_type.h" #include "pdp_mem.h" #include "pdp_debug.h" // debug #define D if (0) static t_pdp_list *conversion_list; #define INIT_MAX_CACHE_SIZE 32 static t_pdp_list *cached_conversion_list; static int max_cache_size; /* mutex */ static pthread_mutex_t pdp_conversion_mutex; static pthread_mutex_t pdp_cache_mutex; /* convert a type to a list */ t_pdp_list *pdp_type_to_list(t_pdp_symbol *type) { #define TMPSIZE 1024 char *c = type->s_name; char *lastname = c; int n = 0; char tmp[strlen(type->s_name)+1]; t_pdp_list *l = pdp_list_new(0); while(*c){ if (*c == '/'){ strncpy(tmp, lastname, n); tmp[n] = 0; pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(tmp)); c++; lastname = c; n = 0; } else{ c++; n++; PDP_ASSERT(n < TMPSIZE); } } pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(lastname)); return l; } /* get the description symbol. */ t_pdp_symbol *pdp_packet_get_description(int packet) { t_pdp *header = pdp_packet_header(packet); if (!header) return pdp_gensym("invalid"); else if (!header->desc){ /* since every packet is obliged to have a description, this is an error */ pdp_post("ERROR: pdp_packet_get_description: packet %d has no description.", packet); pdp_packet_print_debug(packet); return pdp_gensym("unknown"); } else return header->desc; } /* this runs a conversion program */ int _pdp_type_run_conversion_program(t_pdp_conversion_program *program, int packet, t_pdp_symbol *dest_template) { /* run a conversion program: treat the source packet as readonly, and cleanup intermediates, such that the net result is the production of a new packet, with the source packet intact. */ int p, tmp; t_pdp_atom *a; t_pdp_conversion_method m; // run the first line of the program a = program->first; m = a->w.w_pointer; D pdp_post("DEBUG: _pdp_type_run_conversion_program: method = %x", m); p = m(packet, dest_template); D pdp_post("DEBUG: _pdp_type_run_conversion_program:"); D pdp_post(" packet returned = %d, type = %s", p, pdp_packet_get_description(p)->s_name); // run the remaining lines + cleanup intermediates for (a=a->next; a; a=a->next){ m = a->w.w_pointer; D pdp_post("DEBUG: _pdp_type_run_conversion_program: next method ptr = %x", m); tmp = m(p, dest_template); pdp_packet_mark_unused(p); p = tmp; } return p; } /* find a conversion program */ t_pdp_conversion_program * _pdp_type_find_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern) { t_pdp_conversion *c; t_pdp_atom *a; t_pdp_conversion_program *retval = 0; /* lock conversion list */ pthread_mutex_lock(&pdp_conversion_mutex); for (a = conversion_list->first; a; a=a->next){ c = a->w.w_pointer; /* can be a wildcard match */ if (pdp_type_description_match(src_pattern, c->src_pattern) && pdp_type_description_match(dst_pattern, c->dst_pattern)) { /* found a program */ D pdp_post("DEBUG: _pdp_type_find_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name); retval = c->program; goto gotit; } } /* no conversion program was found */ retval = 0; gotit: /* lock conversion list */ pthread_mutex_unlock(&pdp_conversion_mutex); return retval; } /* find a cached conversion program if one is found it will be moved to the back of the queue (MRU) */ t_pdp_conversion_program * _pdp_type_find_cached_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern) { t_pdp_conversion *c, *c_tmp; t_pdp_atom *a; t_pdp_conversion_program *retval = 0; /* lock cached list */ pthread_mutex_lock(&pdp_cache_mutex); for (a = cached_conversion_list->first; a; a=a->next){ c = a->w.w_pointer; /* must be exact match */ if ((src_pattern == c->src_pattern) && (dst_pattern == c->dst_pattern)) { /* found a program */ D pdp_post("DEBUG: _pdp_type_find_cached_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name); retval = c->program; /* make MRU (move to back) */ c_tmp = cached_conversion_list->last->w.w_pointer; cached_conversion_list->last->w.w_pointer = c; a->w.w_pointer = c_tmp; goto gotit; } } retval = 0; gotit: /* un lock cached list */ pthread_mutex_unlock(&pdp_cache_mutex); /* no conversion program was found */ return retval; } /* conversion program manipulations */ void pdp_conversion_program_free(t_pdp_conversion_program *program) { pdp_list_free(program); } /* debug print */ void _pdp_conversion_program_print(t_pdp_conversion_program *program) { D pdp_post("_pdp_conversion_program_print %x", program); pdp_list_print(program); } t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...) { t_pdp_conversion_program *p = pdp_list_new(0); t_pdp_conversion_method m = method; va_list ap; D pdp_post("DEBUG: pdp_conversion_program_new:BEGIN"); pdp_list_add_back_pointer(p, m); va_start(ap, method); while (m = va_arg(ap, t_pdp_conversion_method)) pdp_list_add_back_pointer(p, m); va_end(ap); D pdp_post("DEBUG: pdp_conversion_program_new:END"); return p; } t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program) { if (program) return pdp_list_copy(program); else return 0; } void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail) { return pdp_list_cat(program, tail); } /* conversion registration */ void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program) { t_pdp_conversion *c = (t_pdp_conversion *)pdp_alloc(sizeof(*c)); c->src_pattern = src_pattern; c->dst_pattern = dst_pattern; c->program = program; /* lock conversion list */ pthread_mutex_lock(&pdp_conversion_mutex); pdp_list_add_back_pointer(conversion_list, c); /* unlock conversion list */ pthread_mutex_unlock(&pdp_conversion_mutex); } /* register a cached conversion */ void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program) { /* create the new conversion */ t_pdp_conversion *c = (t_pdp_conversion *)pdp_alloc(sizeof(*c)); c->src_pattern = src_pattern; c->dst_pattern = dst_pattern; c->program = program; /* lock cached conversion list */ pthread_mutex_lock(&pdp_cache_mutex); /* check size, and remove LRU (top) if the cache is full */ while (cached_conversion_list->elements >= max_cache_size){ t_pdp_conversion *c_old = pdp_list_pop(cached_conversion_list).w_pointer; if (c_old->program) pdp_conversion_program_free(c_old->program); pdp_dealloc(c_old); } /* add and make MRU (back) */ pdp_list_add_back_pointer(cached_conversion_list, c); /* unlock cached conversion list */ pthread_mutex_unlock(&pdp_cache_mutex); } /* convert a given packet to a certain type (template) */ int _pdp_packet_convert(int packet, t_pdp_symbol *dest_template) { t_pdp_symbol *type = pdp_packet_get_description(packet); t_pdp_symbol *tmp_type = 0; int tmp_packet = -1; t_pdp_conversion_program *program = 0; t_pdp_conversion_program *program_last = 0; t_pdp_conversion_program *program_tail = 0; /* check if there is a program in the cached list, if so run it */ if (program = _pdp_type_find_cached_conversion_program(type, dest_template)) return _pdp_type_run_conversion_program(program, packet, dest_template); /* if it is not cached, iteratively convert and save program on top of cache list if a conversion path (program) was found */ // run first conversion that matches program = pdp_conversion_program_copy (_pdp_type_find_conversion_program(type, dest_template)); program_last = program; if (!program){ D pdp_post("DEBUG: pdp_type_convert: (1) can't convert %s to %s", type->s_name, dest_template->s_name); return -1; } tmp_packet = _pdp_type_run_conversion_program(program, packet, dest_template); tmp_type = pdp_packet_get_description(tmp_packet); // run more conversions if necessary, deleting intermediate packets while (!pdp_type_description_match(tmp_type, dest_template)){ int new_packet; program_tail = _pdp_type_find_conversion_program(tmp_type, dest_template); if (!program_tail){ D pdp_post("DEBUG: pdp_type_convert: (2) can't convert %s to %s", tmp_type->s_name, dest_template->s_name); pdp_packet_mark_unused(tmp_packet); pdp_conversion_program_free(program); return -1; } if (program_last == program_tail){ //pdp_post("ERROR: pdp_packet_convert: conversion loop detected"); } program_last = program_tail; pdp_conversion_program_add(program, program_tail); new_packet = _pdp_type_run_conversion_program(program_tail, tmp_packet, dest_template); pdp_packet_mark_unused(tmp_packet); tmp_packet = new_packet; tmp_type = pdp_packet_get_description(tmp_packet); } // save the conversion program in the cache pdp_type_register_cached_conversion(type, dest_template, program); // return resulting packet return tmp_packet; } /* convert or copy ro */ int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_template) { t_pdp_symbol *type = pdp_packet_get_description(packet); /* if it is compatible, return a ro copy */ if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_ro(packet); /* if not, convert to a new type */ else return _pdp_packet_convert(packet, dest_template); } /* convert or copy rw */ int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_template) { t_pdp_symbol *type = pdp_packet_get_description(packet); /* if it is compatible, just return a rw copy */ if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_rw(packet); /* if not, convert to a new type */ else return _pdp_packet_convert(packet, dest_template); } /* this is a hack. type cache data: (a type description parsed into a pdp_list for fast comparison) should be setup when a packet symbol is created, but since that can be everywhere, we set it up on first use. type cache is permanent. */ static void _setup_type_cache(t_pdp_symbol *s) { t_pdp_list *l = pdp_type_to_list(s); if (!pdp_symbol_set_typelist(s, l)) pdp_list_free(l); // list was already present -> free cached list } /* check if a type description fits a template this function is symmetric */ int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern) { int match = 0; // no match until all tests are passed t_pdp_atom *ad, *ap; t_pdp_symbol *wildcard = PDP_SYM_WILDCARD; PDP_ASSERT(pattern); PDP_ASSERT(description); /* same type symbol -> match */ if (description == pattern) {match = 1; goto done;} /* check the description list */ if (!(description->s_type)) _setup_type_cache(description); if (!(pattern->s_type)) _setup_type_cache(pattern); /* compare symbols of description list */ for(ad=description->s_type->first, ap=pattern->s_type->first; ad && ap; ad=ad->next, ap=ap->next) { if (ad->w.w_symbol == wildcard) continue; if (ap->w.w_symbol == wildcard) continue; if (ad->w.w_symbol != ap->w.w_symbol) {goto done;} /* difference and not a wildcard */ } /* ok if sizes are equal */ if (! (ad || ap)) {match = 1; goto done;} /* one of the two is shorter, so the shortest list needs to end with a wildcard to have a match */ if (ap && description->s_type->last->w.w_symbol != wildcard) goto done; if (ad && pattern->s_type->last->w.w_symbol != wildcard) goto done; /* all tests passed: type templates match */ match = 1; done: D pdp_post("DEBUG: testing match between %s and %s: %s", description->s_name, pattern->s_name, match ? "match" : "no match"); return match; } /* setup method */ void pdp_type_setup(void) { int i; // create mutexes pthread_mutex_init(&pdp_conversion_mutex, NULL); pthread_mutex_init(&pdp_cache_mutex, NULL); // create conversion lists cached_conversion_list = pdp_list_new(0); conversion_list = pdp_list_new(0); max_cache_size = INIT_MAX_CACHE_SIZE; } pdp-0.14.1+darcs20180201/system/mmx/000077500000000000000000000000001266045153600164235ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/mmx/Makefile000066400000000000000000000007601266045153600200660ustar00rootroot00000000000000include ../../Makefile.config OBJ = \ pixel_pack_s16u8.o \ pixel_unpack_u8s16.o \ pixel_add_s16.o \ pixel_mul_s16.o \ pixel_mix_s16.o \ pixel_randmix_s16.o \ pixel_conv_hor_s16.o \ pixel_conv_ver_s16.o \ pixel_biquad_s16.o \ pixel_ca_s1.o \ pixel_rand_s16.o \ pixel_crot_s16.o \ pixel_gain_s16.o \ pixel_resample_s16.o \ pixel_cheby_s16.o all: $(OBJ) test: pdp_mmx_test.o $(OBJ) gcc -o pdp_mmx_test pdp_mmx_test.o $(OBJ) -g clean: rm -f *.o rm -f *~ rm -f pdp_mmx.a rm -f pdp_mmx_test pdp-0.14.1+darcs20180201/system/mmx/README000066400000000000000000000000701266045153600173000ustar00rootroot00000000000000These are obsoleted by C code using GCC MMX extensions. pdp-0.14.1+darcs20180201/system/mmx/pdp_mmx_test.c000066400000000000000000000023371266045153600212770ustar00rootroot00000000000000#include "pdp_mmx.h" #define FP(x) ((short int)(((float)(x) * 2 * 256.0f))) #define nbp 256 short int a1[4] = {0x0100,0x0100,0x0100,0x0100}; short int a2[4] = {0x0100,0x0100,0x0100,0x0100}; short int b0[4] = {0x0100,0x0100,0x0100,0x0100}; short int b1[4] = {0x0100,0x0100,0x0100,0x0100}; short int b2[4] = {0x0100,0x0100,0x0100,0x0100}; short int u1[4] = {0x0100,0x0100,0x0100,0x0100}; short int u2[4] = {0x0100,0x0100,0x0100,0x0100}; short int x0[4] = {0x0100,0x0100,0x0100,0x0100}; short int x1[4] = {0x0100,0x0100,0x0100,0x0100}; short int x2[4] = {0x0100,0x0100,0x0100,0x0100}; short int x3[4] = {0x0100,0x0100,0x0100,0x0100}; void print_pixel(unsigned int i) { if (i) printf("x "); else printf(". "); } void print_line(void) { printf("\n"); } void print_square(unsigned char *c) { int i,j; for(j=7; j>=0; j--){ for(i=0; i<8; i++) print_pixel(c[j] & (1<<(7-i))); printf("\n"); } } main() { unsigned char src[16]={1,2,3,4,5,6,7,8,-1,-2,-3,-4,-5,-6,-7,-8}; unsigned char dst[8]; print_square(src); print_line(); print_square(src+8); print_line(); pixel_test_s1(dst,src,1,1); print_square(dst); print_line(); } pdp-0.14.1+darcs20180201/system/mmx/pixel_add_s16.s000066400000000000000000000026161266045153600212360ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_add_s16 .type pixel_add_s16,@function # simple add # void pixel_add_s16(int *left, int *right, int nb_4pixel_vectors) pixel_add_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %edi # left array movl 12(%ebp), %esi # right array movl 16(%ebp), %ecx # pixel count .align 16 .loop_mix: # prefetch 128(%esi) movq (%esi), %mm1 # load right 4 pixels from memory movq (%edi), %mm0 # load 4 left pixels from memory paddsw %mm1, %mm0 # mix movq %mm0, (%edi) addl $8, %esi addl $8, %edi decl %ecx jnz .loop_mix # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_biquad_dirI_s16.s000066400000000000000000000177441266045153600227320ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # TODO MOVE TO DIRECT FORM II # y[k] = b0 * x[k] + u1[k-1] # u1[k] = b1 * x[k] + u2[k-1] - a1 * y[k] # u2[k] = b2 * x[k] - a2 * y[k] # input in register: # %mm0-mm3: input 4x4 pixels {x0 x1 x2 x3} # %esi: coef memory (a1, a2, b0, b1, b2) # %edi: state memory (u1, u2) # return in register: # %mm0-mm4: 4x4 pixels result .biquad_4x4_pixels: .align 16 # prescale movq -8(%esi), %mm4 pmulhw %mm4, %mm0 pmulhw %mm4, %mm1 pmulhw %mm4, %mm2 pmulhw %mm4, %mm3 psllw $1, %mm0 psllw $1, %mm1 psllw $1, %mm2 psllw $1, %mm3 # first vector movq 0(%edi), %mm4 # mm4 <- u[-1] movq 8(%edi), %mm5 # mm5 <- u[-2] movq %mm4, %mm6 movq %mm5, %mm7 pmulhw 0(%esi), %mm6 # multiply by a1 pmulhw 8(%esi), %mm7 # multiply by a2 paddsw %mm6, %mm0 # accumulate paddsw %mm7, %mm0 # accumulate paddsw %mm0, %mm0 # scale by 2 (since all fixed point muls are x*y/2) movq %mm0, %mm6 # mm6 <- u[0] movq %mm4, %mm7 # mm7 <- u[-1] pmulhw 16(%esi), %mm0 # multiply by b0 pmulhw 24(%esi), %mm4 # multiply by b1 pmulhw 32(%esi), %mm5 # multiply by b2 paddsw %mm4, %mm0 # accumulate paddsw %mm5, %mm0 # accumulate # mm0 is result 0 # second vector movq %mm6, %mm4 # mm4 <- u[0] movq %mm7, %mm5 # mm5 <- u[-1] pmulhw 0(%esi), %mm6 # multiply by a1 pmulhw 8(%esi), %mm7 # multiply by a2 paddsw %mm6, %mm1 # accumulate paddsw %mm7, %mm1 # accumulate paddsw %mm1, %mm1 # scale by 2 movq %mm1, %mm6 # mm6 <- u[1] movq %mm4, %mm7 # mm7 <- u[0] pmulhw 16(%esi), %mm1 # multiply by b0 pmulhw 24(%esi), %mm4 # multiply by b1 pmulhw 32(%esi), %mm5 # multiply by b2 paddsw %mm4, %mm1 # accumulate paddsw %mm5, %mm1 # accumulate # mm1 is result 1 # third vector movq %mm6, %mm4 # mm4 <- u[1] movq %mm7, %mm5 # mm5 <- u[0] pmulhw 0(%esi), %mm6 # multiply by a1 pmulhw 8(%esi), %mm7 # multiply by a2 paddsw %mm6, %mm2 # accumulate paddsw %mm7, %mm2 # accumulate paddsw %mm2, %mm2 # scale by 2 movq %mm2, %mm6 # mm6 <- u[2] movq %mm4, %mm7 # mm7 <- u[1] pmulhw 16(%esi), %mm2 # multiply by b0 pmulhw 24(%esi), %mm4 # multiply by b1 pmulhw 32(%esi), %mm5 # multiply by b2 paddsw %mm4, %mm2 # accumulate paddsw %mm5, %mm2 # accumulate # mm2 is result 2 # fourth vector movq %mm6, %mm4 # mm4 <- u[2] movq %mm7, %mm5 # mm5 <- u[1] pmulhw 0(%esi), %mm6 # multiply by a1 pmulhw 8(%esi), %mm7 # multiply by a2 paddsw %mm6, %mm3 # accumulate paddsw %mm7, %mm3 # accumulate paddsw %mm3, %mm3 # scale by 2 movq %mm3, 0(%edi) # store u[3] movq %mm4, 8(%edi) # store u[2] pmulhw 16(%esi), %mm3 # multiply by b0 pmulhw 24(%esi), %mm4 # multiply by b1 pmulhw 32(%esi), %mm5 # multiply by b2 paddsw %mm4, %mm3 # accumulate paddsw %mm5, %mm3 # accumulate # mm3 is result 3 ret # in order to use the 4 line parallel biquad routine on horizontal # lines, we need to reorder (rotate or transpose) the matrix, since # images are scanline encoded, and we want to work in parallell # on 4 lines. # # since the 4 lines are independent, it doesnt matter in which order # the the vector elements are present. # # this allows us to use the same routine for left->right and right->left # processing. # # some comments on the non-abelean group of square isometries consisting of # (I) identity # (H) horizontal axis mirror # (V) vertical axis mirror # (T) transpose (diagonal axis mirror) # (A) antitranspose (antidiagonal axis mirror) # (R1) 90deg anticlockwize rotation # (R2) 180deg rotation # (R3) 90deg clockwize rotation # # # we basicly have two options: (R1,R3) or (T,A) # we opt for T and A because they are self inverting, which improves locality # # use antitranspose for right to left an transpose # for left to right (little endian) # antitranspose 4x4 # input # %mm3 == {d0 d1 d2 d3} # %mm2 == {c0 c1 c2 c3} # %mm1 == {b0 b1 b2 b3} # %mm0 == {a0 a1 a2 a3} # output # %mm3 == {a3 b3 c3 d3} # %mm2 == {a2 b2 c2 d2} # %mm1 == {a1 b1 c1 d1} # %mm0 == {a0 b0 c0 d0} .antitranspose_4x4: .align 16 movq %mm3, %mm4 punpcklwd %mm1, %mm4 # mm4 <- {b2 d2 b3 d3} movq %mm3, %mm5 punpckhwd %mm1, %mm5 # mm5 <- {b0 d0 b1 d1} movq %mm2, %mm6 punpcklwd %mm0, %mm6 # mm6 <- {a2 c2 a3 c3} movq %mm2, %mm7 punpckhwd %mm0, %mm7 # mm7 <- {a0 c0 a1 c1} movq %mm4, %mm3 punpcklwd %mm6, %mm3 # mm3 <- {a3 b3 c3 d3} movq %mm4, %mm2 punpckhwd %mm6, %mm2 # mm2 <- {a2 b2 c2 d2} movq %mm5, %mm1 punpcklwd %mm7, %mm1 # mm1 <- {a1 b1 c1 d1} movq %mm5, %mm0 punpckhwd %mm7, %mm0 # mm0 <- {a0 b0 c0 d0} ret # transpose 4x4 # input # %mm3 == {d3 d2 d1 d0} # %mm2 == {c3 c2 c1 c0} # %mm1 == {b3 b2 b1 b0} # %mm0 == {a3 a2 a1 a0} # output # %mm3 == {d3 c3 b3 a3} # %mm2 == {d2 c2 b2 a2} # %mm1 == {d1 c1 b1 a1} # %mm0 == {d0 c0 b0 a0} .transpose_4x4: .align 16 movq %mm0, %mm4 punpcklwd %mm2, %mm4 # mm4 <- {c1 a1 c0 a0} movq %mm0, %mm5 punpckhwd %mm2, %mm5 # mm5 <- {c3 a3 c2 a2} movq %mm1, %mm6 punpcklwd %mm3, %mm6 # mm6 <- {d1 b1 d0 b0} movq %mm1, %mm7 punpckhwd %mm3, %mm7 # mm7 <- {d3 b3 d2 b2} movq %mm4, %mm0 punpcklwd %mm6, %mm0 # mm0 <- {d0 c0 b0 a0} movq %mm4, %mm1 punpckhwd %mm6, %mm1 # mm1 <- {d1 c1 b1 a1} movq %mm5, %mm2 punpcklwd %mm7, %mm2 # mm2 <- {d2 c2 b2 a2} movq %mm5, %mm3 punpckhwd %mm7, %mm3 # mm3 <- {d3 c3 b3 a3} ret .globl pixel_biquad_vertb_s16 .type pixel_biquad_vertb_s16,@function # pixel_biquad_vertbr_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_biquad_vertb_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .biquad_vertb_line_loop: movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 movq (%ebx,%eax,1), %mm3 call .biquad_4x4_pixels movq %mm0, (%ebx) movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) addl %edx, %ebx addl %eax, %ebx decl %ecx jnz .biquad_vertb_line_loop emms pop %edi pop %esi pop %ebx leave ret .globl pixel_biquad_horlr_s16 .type pixel_biquad_horlr_s16,@function # pixel_biquad_hor_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_biquad_horlr_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .biquad_horlr_line_loop: movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 movq (%ebx,%eax,1), %mm3 call .transpose_4x4 call .biquad_4x4_pixels call .transpose_4x4 movq %mm0, (%ebx) movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) addl $8, %ebx decl %ecx jnz .biquad_horlr_line_loop emms pop %edi pop %esi pop %ebx leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_biquad_s16.s000066400000000000000000000233531266045153600217540ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # DIRECT FORM II BIQUAD # # y[k] = b0 * x[k] + u1[k-1] # u1[k] = b1 * x[k] + u2[k-1] - a1 * y[k] # u2[k] = b2 * x[k] - a2 * y[k] # MACRO: df2 # # computes a direct form 2 biquad # does not use {mm0-mm3}\ # # input: == input # %mm4 == state 1 # %mm5 == state 2 # (%esi) == biquad coefs (-a1 -a2 b0 b1 b2) in s1.14 # output: == output # %mm4 == state 1 # %mm5 == state 2 .macro df2 reg movq \reg, %mm6 # mm6 == x[k] movq \reg, %mm7 # mm7 == x[k] pmulhw 16(%esi), %mm6 # mm6 == x[k] * b0 pmulhw 24(%esi), %mm7 # mm7 == x[k] * b1 paddw %mm4, %mm6 # mm6 == x[k] * b0 + u1[k-1] == y[k] paddw %mm5, %mm7 # mm7 == x[k] * b1 + u2[k-1] paddsw %mm6, %mm6 # compensate for mul = x*y/4 (coefs are s1.14 fixed point) paddsw %mm6, %mm6 # paddsw ensures saturation movq \reg, %mm5 # mm5 == x[k] movq %mm6, %mm4 # mm4 == y[k] movq %mm6, \reg # reg == y[k] -------------------- pmulhw 0(%esi), %mm4 # mm4 == y[k] * (-a1) pmulhw 8(%esi), %mm6 # mm6 == y[k] * (-a2) pmulhw 32(%esi), %mm5 # mm5 == x[k] * b2 paddw %mm7, %mm4 # mm4 == u1[k] -------------------- paddw %mm6, %mm5 # mm5 == u2[k] -------------------- .endm # input in register: # %mm0-mm3: input 4x4 pixels {x0 x1 x2 x3} # %esi: coef memory (-a1, -a2, b0, b1, b2) in s1.14 # %edi: state memory (u1, u2) # return in register: # %mm0-mm4: 4x4 pixels result .macro biquad_4x4_pixels .align 16 movq 0(%edi), %mm4 # get state movq 8(%edi), %mm5 df2 %mm0 # compute 4 biquads df2 %mm1 df2 %mm2 df2 %mm3 movq %mm4, 0(%edi) # store state movq %mm5, 8(%edi) .endm # in order to use the 4 line parallel biquad routine on horizontal # lines, we need to reorder (rotate or transpose) the matrix, since # images are scanline encoded, and we want to work in parallell # on 4 lines. # # since the 4 lines are independent, it doesnt matter in which order # the the vector elements are present. # # this allows us to use the same routine for left->right and right->left # processing. # # some comments on the non-abelean group of square isometries consisting of # (I) identity # (H) horizontal axis mirror # (V) vertical axis mirror # (T) transpose (diagonal axis mirror) # (A) antitranspose (antidiagonal axis mirror) # (R1) 90deg anticlockwize rotation # (R2) 180deg rotation # (R3) 90deg clockwize rotation # # # we basicly have two options: (R1,R3) or (T,A) # we opt for T and A because they are self inverting, which improves locality # # use antitranspose for right to left an transpose # for left to right (little endian) # antitranspose 4x4 # input # %mm3 == {d0 d1 d2 d3} # %mm2 == {c0 c1 c2 c3} # %mm1 == {b0 b1 b2 b3} # %mm0 == {a0 a1 a2 a3} # output # %mm3 == {a3 b3 c3 d3} # %mm2 == {a2 b2 c2 d2} # %mm1 == {a1 b1 c1 d1} # %mm0 == {a0 b0 c0 d0} .macro antitranspose_4x4 movq %mm3, %mm4 punpcklwd %mm1, %mm4 # mm4 <- {b2 d2 b3 d3} movq %mm3, %mm5 punpckhwd %mm1, %mm5 # mm5 <- {b0 d0 b1 d1} movq %mm2, %mm6 punpcklwd %mm0, %mm6 # mm6 <- {a2 c2 a3 c3} movq %mm2, %mm7 punpckhwd %mm0, %mm7 # mm7 <- {a0 c0 a1 c1} movq %mm4, %mm3 punpcklwd %mm6, %mm3 # mm3 <- {a3 b3 c3 d3} movq %mm4, %mm2 punpckhwd %mm6, %mm2 # mm2 <- {a2 b2 c2 d2} movq %mm5, %mm1 punpcklwd %mm7, %mm1 # mm1 <- {a1 b1 c1 d1} movq %mm5, %mm0 punpckhwd %mm7, %mm0 # mm0 <- {a0 b0 c0 d0} .endm # transpose 4x4 # input # %mm3 == {d3 d2 d1 d0} # %mm2 == {c3 c2 c1 c0} # %mm1 == {b3 b2 b1 b0} # %mm0 == {a3 a2 a1 a0} # output # %mm3 == {d3 c3 b3 a3} # %mm2 == {d2 c2 b2 a2} # %mm1 == {d1 c1 b1 a1} # %mm0 == {d0 c0 b0 a0} .macro transpose_4x4 movq %mm0, %mm4 punpcklwd %mm2, %mm4 # mm4 <- {c1 a1 c0 a0} movq %mm0, %mm5 punpckhwd %mm2, %mm5 # mm5 <- {c3 a3 c2 a2} movq %mm1, %mm6 punpcklwd %mm3, %mm6 # mm6 <- {d1 b1 d0 b0} movq %mm1, %mm7 punpckhwd %mm3, %mm7 # mm7 <- {d3 b3 d2 b2} movq %mm4, %mm0 punpcklwd %mm6, %mm0 # mm0 <- {d0 c0 b0 a0} movq %mm4, %mm1 punpckhwd %mm6, %mm1 # mm1 <- {d1 c1 b1 a1} movq %mm5, %mm2 punpcklwd %mm7, %mm2 # mm2 <- {d2 c2 b2 a2} movq %mm5, %mm3 punpckhwd %mm7, %mm3 # mm3 <- {d3 c3 b3 a3} .endm .globl pixel_biquad_vertb_s16 .type pixel_biquad_vertb_s16,@function # pixel_biquad_vertbr_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_biquad_vertb_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .biquad_vertb_line_loop: movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 movq (%ebx,%eax,1), %mm3 biquad_4x4_pixels movq %mm0, (%ebx) movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) addl %edx, %ebx addl %eax, %ebx decl %ecx jnz .biquad_vertb_line_loop emms pop %edi pop %esi pop %ebx leave ret .globl pixel_biquad_verbt_s16 .type pixel_biquad_verbt_s16,@function # pixel_biquad_vertbt_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_biquad_verbt_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %eax # line with shll $3, %eax # 4 line byte spacing decl %ecx mul %ecx incl %ecx addl %eax, %ebx # ebx points to last pixblock movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .biquad_verbt_line_loop: movq (%ebx), %mm3 movq (%ebx,%edx,1), %mm2 movq (%ebx,%edx,2), %mm1 movq (%ebx,%eax,1), %mm0 biquad_4x4_pixels movq %mm3, (%ebx) movq %mm2, (%ebx,%edx,1) movq %mm1, (%ebx,%edx,2) movq %mm0, (%ebx,%eax,1) subl %edx, %ebx subl %eax, %ebx decl %ecx jnz .biquad_verbt_line_loop emms pop %edi pop %esi pop %ebx leave ret .globl pixel_biquad_horlr_s16 .type pixel_biquad_horlr_s16,@function # pixel_biquad_hor_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_biquad_horlr_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .biquad_horlr_line_loop: movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 movq (%ebx,%eax,1), %mm3 transpose_4x4 biquad_4x4_pixels transpose_4x4 movq %mm0, (%ebx) movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) addl $8, %ebx decl %ecx jnz .biquad_horlr_line_loop emms pop %edi pop %esi pop %ebx leave ret .globl pixel_biquad_horrl_s16 .type pixel_biquad_horrl_s16,@function # pixel_biquad_horrl_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_biquad_horrl_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl %ecx, %eax decl %eax shll $3, %eax addl %eax, %ebx # ebx points to last pixblock movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .biquad_horrl_line_loop: movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 movq (%ebx,%eax,1), %mm3 antitranspose_4x4 biquad_4x4_pixels antitranspose_4x4 movq %mm0, (%ebx) movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) subl $8, %ebx decl %ecx jnz .biquad_horrl_line_loop emms pop %edi pop %esi pop %ebx leave ret .globl pixel_biquad_time_s16 .type pixel_biquad_time_s16,@function # pixel_biquad_time_s16(short int *pixel_array, short int *s1, short int *s2, short int *coefs, int nb_4_pix_vectors) pixel_biquad_time_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %edx # state 1 array movl 16(%ebp), %edi # state 2 array movl 20(%ebp), %esi # coefs movl 24(%ebp), %ecx # nb of 4 pixel vectors .align 16 .biquad_time_loop: movq (%ebx), %mm0 # get input movq (%edx), %mm4 # get state 1 movq (%edi), %mm5 # get state 2 df2 %mm0 # compute direct form 2 movq %mm0, (%ebx) # write output movq %mm5, (%edi) # write state 2 movq %mm4, (%edx) # write state 1 addl $8, %ebx addl $8, %edi addl $8, %edx decl %ecx jnz .biquad_time_loop emms pop %edi pop %esi pop %ebx leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_ca_s1.s000066400000000000000000000101551266045153600210000ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # this file contains assembler routines for 2D 1 bit cellular automata # processing. it is organized around a feeder kernel and a # stack based bit processor (virtual forth machine) # # the feeder kernel is responsable for loading/storing CA cells # from/to memory. data in memory is organized as a scanline # encoded toroidial bitplane (lsb = left). to simplify the kernel, the top # left corner of the rectangular grid of pixels will shift down # every processing step. # # the stack machine has the following architecture: # CA stack: %esi, TOS: %mm0 (32x2 pixels. lsw = top row) # CA horizon: %mm4-%mm7 (64x4 pixels. %mm4 = top row) # # the stack size / organization is not known to the stack machine. # it can be thought of as operating on a 3x3 cell neightbourhood. # the only purpose of forth program is to determine the CA local update rule. # # the machine is supposed to be very minimal. no looping control. # no adressing modes. no conditional code (hey, this is an experiment!) # so recursion is not allowed (no way to stop it) # there are 9 words to load the cell neigbourhood on the stack. # the rest is just logic and stack manips. # this file contains pure asm macros. it is to be included before assembly # after scaforth.pl has processed the .scaf file # *************************** CA CELL ACCESS MACROS ***************************** # fetchTL - fetchBR # shift / load rectangle macros: # shift rectangle horizontal # result is in reg1 .macro shift reg1 reg2 count psllq $(32+\count), \reg1 psrlq $(32-\count), \reg2 psrlq $32, \reg1 psllq $32, \reg2 por \reg2, \reg1 .endm .macro ldtop reg1 reg2 movq %mm4, \reg1 movq %mm5, \reg2 .endm .macro ldcenter reg1 reg2 movq %mm5, \reg1 movq %mm6, \reg2 .endm .macro ldbottom reg1 reg2 movq %mm6, \reg1 movq %mm7, \reg2 .endm # fetch from top row # fetch the top left square .macro fetchTL ldtop %mm0, %mm1 shift %mm0, %mm1, -1 .endm # fetch the top mid square .macro fetchTM ldtop %mm0, %mm1 shift %mm0, %mm1, 0 .endm # fetch the top right square .macro fetchTR ldtop %mm0, %mm1 shift %mm0, %mm1, 1 .endm # fetch from center row # fetch the mid left square .macro fetchML ldcenter %mm0, %mm1 shift %mm0, %mm1, -1 .endm # fetch the mid mid square .macro fetchMM ldcenter %mm0, %mm1 shift %mm0, %mm1, 0 .endm # fetch the mid right square .macro fetchMR ldcenter %mm0, %mm1 shift %mm0, %mm1, 1 .endm # fetch from bottom row # fetch the bottom left square .macro fetchBL ldbottom %mm0, %mm1 shift %mm0, %mm1, -1 .endm # fetch the bottom mid square .macro fetchBM ldbottom %mm0, %mm1 shift %mm0, %mm1, 0 .endm # fetch the bottom right square .macro fetchBR ldbottom %mm0, %mm1 shift %mm0, %mm1, 1 .endm # *************************** CA STACK MANIP MACROS ***************************** # dup drop dropdup swap nip dropover .macro dup lea -8(%esi), %esi movq %mm0, (%esi) .endm .macro drop movq (%esi), %mm0 lea 8(%esi), %esi .endm .macro dropdup movq (%esi), %mm0 .endm .macro swap movq (%esi), %mm1 movq %mm0, (%esi) movq %mm1, %mm0 .endm .macro nip lea 8(%esi), %esi .endm .macro dropover movq 8(%esi), %mm0 .endm # *************************** CA BOOLEAN LOGIC MACROS ***************************** # overxor .macro overxor pxor (%esi), %mm0 .endm pdp-0.14.1+darcs20180201/system/mmx/pixel_cascade_s16.s000066400000000000000000000157711266045153600220770ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # TODO: COUPLED CASCADE SECOND ORDER SECTION # # s1[k] = ar * s1[k-1] + ai * s2[k-1] + x[k] # s2[k] = ar * s2[k-1] - ai * s1[k-1] # y[k] = c0 * x[k] + c1 * s1[k-1] + c2 * s2[k-1] # MACRO: df2 # # computes a coupled cascade # # input: %mm0 == input # %mm1 == state 1 # %mm2 == state 2 # (%esi) == cascade coefs (ar ai c0 c1 c2) in s0.15 # output: %mm0 == output # %mm1 == state 1 # %mm2 == state 2 .macro coupled pmovq %mm1, %mm3 # mm3 == s1[k-1] pmovq %mm1, %mm4 # mm4 == s1[k-1] pmovq %mm2, %mm5 # mm5 == s2[k-1] pmovq %mm2, %mm6 # mm5 == s2[k-1] pmulhw (%esi), %mm1 # mm1 == s1[k-1] * ar pmulhw 8(%esi), %mm3 # mm3 == s1[k-1] * ai pmulhw 24(%esi), %mm4 # mm4 == s1[k-1] * c1 pmulhw (%esi), %mm2 # mm2 == s2[k-1] * ar pmulhw 8(%esi), %mm5 # mm5 == s2[k-1] * ai pmulhw 32(%esi), %mm6 # mm6 == s2[k-1] * c2 paddw %mm5, %mm1 # mm1 == s1[k-1] * ar + s2[k-1] * ai psubw %mm3, %mm2 # mm2 == s2[k-1] * ar - s1[k-1] * ai == s2[k] paddw %mm0, %mm1 # mm1 == s1[k] pmulhw 16(%esi), %mm0 # mm0 == x[k] * c0 paddw %mm6, %mm4 # mm4 == s1[k-1] * c1 + s2[k-1] * c2 paddw %mm4, %mm0 # mm0 == y[k] .endm # in order to use the 4 line parallel cascade routine on horizontal # lines, we need to reorder (rotate or transpose) the matrix, since # images are scanline encoded, and we want to work in parallell # on 4 lines. # # since the 4 lines are independent, it doesnt matter in which order # the the vector elements are present. # # this allows us to use the same routine for left->right and right->left # processing. # # some comments on the non-abelean group of square isometries consisting of # (I) identity # (H) horizontal axis mirror # (V) vertical axis mirror # (T) transpose (diagonal axis mirror) # (A) antitranspose (antidiagonal axis mirror) # (R1) 90deg anticlockwize rotation # (R2) 180deg rotation # (R3) 90deg clockwize rotation # # # we basicly have two options: (R1,R3) or (T,A) # we opt for T and A because they are self inverting, which improves locality # # use antitranspose for right to left an transpose # for left to right (little endian) # antitranspose 4x4 # input # %mm3 == {d0 d1 d2 d3} # %mm2 == {c0 c1 c2 c3} # %mm1 == {b0 b1 b2 b3} # %mm0 == {a0 a1 a2 a3} # output # %mm3 == {a3 b3 c3 d3} # %mm2 == {a2 b2 c2 d2} # %mm1 == {a1 b1 c1 d1} # %mm0 == {a0 b0 c0 d0} .macro antitranspose_4x4: movq %mm3, %mm4 punpcklwd %mm1, %mm4 # mm4 <- {b2 d2 b3 d3} movq %mm3, %mm5 punpckhwd %mm1, %mm5 # mm5 <- {b0 d0 b1 d1} movq %mm2, %mm6 punpcklwd %mm0, %mm6 # mm6 <- {a2 c2 a3 c3} movq %mm2, %mm7 punpckhwd %mm0, %mm7 # mm7 <- {a0 c0 a1 c1} movq %mm4, %mm3 punpcklwd %mm6, %mm3 # mm3 <- {a3 b3 c3 d3} movq %mm4, %mm2 punpckhwd %mm6, %mm2 # mm2 <- {a2 b2 c2 d2} movq %mm5, %mm1 punpcklwd %mm7, %mm1 # mm1 <- {a1 b1 c1 d1} movq %mm5, %mm0 punpckhwd %mm7, %mm0 # mm0 <- {a0 b0 c0 d0} .endm # transpose 4x4 # input # %mm3 == {d3 d2 d1 d0} # %mm2 == {c3 c2 c1 c0} # %mm1 == {b3 b2 b1 b0} # %mm0 == {a3 a2 a1 a0} # output # %mm3 == {d3 c3 b3 a3} # %mm2 == {d2 c2 b2 a2} # %mm1 == {d1 c1 b1 a1} # %mm0 == {d0 c0 b0 a0} .macro transpose_4x4: movq %mm0, %mm4 punpcklwd %mm2, %mm4 # mm4 <- {c1 a1 c0 a0} movq %mm0, %mm5 punpckhwd %mm2, %mm5 # mm5 <- {c3 a3 c2 a2} movq %mm1, %mm6 punpcklwd %mm3, %mm6 # mm6 <- {d1 b1 d0 b0} movq %mm1, %mm7 punpckhwd %mm3, %mm7 # mm7 <- {d3 b3 d2 b2} movq %mm4, %mm0 punpcklwd %mm6, %mm0 # mm0 <- {d0 c0 b0 a0} movq %mm4, %mm1 punpckhwd %mm6, %mm1 # mm1 <- {d1 c1 b1 a1} movq %mm5, %mm2 punpcklwd %mm7, %mm2 # mm2 <- {d2 c2 b2 a2} movq %mm5, %mm3 punpckhwd %mm7, %mm3 # mm3 <- {d3 c3 b3 a3} .endm .globl pixel_cascade_vertb_s16 .type pixel_cascade_vertb_s16,@function # pixel_cascade_vertbr_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_cascade_vertb_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing subl %edx, %ebx movq 0(%edi), %mm1 # s1[k-1] movq 8(%edi), %mm2 # s2[k-1] .align 16 .cascade_vertb_line_loop: movq (%ebx,%edx,1), %mm3 movq %mm3, %mm0 addl %edx, %ebx coupled movq %mm0, (%ebx) movq (%ebx,%edx,1), %mm3 movq %mm3, %mm0 addl %edx, %ebx coupled movq %mm0, (%ebx) movq (%ebx,%edx,1), %mm3 movq %mm3, %mm0 addl %edx, %ebx coupled movq %mm0, (%ebx) movq (%ebx,%edx,1), %mm3 movq %mm3, %mm0 addl %edx, %ebx coupled movq %mm0, (%ebx) decl %ecx jnz .cascade_vertb_line_loop movq %mm1, 0(%edi) # s1[k-1] movq %mm2, 8(%edi) # s2[k-1] emms pop %edi pop %esi pop %ebx leave ret .globl pixel_cascade_horlr_s16 .type pixel_cascade_horlr_s16,@function # pixel_cascade_hor_s16(char *pixel_array, int nb_rows, int linewidth, short int coef[20], short int state[8]) pixel_cascade_horlr_s16: pushl %ebp movl %esp, %ebp push %ebx push %esi push %edi movl 8(%ebp), %ebx # pixel array offset movl 12(%ebp), %ecx # nb of 4x4 pixblocks movl 16(%ebp), %edx # line with movl 20(%ebp), %esi # coefs movl 24(%ebp), %edi # state shll $1, %edx # short int addressing movl %edx, %eax shll $1, %eax addl %edx, %eax # eax = 3 * edx .align 16 .cascade_horlr_line_loop: movq (%edi), %mm1 movq 8(%edi), %mm2 movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 movq (%ebx,%eax,1), %mm3 transpose_4x4 movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) coupled movq %mm0, (%ebx) movq (%ebx,%edx,1), %mm3 movq %mm3, %mm0 coupled movq %mm0, (%ebx, %edx,1) movq (%ebx,%edx,2), %mm3 movq %mm3, %mm0 coupled movq %mm0, (%ebx, %edx,2) movq (%ebx,%eax,1), %mm3 movq %mm3, %mm0 coupled movq %mm1, 0(%edi) # s1[k-1] movq %mm2, 8(%edi) # s2[k-1] movq %mm0, %mm3 movq (%ebx), %mm0 movq (%ebx,%edx,1), %mm1 movq (%ebx,%edx,2), %mm2 transpose_4x4 movq %mm0, (%ebx) movq %mm1, (%ebx,%edx,1) movq %mm2, (%ebx,%edx,2) movq %mm3, (%ebx,%eax,1) addl $8, %ebx decl %ecx jnz .cascade_horlr_line_loop emms pop %edi pop %esi pop %ebx leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_cheby_s16.s000066400000000000000000000045731266045153600216040ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_cheby_s16_3plus .type pixel_cheby_s16_3plus,@function # void pixel_cheby_s16(int *buf, int nb_8pixel_vectors, int order+1, short int *coefs) # coefs are s2.13 fixed point (-4->4) pixel_cheby_s16_3plus: pushl %ebp movl %esp, %ebp push %esi push %edi push %edx movl 8(%ebp), %esi # input array movl 12(%ebp), %ecx # vector count movl 16(%ebp), %eax # get order+1 shll $3, %eax movl 20(%ebp), %edx addl %eax, %edx # edx = coef endx address # jmp skip .align 16 .loop_cheby: movl 20(%ebp), %edi # get coefs movq (%esi), %mm0 # load 4 pixels from memory (mm0 = x) pcmpeqw %mm2, %mm2 movq %mm0, %mm1 # mm1 (T_n-1) <- x psrlw $1, %mm2 # mm2 (T_n-2) <- 1 movq (%edi), %mm4 # mm4 (acc) == a0 psraw $1, %mm4 # mm4 == a0/2 movq %mm0, %mm5 # mm5 (intermediate) pmulhw 8(%edi), %mm5 # mm5 == (x * a1)/2 paddsw %mm5, %mm4 # acc = c0 + c1 x addl $16, %edi .loop_cheby_inner: movq %mm1, %mm3 # mm3 == T_n-1 psraw $2, %mm2 # mm2 == T_n-2 / 4 pmulhw %mm0, %mm3 # mm3 == (2 x T_n-1) / 4 psubsw %mm2, %mm3 # mm3 == (2 x T_n-1 - T_n-2) / 4 paddsw %mm3, %mm3 paddsw %mm3, %mm3 # mm3 == T_n movq %mm1, %mm2 # mm2 == new T_n-2 movq %mm3, %mm1 # mm3 == new T_n-1 pmulhw (%edi), %mm3 # mm3 = a_n * T_n / 2 paddsw %mm3, %mm4 # accumulate addl $8, %edi cmpl %edx, %edi jne .loop_cheby_inner paddsw %mm4, %mm4 # compensate for 0.125 factor paddsw %mm4, %mm4 paddsw %mm4, %mm4 movq %mm4, (%esi) # store result in memory addl $8, %esi # increment source/dest pointer decl %ecx jnz .loop_cheby # loop skip: emms pop %edx pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_conv_hor_s16.s000066400000000000000000000057661266045153600223340ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # intermediate function # input in register: # %mm0: left 4 pixels # %mm1: middle 4 pixels # %mm2: right 4 pixels # %mm5: left 4 pixel masks # %mm6: middle 4 pixel masks # %mm7: right 4 pixel masks # return in register: # %mm0: middle 4 pixels result .conv_hor_4_pixels: .align 16 # compute quadruplet # get left pixels psrlq $48, %mm0 # shift word 3 to byte 0 movq %mm1, %mm4 psllq $16, %mm4 # shift word 0,1,2 to 1,2,3 por %mm4, %mm0 # combine pmulhw %mm5, %mm0 psllw $1, %mm0 # get middle pixels movq %mm1, %mm4 pmulhw %mm6, %mm4 psllw $1, %mm4 paddsw %mm4, %mm0 # get right pixels movq %mm2, %mm3 psllq $48, %mm3 # shift word 0 to word 3 movq %mm1, %mm4 psrlq $16, %mm4 # shift word 1,2,3 to 0,1,2 por %mm4, %mm3 # combine pmulhw %mm7, %mm3 psllw $1, %mm3 paddsw %mm3, %mm0 # accumulate ret .globl pixel_conv_hor_s16 .type pixel_conv_hor_s16,@function # pixel_conv_hor_s16(short int *pixel_array, int nb_4_pixel_vectors, short int border[4], short int mask[12]) # horizontal unsigned pixel conv (1/4 1/2 1/4) not tested # NOT TESTED pixel_conv_hor_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %esi # pixel array offset movl 12(%ebp), %ecx # nb of 8 pixel vectors in a row (at least 2) movl 20(%ebp), %edi # mask vector movq (%edi), %mm5 movq 8(%edi), %mm6 movq 16(%edi), %mm7 movl 16(%ebp), %edi # boundary pixel vector movq (%edi), %mm0 # init regs (left edge, so mm0 is zero) movq (%esi), %mm1 movq 8(%esi), %mm2 decl %ecx # loop has 2 terminator stubs decl %ecx # todo: handle if ecx < 3 jmp .conv_line_loop .align 16 .conv_line_loop: call .conv_hor_4_pixels # compute conv movq %mm0, (%esi) # store result movq %mm1, %mm0 # mm0 <- prev (%esi) movq %mm2, %mm1 # mm1 <- 8(%esi) movq 16(%esi), %mm2 # mm2 <- 16(%esi) addl $8, %esi # increase pointer decl %ecx jnz .conv_line_loop call .conv_hor_4_pixels # compute conv movq %mm0, (%esi) # store result movq %mm1, %mm0 # mm0 <- prev (%esi) movq %mm2, %mm1 # mm1 <- 8(%esi) movq (%edi), %mm2 # mm2 <- border call .conv_hor_4_pixels # compute last vector movq %mm0, 8(%esi) # store it emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_conv_ver_s16.s000066400000000000000000000056531266045153600223330ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # #TODO: fix out of bound acces in conv_ver and conv_hor # intermediate function # input in register: # %mm0: top 4 pixels # %mm1: middle 4 pixels # %mm2: bottom 4 pixels # %mm5: top 4 pixel mask # %mm6: middle 4 pixel mask # %mm7: bottom 4 pixel mask # return in register: # %mm0: middle 4 pixels result .conv_ver_4_pixels: .align 16 # compute quadruplet # get top pixel pmulhw %mm5, %mm0 psllw $1, %mm0 # get middle pixel movq %mm1, %mm4 pmulhw %mm6, %mm4 psllw $1, %mm4 paddsw %mm4, %mm0 # get bottom pixel movq %mm2, %mm3 pmulhw %mm7, %mm3 psllw $1, %mm3 # mm3 <- mm3/4 paddsw %mm3, %mm0 ret .globl pixel_conv_ver_s16 .type pixel_conv_ver_s16,@function # pixel_conv_ver_s16(short int *pixel_array, int nb_4_pixel_vectors, int row_byte_size, short int border[4]) # horizontal unsigned pixel conv (1/4 1/2 1/4) not tested # NOT TESTED pixel_conv_ver_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %esi # pixel array offset movl 12(%ebp), %ecx # nb of 4 pixel vectors in a row (at least 2) movl 16(%ebp), %edx # rowsize in bytes movl 24(%ebp), %edi # mask vector movq (%edi), %mm5 movq 8(%edi), %mm6 movq 16(%edi), %mm7 movl 20(%ebp), %edi # edge vector shll $1, %edx decl %ecx # loop has a terminator stub decl %ecx # loop has another terminator stub movq (%edi), %mm0 # init regs (left edge, so mm0 is zero) movq (%esi), %mm1 movq (%esi,%edx,1), %mm2 jmp .conv_line_loop .align 16 .conv_line_loop: call .conv_ver_4_pixels # compute conv movq %mm0, (%esi) # store result movq %mm1, %mm0 # mm0 <- prev (%esi) movq %mm2, %mm1 # mm1 <- (%esi,%edx,1) movq (%esi,%edx,2), %mm2 # mm2 <- (%esi,%edx,2) addl %edx, %esi # increase pointer decl %ecx jnz .conv_line_loop call .conv_ver_4_pixels # compute conv movq %mm0, (%esi) # store result movq %mm1, %mm0 # mm0 <- prev (%esi) movq %mm2, %mm1 # mm1 <- (%esi,%edx,1) movq (%edi), %mm2 # clear invalid edge vector addl %edx, %esi # increase pointer call .conv_ver_4_pixels # compute last vector movq %mm0, (%esi) # store it emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_crot_s16.s000066400000000000000000000066711266045153600214620ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_crot3d_s16 .type pixel_crot3d_s16,@function # 3 dimensional colour space rotation # 3x3 matrix is column encoded, each coefficient is a 4x16 bit fixed point vector # void pixel_crot3d_s16(int *buf, int nb_4pixel_vectors_per_plane, short int *matrix) pixel_crot3d_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %esi # input array movl 12(%ebp), %ecx # pixel count movl 16(%ebp), %edi # rotation matrix movl %ecx, %edx shll $3, %edx # %edx = plane spacing .align 16 .loop_crot3d: movq (%esi), %mm0 # get 1st component movq (%esi,%edx,1), %mm6 # get 2nd component movq (%esi,%edx,2), %mm7 # get 3rd component movq %mm0, %mm1 # copy 1st component movq %mm0, %mm2 pmulhw (%edi), %mm0 # mul first column pmulhw 8(%edi), %mm1 pmulhw 16(%edi), %mm2 movq %mm6, %mm5 # copy 2nd component movq %mm6, %mm3 pmulhw 24(%edi), %mm6 # mul second column pmulhw 32(%edi), %mm5 pmulhw 40(%edi), %mm3 paddsw %mm6, %mm0 # accumulate paddsw %mm5, %mm1 paddsw %mm3, %mm2 movq %mm7, %mm4 # copy 3rd component movq %mm7, %mm6 pmulhw 48(%edi), %mm4 # mul third column pmulhw 56(%edi), %mm6 pmulhw 64(%edi), %mm7 paddsw %mm4, %mm0 # accumulate paddsw %mm6, %mm1 paddsw %mm7, %mm2 paddsw %mm0, %mm0 # double (fixed point normalization) paddsw %mm1, %mm1 paddsw %mm2, %mm2 movq %mm0, (%esi) # store movq %mm1, (%esi, %edx, 1) movq %mm2, (%esi, %edx, 2) addl $8, %esi # increment source pointer decl %ecx jnz .loop_crot3d # loop emms pop %edi pop %esi leave ret .globl pixel_crot2d_s16 .type pixel_crot2d_s16,@function # 2 dimensional colour space rotation # 2x2 matrix is column encoded, each coefficient is a 4x16 bit fixed point vector # void pixel_crot2d_s16(int *buf, int nb_4pixel_vectors_per_plane, short int *matrix) pixel_crot2d_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %esi # input array movl 12(%ebp), %ecx # pixel count movl 16(%ebp), %edi # rotation matrix movl %ecx, %edx shll $3, %edx # %edx = plane spacing .align 16 .loop_crot2d: movq (%esi), %mm0 # get 1st component movq (%esi,%edx,1), %mm2 # get 2nd component movq %mm0, %mm1 # copy 1st component movq %mm2, %mm3 # copy 2nd component pmulhw (%edi), %mm0 # mul first column pmulhw 8(%edi), %mm1 pmulhw 16(%edi), %mm2 # mul second column pmulhw 24(%edi), %mm3 paddsw %mm2, %mm0 # accumulate paddsw %mm3, %mm1 paddsw %mm0, %mm0 # fixed point gain correction paddsw %mm1, %mm1 movq %mm0, (%esi) # store movq %mm1, (%esi, %edx, 1) addl $8, %esi # increment source pointer decl %ecx jnz .loop_crot2d # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_gain.s000066400000000000000000000044261266045153600207340ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_gain .type pixel_gain,@function # mmx rgba pixel gain # void asmtest(char *pixelarray, int32 nbpixels, int *rgba_gain) # gains are 7.9 fixed point for rgba pixel_gain: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %esi # pixel array offset movl 12(%ebp), %ecx # nb of elements movl 16(%ebp), %edi # int16[4] array of gains prefetch (%esi) emms sarl $2, %ecx # process 4 pixels per loop iteration jz .exit movq (%edi), %mm7 # read gain array from memory jmp .loop_gain .align 16 .loop_gain: prefetch 128(%esi) movq (%esi), %mm5 # load pixel 1-2 from memory movq 8(%esi), %mm6 # load pixel 3-4 from memory pxor %mm0, %mm0 # zero mm0 - mm3 pxor %mm1, %mm1 pxor %mm2, %mm2 pxor %mm3, %mm3 punpcklbw %mm5, %mm0 # unpack 1st pixel into 8.8 bit ints punpckhbw %mm5, %mm1 # unpack 2nd punpcklbw %mm6, %mm2 # unpack 3rd punpckhbw %mm6, %mm3 # unpack 4th psrlw $0x1, %mm0 # shift right to clear sign bit 9.7 psrlw $0x1, %mm1 psrlw $0x1, %mm2 psrlw $0x1, %mm3 pmulhw %mm7, %mm0 # multiply 1st pixel 9.7 * 7.9 -> 16.0 pmulhw %mm7, %mm1 # multiply 2nd pmulhw %mm7, %mm2 # multiply 3rd pmulhw %mm7, %mm3 # multiply 4th packuswb %mm1, %mm0 # pack & saturate to 8bit vector movq %mm0, (%esi) # store result in memory packuswb %mm3, %mm2 # pack & saturate to 8bit vector movq %mm2, 8(%esi) # store result in memory addl $16, %esi # increment source pointer decl %ecx jnz .loop_gain # loop .exit: emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_gain_s16.s000066400000000000000000000034741266045153600214270ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_gain_s16 .type pixel_gain_s16,@function # gain is integer, shift count is down # void pixel_gain_s16(int *buf, int nb_8pixel_vectors, short int gain[4], unsigned long long *shift) pixel_gain_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 20(%ebp), %edi movq (%edi), %mm6 # get shift vector movl 16(%ebp), %edi movq (%edi), %mm7 # get gain vector movl 8(%ebp), %esi # input array movl 12(%ebp), %ecx # pixel count .align 16 .loop_gain: movq (%esi), %mm0 # load 4 pixels from memory movq %mm0, %mm1 pmulhw %mm7, %mm1 # apply gain (s15.0) fixed point, high word pmullw %mm7, %mm0 # low word movq %mm0, %mm2 # copy movq %mm1, %mm3 punpcklwd %mm1, %mm0 # unpack lsw components punpckhwd %mm3, %mm2 # unpack msw components psrad %mm6, %mm0 # apply signed shift psrad %mm6, %mm2 packssdw %mm2, %mm0 # pack result & saturate movq %mm0, (%esi) # store result addl $8, %esi # increment source pointer decl %ecx jnz .loop_gain # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_mix_s16.s000066400000000000000000000035531266045153600213040ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_mix_s16 .type pixel_mix_s16,@function # mmx rgba pixel gain # void pixel_mix_s16(int *left, int *right, int nb_4pixel_vectors, # short int gain_left[4], short int gain_right[4]) pixel_mix_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 20(%ebp), %edi # int16[4] array of gains movq (%edi), %mm6 # get left gain array movl 24(%ebp), %edi # int16[4] array of gains movq (%edi), %mm7 # get right gain array movl 8(%ebp), %edi # left array movl 12(%ebp), %esi # right array movl 16(%ebp), %ecx # pixel count .align 16 .loop_mix: # prefetch 128(%esi) movq (%esi), %mm1 # load right 4 pixels from memory pmulhw %mm7, %mm1 # apply right gain movq (%edi), %mm0 # load 4 left pixels from memory pmulhw %mm6, %mm0 # apply left gain # pslaw $1, %mm1 # shift left ((s).15 x (s).15 -> (s0).14)) # pslaw $1, %mm0 paddsw %mm0, %mm0 # no shift left arithmic, so use add instead paddsw %mm1, %mm1 paddsw %mm1, %mm0 # mix movq %mm0, (%edi) addl $8, %esi addl $8, %edi decl %ecx jnz .loop_mix # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_mul_s16.s000066400000000000000000000026761266045153600213110ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_mul_s16 .type pixel_mul_s16,@function # simple add # void pixel_mul_s16(int *left, int *right, int nb_4pixel_vectors) pixel_mul_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %edi # left array movl 12(%ebp), %esi # right array movl 16(%ebp), %ecx # pixel count .align 16 .loop_mix: # prefetch 128(%esi) movq (%esi), %mm1 # load right 4 pixels from memory movq (%edi), %mm0 # load 4 left pixels from memory pmulhw %mm1, %mm0 # mul psllw $1, %mm0 # fixed point shift correction movq %mm0, (%edi) addl $8, %esi addl $8, %edi decl %ecx jnz .loop_mix # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_pack_s16u8.s000066400000000000000000000060351266045153600217000ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_pack_s16u8_y .type pixel_pack_s16u8_y,@function # mmx rgba pixel gain # void pixel_pack_s16u8_y(int *input, int *output, int nb_8pixel_vectors) pixel_pack_s16u8_y: pushl %ebp movl %esp, %ebp push %esi push %edi # movl 20(%ebp), %edi # int16[4] array of gains # movq (%edi), %mm7 # get gain array # psllw $1, %mm7 # adjust for shifted sign bit movl 8(%ebp), %esi # input array movl 12(%ebp), %edi # output array movl 16(%ebp), %ecx # pixel count pxor %mm6, %mm6 .align 16 .loop_pack_y: # prefetch 128(%esi) movq (%esi), %mm0 # load 4 pixels from memory # pmulhw %mm7, %mm0 # apply gain movq 8(%esi), %mm1 # load 4 pixels from memory # pmulhw %mm7, %mm1 # apply gain # movq %mm0, %mm2 # pcmpgtw %mm6, %mm2 # mm2 > 0 ? 0xffff : 0 # pand %mm2, %mm0 # movq %mm1, %mm3 # pcmpgtw %mm6, %mm3 # mm3 > 0 ? 0xffff : 0 # pand %mm3, %mm1 # psllw $1, %mm0 # shift out sign bit # psllw $1, %mm1 # shift out sign bit psraw $7, %mm0 # shift to lsb psraw $7, %mm1 # shift to lsb packuswb %mm1, %mm0 # pack & saturate to 8bit vector movq %mm0, (%edi) # store result in memory addl $16, %esi # increment source pointer addl $8, %edi # increment dest pointer decl %ecx jnz .loop_pack_y # loop emms pop %edi pop %esi leave ret .globl pixel_pack_s16u8_uv .type pixel_pack_s16u8_uv,@function pixel_pack_s16u8_uv: pushl %ebp movl %esp, %ebp push %esi push %edi # movl 20(%ebp), %edi # int16[4] array of gains # movq (%edi), %mm7 # get gain array movl 8(%ebp), %esi # pixel array offset movl 12(%ebp), %edi # nb of elements movl 16(%ebp), %ecx # pixel count pcmpeqw %mm6, %mm6 psllw $15, %mm6 movq %mm6, %mm5 psrlw $8, %mm5 por %mm5, %mm6 # mm6 <- 8 times 0x80 .align 16 .loop_pack_uv: # prefetch 128(%esi) movq (%esi), %mm0 # load 4 pixels from memory # pmulhw %mm7, %mm0 # apply gain movq 8(%esi), %mm1 # load 4 pixels from memory # pmulhw %mm7, %mm1 # apply gain psraw $8, %mm0 # shift to msb psraw $8, %mm1 packsswb %mm1, %mm0 # pack & saturate to 8bit vector pxor %mm6, %mm0 # flip sign bits movq %mm0, (%edi) # store result in memory addl $16, %esi # increment source pointer addl $8, %edi # increment dest pointer decl %ecx jnz .loop_pack_uv # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_rand_s16.s000066400000000000000000000035431266045153600214320ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_rand_s16 .type pixel_rand_s16,@function # mmx rgba pixel gain # void pixel_rand_s16(int *dst, nb_4pixel_vectors, short int random_seed[4]) pixel_rand_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 16(%ebp), %esi # int16[4] array of random seeds movl 8(%ebp), %edi # dst array movl 12(%ebp), %ecx # pixel count movq (%esi), %mm6 pcmpeqw %mm3, %mm3 psrlw $15, %mm3 # get bit mask 4 times 0x0001 .align 16 .loop_rand: # prefetch 128(%esi) movq %mm6, %mm4 # get random vector psrlw $15, %mm4 # get first component movq %mm6, %mm5 psrlw $14, %mm5 # get second component pxor %mm5, %mm4 movq %mm6, %mm5 psrlw $12, %mm5 # get third component pxor %mm5, %mm4 movq %mm6, %mm5 psrlw $3, %mm5 # get forth component pxor %mm5, %mm4 psllw $1, %mm6 # shift left original random vector pand %mm3, %mm4 # isolate new bit por %mm4, %mm6 # combine into new random vector movq %mm6, (%edi) addl $8, %edi decl %ecx jnz .loop_rand # loop movq %mm6, (%esi) # store random seeds emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_randmix_s16.s000066400000000000000000000046571266045153600221570ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_randmix_s16 .type pixel_randmix_s16,@function # mmx rgba pixel gain # void pixel_randmix_s16(int *left, int *right, int nb_4pixel_vectors, short int random_seed[4], short int threshold[4]) pixel_randmix_s16: pushl %ebp movl %esp, %ebp push %esi push %edi movl 20(%ebp), %edi # int16[4] array of random seeds movq (%edi), %mm6 movl 24(%ebp), %edi # int16[4] array of thresholds movq (%edi), %mm7 movl 8(%ebp), %edi # left array movl 12(%ebp), %esi # right array movl 16(%ebp), %ecx # pixel count pcmpeqw %mm3, %mm3 psrlw $15, %mm3 # get bit mask 4 times 0x0001 .align 16 .loop_randmix: # prefetch 128(%esi) movq (%esi), %mm1 # load right 4 pixels from memory movq (%edi), %mm0 # load 4 left pixels from memory movq %mm6, %mm2 # get random vector pcmpgtw %mm7, %mm2 # compare random vector with threshold movq %mm2, %mm5 pand %mm0, %mm2 # get left array's components pandn %mm1, %mm5 # get right array's components por %mm2, %mm5 movq %mm5, (%edi) # store pixels movq %mm6, %mm4 # get random vector psrlw $15, %mm4 # get first component movq %mm6, %mm5 psrlw $14, %mm5 # get second component pxor %mm5, %mm4 movq %mm6, %mm5 psrlw $12, %mm5 # get third component pxor %mm5, %mm4 movq %mm6, %mm5 psrlw $3, %mm5 # get forth component pxor %mm5, %mm4 psllw $1, %mm6 # shift left original random vector pand %mm3, %mm4 # isolate new bit por %mm4, %mm6 # combine into new random vector addl $8, %esi addl $8, %edi decl %ecx jnz .loop_randmix # loop movl 20(%ebp), %edi # int16[4] array of random seeds movq %mm6, (%edi) # store random seeds emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_resample_s16.s000066400000000000000000000163151266045153600223170ustar00rootroot00000000000000 #interpolation data: #* 4 vectors: neighbourhood for samples (TL, TR, BL, BR) #* 2 vectors: fractional part (unsigned) #* 2 vectors: addresses of pixel blocks #coord conversion data: #1 vector: 32bit splatted address #1 vector: 16bit splatted w-1 #1 vector: 16bit splatted h-1 #1 vector: 16bit splatted w (reuse w-1 with add?) #1 dword: 32 bit line offset #coord generation data: several vectors for parameter update stuff.. #coordinate systems: 16 bit virtual coordinates (signed, center relative) #* 2 vectors: virtual coordinates #(evt tussenstap + conversie naar 16 bit virtual) #step 1: generate virtual coords #step 2: virtual coords -> block adresses + fractional adresses #* mulhigh: real coords (x,y) (center relative) #* add center -> unsigned (top left relative) #* mullow: fractional part (x_frac, y_frac) #* mulhigh, mullow, pack 32bit: y_offset #* pack 32bit: x_offset #* add, shift, add start address: real addresses #step3: data fetch using generated addresses: # this step would be much simpler in 4x16bit rgba. life's a bitch.. #step4: billinear interpolation #stat5: store # this can be simplified by doing 32 bit unaligned moves # and vector unpacking on the data # cooked image data structure # pixel environment temp storage TL1 = 0x00 TL2 = 0x02 TL3 = 0x04 TL4 = 0x06 TR1 = 0x08 TR2 = 0x0A TR3 = 0x0C TR4 = 0x0E BL1 = 0x10 BL2 = 0x12 BL3 = 0x14 BL4 = 0x16 BR1 = 0x18 BR2 = 0x1A BR3 = 0x1C BR4 = 0x1E # addresses of pixel blocks ADDRESS1 = 0x20 ADDRESS2 = 0x24 ADDRESS3 = 0x28 ADDRESS4 = 0x2C # second env + address buffer (testing: not used) SECONDBUFFER = 0x30 # 32bit splatted bitmap address V2PLANEADDRESS = 0x60 # 16bit splatted image constants V4TWOWIDTHM1 = 0x68 V4TWOHEIGHTM1 = 0x70 V4LINEOFFSET = 0x78 # data struct size RESAMPLEDATASIZE = 0x80 # interpolation routine # input: %mm0, %mm1 4 x 16bit unsigned top left relative virtual x and y coordinates # %esi: temp & algo data structure getpixelsbilin: psrlw $1, %mm0 # convert to range 0->0x7fff [0,0.5[ psrlw $1, %mm1 movq %mm0, %mm2 movq %mm1, %mm3 movq V4TWOWIDTHM1(%esi), %mm4 # 2 * (width - 1) movq V4TWOHEIGHTM1(%esi), %mm5 # 2 * (height - 1) pmulhw %mm5, %mm3 # mm3 == y coord (topleft relative) pmulhw %mm4, %mm2 # mm2 == x coord (topleft relative) pmullw %mm5, %mm1 # mm1 == y frac (unsigned) pmullw %mm4, %mm0 # mm0 == x frac (unsigned) movq %mm3, %mm5 # copy y coord pmullw V4LINEOFFSET(%esi), %mm3 # low part of line offset pmulhw V4LINEOFFSET(%esi), %mm5 # high part of line offset movq %mm2, %mm7 # copy x coord vector pxor %mm4, %mm4 punpcklwd %mm4, %mm2 # low part in %mm2 punpckhwd %mm4, %mm7 # hight part in %mm7 movq %mm3, %mm6 # copy punpcklwd %mm5, %mm3 # unpack low part in %mm3 punpckhwd %mm5, %mm6 # high part int %mm6 paddd %mm2, %mm3 paddd %mm7, %mm6 pslld $1, %mm3 # convert to word adresses pslld $1, %mm6 paddd V2PLANEADDRESS(%esi), %mm3 # add pixel plane address paddd V2PLANEADDRESS(%esi), %mm6 movq %mm3, ADDRESS1(%esi) # store adresses movq %mm6, ADDRESS3(%esi) pcmpeqw %mm2, %mm2 # all ones movq %mm0, %mm4 # copy x frac movq %mm1, %mm5 # copy y frac pxor %mm2, %mm4 # compute compliment (approx negative) pxor %mm2, %mm5 psrlw $1, %mm0 # shift right (0.5 * (frac x) psrlw $1, %mm1 # shift right (0.5 * (frac y) psrlw $1, %mm4 # shift right (0.5 * (1 - frac x) psrlw $1, %mm5 # shift right (0.5 * (1 - frac y) movq %mm0, %mm2 # copy of frac x movq %mm4, %mm3 # copy of (1-frac x) # fetch data #jmp skipfetch # seems the fetch is the real killer. try to optimize this # using 32 bit accesses & shifts # the src image data struct is padded to the cooked data struct movl RESAMPLEDATASIZE(%esi), %edi shll $1, %edi movl ADDRESS1(%esi), %ecx movl ADDRESS2(%esi), %edx movw (%ecx), %ax movw (%edx), %bx movw %ax, TL1(%esi) movw %bx, TL2(%esi) movw 2(%ecx), %ax movw 2(%edx), %bx movw %ax, TR1(%esi) movw %bx, TR2(%esi) addl %edi, %ecx addl %edi, %edx movw (%ecx), %ax movw (%edx), %bx movw %ax, BL1(%esi) movw %bx, BL2(%esi) movw 2(%ecx), %ax movw 2(%edx), %bx movw %ax, BR1(%esi) movw %bx, BR2(%esi) movl ADDRESS3(%esi), %ecx movl ADDRESS4(%esi), %edx movw (%ecx), %ax movw (%edx), %bx movw %ax, TL3(%esi) movw %bx, TL4(%esi) movw 2(%ecx), %ax movw 2(%edx), %bx movw %ax, TR3(%esi) movw %bx, TR4(%esi) addl %edi, %ecx addl %edi, %edx movw (%ecx), %ax movw (%edx), %bx movw %ax, BL3(%esi) movw %bx, BL4(%esi) movw 2(%ecx), %ax movw 2(%edx), %bx movw %ax, BR3(%esi) movw %bx, BR4(%esi) skipfetch: pmulhw TL1(%esi), %mm4 # bilin interpolation pmulhw TR1(%esi), %mm0 pmulhw BL1(%esi), %mm3 pmulhw BR1(%esi), %mm2 paddw %mm4, %mm0 paddw %mm3, %mm2 pmulhw %mm5, %mm0 pmulhw %mm1, %mm2 paddw %mm2, %mm0 psllw $2, %mm0 # compensate for gain reduction ret // linear mapping data struct ROWSTATEX = 0x0 ROWSTATEY = 0x8 COLSTATEX = 0x10 COLSTATEY = 0x18 ROWINCX = 0x20 ROWINCY = 0x28 COLINCX = 0x30 COLINCY = 0x38 // image data struct LINEOFFSET = 0x0 IMAGEADDRESS = 0x4 WIDTH = 0x8 HEIGHT = 0xC IMAGEDATASIZE = 0x10 # pixel_resample_linmap_s16(void *x) .globl pixel_resample_linmap_s16 .type pixel_resample_linmap_s16,@function SOURCEIMAGE = RESAMPLEDATASIZE DESTIMAGE = SOURCEIMAGE + IMAGEDATASIZE LINMAPDATA = DESTIMAGE + IMAGEDATASIZE pixel_resample_linmap_s16: pushl %ebp movl %esp, %ebp pushl %esi pushl %edi pushl %ebx movl 8(%ebp), %esi # get data struct movl DESTIMAGE+HEIGHT(%esi), %edx # image height movl DESTIMAGE+IMAGEADDRESS(%esi), %edi # dest image address movl DESTIMAGE+WIDTH(%esi), %ecx # image width shrl $2, %ecx # vector count .align 16 linmap_looprow: movq LINMAPDATA+ROWSTATEX(%esi), %mm0 # get current coordinates movq LINMAPDATA+ROWSTATEY(%esi), %mm1 linmap_loopcol: movq %mm0, %mm4 # copy movq %mm1, %mm5 paddd LINMAPDATA+ROWINCX(%esi), %mm4 # increment paddd LINMAPDATA+ROWINCY(%esi), %mm5 movq %mm4, %mm6 # copy movq %mm5, %mm7 paddd LINMAPDATA+ROWINCX(%esi), %mm6 # increment paddd LINMAPDATA+ROWINCY(%esi), %mm7 movq %mm6, LINMAPDATA+ROWSTATEX(%esi) # store next state movq %mm7, LINMAPDATA+ROWSTATEY(%esi) psrad $16, %mm0 # round to 16 bit psrad $16, %mm1 psrad $16, %mm4 psrad $16, %mm5 packssdw %mm4, %mm0 # pack new coordinates packssdw %mm5, %mm1 push %ecx push %edx push %edi call getpixelsbilin # do interpolation pop %edi pop %edx pop %ecx movq %mm0, (%edi) # store 4 pixels addl $0x8, %edi # point to next 4 pixels decl %ecx # dec row counter jnz linmap_looprow movq LINMAPDATA+COLSTATEX(%esi), %mm0 # get column state vector movq LINMAPDATA+COLSTATEY(%esi), %mm1 movl DESTIMAGE+WIDTH(%esi), %ecx # image width shrl $2, %ecx # vector count paddd LINMAPDATA+COLINCX(%esi), %mm0 # increment paddd LINMAPDATA+COLINCY(%esi), %mm1 movq %mm0, LINMAPDATA+COLSTATEX(%esi) # store movq %mm1, LINMAPDATA+COLSTATEY(%esi) decl %edx # dec column counter jnz linmap_loopcol emms popl %ebx popl %edi popl %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_s1.s000066400000000000000000000075221266045153600203410ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # this file contains ops for binary image processing # 8x8 bit tile encoded # low byte = bottom row # low bit = right column # %mm7 = scratch reg for all macros # ************ load mask ******************* # compute bit masks for rows and columns # %mm7: scratch reg # load mask top .macro ldmt count reg pcmpeqb \reg, \reg psllq $(64-(\count<<3)), \reg .endm # load mask bottom .macro ldmb count reg pcmpeqb \reg, \reg psrlq $(64-(\count<<3)), \reg .endm # load mask top and bottom .macro ldmtb count regt regb ldmb \count, \regb ldmt \count, \regt .endm # load mask right .macro ldmr count reg pcmpeqb %mm7, %mm7 psrlw $(16-\count), %mm7 movq %mm7, \reg psllq $8, %mm7 por %mm7, \reg .endm # load mask left .macro ldml count reg pcmpeqb %mm7, %mm7 psllw $(16-\count), %mm7 movq %mm7, \reg psrlq $8, %mm7 por %mm7, \reg .endm # load mask left and right .macro ldmlr count regl regr pcmpeqb %mm7, %mm7 psllw $(16-\count), %mm7 movq %mm7, \regl psrlq $8, %mm7 por %mm7, \regl movq \regl, \regr psrlq $(8-\count), \regr .endm # ************* shift square ********** # shifts a square in reg, fills with zeros # shift square top .macro sst count reg psllq $(\count<<3), \reg .endm # shift square bottom .macro ssb count reg psrlq $(\count<<3), \reg .endm # not tested # shift square left .macro ssl count reg movq \reg, %mm7 pcmpeqb \reg, \reg psllw $(16-\count), \reg psrlw $8, \reg pandn %mm7, \reg psllw $(\count), \reg .endm # shift square right .macro ssr count reg movq \reg, %mm7 pcmpeqb \reg, \reg psrlw $(16-\count), \reg psllw $8, \reg pandn %mm7, \reg psrlw $(\count), \reg .endm # ********** combine square ************* # combines 2 squares # combine right .macro csr count regr reg ssl \count, \reg ssr (8-\count), \regr por \regr, \reg .endm # combine left .macro csl count regl reg ssr \count, \reg ssl (8-\count), \regl por \regl, \reg .endm # combine top .macro cst count regt reg ssb \count, \reg sst (8-\count), \regt por \regt, \reg .endm # combine bottom .macro csb count regb reg sst \count, \reg ssb (8-\count), \regb por \regb, \reg .endm # ********** load combine square ************* # loads combined square using mask # load combined square left # mask should be count bits set right (i.e. 0x01) .macro lcsml count mask source sourcel dstreg movq \mask, \dstreg movq \mask, %mm7 pandn \source, \dstreg pand \sourcel, %mm7 psrlq $(\count), \dstreg psllq $(8-\count), %mm7 por %mm7, \dstreg .endm .globl pixel_test_s1 .type pixel_test_s1,@function # simple add # void pixel_add_s16(void *dest, void *source, int nb_squares, int spacing) # pixel_test_s1: pushl %ebp movl %esp, %ebp push %esi push %edi movl 8(%ebp), %edi # dest movl 12(%ebp), %esi # source movl 16(%ebp), %ecx # count movl 20(%ebp), %edx # row distance ldmr 1, %mm6 lcsml 1, %mm6, (%esi), 8(%esi), %mm0 movq %mm0, (%edi) # movq (%esi), %mm0 # movq 8(%esi), %mm1 # csl 4, %mm1, %mm0 # movq %mm0, (%edi) emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/mmx/pixel_unpack_u8s16.s000066400000000000000000000055631266045153600222500ustar00rootroot00000000000000# Pure Data Packet mmx routine. # Copyright (c) by Tom Schouten # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # .globl pixel_unpack_u8s16_y .type pixel_unpack_u8s16_y,@function # mmx rgba pixel gain # void pixel_unpack_u8s16_y(char *input, char *output, int32 nb_pixels_div8) pixel_unpack_u8s16_y: pushl %ebp movl %esp, %ebp push %esi push %edi # movl 20(%ebp), %edi # int16[4] array of gains # movq (%edi), %mm7 # get gain array movl 8(%ebp), %esi # input uint8 pixel array movl 12(%ebp), %edi # output sint16 pixel array movl 16(%ebp), %ecx # nb of elements div 8 .align 16 .loop_unpack_y: movq (%esi), %mm5 # load 8 pixels from memory pxor %mm0, %mm0 # zero mm0 - mm3 pxor %mm1, %mm1 punpcklbw %mm5, %mm0 # unpack 1st 4 pixels punpckhbw %mm5, %mm1 # unpack 2nd 4 pixles psrlw $0x1, %mm0 # shift right to clear sign bit 9.7 psrlw $0x1, %mm1 # pmulhw %mm7, %mm0 # apply gain # pmulhw %mm7, %mm1 # paddsw %mm0, %mm0 # correct factor 2 # paddsw %mm1, %mm1 movq %mm0, (%edi) # store movq %mm1, 8(%edi) addl $8, %esi # increment source pointer addl $16, %edi # increment dest pointer decl %ecx jnz .loop_unpack_y # loop emms pop %edi pop %esi leave ret .globl pixel_unpack_u8s16_uv .type pixel_unpack_u8s16_uv,@function pixel_unpack_u8s16_uv: pushl %ebp movl %esp, %ebp push %esi push %edi # movl 20(%ebp), %edi # int16[4] array of gains # movq (%edi), %mm7 # get gain array movl 8(%ebp), %esi # input uint8 pixel array movl 12(%ebp), %edi # output sint16 pixel array movl 16(%ebp), %ecx # nb of elements div 8 pcmpeqw %mm6, %mm6 psllw $15, %mm6 .align 16 .loop_unpack_uv: movq (%esi), %mm5 # load 8 pixels from memory pxor %mm0, %mm0 # zero mm0 - mm3 pxor %mm1, %mm1 punpcklbw %mm5, %mm0 # unpack 1st 4 pixels punpckhbw %mm5, %mm1 # unpack 2nd 4 pixles pxor %mm6, %mm0 # flip sign bit (Cr and Cb are ofset by 128) pxor %mm6, %mm1 # pmulhw %mm7, %mm0 # apply gain # pmulhw %mm7, %mm1 # paddsw %mm0, %mm0 # correct factor 2 # paddsw %mm1, %mm1 movq %mm0, (%edi) # store movq %mm1, 8(%edi) addl $8, %esi # increment source pointer addl $16, %edi # increment dest pointer decl %ecx jnz .loop_unpack_uv # loop emms pop %edi pop %esi leave ret pdp-0.14.1+darcs20180201/system/net/000077500000000000000000000000001266045153600164105ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/net/Makefile000066400000000000000000000001431266045153600200460ustar00rootroot00000000000000 OBJECTS = pdp_net.o include ../../Makefile.config all: $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/system/net/pdp_net.c000066400000000000000000000425021266045153600202100ustar00rootroot00000000000000 #include "pdp_net.h" #include "pdp_debug.h" #include "pdp_post.h" #include "pdp_mem.h" #define D if (0) // DEBUG MSG #define DD if (0) // DROP DEBUG MSG /* shared internals */ static int _is_udp_header(t_pdp_udp_header *header, unsigned int size) { if (size < sizeof(t_pdp_udp_header)) return 0; if (strcmp(header->signature, "PDP")) return 0; if (PDP_UDP_VERSION != header->version) return 0; return 1; } static void _make_udp_header(t_pdp_udp_header *header) { strcpy(header->signature, "PDP"); header->version = PDP_UDP_VERSION; } /* R E C E I V E R */ /* INTERNALS */ static void _send_packet(t_pdp_udp_receiver *x) { _make_udp_header(&x->x_resend_header); PDP_ASSERT(x->x_resend_udp_packet_size <= sizeof(t_pdp_udp_header) + sizeof(x->x_resend_chunks)); /* send the packet */ if (-1 == sendto (x->x_socket, &x->x_resend_header, x->x_resend_udp_packet_size, 0, (struct sockaddr *)&x->x_source_socket, x->x_sslen)){ pdp_post("pdp_netreceive: send failed"); } } static void _send_ack_new(t_pdp_udp_receiver *x) { /* setup resend header */ x->x_resend_header.connection_id = x->x_connection_id; x->x_resend_header.sequence_number = PDP_UDP_ACKNEW; x->x_resend_udp_packet_size = sizeof(t_pdp_udp_header); _send_packet(x); } static int _handle_PDP_UDP_NEW(t_pdp_udp_receiver *x) { /* we've got a PDP_UDP_NEW packet, so prepare to receive the data */ t_pdp_udp_newpacket *np = (t_pdp_udp_newpacket *)x->x_buf; //pdp_post("conn_id = %x", x->x_header.connection_id); //pdp_post("size = %d", np->data_size); //pdp_post("nb_chunks = %d", np->nb_chunks); //pdp_post("chunk_size = %d", np->chunk_size); //pdp_post("type = %s", np->type); /* check if it is a resend of the PDP_UDP_NEW packet (if NEW_ACK didn't get through) if not, prepare for reception */ if (x->x_connection_id != x->x_header.connection_id){ /* prepare for reception : TODO add some more checks here */ // setup type info if (x->x_data_type) pdp_dealloc (x->x_data_type); x->x_data_type = pdp_alloc(1 + strlen(np->type)); strcpy(x->x_data_type, np->type); // setup data buffer x->x_data_size = np->data_size; if (x->x_data) pdp_dealloc (x->x_data); x->x_data = pdp_alloc(x->x_data_size); memset(x->x_data, 0, x->x_data_size); // clear for debug // setup connection info x->x_connection_id = x->x_header.connection_id; x->x_nb_chunks = np->nb_chunks; x->x_chunk_size = np->chunk_size; /* setup chunk list */ if (x->x_chunk_list) pdp_dealloc(x->x_chunk_list); x->x_chunk_list = pdp_alloc(sizeof(unsigned int)*x->x_nb_chunks); memset(x->x_chunk_list, 0, sizeof(unsigned int)*x->x_nb_chunks); x->x_receive_finished = 0; // we're in a receiving state x->x_packet_transferred = 0; // we didn't pass the packet yet } /* send ACK */ _send_ack_new(x); return 1; } static void _handle_PDP_UDP_DONE(t_pdp_udp_receiver *x) { unsigned int chunk; unsigned int missing; unsigned int i; unsigned int resend_packet_size; /* check the connection id */ if (x->x_connection_id != x->x_header.connection_id) return; /* determine how many packets are missing */ missing = 0; for (i=0; ix_nb_chunks; i++) if (!x->x_chunk_list[i]) missing++; D pdp_post ("last packet %x had %d/%d dropped chunks", x->x_connection_id, missing, x->x_nb_chunks); /* build the resend request (chunk list )*/ if (missing > RESEND_MAX_CHUNKS) missing = RESEND_MAX_CHUNKS; chunk = 0; i = missing; while(i--){ while (x->x_chunk_list[chunk]) chunk++; // find next missing chunk x->x_resend_chunks[i] = chunk++; // store it in list } /* set the packet size to include the list */ x->x_resend_udp_packet_size = sizeof(t_pdp_udp_header) + missing * sizeof(unsigned int); /* setup resend header */ strcpy((char *)&x->x_resend_header, "PDP"); x->x_resend_header.version = PDP_UDP_VERSION; x->x_resend_header.connection_id = x->x_connection_id; x->x_resend_header.sequence_number = PDP_UDP_RESEND; D pdp_post("pdp_netreceive: sending RESEND response for %u chunks", missing); /* send out */ _send_packet(x); /* indicate we're done if there's no chunks missing */ if (!missing) x->x_receive_finished = 1; } static int _handle_UDP_DATA(t_pdp_udp_receiver *x) { unsigned int seq = x->x_header.sequence_number; unsigned int offset = x->x_chunk_size * seq; /* ignore the packet if we're not expecting it */ if ((!x->x_connection_id) || (x->x_connection_id != x->x_header.connection_id)){ //pdp_post("pdp_netreceive: got invalid data packet: transmission id %x is not part of current transmisson %x", // x->x_header.connection_id, x->x_connection_id); return 0; } /* check if it is valid */ if (seq >= x->x_nb_chunks){ pdp_post("pdp_netreceive: got invalid data packet: sequence number %u out of bound (nb_chunks=%u)", seq, x->x_nb_chunks); return 0; } /* final check */ PDP_ASSERT(offset + x->x_buf_size <= x->x_data_size); /* write & log it */ memcpy(x->x_data + offset, x->x_buf, x->x_buf_size); x->x_chunk_list[seq] = 1; return 1; } /* INTERFACE */ /* setup */ t_pdp_udp_receiver *pdp_udp_receiver_new(int port) { t_pdp_udp_receiver *x = pdp_alloc(sizeof(*x)); memset(x, 0, sizeof(*x)); /* init */ x->x_data = 0; x->x_data_type = 0; x->x_data_size = 0; x->x_chunk_list = 0; x->x_receive_finished = 0; x->x_packet_transferred = 0; x->x_zero_terminator = 0; x->x_socket = socket(PF_INET, SOCK_DGRAM, 0); x->x_connection_id = 0; /* zero for bootstrap (0 == an invalid id) */ x->x_sslen = sizeof(struct sockaddr_in); /* bind socket */ x->x_sa.sin_port = htons(port); x->x_sa.sin_addr.s_addr = 0; if (-1 != bind (x->x_socket, (struct sockaddr *)&x->x_sa, sizeof(struct sockaddr_in))) return x; /* suicide if find failed */ else { pdp_dealloc(x); return 0; } } void pdp_udp_receiver_free(t_pdp_udp_receiver *x) { if (!x) return; if (x->x_socket != 1) close (x->x_socket); if (x->x_data) pdp_dealloc(x->x_data); if (x->x_data_type) pdp_dealloc (x->x_data_type); if (x->x_chunk_list) pdp_dealloc (x->x_chunk_list); } void pdp_udp_receiver_reset(t_pdp_udp_receiver *x) { x->x_connection_id = 0; } /* receive loop, returns 1 on success, -1 on error, 0 on timeout */ int pdp_udp_receiver_receive(t_pdp_udp_receiver *x, unsigned int timeout_ms) { /* listen for packets */ unsigned int size; struct timeval tv = {0,1000 * timeout_ms}; fd_set inset; FD_ZERO(&inset); FD_SET(x->x_socket, &inset); switch(select (x->x_socket+1, &inset, NULL, NULL, &tv)){ case -1: return -1; /* select error */ case 0: return 0; /* select time out */ default: break; /* data ready */ } /* this won't block, since there's data available */ if (-1 == (int)(size = recvfrom(x->x_socket, (void *)&x->x_header, PDP_UDP_BUFSIZE+sizeof(x->x_header), 0, (struct sockaddr *)&x->x_source_socket, &x->x_sslen))) return -1; /* store the data size of the packet */ x->x_buf_size = size - sizeof(t_pdp_udp_header); /* parse the udp packet */ if (_is_udp_header(&x->x_header, size)){ /* it is a control packet */ if ((int)x->x_header.sequence_number < 0){ switch (x->x_header.sequence_number){ case PDP_UDP_NEW: _handle_PDP_UDP_NEW(x); break; case PDP_UDP_DONE: _handle_PDP_UDP_DONE(x); /* check if we got a complete packet and signal arrival if we haven't done this already */ if (x->x_receive_finished && !x->x_packet_transferred){ x->x_packet_transferred = 1; return 1; // data complete, please receive } break; default: pdp_post("got unknown msg"); break; } } /* it is a data packet */ else { _handle_UDP_DATA(x); } } else { pdp_post("pdp_netreceive: got invalid UDP packet (size = %d)", size); } return 0; //no major event, please poll again } /* get meta & data */ char *pdp_udp_receiver_type(t_pdp_udp_receiver *x){return x->x_data_type;} unsigned int pdp_udp_receiver_size(t_pdp_udp_receiver *x){return x->x_data_size;} void *pdp_udp_receiver_data(t_pdp_udp_receiver *x){return x->x_data;} /* S E N D E R */ /* INTERNALS */ static void _sleep(t_pdp_udp_sender *x) { int sleep_period = x->x_sleep_period; if (sleep_period) { if (!x->x_sleep_count++) usleep(x->x_sleepgrain_us); x->x_sleep_count %= sleep_period; } } static void _send(t_pdp_udp_sender *x) { //post("sending %u data bytes", x->x_buf_size); _make_udp_header(&x->x_header); PDP_ASSERT (x->x_buf_size <= PDP_UDP_BUFSIZE); if (-1 == sendto (x->x_socket, &x->x_header, x->x_buf_size + sizeof(t_pdp_udp_header), 0, (struct sockaddr *)&x->x_sa, sizeof(struct sockaddr_in))) pdp_post("pdp_netsend: send FAILED"); _sleep(x); } static void _prepare_for_new_transmission(t_pdp_udp_sender *x, char *type, unsigned int size, void *data) { unsigned int i; /* setup data for transmission */ x->x_data_type = type; x->x_data_size = size; x->x_data = data; x->x_chunk_size = x->x_udp_payload_size; x->x_nb_chunks = (x->x_data_size - 1) / x->x_chunk_size + 1; /* generate a connection id (non-zero) */ while (!(x->x_connection_id = rand())); /* setup chunk list to contain all chunks */ if (x->x_chunk_list) free (x->x_chunk_list); x->x_chunk_list_size = x->x_nb_chunks; x->x_chunk_list = malloc(sizeof(unsigned int)*x->x_chunk_list_size); for (i=0; ix_chunk_list_size; i++) x->x_chunk_list[i] = i; } static void _send_header_packet(t_pdp_udp_sender *x) { t_pdp_udp_newpacket *np = (t_pdp_udp_newpacket *)x->x_buf; /* buf contains the PDP_UDP_NEW body */ /* init packet */ x->x_header.sequence_number = PDP_UDP_NEW; x->x_header.connection_id = x->x_connection_id; np->data_size = x->x_data_size; np->nb_chunks = x->x_nb_chunks; np->chunk_size = x->x_chunk_size; strcpy(np->type, x->x_data_type); x->x_buf_size = sizeof(*np) + strlen(np->type) + 1; PDP_ASSERT(x->x_buf_size <= PDP_UDP_BUFSIZE); /* send the packet */ _send(x); } /* saend the chunks in the chunk list */ static void _send_chunks(t_pdp_udp_sender *x){ unsigned int i; unsigned int count = 0; /* send chunks: this requires header is setup ok (sig,ver,connid)*/ for (i=0; ix_chunk_list_size; i++){ unsigned int offset; unsigned int current_chunk_size; unsigned int seq = x->x_chunk_list[i]; PDP_ASSERT(seq < x->x_nb_chunks); x->x_header.sequence_number = seq; // store chunk number /* get current chunk offset */ offset = seq * x->x_chunk_size; PDP_ASSERT(offset < x->x_data_size); /* get current chunk size */ current_chunk_size = (offset + x->x_chunk_size > x->x_data_size) ? (x->x_data_size - offset) : x->x_chunk_size; x->x_buf_size = current_chunk_size; PDP_ASSERT(x->x_buf_size <= PDP_UDP_BUFSIZE); /* copy chunk to transmission buffer & send */ PDP_ASSERT(offset + current_chunk_size <= x->x_data_size); memcpy(x->x_buf, x->x_data + offset, current_chunk_size); /* send the chunk */ _send(x); count++; } D pdp_post("sent %d chunks, id=%x", count,x->x_connection_id); } /* send a DONE packet */ static void _send_done(t_pdp_udp_sender *x){ x->x_header.sequence_number = PDP_UDP_DONE; x->x_buf_size = 0; _send(x); } static int _receive_packet(t_pdp_udp_sender *x, int desired_type) /* 0 == timeout, -1 == error, 1 == got packet */ { unsigned int size; int type; struct timeval tv; fd_set inset; int sr; while (1){ int retval; /* wait for incoming */ tv.tv_sec = 0; tv.tv_usec = x->x_timeout_us; FD_ZERO(&inset); FD_SET(x->x_socket, &inset); switch (select (x->x_socket+1, &inset, NULL, NULL, &tv)){ case -1: return -1; /* select error */ case 0: return 0; /* select time out */ default: break; /* data ready */ } /* read packet */ if (-1 == (int)(size = recv(x->x_socket, (void *)&x->x_resend_header, MAX_UDP_PACKET, 0))){ pdp_post("pdp_netsend: error while reading from socket"); return -1; } /* check if it is a valid PDP_UDP packet */ if (!_is_udp_header(&x->x_resend_header, size)){ pdp_post("pdp_netsend: ignoring invalid UDP packet (size = %u)", size); continue; } /* check connection id */ if (x->x_connection_id != x->x_resend_header.connection_id){ D pdp_post("pdp_netsend: ignoring ghost packet id=%x, current id=%x", x->x_resend_header.connection_id, x->x_connection_id); continue; } /* check type */ type = x->x_resend_header.sequence_number; if (type != desired_type) continue; /* setup data buffer for known packets */ switch(type){ case PDP_UDP_RESEND: x->x_resend_items = (size - sizeof(t_pdp_udp_header)) / sizeof(unsigned int); break; default: break; } return 1; } } /* get the resend list */ static int _need_resend(t_pdp_udp_sender *x) { int retries = 3; int retval; while (retries--){ /* send a DONE msg */ _send_done(x); /* wait for ACK */ switch(_receive_packet(x, PDP_UDP_RESEND)){ case 0: /* timeout, retry */ continue; case -1: /* error */ goto move_on; default: /* got PDP_UDP_RESEND packet: setup resend list */ if (x->x_resend_items > x->x_nb_chunks){ pdp_post("pdp_netsend: WARNING: chunk list size (%d) is too big, ignoring RESEND request", x->x_resend_items); x->x_resend_items = 0; continue; } x->x_chunk_list_size = x->x_resend_items; memcpy(x->x_chunk_list, x->x_resend_chunks, sizeof(unsigned int) * x->x_resend_items); D pdp_post("got RESEND request for %d chunks (id %x)", x->x_resend_items,x->x_connection_id); return x->x_chunk_list_size > 0; } } /* timeout */ move_on: x->x_chunk_list_size = 0; return 0; } /* INTERFACE */ /* some flow control hacks */ void pdp_udp_sender_timeout_us(t_pdp_udp_sender *x, unsigned int timeout_us) { x->x_timeout_us = timeout_us; } void pdp_udp_sender_sleepgrain_us(t_pdp_udp_sender *x, unsigned int sleepgrain_us) { x->x_sleepgrain_us = sleepgrain_us; } void pdp_udp_sender_sleepperiod(t_pdp_udp_sender *x, unsigned int sleepperiod) { x->x_sleep_period = sleepperiod; } void pdp_udp_sender_udp_packet_size(t_pdp_udp_sender *x, unsigned int udp_packet_size) { int i = (int)udp_packet_size - sizeof(t_pdp_udp_header); // if (i < 1024) i = 1024; if (i > PDP_UDP_BUFSIZE) i = PDP_UDP_BUFSIZE; x->x_udp_payload_size = i; } void pdp_udp_sender_connect(t_pdp_udp_sender *x, char *host, unsigned int port) { struct hostent *hp; hp = gethostbyname(host); if (!hp){ pdp_post("pdp_udp_sender: host %s not found", host); } else{ /* host ok, setup address */ x->x_sa.sin_family = AF_INET; x->x_sa.sin_port = htons(port); memcpy((char *)&x->x_sa.sin_addr, (char *)hp->h_addr, hp->h_length); /* create the a socket if necessary */ if (x->x_socket == -1){ if (-1 == (x->x_socket = socket(PF_INET, SOCK_DGRAM, 0))){ pdp_post("pdp_udp_sender: can't create socket"); } if (1){ int on = 1; if (setsockopt(x->x_socket,SOL_SOCKET,SO_BROADCAST,(char *)&on,sizeof(on))<0) pdp_post("pdp_udp_sender: can't set broadcast flag"); } } } } /* setup */ t_pdp_udp_sender *pdp_udp_sender_new(void) { t_pdp_udp_sender *x = pdp_alloc(sizeof(*x)); memset(x,0,sizeof(*x)); x->x_chunk_list = 0; /* no connection */ x->x_socket = -1; /* set flow control */ pdp_udp_sender_timeout_us(x, 50000); x->x_sleep_count = 0; pdp_udp_sender_sleepgrain_us(x, 0); pdp_udp_sender_sleepperiod(x, 50); pdp_udp_sender_udp_packet_size(x, 1472); //optimal udp packet size (ip: 1500 = 28 + 1472) return x; } void pdp_udp_sender_free(t_pdp_udp_sender *x) { int i; void* retval; if (x->x_socket != -1) close(x->x_socket); if (x->x_chunk_list) free (x->x_chunk_list); } /* send, returns 1 on success, 0 on error */ int pdp_udp_sender_send(t_pdp_udp_sender *x, char* type, unsigned int size, void *data) { /* SEND A PACKET */ /* get the type and data from caller */ /* send header packet and make sure it has arrived */ /* send a chunk burst */ /* send done packet and get the resend list */ /* repeat until send list is empty */ int hs_retry = 5; // retry count for initial handshake int rs_retry = 5; // retry count for resends /* check if we have a target */ if (-1 == x->x_socket) goto transerror; /* setup internal state */ _prepare_for_new_transmission(x,type,size,data); /* handshake a new transmission */ do { if (!(hs_retry--)) break; // pdp_post("handshake retry %d for packet %x", hscount, x->x_connection_id); _send_header_packet(x); } while (!_receive_packet(x, PDP_UDP_ACKNEW)); /* exit if no handshake was possible */ if (hs_retry < 0){ DD pdp_post("pdp_netsend: DROP: receiver does not accept new transmission"); goto transerror; } /* transmission loop */ do { if (!(rs_retry--)) break; _send_chunks(x); } while (_need_resend(x)); /* exit if transmission was not successful */ if (rs_retry < 0){ DD pdp_post("pdp_netsend: DROP: receiver did not confirm reception"); goto transerror; } /* send successful */ return 1; transerror: /* transmission error */ return 0; } pdp-0.14.1+darcs20180201/system/pdp.c000066400000000000000000000117221266045153600165540ustar00rootroot00000000000000/* * Pure Data Packet system implementation: setup code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include "pdp_config.h" #include "pdp_post.h" static int initialized = 0; /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* module setup declarations (all C-style) */ /* pdp system / internal stuff */ void pdp_debug_setup(void); void pdp_list_setup(void); void pdp_pdsym_setup(void); void pdp_forth_setup(void); void pdp_forth_def_setup(void); void pdp_symbol_setup(void); void pdp_type_setup(void); void pdp_packet_setup(void); void pdp_ut_setup(void); void pdp_queue_setup(void); void pdp_control_setup(void); void pdp_image_setup(void); void pdp_bitmap_setup(void); void pdp_matrix_setup(void); /* pdp modules */ void pdp_xv_setup(void); void pdp_add_setup(void); void pdp_mul_setup(void); void pdp_mix_setup(void); void pdp_randmix_setup(void); void pdp_qt_setup(void); void pdp_v4l_setup(void); void pdp_reg_setup(void); void pdp_conv_setup(void); void pdp_bq_setup(void); void pdp_del_setup(void); void pdp_snap_setup(void); void pdp_trigger_setup(void); void pdp_route_setup(void); void pdp_noise_setup(void); void pdp_gain_setup(void); void pdp_chrot_setup(void); void pdp_scope_setup(void); void pdp_scale_setup(void); void pdp_zoom_setup(void); void pdp_scan_setup(void); void pdp_scanxy_setup(void); void pdp_sdl_setup(void); void pdp_cheby_setup(void); void pdp_grey2mask_setup(void); void pdp_constant_setup(void); void pdp_logic_setup(void); void pdp_glx_setup(void); void pdp_loop_setup(void); void pdp_description_setup(void); void pdp_convert_setup(void); void pdp_stateless_setup(void); void pdp_mat_mul_setup(void); void pdp_mat_lu_setup(void); void pdp_mat_vec_setup(void); void pdp_plasma_setup(void); void pdp_cog_setup(void); void pdp_histo_setup(void); void pdp_array_setup(void); void pdp_udp_send_setup(void); void pdp_udp_receive_setup(void); void pdp_rawin_setup(void); void pdp_rawout_setup(void); void pdp_metro_setup(void); /* hacks */ void pdp_inspect_setup(void); /* testing */ void pdp_dpd_test_setup(void); /* library setup routine */ void pdp_setup(void){ if (initialized) return; /* babble */ #ifdef PDP_VERSION # if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43 pdp_post("PDP: pure data packet version " PDP_VERSION ); # else logpost(NULL, 3, "PDP: pure data packet version " PDP_VERSION ); # endif #else pdp_post ("PDP: pure data packet"); #endif /* setup pdp system */ /* kernel */ pdp_pdsym_setup(); pdp_debug_setup(); pdp_symbol_setup(); pdp_list_setup(); pdp_type_setup(); pdp_packet_setup(); pdp_control_setup(); /* types */ pdp_image_setup(); pdp_bitmap_setup(); #ifdef HAVE_PDP_GSL pdp_matrix_setup(); #endif pdp_queue_setup(); /* setup utility toolkit */ pdp_ut_setup(); /* setup pdp pd modules*/ pdp_add_setup(); pdp_mul_setup(); pdp_mix_setup(); pdp_randmix_setup(); pdp_reg_setup(); pdp_conv_setup(); pdp_bq_setup(); pdp_del_setup(); pdp_snap_setup(); pdp_trigger_setup(); pdp_route_setup(); pdp_noise_setup(); pdp_plasma_setup(); pdp_gain_setup(); pdp_chrot_setup(); pdp_scope_setup(); pdp_scale_setup(); pdp_zoom_setup(); pdp_scan_setup(); pdp_scanxy_setup(); pdp_grey2mask_setup(); pdp_constant_setup(); pdp_logic_setup(); pdp_loop_setup(); pdp_description_setup(); pdp_convert_setup(); pdp_stateless_setup(); pdp_cog_setup(); pdp_array_setup(); pdp_rawin_setup(); pdp_rawout_setup(); pdp_metro_setup(); /* experimental stuff */ pdp_inspect_setup(); pdp_udp_send_setup(); pdp_udp_receive_setup(); /* testing */ //pdp_dpd_test_setup(); /* optional stuff */ #ifdef HAVE_PDP_READLINE pdp_forthconsole_setup(); #endif #ifdef HAVE_PDP_GSL pdp_histo_setup(); pdp_cheby_setup(); pdp_mat_mul_setup(); pdp_mat_lu_setup(); pdp_mat_vec_setup(); #endif #ifdef HAVE_PDP_QT pdp_qt_setup(); #endif #ifdef HAVE_PDP_XV pdp_xv_setup(); #endif #ifdef HAVE_PDP_SDL pdp_sdl_setup(); #endif #ifdef HAVE_PDP_V4L pdp_v4l_setup(); #endif #ifdef HAVE_PDP_GLX pdp_glx_setup(); #endif initialized++; } #ifdef __cplusplus } #endif pdp-0.14.1+darcs20180201/system/png/000077500000000000000000000000001266045153600164065ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/png/Makefile000066400000000000000000000001431266045153600200440ustar00rootroot00000000000000 OBJECTS = pdp_png.o include ../../Makefile.config all: $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/system/png/pdp_png.c000066400000000000000000000222461266045153600202070ustar00rootroot00000000000000 /* * Pure Data Packet system module. - png glue code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp_packet.h" #include "pdp_mem.h" #include "pdp_post.h" #include "pdp_debug.h" // this is an optional module #include "pdp_config.h" #ifdef HAVE_PDP_PNG //if 0 #include #define READING 1 #define WRITING 2 #define SIG_BYTES 8 #define D if(0) typedef struct { FILE *x_fp; int x_kindof; //READING or WRITING png_structp x_png; png_infop x_info; png_infop x_end_info; png_uint_32 x_width; png_uint_32 x_height; int x_bit_depth; int x_color_type; int x_interlace_type; int x_compression_type; int x_filter_type; int x_pdp_bitmap_type; int x_packet; } t_png_image; static t_png_image *_init(t_png_image *x) { x->x_png = 0; x->x_info = 0; x->x_end_info = 0; x->x_fp = 0; x->x_packet = -1; return x; } static int _cleanup(t_png_image *x) { #define INTERNAL_ERROR 1 if (!x) return 1; pdp_packet_mark_unused(x->x_packet); if (x->x_png) switch(x->x_kindof){ case READING: png_destroy_read_struct(&x->x_png, &x->x_info, &x->x_end_info); break; case WRITING: png_destroy_write_struct(&x->x_png, &x->x_info); break; default: PDP_ASSERT(INTERNAL_ERROR); } if (x->x_fp) fclose(x->x_fp); return 1; } static int _open_read(t_png_image* x, char *file) { unsigned char header[SIG_BYTES]; int is_png; x->x_fp = fopen(file, "r"); if (!x->x_fp) { D pdp_post("can't open %s for reading", file); return 0; } fread(header, 1, SIG_BYTES, x->x_fp); is_png = !png_sig_cmp(header, 0, SIG_BYTES); D pdp_post("%s is %s png file", file, is_png ? "a" : "not a"); return is_png; } static int _open_write(t_png_image* x, char *file) { char header[SIG_BYTES]; int is_png; x->x_fp = fopen(file, "w"); if (!x->x_fp) { D pdp_post("can't open %s for writing", file); return 0; } return 1; } /* progress callback */ static void _row_callback(png_structp __attribute__((unused)) p, png_uint_32 __attribute__((unused)) row, int __attribute__((unused)) pass) { fprintf(stderr, "."); } static int _initio_read(t_png_image *x) { png_init_io(x->x_png, x->x_fp); png_set_sig_bytes(x->x_png, SIG_BYTES); D png_set_read_status_fn(x->x_png, _row_callback); return 1; } static int _initio_write(t_png_image *x) { png_init_io(x->x_png, x->x_fp); D png_set_write_status_fn(x->x_png, _row_callback); return 1; } static int _checkimagetype(t_png_image *x) { png_read_info(x->x_png, x->x_info); png_get_IHDR(x->x_png, x->x_info, &x->x_width, &x->x_height, &x->x_bit_depth, &x->x_color_type, &x->x_interlace_type, &x->x_compression_type, &x->x_filter_type); D pdp_post("image info: w=%d, h=%d, depth=%d, type=%d", (int)x->x_width, (int)x->x_height, (int)x->x_bit_depth, (int)x->x_color_type); /* handle paletted images: convert to 8 bit RGB(A) */ if (x->x_color_type == PNG_COLOR_TYPE_PALETTE && x->x_bit_depth <= 8) { png_set_expand(x->x_png); D pdp_post("convert palette"); /* check if there's an alpha channel and set PDP_BITMAP type */ x->x_pdp_bitmap_type = (png_get_valid(x->x_png, x->x_info, PNG_INFO_tRNS)) ? PDP_BITMAP_RGBA : PDP_BITMAP_RGB; return 1; } /* handle bitdepth */ if (x->x_bit_depth < 8) { png_set_expand(x->x_png); D pdp_post("convert greyscale to 8 bit"); } if (x->x_bit_depth == 16){ D pdp_post("stripping 16 bit to 8 bit"); png_set_strip_16(x->x_png); } /* handle greyscale images */ if (x->x_color_type == PNG_COLOR_TYPE_GRAY){ x->x_pdp_bitmap_type = PDP_BITMAP_GREY; if (png_get_valid(x->x_png, x->x_info, PNG_INFO_tRNS)){ D pdp_post("no support for greyscale images with alpha info"); return 0; } return 1; } /* handle RGB imges */ if (x->x_color_type = PNG_COLOR_TYPE_RGB){ x->x_pdp_bitmap_type = PDP_BITMAP_RGB; return 1; } /* handle RGBA imges */ if (x->x_color_type = PNG_COLOR_TYPE_RGBA){ x->x_pdp_bitmap_type = PDP_BITMAP_RGBA; return 1; } /* can't handle image type */ D pdp_post("image type not supported"); return 0; } #define user_error_ptr NULL #define user_error_fn NULL #define user_warning_fn NULL static int _buildstruct_read(t_png_image *x) { x->x_kindof = READING; if (!(x->x_png = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn))) return 0; if (!(x->x_info = png_create_info_struct(x->x_png))) return 0; if (!(x->x_end_info = png_create_info_struct(x->x_png))) return 0; return 1; } static int _buildstruct_write(t_png_image *x) { x->x_kindof = WRITING; if (!(x->x_png = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn))) return 0; if (!(x->x_info = png_create_info_struct(x->x_png))) return 0; return 1; } static int _getimagedata(t_png_image *x) { int nbchans = 0; unsigned char *image_data; png_bytep row_pointers[x->x_height]; png_uint_32 i; D pdp_post("reading %d rows ", (int)x->x_height); switch (x->x_pdp_bitmap_type){ case PDP_BITMAP_GREY: nbchans = 1; break; case PDP_BITMAP_RGB: nbchans = 3; break; case PDP_BITMAP_RGBA: nbchans = 4; break; default: return 0; } x->x_packet = pdp_packet_new_bitmap(x->x_pdp_bitmap_type, x->x_width, x->x_height); if (!(image_data = pdp_packet_data(x->x_packet))) return 0; for(i=0; ix_height; i++) row_pointers[i] = image_data + nbchans * i * x->x_width; png_read_image(x->x_png, row_pointers); D pdp_post("DONE"); return 1; } static int _saveimagedata(t_png_image *x, int packet) { png_bytep *row_pointers; png_uint_32 i; int nbchans; t_pdp *h = pdp_packet_header(packet); unsigned char *image_data = (unsigned char *)pdp_packet_data(packet); if (!h) return 0; if (PDP_BITMAP != h->type) return 0; if (!image_data) return 0; x->x_width = h->info.bitmap.width; x->x_height = h->info.bitmap.height; switch(h->info.image.encoding){ case PDP_BITMAP_GREY: x->x_color_type = PNG_COLOR_TYPE_GRAY; nbchans = 1; break; case PDP_BITMAP_RGB: x->x_color_type = PNG_COLOR_TYPE_RGB; nbchans = 3; break; case PDP_BITMAP_RGBA: x->x_color_type = PNG_COLOR_TYPE_RGBA; nbchans = 4; break; default: return 0; } png_set_IHDR(x->x_png, x->x_info, x->x_width, x->x_height, 8, x->x_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(x->x_png, x->x_info); D pdp_post("writing %d rows ", (int)x->x_height); row_pointers = (png_bytep *)pdp_alloc(sizeof(png_bytep) * x->x_height); for(i=0; ix_height; i++) row_pointers[i] = image_data + nbchans * i * x->x_width; png_write_image(x->x_png, row_pointers); png_write_end(x->x_png, x->x_info); pdp_dealloc(row_pointers); D pdp_post("DONE"); return 1; } /* simple functions to load and save png images */ int pdp_packet_bitmap_from_png_file(char *filename) { int packet = -1; t_png_image _x; t_png_image *x = &_x; if (!_init(x)) goto exit; if (!_open_read(x, filename)) goto exit; if (!_buildstruct_read(x)) goto exit; if (!_initio_read(x)) goto exit; if (!_checkimagetype(x)) goto exit; if (!_getimagedata(x)) goto exit; packet = x->x_packet; x->x_packet = -1; _cleanup(x); return packet; exit: _cleanup(x); return -1; } int pdp_packet_bitmap_save_png_file(int packet, char *filename) { t_png_image _x; t_png_image *x = &_x; if (!_init(x)) goto exit; if (!_open_write(x, filename)) goto exit; if (!_buildstruct_write(x)) goto exit; if (!_initio_write(x)) goto exit; if (!_saveimagedata(x, packet)) goto exit; _cleanup(x); return 1; exit: _cleanup(x); return 0; } #else //PDP_HAVE_PNG int pdp_packet_bitmap_save_png_file(int packet, char *filename) { pdp_post("WARNING: no png support, can't save png file %s", filename); return 0; } int pdp_packet_bitmap_from_png_file(char *filename) { pdp_post("WARNING: no png support, can't load png file %s", filename); return -1; } #endif //PDP_HAVE_PNG #if 0 int main(int argc, char **argv) { char *image = 0; if (argc != 2) pdp_post("usage: %s ", argv[0]); else image = load_png(argv[1]); pdp_post ("%s", image ? "OK" : "ERROR"); } #endif pdp-0.14.1+darcs20180201/system/type/000077500000000000000000000000001266045153600166035ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/type/Makefile000066400000000000000000000002021266045153600202350ustar00rootroot00000000000000 OBJECTS = pdp_bitmap.o pdp_image.o $(PDP_OPTTYPES) include ../../Makefile.config all: $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/system/type/pdp_bitmap.c000066400000000000000000000505451266045153600210770ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : 8 bit image packet implementation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include "pdp_packet.h" #include "pdp_type.h" #include "pdp_llconv.h" #include "pdp_internals.h" #include "pdp_post.h" /* the class object */ static t_pdp_class* bitmap_class; t_bitmap *pdp_packet_bitmap_info(int packet) { return (t_bitmap *)pdp_packet_subheader(packet); } /* check if packet is a valid image packet */ int pdp_packet_bitmap_isvalid(int packet) { t_pdp *header = pdp_packet_header(packet); t_bitmap *image = pdp_packet_bitmap_info(packet); if (!header) return 0; if (PDP_BITMAP != header->type) return 0; return 1; } /* bitmap constructors */ t_pdp_symbol *pdp_packet_bitmap_get_description(int packet) { t_pdp *header = pdp_packet_header(packet); t_bitmap *bitmap = pdp_packet_bitmap_info(packet); char description[1024]; char *c = description; int encoding; if (!header) return pdp_gensym("invalid"); else if (!header->desc){ /* if description is not defined, try to reconstruct it (for backwards compat) */ if (header->type == PDP_BITMAP){ c += sprintf(c, "bitmap"); encoding = bitmap->encoding; switch(encoding){ case PDP_BITMAP_RGB: c += sprintf(c, "/rgb"); break; case PDP_BITMAP_RGBA: c += sprintf(c, "/rgba"); break; case PDP_BITMAP_GREY: c += sprintf(c, "/grey"); break; case PDP_BITMAP_YV12: c += sprintf(c, "/yv12"); break; case PDP_BITMAP_I420: c += sprintf(c, "/i420"); break; default: c += sprintf(c, "/unknown"); goto exit; } c += sprintf(c, "/%dx%d", bitmap->width, bitmap->height); exit: return pdp_gensym(description); } else return pdp_gensym("unknown"); } else return header->desc; } int pdp_packet_new_bitmap_yv12(u32 w, u32 h) { t_pdp *header; t_bitmap *bitmap; int packet; u32 size = w*h; u32 totalnbpixels = size; u32 packet_size = size + (size >> 1); packet = pdp_packet_new(PDP_BITMAP, packet_size); header = pdp_packet_header(packet); bitmap = pdp_packet_bitmap_info(packet); if (!header) return -1; bitmap->encoding = PDP_BITMAP_YV12; bitmap->width = w; bitmap->height = h; header->desc = pdp_packet_bitmap_get_description(packet); header->theclass = bitmap_class; return packet; } int pdp_packet_new_bitmap_i420(u32 w, u32 h){ int p = pdp_packet_new_bitmap_yv12(w,h); if (-1 == p) return -1; t_pdp *header = pdp_packet_header(p); t_bitmap *bitmap = pdp_packet_subheader(p); bitmap->encoding = PDP_BITMAP_I420; header->desc = 0; // structured programming.. ha! header->desc = pdp_packet_bitmap_get_description(p); return p; } int pdp_packet_new_bitmap_grey(u32 w, u32 h) { t_pdp *header; t_bitmap *bitmap; int packet; u32 size = w*h; u32 totalnbpixels = size; u32 packet_size = totalnbpixels; packet = pdp_packet_new(PDP_BITMAP, packet_size); header = pdp_packet_header(packet); bitmap = pdp_packet_bitmap_info(packet); if (!header) return -1; bitmap->encoding = PDP_BITMAP_GREY; bitmap->width = w; bitmap->height = h; header->desc = pdp_packet_bitmap_get_description(packet); header->theclass = bitmap_class; return packet; } int pdp_packet_new_bitmap_rgb(u32 w, u32 h) { t_pdp *header; t_bitmap *bitmap; int packet; u32 size = w*h; u32 totalnbpixels = size; u32 packet_size = totalnbpixels * 3; packet = pdp_packet_new(PDP_BITMAP, packet_size); header = pdp_packet_header(packet); bitmap = pdp_packet_bitmap_info(packet); if (!header) return -1; bitmap->encoding = PDP_BITMAP_RGB; bitmap->width = w; bitmap->height = h; header->desc = pdp_packet_bitmap_get_description(packet); header->theclass = bitmap_class; return packet; } int pdp_packet_new_bitmap_rgba(u32 w, u32 h) { t_pdp *header; t_bitmap *bitmap; int packet; u32 size = w*h; u32 totalnbpixels = size; u32 packet_size = totalnbpixels * 4; packet = pdp_packet_new(PDP_BITMAP, packet_size); header = pdp_packet_header(packet); bitmap = pdp_packet_bitmap_info(packet); if (!header) return -1; bitmap->encoding = PDP_BITMAP_RGBA; bitmap->width = w; bitmap->height = h; header->desc = pdp_packet_bitmap_get_description(packet); header->theclass = bitmap_class; return packet; } int pdp_packet_new_bitmap(int type, u32 w, u32 h) { switch(type){ case PDP_BITMAP_GREY: return pdp_packet_new_bitmap_grey(w,h); case PDP_BITMAP_YV12: return pdp_packet_new_bitmap_yv12(w,h); case PDP_BITMAP_I420: return pdp_packet_new_bitmap_i420(w,h); case PDP_BITMAP_RGB: return pdp_packet_new_bitmap_rgb(w,h); case PDP_BITMAP_RGBA: return pdp_packet_new_bitmap_rgba(w,h); default: return -1; } } /* some utility methods */ void pdp_llconv_flip_top_bottom(char *data, int width, int height, int pixelsize); /* flip top & bottom */ void pdp_packet_bitmap_flip_top_bottom(int packet) { t_bitmap *b = (t_bitmap *)pdp_packet_subheader(packet); char *d = (char *)pdp_packet_data(packet); int w,h; if (!pdp_packet_bitmap_isvalid(packet)) return; if (!b) return; w = b->width; h = b->height; switch(b->encoding){ case PDP_BITMAP_GREY: pdp_llconv_flip_top_bottom(d,w,h,1); break; case PDP_BITMAP_RGB: pdp_llconv_flip_top_bottom(d,w,h,3); break; case PDP_BITMAP_RGBA: pdp_llconv_flip_top_bottom(d,w,h,4); break; default: break; } } /* conversion methods */ // image/grey/* -> bitmap/grey/* static int _pdp_packet_bitmap_convert_grey_to_grey8( int packet, __attribute__((unused)) t_pdp_symbol *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); s16 *data = (s16 *)pdp_packet_data(packet); u8 *new_data; u32 w,h; int new_p; if (!pdp_packet_image_isvalid(packet)) return -1; w = image->width; h = image->height; if (!((image->encoding == PDP_IMAGE_GREY) || (image->encoding == PDP_IMAGE_YV12))) return -1; new_p = pdp_packet_new_bitmap_grey(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); /* convert image to greyscale 8 bit */ pdp_llconv(data,RIF_GREY______S16, new_data, RIF_GREY______U8, w, h); return new_p; } static int _pdp_packet_bitmap_convert_YCrCb_to_rgb8( int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); s16 *data = (s16 *)pdp_packet_data(packet); u8 *new_data; u32 w,h; int new_p; if (!pdp_packet_image_isvalid(packet)) return -1; w = image->width; h = image->height; if (!((image->encoding == PDP_IMAGE_YV12))) return -1; new_p = pdp_packet_new_bitmap_rgb(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); /* convert image to greyscale 8 bit */ pdp_llconv(data,RIF_YVU__P411_S16, new_data, RIF_RGB__P____U8, w, h); return new_p; } static int _pdp_packet_bitmap_convert_image_to_yv12( int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); s16 *data = (s16 *)pdp_packet_data(packet); u8 *new_data; u32 w,h, nbpixels; int new_p; int encoding = image->encoding; if (!pdp_packet_image_isvalid(packet)) return -1; w = image->width; h = image->height; nbpixels = w*h; new_p = pdp_packet_new_bitmap_yv12(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); switch (encoding){ case PDP_IMAGE_YV12: pdp_llconv(data, RIF_YVU__P411_S16, new_data, RIF_YVU__P411_U8, w, h); break; case PDP_IMAGE_GREY: pdp_llconv(data, RIF_GREY______S16, new_data, RIF_GREY______U8, w, h); memset(new_data + nbpixels, 0x80, nbpixels>>1); break; default: /* not supported, $$$TODO add more */ pdp_packet_mark_unused(new_p); new_p = -1; break; } return new_p; } static int _pdp_packet_bitmap_convert_rgb8_to_YCrCb( int packet, __attribute__((unused)) t_pdp_symbol *dest_template) { t_pdp *header = pdp_packet_header(packet); t_bitmap *bitmap = pdp_packet_bitmap_info(packet); u8 *data = (u8 *)pdp_packet_data(packet); s16 *new_data; u32 w,h; int new_p; w = bitmap->width; h = bitmap->height; new_p = pdp_packet_new_image_YCrCb(w,h); if (-1 == new_p) return -1; new_data = (s16 *)pdp_packet_data(new_p); /* convert image to greyscale 8 bit */ pdp_llconv(data, RIF_RGB__P____U8, new_data, RIF_YVU__P411_S16, w, h); return new_p; } static int _pdp_packet_bitmap_convert_rgb8_to_bitmap_YCrCb( int packet, __attribute__((unused)) t_pdp_symbol *dest_template) { t_pdp *header = pdp_packet_header(packet); t_bitmap *bitmap = pdp_packet_bitmap_info(packet); u8 *data = (u8 *)pdp_packet_data(packet); u8 *new_data; u32 w,h; int new_p; w = bitmap->width; h = bitmap->height; new_p = pdp_packet_new_bitmap_yv12(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); /* convert image to greyscale 8 bit */ pdp_llconv(data, RIF_RGB__P____U8, new_data, RIF_YVU__P411_U8, w, h); return new_p; } static int _pdp_packet_bitmap_convert_grey8_to_grey( int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_bitmap *bitmap = pdp_packet_bitmap_info(packet); s16 *data = (s16 *)pdp_packet_data(packet); u8 *new_data; u32 w,h; int new_p; w = bitmap->width; h = bitmap->height; new_p = pdp_packet_new_image_grey(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); /* convert image to greyscale 8 bit */ pdp_llconv(data, RIF_GREY______U8, new_data, RIF_GREY______S16, w, h); return new_p; } static int _pdp_packet_bitmap_convert_rgb8_to_rgba8( int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_bitmap *bitmap = pdp_packet_bitmap_info(packet); u8 *data = (u8 *)pdp_packet_data(packet); u8 *new_data; int w,h, new_p, i; w = bitmap->width; h = bitmap->height; new_p = pdp_packet_new_bitmap_rgba(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); for(i=0; iwidth; h = bitmap->height; new_p = pdp_packet_new_bitmap_rgb(w,h); if (-1 == new_p) return -1; new_data = (u8 *)pdp_packet_data(new_p); for(i=0; iwidth; h = bitmap->height; plane = w*h; new_p = pdp_packet_new_image_multi(w,h,3); if (-1 == new_p) return -1; new_data = (s16 *)pdp_packet_data(new_p); for(i=0; iwidth; int h = in->height; int out_encoding; if (in->encoding == PDP_BITMAP_YV12) out_encoding = PDP_BITMAP_I420; else if (in->encoding == PDP_BITMAP_I420) out_encoding = PDP_BITMAP_YV12; else return -1; int new_p = pdp_packet_new_bitmap(out_encoding, w,h); // t_pdp *out_h = pdp_packet_header(new_p); // pdp_post("%x %s", out_encoding, out_h->desc->s_name); if (-1 == new_p) return -1; unsigned char *in_d = pdp_packet_data(packet); unsigned char *out_d = pdp_packet_data(new_p); int plane = w*h; memcpy(out_d, in_d, plane); out_d += plane; in_d += plane; plane /= 4; memcpy(out_d, in_d+plane, plane); memcpy(out_d+plane, in_d, plane); return new_p; } static int _pdp_packet_bitmap_convert_yv12_to_image( int packet, __attribute__((unused)) t_pdp_symbol *dest_template) { t_pdp *header = pdp_packet_header(packet); t_bitmap *bitmap = pdp_packet_bitmap_info(packet); u8 *data = (u8 *)pdp_packet_data(packet); s16 *new_data; int w,h; int new_p; w = bitmap->width; h = bitmap->height; new_p = pdp_packet_new_image_YCrCb(w,h); new_data = pdp_packet_data(new_p); if (-1 == new_p || !new_data) return -1; pdp_llconv(data, RIF_YVU__P411_U8, new_data, RIF_YVU__P411_S16, w, h); return new_p; } static int _pdp_packet_bitmap_convert_mchp_to_rgb8( int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = (t_image *)pdp_packet_subheader(packet); s16 *data = (s16 *)pdp_packet_data(packet); u8 *new_data; int w = image->width; int h = image->height; int plane = w*h; int nb_channels = image->depth; int new_p, i; // static inline u8 _map(s32 pixel){ inline u8 _map(s32 pixel){ s32 mask = ~(pixel>>16); return ((pixel >> 7) & mask); } switch(nb_channels){ default: return -1; case 1: if (-1 == (new_p = pdp_packet_new_bitmap_grey(w,h))) return -1; new_data = (u8*)pdp_packet_data(new_p); for(i=0; is_name, dest_template->s_name); return -1; } static int pdp_bitmap_factory(t_pdp_symbol *type) { t_pdp_list *l; t_pdp_symbol *s; int t; int w = 0; int h = 0; int d = 0; int p = -1; int n = 0; int m = 0; char *garbage = 0; //pdp_post("creating:"); //pdp_post("%s", type->s_name); l = pdp_type_to_list(type); s = pdp_list_pop(l).w_symbol; // first element is "bitmap" s = pdp_list_pop(l).w_symbol; /* get image type */ if (s == pdp_gensym("grey")) t = PDP_BITMAP_GREY; else if (s == pdp_gensym("yv12")) t = PDP_BITMAP_YV12; else if (s == pdp_gensym("rgb")) t = PDP_BITMAP_RGB; else goto exit; /* get image dimensions and create image */ s = pdp_list_pop(l).w_symbol; sscanf(s->s_name, "%dx%d", &w, &h); p = pdp_packet_new_bitmap(t,w,h); if (p != -1){ t_pdp *header = pdp_packet_header(p); /* if type is not exact, delete the packet */ if (type != header->desc) { pdp_packet_delete(p); p = -1; } } exit: pdp_list_free(l); return p; } void pdp_bitmap_setup(void) { t_pdp_conversion_program *program; /* setup class object */ bitmap_class = pdp_class_new(pdp_gensym("bitmap/*/*"), pdp_bitmap_factory); /* setup conversion programs */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_grey_to_grey8, 0); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("bitmap/grey/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_grey8_to_grey, 0); pdp_type_register_conversion(pdp_gensym("bitmap/grey/*"), pdp_gensym("image/grey/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_YCrCb_to_rgb8, 0); pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("bitmap/rgb/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_image_to_yv12, 0); pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("bitmap/yv12/*"), program); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("bitmap/yv12/*"), program); pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("bitmap/*"), program); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("bitmap/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_yv12_to_image, 0); pdp_type_register_conversion(pdp_gensym("bitmap/yv12/*"), pdp_gensym("image/YCrCb/*"), program); /* rgb->YCrCb converts the colour space */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_rgb8_to_YCrCb, 0); pdp_type_register_conversion(pdp_gensym("bitmap/rgb/*"), pdp_gensym("image/YCrCb/*"), program); /* rgb <-> multi does not convert the colour space */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_rgb8_to_mchp, 0); pdp_type_register_conversion(pdp_gensym("bitmap/rgb/*"), pdp_gensym("image/multi/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_mchp_to_rgb8, 0); pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("bitmap/*/*"), program); /* yv12 <-> i420 */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_yv12_tofrom_i420, 0); pdp_type_register_conversion(pdp_gensym("bitmap/yv12/*"), pdp_gensym("bitmap/i420/*"), program); pdp_type_register_conversion(pdp_gensym("bitmap/i420/*"), pdp_gensym("bitmap/yv12/*"), program); /* rgb <-> rgba */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_rgb8_to_rgba8, 0); pdp_type_register_conversion(pdp_gensym("bitmap/rgb/*"), pdp_gensym("bitmap/rgba/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_rgba8_to_rgb8, 0); pdp_type_register_conversion(pdp_gensym("bitmap/rgba/*"), pdp_gensym("bitmap/rgb/*"), program); /* fallback rgb convertor */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_rgb8_to_YCrCb, 0); pdp_type_register_conversion(pdp_gensym("bitmap/rgb/*"), pdp_gensym("image/*/*"), program); program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_rgb8_to_bitmap_YCrCb, 0); pdp_type_register_conversion(pdp_gensym("bitmap/rgb/*"), pdp_gensym("bitmap/yv12/*"), program); /* fallbacks */ program = pdp_conversion_program_new(_pdp_packet_bitmap_convert_fallback, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("bitmap/*/*"), program); pdp_type_register_conversion(pdp_gensym("bitmap/*/*"), pdp_gensym("image/*/*"), program); pdp_type_register_conversion(pdp_gensym("bitmap/*/*"), pdp_gensym("bitmap/*/*"), program); } pdp-0.14.1+darcs20180201/system/type/pdp_image.c000066400000000000000000000411511266045153600206760ustar00rootroot00000000000000/* * Pure Data Packet system implementation. : 16 bit image packet implementation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* This file contains methods for the image packets pdp_packet_new_* methods are several image packet constructors pdp_type_* are image type checkers & converters */ #include #include #include "pdp_internals.h" #include "pdp_packet.h" #include "pdp_imageproc.h" #include "pdp_resample.h" #include "pdp_list.h" #include "pdp_post.h" #include "pdp_type.h" /* the class object */ static t_pdp_class* image_class; /* check dimensions */ static void _checkdim(u32 width, u32 height){ if ((pdp_imageproc_legalwidth(width) != width) || (pdp_imageproc_legalheight(height) != height)){ pdp_post("WARNING: request to create image packet with illegal dimensions %d x %d", width, height); } } /* image packet constructors */ int pdp_packet_new_image_YCrCb(u32 w, u32 h) { t_pdp *header; t_image *image; int packet; u32 size = w*h; u32 totalnbpixels = size + (size >> 1); u32 packet_size = totalnbpixels << 1; _checkdim(w,h); packet = pdp_packet_new(PDP_IMAGE, packet_size); header = pdp_packet_header(packet); image = pdp_packet_image_info(packet); if (!header) return -1; image->encoding = PDP_IMAGE_YV12; image->width = w; image->height = h; header->desc = pdp_packet_image_get_description(packet); header->theclass = image_class; return packet; } int pdp_packet_new_image_grey(u32 w, u32 h) { t_pdp *header; t_image *image; int packet; u32 size = w*h; u32 totalnbpixels = size; u32 packet_size = totalnbpixels << 1; //pdp_post("grey %d x %d = %d bytes", w,h,packet_size); _checkdim(w,h); packet = pdp_packet_new(PDP_IMAGE, packet_size); header = pdp_packet_header(packet); image = pdp_packet_image_info(packet); if (!header) return -1; image->encoding = PDP_IMAGE_GREY; image->width = w; image->height = h; header->desc = pdp_packet_image_get_description(packet); header->theclass = image_class; return packet; } int pdp_packet_new_image_mchp(u32 w, u32 h, u32 d) { t_pdp *header; t_image *image; int packet; u32 size = w*h*d; u32 totalnbpixels = size; u32 packet_size = totalnbpixels << 1; _checkdim(w,h); packet = pdp_packet_new(PDP_IMAGE, packet_size); header = pdp_packet_header(packet); image = pdp_packet_image_info(packet); if (!header) return -1; image->encoding = PDP_IMAGE_MCHP; image->width = w; image->height = h; image->depth = d; header->desc = pdp_packet_image_get_description(packet); header->theclass = image_class; return packet; } int pdp_packet_new_image(u32 type, u32 w, u32 h) { switch (type){ case PDP_IMAGE_YV12: return pdp_packet_new_image_YCrCb(w,h); case PDP_IMAGE_GREY: return pdp_packet_new_image_grey(w,h); default: return -1; } } /****************** packet type checking and conversion methods ********************/ /* check if two image packets are allocated and of the same type */ int pdp_packet_image_compat(int packet0, int packet1) { t_pdp *header0 = pdp_packet_header(packet0); t_pdp *header1 = pdp_packet_header(packet1); t_image *image0 = pdp_packet_image_info(packet0); t_image *image1 = pdp_packet_image_info(packet1); if (!(pdp_packet_compat(packet0, packet1))) return 0; if (header0->type != PDP_IMAGE){ //pdp_post("pdp_type_compat_image: not a PDP_IMAGE"); return 0; } if (image0->encoding != image1->encoding){ //pdp_post("pdp_type_compat_image: encodings differ"); return 0; } if (image0->width != image1->width){ //pdp_post("pdp_type_compat_image: image withs differ"); return 0; } if (image0->height != image1->height){ //pdp_post("pdp_type_compat_image: image heights differ"); return 0; } return 1; } /* check if packet is a valid image packet */ int pdp_packet_image_isvalid(int packet) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); if (!header) return 0; if (PDP_IMAGE != header->type) return 0; if ((PDP_IMAGE_YV12 != image->encoding) && (PDP_IMAGE_GREY != image->encoding) && (PDP_IMAGE_MCHP != image->encoding)) return 0; return 1; } /* set the channel mask for the image */ void pdp_packet_image_set_chanmask(int packet, unsigned int chanmask) { if (pdp_packet_image_isvalid(packet)) pdp_packet_image_info(packet)->chanmask = chanmask; } t_image *pdp_packet_image_info(int packet) { return (t_image *)pdp_packet_subheader(packet); } t_pdp_symbol *pdp_packet_image_get_description(int packet) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); char description[1024]; char *c = description; int encoding; if (!header) return pdp_gensym("invalid"); else if (!header->desc){ /* if description is not defined, try to reconstruct it (for backwards compat) */ if (header->type == PDP_IMAGE){ c += sprintf(c, "image"); encoding = image->encoding; switch(encoding){ case PDP_IMAGE_YV12: c += sprintf(c, "/YCrCb"); break; case PDP_IMAGE_GREY: c += sprintf(c, "/grey"); break; case PDP_IMAGE_MCHP: c += sprintf(c, "/multi"); break; default: c += sprintf(c, "/unknown"); goto exit; } if (encoding == PDP_IMAGE_MCHP){ c += sprintf(c, "/%dx%dx%d", image->width, image->height, image->depth); } else { c += sprintf(c, "/%dx%d", image->width, image->height); } exit: return pdp_gensym(description); } else return pdp_gensym("unknown"); } else return header->desc; } /* IMAGE PACKAGE CONVERSION ROUTINES */ /* note: these are internal: no extra checking is done it is assumed the packets are of correct type (the type template associated with the conversion program) */ // image/YCrCb/* -> image/grey/* // image/multi/* -> image/grey/* (only first channel) static int _pdp_packet_image_convert_YCrCb_to_grey(int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); int w = image->width; int h = image->height; int p = pdp_packet_new_image_grey(w,h); if (p == -1) return p; memcpy(pdp_packet_data(p), pdp_packet_data(packet), 2*w*h); return p; } // image/grey/* -> image/YCrCb/* static int _pdp_packet_image_convert_grey_to_YCrCb(int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); int w = image->width; int h = image->height; int p = pdp_packet_new_image_YCrCb(w,h); int y_bytes = 2*w*h; void *data; if (p == -1) return p; data = pdp_packet_data(p); memcpy(data, pdp_packet_data(packet), y_bytes); memset(data+y_bytes, 0, y_bytes >> 1); return p; } // image/grey/* -> image/multi/* static int _pdp_packet_image_convert_grey_to_multi(int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); int w = image->width; int h = image->height; int p = pdp_packet_new_image_mchp(w,h,1); int y_bytes = 2*w*h; void *data; if (p == -1) return p; data = pdp_packet_data(p); memcpy(data, pdp_packet_data(packet), y_bytes); return p; } // image/multi/* -> image/YCrCb/* (only first 3 channels) static int _pdp_packet_image_convert_multi_to_YCrCb(int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); s16 *data, *newdata; /* get info */ int w = image->width; int h = image->height; int d = image->depth; int plane_size = w*h; /* create new packet */ int newpacket = pdp_packet_new_image_YCrCb(w, h); if (-1 == newpacket) return -1; data = pdp_packet_data(packet); newdata = pdp_packet_data(newpacket); /* copy channel 0 */ memcpy(newdata, data, plane_size<<1); newdata += plane_size; data += plane_size; /* copy channel 1 */ if (d >= 1) pdp_resample_halve(data, newdata, w, h); else memset(newdata, 0, plane_size >> 1); data += plane_size; newdata += (plane_size >> 2); /* copy channel 2 */ if (d >= 2) pdp_resample_halve(data, newdata, w, h); else memset(newdata, 0, plane_size >> 1); return newpacket; } // image/YCrCb/* -> image/multi/* static int _pdp_packet_image_convert_YCrCb_to_multi(int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_image *image = pdp_packet_image_info(packet); s16 *data, *newdata; /* get info */ int w = image->width; int h = image->height; int plane_size = w*h; /* create new packet */ int newpacket = pdp_packet_new_image_mchp(w, h, 3); if (-1 == newpacket) return -1; data = pdp_packet_data(packet); newdata = pdp_packet_data(newpacket); /* copy channel 0 */ memcpy(newdata, data, plane_size<<1); newdata += plane_size; data += plane_size; w >>= 1; h >>= 1; /* copy channel 1 */ pdp_resample_double(data, newdata, w, h); data += (plane_size >> 2); newdata += plane_size; /* copy channel 2 */ pdp_resample_double(data, newdata, w, h); return newpacket; } static void _pdp_description_get_dims(t_pdp_symbol *template, int *w, int *h, int *d) { char *c = template->s_name; // get requested dimensions *w = 0; *h = 0; *d = 0; while (*c++ != '/'); while (*c++ != '/'); sscanf(c, "%dx%dx%d", w, h, d); } // resample image/YCrCb/* static int _pdp_packet_image_convert_resample_YCrCb(int packet, t_pdp_symbol *dest_template) { int quality = 1; int dst_w, dst_h, dummy; int new_packet; unsigned int src_size, src_voffset, src_uoffset; unsigned int dst_size, dst_voffset, dst_uoffset; t_pdp *header0 = pdp_packet_header(packet); t_image *image0 = pdp_packet_image_info(packet); unsigned int src_w = image0->width; unsigned int src_h = image0->height; short int *src_image = (short int *)pdp_packet_data(packet); short int *dst_image; _pdp_description_get_dims(dest_template, &dst_w, &dst_h, &dummy); new_packet = pdp_packet_new_image_YCrCb(dst_w, dst_h); if (-1 == new_packet) return -1; dst_image = (short int*)pdp_packet_data(new_packet); src_size = src_w*src_h; src_voffset = src_size; src_uoffset = src_size + (src_size>>2); dst_size = dst_w*dst_h; dst_voffset = dst_size; dst_uoffset = dst_size + (dst_size>>2); if (quality){ pdp_resample_scale_bilin(src_image, dst_image, src_w, src_h, dst_w, dst_h); pdp_resample_scale_bilin(src_image+src_voffset, dst_image+dst_voffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); pdp_resample_scale_bilin(src_image+src_uoffset, dst_image+dst_uoffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); } else{ pdp_resample_scale_nn(src_image, dst_image, src_w, src_h, dst_w, dst_h); pdp_resample_scale_nn(src_image+src_voffset, dst_image+dst_voffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); pdp_resample_scale_nn(src_image+src_uoffset, dst_image+dst_uoffset, src_w>>1, src_h>>1, dst_w>>1, dst_h>>1); } return new_packet; } // resample image/grey/* and image/multi/* static int _pdp_packet_image_convert_resample_multi(int packet, t_pdp_symbol *dest_template) { int quality = 1; int dst_w, dst_h, depth; int new_packet; unsigned int src_size; unsigned int dst_size; t_pdp *header0 = pdp_packet_header(packet); t_image *image0 = pdp_packet_image_info(packet); unsigned int src_w = image0->width; unsigned int src_h = image0->height; short int *src_image = (short int *)pdp_packet_data(packet); short int *dst_image; _pdp_description_get_dims(dest_template, &dst_w, &dst_h, &depth); if (depth == 0){ depth = 1; new_packet = pdp_packet_new_image_grey(dst_w, dst_h); } else { new_packet = pdp_packet_new_image_mchp(dst_w, dst_h, depth); } if (-1 == new_packet) return -1; dst_image = (short int*)pdp_packet_data(new_packet); src_size = src_w*src_h; dst_size = dst_w*dst_h; while (depth--){ if (quality){ pdp_resample_scale_bilin(src_image, dst_image, src_w, src_h, dst_w, dst_h); } else{ pdp_resample_scale_nn(src_image, dst_image, src_w, src_h, dst_w, dst_h); } src_image += src_size; dst_image += dst_size; } return new_packet; } static int _pdp_packet_image_convert_fallback(int packet, t_pdp_symbol *dest_template) { pdp_post("can't convert image type %s to %s", pdp_packet_get_description(packet)->s_name, dest_template->s_name); return -1; } /* the expensive factory method */ static int pdp_image_factory(t_pdp_symbol *type) { t_pdp_list *l; t_pdp_symbol *s; int t; int w = 0; int h = 0; int d = 0; int p = -1; int n = 0; int m = 0; char *garbage = 0; //pdp_post("creating:"); //pdp_post("%s", type->s_name); l = pdp_type_to_list(type); s = pdp_list_pop(l).w_symbol; // first element is "image" s = pdp_list_pop(l).w_symbol; /* get image type */ if (s == pdp_gensym("grey")) t = PDP_IMAGE_GREY; else if (s == pdp_gensym("YCrCb")) t = PDP_IMAGE_YV12; else if (s == pdp_gensym("multi")) t = PDP_IMAGE_MCHP; else goto exit; /* get image dimensions and create image */ s = pdp_list_pop(l).w_symbol; switch (t){ case PDP_IMAGE_MCHP: m = sscanf(s->s_name, "%dx%dx%d", &w, &h, &d); p = pdp_packet_new_image_mchp(w,h,d); break; default: sscanf(s->s_name, "%dx%d", &w, &h); p = pdp_packet_new_image(t,w,h); break; } if (p != -1){ t_pdp *header = pdp_packet_header(p); /* if type is not exact, delete the packet */ if (type != header->desc) { pdp_packet_delete(p); p = -1; } } exit: pdp_list_free(l); return p; } void pdp_image_words_setup(t_pdp_class *c); void pdp_image_setup(void) { t_pdp_conversion_program *program; /* setup the class object */ image_class = pdp_class_new(pdp_gensym("image/*/*"), pdp_image_factory); /* setup conversion programs */ program = pdp_conversion_program_new(_pdp_packet_image_convert_YCrCb_to_grey, 0); pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("image/grey/*"), program); pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("image/grey/*"), program); program = pdp_conversion_program_new(_pdp_packet_image_convert_grey_to_YCrCb, 0); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("image/YCrCb/*"), program); program = pdp_conversion_program_new(_pdp_packet_image_convert_grey_to_multi, 0); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("image/multi/*"), program); program = pdp_conversion_program_new(_pdp_packet_image_convert_multi_to_YCrCb, 0); pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("image/YCrCb/*"), program); program = pdp_conversion_program_new(_pdp_packet_image_convert_YCrCb_to_multi, 0); pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("image/multi/*"), program); program = pdp_conversion_program_new(_pdp_packet_image_convert_resample_YCrCb, 0); pdp_type_register_conversion(pdp_gensym("image/YCrCb/*"), pdp_gensym("image/YCrCb/*"), program); program = pdp_conversion_program_new(_pdp_packet_image_convert_resample_multi, 0); pdp_type_register_conversion(pdp_gensym("image/multi/*"), pdp_gensym("image/multi/*"), program); pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("image/grey/*"), program); /* catch-all fallback */ program = pdp_conversion_program_new(_pdp_packet_image_convert_fallback, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("image/*/*"), program); } pdp-0.14.1+darcs20180201/system/type/pdp_matrix.c000066400000000000000000000471711266045153600211300ustar00rootroot00000000000000 #include #include "pdp_matrix.h" #include "pdp_packet.h" #include "pdp_symbol.h" #include "pdp_internals.h" // for pdp_packet_new, which is not a proper constructor #include "pdp_post.h" #include "pdp_type.h" /* the class object */ static t_pdp_class *matrix_class; /* declare header and subheader variables and exit with errval if invalid */ #define VALID_MATRIX_HEADER(packet, header, subheader, mtype, errval) \ t_pdp * header = pdp_packet_header( packet ); \ t_matrix * subheader = (t_matrix *)pdp_packet_subheader( packet ); \ if (! header ) return errval; \ if (PDP_MATRIX != header->type) return errval; \ if (mtype) {if (subheader->type != mtype) return errval;} int pdp_packet_matrix_isvalid(int p) { VALID_MATRIX_HEADER(p, h, m, 0, 0); return 1; } void *pdp_packet_matrix_get_gsl_matrix(int p, u32 type) { VALID_MATRIX_HEADER(p, h, m, type, 0); return &m->matrix; } void *pdp_packet_matrix_get_gsl_vector(int p, u32 type) { VALID_MATRIX_HEADER(p, h, m, type, 0); return &m->vector; } int pdp_packet_matrix_get_type(int p) { VALID_MATRIX_HEADER(p, h, m, 0, 0); return m->type; } int pdp_packet_matrix_isvector(int p) { VALID_MATRIX_HEADER(p, h, m, 0, 0); return ((m->rows == 1) || (m->columns == 1)); } int pdp_packet_matrix_ismatrix(int p) { VALID_MATRIX_HEADER(p, h, m, 0, 0); return ((m->rows != 1) && (m->columns != 1)); } /* gsl blas matrix/vector multiplication: vector.vector (const gsl_vector * x, const gsl_vector * y, double * result) gsl_blas_sdot gsl_blas_ddot gsl_blas_cdot gsl_blas_zdot gsl_blas_cdotu gsl_blas_zdotu matrix.vector ( CBLAS_TRANSPOSE_t TransA, double alpha, const gsl_matrix * A, const gsl_vector * x, double beta, gsl_vector * y ) gsl_blas_sgemv gsl_blas_dgemv gsl_blas_cgemv gsl_blas_zgemv matrix.matrix ( CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, double alpha, const gsl_matrix * A, const gsl_matrix * B, double beta, gsl_matrix * C ) gsl_blas_sgemm gsl_blas_dgemm gsl_blas_cgemm gsl_blas_zgemm */ /* compute the matrix inverse using the LU decomposition */ /* it only works for double real/complex */ int pdp_packet_matrix_LU_to_inverse(int p) { int new_p; u32 n; int type = pdp_packet_matrix_get_type(p); t_matrix *sheader = (t_matrix *)pdp_packet_subheader(p); gsl_matrix *m = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p, type); gsl_matrix *im; if (!m) return -1; n = m->gsl_rows; if (n != m->gsl_columns) return -1; new_p = pdp_packet_new_matrix(n, n, type); if (-1 == new_p) return -1; im = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(new_p, type); switch(type){ case PDP_MATRIX_TYPE_RDOUBLE: gsl_linalg_LU_invert (m, &sheader->perm, im); break; case PDP_MATRIX_TYPE_CDOUBLE: gsl_linalg_complex_LU_invert ((gsl_matrix_complex *)m, &sheader->perm, (gsl_matrix_complex *)im); break; default: pdp_packet_mark_unused(new_p); new_p = -1; } return new_p; } /* compute the LU decomposition of a square matrix */ /* it only works for double real/complex */ int pdp_packet_matrix_LU(int p) { int p_LU, bytes; u32 n; int type = pdp_packet_matrix_get_type(p); t_matrix *sh_m_LU; t_matrix *sh_m = (t_matrix *)pdp_packet_subheader(p); gsl_matrix *m = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p, type); gsl_matrix *m_LU; if (!m) return -1; n = m->gsl_rows; if (n != m->gsl_columns) return -1; p_LU = pdp_packet_new_matrix(n, n, type); if (-1 == p_LU) return -1; sh_m_LU = (t_matrix *)pdp_packet_subheader(p_LU); m_LU = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p_LU, type); /* copy matrix data: move this to copy method */ memcpy(pdp_packet_data(p_LU), pdp_packet_data(p), sh_m->block.size); switch(type){ case PDP_MATRIX_TYPE_RDOUBLE: gsl_linalg_LU_decomp (m_LU, &sh_m_LU->perm, &sh_m_LU->signum); break; case PDP_MATRIX_TYPE_CDOUBLE: gsl_linalg_complex_LU_decomp ((gsl_matrix_complex *)m_LU, &sh_m_LU->perm, &sh_m_LU->signum); break; default: pdp_packet_mark_unused(p_LU); p_LU = -1; } return p_LU; } int pdp_packet_matrix_LU_solve(int p_matrix, int p_vector) { int type = pdp_packet_matrix_get_type(p_matrix); int p_result_vector = pdp_packet_clone_rw(p_vector); gsl_matrix *m = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(p_matrix, type); gsl_vector *v = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(p_vector, type); gsl_vector *rv = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(p_result_vector, type); t_matrix *sh_m = (t_matrix *)pdp_packet_subheader(p_matrix); if (!(m && v && rv)) goto error; switch(type){ case PDP_MATRIX_TYPE_RDOUBLE: if (gsl_linalg_LU_solve (m, &sh_m->perm, v, rv)) goto error; break; case PDP_MATRIX_TYPE_CDOUBLE: if(gsl_linalg_complex_LU_solve ((gsl_matrix_complex*)m, &sh_m->perm, (gsl_vector_complex *)v, (gsl_vector_complex *)rv)) goto error; break; default: goto error; } return p_result_vector; error: pdp_packet_mark_unused(p_result_vector); //post("error"); return -1; } /* matrix matrix mul: C is defining type returns 0 on success */ int pdp_packet_matrix_blas_mm ( CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, int pA, int pB, int pC, float scale_r, float scale_i ) { gsl_complex_float cf_scale = {{scale_r, scale_i}}; gsl_complex cd_scale = {{(double)scale_r, (double)scale_i}}; gsl_complex_float cf_one = {{1.0f, 0.0f}}; gsl_complex cd_one = {{1.0, 0.0}}; gsl_matrix *mA, *mB, *mC; int type; type = pdp_packet_matrix_get_type(pC); mA = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pA,type); mB = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pB,type); mC = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pC,type); if (!(mA && mB)) return 1; switch(type){ case PDP_MATRIX_TYPE_RFLOAT: return gsl_blas_sgemm(TransA, TransB, scale_r, (gsl_matrix_float *)mA, (gsl_matrix_float *)mB, 1.0f, (gsl_matrix_float *)mC); case PDP_MATRIX_TYPE_RDOUBLE: return gsl_blas_dgemm(TransA, TransB, (double)scale_r, (gsl_matrix *)mA, (gsl_matrix *)mB, 1.0, (gsl_matrix *)mC); case PDP_MATRIX_TYPE_CFLOAT: return gsl_blas_cgemm(TransA, TransB, cf_scale, (gsl_matrix_complex_float *)mA, (gsl_matrix_complex_float *)mB, cf_one, (gsl_matrix_complex_float *)mC); case PDP_MATRIX_TYPE_CDOUBLE: return gsl_blas_zgemm(TransA, TransB, cd_scale, (gsl_matrix_complex *)mA, (gsl_matrix_complex *)mB, cd_one, (gsl_matrix_complex *)mC); default: return 0; } } /* matrix vector mul: C is defining type returns 0 on success */ int pdp_packet_matrix_blas_mv ( CBLAS_TRANSPOSE_t TransA, int pA, int pb, int pc, float scale_r, float scale_i ) { gsl_complex_float cf_scale = {{scale_r, scale_i}}; gsl_complex cd_scale = {{(double)scale_r, (double)scale_i}}; gsl_complex_float cf_one = {{1.0f, 0.0f}}; gsl_complex cd_one = {{1.0, 0.0}}; gsl_matrix *mA; gsl_vector *vb, *vc; int type; type = pdp_packet_matrix_get_type(pA); mA = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pA,type); vb = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(pb,type); vc = (gsl_vector *)pdp_packet_matrix_get_gsl_vector(pc,type); if (!(vb && vc)) return 1; switch(type){ case PDP_MATRIX_TYPE_RFLOAT: return gsl_blas_sgemv(TransA, scale_r, (gsl_matrix_float *)mA, (gsl_vector_float *)vb, 1.0f, (gsl_vector_float *)vc); case PDP_MATRIX_TYPE_RDOUBLE: return gsl_blas_dgemv(TransA, (double)scale_r, (gsl_matrix *)mA, (gsl_vector *)vb, 1.0, (gsl_vector *)vc); case PDP_MATRIX_TYPE_CFLOAT: return gsl_blas_cgemv(TransA, cf_scale, (gsl_matrix_complex_float *)mA, (gsl_vector_complex_float *)vb, cf_one, (gsl_vector_complex_float *)vc); case PDP_MATRIX_TYPE_CDOUBLE: return gsl_blas_zgemv(TransA, cd_scale, (gsl_matrix_complex *)mA, (gsl_vector_complex *)vb, cd_one, (gsl_vector_complex *)vc); default: return 0; } } t_pdp_symbol *_pdp_matrix_get_description(t_pdp *header) { t_matrix *m = (t_matrix *)(&header->info.raw); char description[100]; char *c = description; int encoding; if (!header) return pdp_gensym("invalid"); else if (!header->desc){ /* if description is not defined, try to reconstruct it (for backwards compat) */ if (header->type == PDP_MATRIX){ c += sprintf(c, "matrix"); switch(m->type){ case PDP_MATRIX_TYPE_RFLOAT: c += sprintf(c, "/float/real"); break; case PDP_MATRIX_TYPE_CFLOAT: c += sprintf(c, "/float/complex"); break; case PDP_MATRIX_TYPE_RDOUBLE: c += sprintf(c, "/double/real"); break; case PDP_MATRIX_TYPE_CDOUBLE: c += sprintf(c, "/double/complex"); break; default: c += sprintf(c, "/unknown"); goto exit; } c += sprintf(c, "/%dx%d", (int)m->rows, (int)m->columns); exit: return pdp_gensym(description); } else return pdp_gensym("unknown"); } else return header->desc; } static void _pdp_matrix_copy(t_pdp *dst, t_pdp *src); static void _pdp_matrix_clone(t_pdp *dst, t_pdp *src); static void _pdp_matrix_reinit(t_pdp *dst); static void _pdp_matrix_cleanup(t_pdp *dst); static size_t _pdp_matrix_mdata_byte_size(u32 rows, u32 columns, u32 type) { size_t dsize = rows * columns; switch (type){ case PDP_MATRIX_TYPE_RFLOAT: dsize *= sizeof(float); break; case PDP_MATRIX_TYPE_CFLOAT: dsize *= 2*sizeof(float); break; case PDP_MATRIX_TYPE_RDOUBLE: dsize *= sizeof(double); break; case PDP_MATRIX_TYPE_CDOUBLE: dsize *= 2*sizeof(double); break; default: dsize = 0; } return dsize; } static size_t _pdp_matrix_pdata_vector_size(u32 rows, u32 columns) { return (rows>columns ? rows : columns); } static void _pdp_matrix_init(t_pdp *dst, u32 rows, u32 columns, u32 type) { int i; t_matrix *m = (t_matrix *)(&dst->info.raw); void *d = ((void *)dst) + PDP_HEADER_SIZE; int matrix_bytesize = _pdp_matrix_mdata_byte_size(rows, columns, type); int permsize = _pdp_matrix_pdata_vector_size(rows, columns); /* set meta data */ m->type = type; m->rows = rows; m->columns = columns; /* set the block data */ m->block.size = matrix_bytesize; m->block.data = (double *)d; /* set the vector view */ m->vector.size = (1==columns) ? rows : columns; m->vector.stride = 1; m->vector.data = (double *)d; m->vector.block = &m->block; m->vector.owner = 0; /* set the matrix view */ m->matrix.gsl_rows = rows; m->matrix.gsl_columns = columns; m->matrix.tda = columns; m->matrix.data = (double *)d; m->matrix.block = &m->block; m->matrix.owner = 0; /* set the permutation object & init */ m->perm.size = permsize; m->perm.data = (size_t *)(d + matrix_bytesize); for(i=0; iperm.data[i] = i; m->signum = -1; /* init packet header */ dst->theclass = matrix_class; dst->desc = _pdp_matrix_get_description(dst); } static void _pdp_matrix_clone(t_pdp *dst, t_pdp *src) { t_matrix *m = (t_matrix *)(&src->info.raw); _pdp_matrix_init(dst, m->rows, m->columns, m->type); } static void _pdp_matrix_copy(t_pdp *dst, t_pdp *src) { _pdp_matrix_clone(dst, src); memcpy(dst + PDP_HEADER_SIZE, src + PDP_HEADER_SIZE, src->size - PDP_HEADER_SIZE); //post("matrix copy successful"); } static void _pdp_matrix_reinit(t_pdp __attribute__((unused)) *dst) { /* nothing to do, assuming data is correct */ } static void _pdp_matrix_cleanup(t_pdp __attribute__((unused)) *dst) { /* no extra memory to free */ } int pdp_packet_new_matrix(u32 rows, u32 columns, u32 type) { t_pdp *header; int dsize, p; /* compute the blocksize for the matrix data */ /* if 0, something went wrong -> return invalid packet */ if (!(dsize = _pdp_matrix_mdata_byte_size(rows, columns, type))) return -1; dsize += sizeof(size_t) * _pdp_matrix_pdata_vector_size(rows, columns); p = pdp_packet_new(PDP_MATRIX, dsize); if (-1 == p) return -1; header = pdp_packet_header(p); _pdp_matrix_init(header, rows, columns, type); return p; } int pdp_packet_new_matrix_product_result(CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, int pA, int pB) { gsl_matrix *mA, *mB; u32 type = pdp_packet_matrix_get_type(pA); u32 colA, colB, rowA, rowB; /* check if A is a matrix */ if (!type) return -1; mA = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pA, type); mB = (gsl_matrix *)pdp_packet_matrix_get_gsl_matrix(pB, type); /* check if A and B are same type */ if (!mB) return -1; /* get dims A */ if (TransA == CblasNoTrans){ rowA = mA->gsl_rows; colA = mA->gsl_columns; } else { rowA = mA->gsl_columns; colA = mA->gsl_rows; } /* get dims B */ if (TransB == CblasNoTrans){ rowB = mB->gsl_rows; colB = mB->gsl_columns; } else { rowB = mB->gsl_columns; colB = mB->gsl_rows; } /* check if sizes are compatible */ if (colA != rowB) return -1; /* create new packet */ return pdp_packet_new_matrix(rowA, colB, type); } void pdp_packet_matrix_setzero(int p) { t_matrix *m; if (!pdp_packet_matrix_isvalid(p)) return; m = (t_matrix *) pdp_packet_subheader(p); memset(m->block.data, 0, m->block.size); } /* type conversion programs */ static int _pdp_packet_convert_matrix_to_greyimage(int packet, t_pdp_symbol __attribute__((unused)) *dest_template) { t_pdp *header = pdp_packet_header(packet); t_matrix *matrix = (t_matrix *)pdp_packet_subheader(packet); void *data = pdp_packet_data(packet); s16 *new_data; u32 c,r, nbelements; int new_p; u32 i; c = matrix->columns; r = matrix->rows; nbelements = c*r; new_p = pdp_packet_new_image_grey(c,r); if (-1 == new_p) return -1; new_data = (s16 *)pdp_packet_data(new_p); /* convert first channel */ switch(matrix->type){ case PDP_MATRIX_TYPE_RFLOAT: for (i=0; iencoding; u32 i; if (!pdp_packet_image_isvalid(packet)) return -1; w = image->width; h = image->height; nbelements = w*h; new_p = pdp_packet_new_matrix(h,w, type); if (-1 == new_p) return -1; new_data = pdp_packet_data(new_p); switch (encoding){ case PDP_IMAGE_YV12: case PDP_IMAGE_GREY: case PDP_IMAGE_MCHP: /* convert first channel */ switch(type){ case PDP_MATRIX_TYPE_RFLOAT: for (i=0; is_name, dest_template->s_name); return -1; } /* this seems like a nice spot to place a dummy gsl signal handler */ static void _gsl_error_handler (const char __attribute__((unused)) *reason, const char __attribute__((unused)) *file, int __attribute__((unused)) line, int __attribute__((unused)) gsl_errno) { //pdp_post("gsl error:\nREASON: %s\nFILE:%s\nLINE:%d\nERRNO:%d", reason, file, line, gsl_errno); } static int pdp_matrix_factory(t_pdp_symbol __attribute__((unused)) *type) { return -1; } void pdp_matrix_setup(void) { t_pdp_conversion_program *program; /* setup the class */ matrix_class = pdp_class_new(pdp_gensym("matrix/*/*/*"), pdp_matrix_factory); matrix_class->copy = _pdp_matrix_copy; //matrix_class->clone = _pdp_matrix_clone; // is now solved through (symbol based) constructor matrix_class->wakeup = _pdp_matrix_reinit; matrix_class->cleanup = _pdp_matrix_cleanup; /* image -> matrix: default = double/real (most ops available) */ program = pdp_conversion_program_new(_pdp_packet_convert_image_to_doublematrix, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/double/real/*"), program); program = pdp_conversion_program_new(_pdp_packet_convert_image_to_floatmatrix, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/float/real/*"), program); program = pdp_conversion_program_new(_pdp_packet_convert_image_to_complexdoublematrix, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/double/complex/*"), program); program = pdp_conversion_program_new(_pdp_packet_convert_image_to_complexfloatmatrix, 0); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/float/complex/*"), program); /* matrix -> image */ program = pdp_conversion_program_new(_pdp_packet_convert_matrix_to_greyimage, 0); pdp_type_register_conversion(pdp_gensym("matrix/*/*/*"), pdp_gensym("image/grey/*"), program); /* fallbacks */ program = pdp_conversion_program_new(_pdp_packet_matrix_convert_fallback, 0); pdp_type_register_conversion(pdp_gensym("matrix/*/*/*"), pdp_gensym("image/*/*"), program); pdp_type_register_conversion(pdp_gensym("matrix/*/*/*"), pdp_gensym("bitmap/*/*"), program); pdp_type_register_conversion(pdp_gensym("image/*/*"), pdp_gensym("matrix/*/*/*/*"), program); pdp_type_register_conversion(pdp_gensym("bitmap/*/*"), pdp_gensym("matrix/*/*/*/*"), program); /* setup gsl handler */ if(gsl_set_error_handler(_gsl_error_handler)){ pdp_post("pdp_matrix_setup: WARNING: overriding gsl error handler."); } } pdp-0.14.1+darcs20180201/system/zl/000077500000000000000000000000001266045153600162475ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/zl/3Dcontext.h000066400000000000000000000061701266045153600202770ustar00rootroot00000000000000/* * 3d render context object * Copyright (c) 2003-2013 by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* the 3d render context packet: platform independent data structure and method prototypes */ #ifndef __zl_3dcontext_h__ #define __zl_3dcontext_h__ #include #include "zl/xwindow.h" typedef struct zl_3Dcontext { uint32_t encoding; /* the kind of render context */ uint32_t width; /* context width */ uint32_t height; /* context height */ uint32_t sub_width; /* portion that is currently used */ uint32_t sub_height; union { zl_xwindow *xwindow; } drawable; /* context's drawable (i.e. Window, GLXPbuffer, ...) */ void *context; /* context's context object */ } zl_3Dcontext; #define ZL_3DCONTEXT_WINDOW 1 /* window context packet id */ #define ZL_3DCONTEXT_PBUFFER 2 /* pbuf context packet id */ /* all symbols are C-style */ #ifdef __cplusplus extern "C" { #endif uint32_t zl_3Dcontext_width(zl_3Dcontext *c); uint32_t zl_3Dcontext_height(zl_3Dcontext *c); uint32_t zl_3Dcontext_subwidth(zl_3Dcontext *c); uint32_t zl_3Dcontext_subheight(zl_3Dcontext *c); float zl_3Dcontext_subaspect(zl_3Dcontext *c); /* setters */ void zl_3Dcontext_set_subwidth(zl_3Dcontext *c, uint32_t w); void zl_3Dcontext_set_subheight(zl_3Dcontext *c, uint32_t h); /* render context activation and initialization */ void zl_3Dcontext_set_rendering_context(zl_3Dcontext *c); void zl_3Dcontext_unset_rendering_context(zl_3Dcontext *c); void zl_3Dcontext_setup_3d_context(zl_3Dcontext *c); void zl_3Dcontext_setup_2d_context(zl_3Dcontext *c); /* constructors */ zl_3Dcontext* zl_3Dcontext_pbuf_new(uint32_t width, uint32_t height, uint32_t depth); zl_3Dcontext* zl_3Dcontext_win_new(void); /* window specific methods, just return window instance? */ void zl_3Dcontext_win_resize(zl_3Dcontext *c, int width, int height); void zl_3Dcontext_win_cursor(zl_3Dcontext *c, int toggle); void zl_3Dcontext_for_parsed_events(zl_3Dcontext *c, zl_receiver recever, void *context); void zl_3Dcontext_win_swapbuffers(zl_3Dcontext *c); /* converters */ void zl_3Dcontext_snap_to_bitmap(zl_3Dcontext *c, int w, int h, void *data); void zl_3Dcontext_free(zl_3Dcontext *c); /* global setup */ void zl_3Dcontext_glx_setup(void); #ifdef __cplusplus } #endif #endif pdp-0.14.1+darcs20180201/system/zl/3Dcontext_common.c000066400000000000000000000106111266045153600216350ustar00rootroot00000000000000 /* * zl - pbuffer packet implementation * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this code uses glx. i don't know if it is worth to take into account portabiliy. since it will take a while until pdp runs on anything else than linux. but in any case, providing a windows/osx implementation here should not be too difficult.. */ #include "zl/3Dcontext.h" #include #include #define D if (0) /* constructor */ /* pbuf operators */ uint32_t zl_3Dcontext_width(zl_3Dcontext *c) { if (c) return c->width; else return 0; } uint32_t zl_3Dcontext_height(zl_3Dcontext *c) { if (c) return c->height; else return 0; } uint32_t zl_3Dcontext_subwidth(zl_3Dcontext *c) { if (c) return c->sub_width; else return 0; } uint32_t zl_3Dcontext_subheight(zl_3Dcontext *c) { if (c) return c->sub_height; else return 0; } void zl_3Dcontext_set_subwidth(zl_3Dcontext *c, uint32_t w) { if (c) c->sub_width = w; } void zl_3Dcontext_set_subheight(zl_3Dcontext *c, uint32_t h) { if (c) c->sub_height = h; } float zl_3Dcontext_subaspect(zl_3Dcontext *c) { if (c) return (float)c->sub_width/c->sub_height; else return 0; } void zl_3Dcontext_snap_to_bitmap(zl_3Dcontext *c, int w, int h, void *_data) { int x, y; char *data = _data; x = zl_3Dcontext_subwidth(c); y = zl_3Dcontext_subheight(c); // ??? x = (x - w) >> 1; y = (y - h) >> 1; x = (x < 0 ) ? 0 : x; y = (y < 0 ) ? 0 : y; zl_3Dcontext_set_rendering_context(c); glReadPixels(x,y, w ,h,GL_RGB,GL_UNSIGNED_BYTE, data); } /* setup for 2d operation from pbuf dimensions */ void zl_3Dcontext_setup_2d_context(zl_3Dcontext *c) { uint32_t w; uint32_t h; float asp; w = zl_3Dcontext_subwidth(c); h = zl_3Dcontext_subheight(c); asp = zl_3Dcontext_subaspect(c); /* set the viewport to the size of the sub frame */ glViewport(0, 0, w, h); /* set orthogonal projection, with a relative frame size of (2asp x 2) */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, 2*asp, 0, 2); /* set the center of view */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(asp, 1, 0); glScalef(1,-1,1); } /* setup for 3d operation from pbuf dimensions */ void zl_3Dcontext_setup_3d_context(zl_3Dcontext *c) { uint32_t w; uint32_t h; int i; float asp; float m_perspect[] = {-1.f, /* left */ 1.f, /* right */ -1.f, /* bottom */ 1.f, /* top */ 1.f, /* front */ 20.f};/* back */ w = zl_3Dcontext_subwidth(c); h = zl_3Dcontext_subheight(c); asp = zl_3Dcontext_subaspect(c); /* set the viewport to the size of the sub frame */ glViewport(0, 0, w, h); /* set orthogonal projection, with a relative frame size of (2asp x 2) */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(m_perspect[0] * asp, m_perspect[1] * asp, // left, right m_perspect[2], m_perspect[3], // bottom, top m_perspect[4], m_perspect[5]); // front, back /* reset texture matrix */ glMatrixMode(GL_TEXTURE); glLoadIdentity(); /* set the center of view */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0); //glTranslatef(asp, 1, 0); glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); //glShadeModel(GL_FLAT); /* disable everything that is enabled in other modules this resets the ogl state to its initial conditions */ glDisable(GL_LIGHTING); for (i=0; i<8; i++) glDisable(GL_LIGHT0 + i); glDisable(GL_COLOR_MATERIAL); } pdp-0.14.1+darcs20180201/system/zl/3Dcontext_glx.c000066400000000000000000000141441266045153600211440ustar00rootroot00000000000000 /* * OpenGL Extension Module for pdp - opengl system stuff * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* this file contains the platform dependent opengl setup routines (glx) and pdp_packet_3Dcontext methods */ #include "zl/config.h" #include "zl/xwindow.h" #include "zl/glx.h" //#include "pdp_packet.h" #include "zl/3Dcontext.h" #include #include #include /* all symbols are C-style */ #ifdef __cplusplus //extern "C" //{ #endif // this is buggy: disabled #define PRIVATE_CONTEXT 0 /* structure to hold the (platform dependent) gl environment setup */ typedef struct _gl_env { zl_glx *glx; zl_xdisplay *xdisplay; zl_3Dcontext *last_context; /* the packet that is currently rendered too (for caching) */ } gl_env; static gl_env glx_env; /* PDP_3DCONTEXT packet methods */ /* set/unset ogl rendering context to pbuf */ void zl_3Dcontext_set_rendering_context(zl_3Dcontext *c) { /* don't do a glx call if the context is still the same */ if (glx_env.last_context == c) return; /* pbuffer */ switch(c->encoding){ case ZL_3DCONTEXT_WINDOW: zl_glx_makecurrent(glx_env.glx, c->drawable.xwindow); glx_env.last_context = c; break; case ZL_3DCONTEXT_PBUFFER: glx_env.last_context = NULL; break; default: glx_env.last_context = NULL; break; } } void zl_3Dcontext_unset_rendering_context(zl_3Dcontext *c) { if (!c) c = glx_env.last_context; if (!c) return; /* pbuffer */ switch(c->encoding){ case ZL_3DCONTEXT_WINDOW: zl_glx_makecurrent(glx_env.glx, NULL); break; case ZL_3DCONTEXT_PBUFFER: break; default: break; } glx_env.last_context = NULL; } /* window specific methods */ static void zl_3Dcontext_set_window_size(zl_3Dcontext *c, zl_xwindow *xwin) { c->width = c->sub_width = zl_xwindow_winwidth(xwin); c->height = c->sub_height= zl_xwindow_winheight(xwin); } /* resize the window */ void zl_3Dcontext_win_resize(zl_3Dcontext *c, int width, int height) { zl_xwindow *xwin; if (!c) return; if (ZL_3DCONTEXT_WINDOW != c->encoding) return; xwin = c->drawable.xwindow; zl_xwindow_resize(xwin, width, height); zl_3Dcontext_set_window_size(c, xwin); } void zl_3Dcontext_for_parsed_events(zl_3Dcontext *c, zl_receiver receiver, void *context) { if (!c) return; if (ZL_3DCONTEXT_WINDOW != c->encoding) return; zl_xwindow *xwin = c->drawable.xwindow; zl_xwindow_route_events(xwin); zl_xwindow_for_parsed_events(xwin, receiver, context); zl_3Dcontext_set_window_size(c, xwin); // Update from window size } void zl_3Dcontext_win_cursor(zl_3Dcontext *c, int toggle) { if (!c) return; if (ZL_3DCONTEXT_WINDOW != c->encoding) return; zl_xwindow *xwin = c->drawable.xwindow; zl_xwindow_cursor(xwin, toggle); } void zl_3Dcontext_win_swapbuffers(zl_3Dcontext *c) { if (!c) return; if (ZL_3DCONTEXT_WINDOW != c->encoding) return; zl_xwindow *xwin = c->drawable.xwindow; // ZL_LOG("%p %p %p\n", c, glx_env.glx, xwin); zl_glx_swapbuffers(glx_env.glx, xwin); } /* constructors */ /* construct (or reuse) a window packet */ zl_3Dcontext *zl_3Dcontext_win_new(void) { zl_3Dcontext *c = calloc(1,sizeof(*c)); zl_xwindow *xwin = zl_xwindow_new(); c->drawable.xwindow = xwin; c->encoding = ZL_3DCONTEXT_WINDOW; zl_glx_open_on_display(glx_env.glx, xwin, glx_env.xdisplay); zl_xwindow_config(xwin, glx_env.xdisplay); zl_3Dcontext_set_window_size(c, xwin); return c; } /* pbuf constructor */ // FIXME: why is this not implemented? Check PF code. zl_3Dcontext *zl_3Dcontext_pbuf_new(uint32_t width __attribute__((__unused__)), uint32_t height __attribute__((__unused__)), uint32_t depth __attribute__((__unused__))) { return NULL; } void zl_3Dcontext_free(zl_3Dcontext *c) { // ZL_LOG("zl_3Dcontext_free(%p,%p)\n", c, c->drawable.xwindow); zl_3Dcontext_unset_rendering_context(c); glx_env.last_context = NULL; switch(c->encoding){ case ZL_3DCONTEXT_WINDOW: zl_xdisplay_unregister_window(glx_env.xdisplay, c->drawable.xwindow); zl_xwindow_free(c->drawable.xwindow); c->drawable.xwindow = 0; // FIXME: where does glXDestroyContext get called? // glXDestroyContext (pdp_glx_env.dpy, (GLXContext)c->context); break; case ZL_3DCONTEXT_PBUFFER: break; //glXDestroyContext(c->dpy, c->context); //glXDestroyPbuffer(c->dpy, c->drawable.pbuf); default: break; } } /* setup routine */ void zl_3Dcontext_glx_setup(void) { /* open display: the first display on the local machine is opened, not DISPLAY. since pdp_opengl is all about direct rendering, and there is no way to specify another display, or even close it and open it again, this seems to be the "least surprise" solution. it enables the pd interface to be displayed on another display, using the DISPLAY environment variable. */ const char *display = ":0"; if (NULL == (glx_env.xdisplay = zl_xdisplay_new(display))){ ZL_LOG("3DContext: Can't open display %s\n", display); goto init_failed; } if (NULL == (glx_env.glx = zl_glx_new())) { ZL_LOG("3DContext: Can't create glx object\n"); goto init_failed; } return; init_failed: // This is a bit drastic.. exit(1); } #ifdef __cplusplus //} #endif pdp-0.14.1+darcs20180201/system/zl/Makefile000066400000000000000000000001461266045153600177100ustar00rootroot00000000000000 include ../../Makefile.config OBJECTS = $(ZL_OPTMOD) all: $(OBJECTS) clean: rm -f *~ rm -f *.o pdp-0.14.1+darcs20180201/system/zl/README000066400000000000000000000013621266045153600171310ustar00rootroot00000000000000ZL - Zwizwa Lib Date: Fri Oct 11 19:07:16 EDT 2013 This is a grab bag of "old tech" plain C objects without any bindings or fancy dependencies. It is a shared pool of objects used in pdp[1] and libprim[2]. Code is duplicated in those projects, and available as a stand-alone archive here[3]. License is defaulted to GPL, but drop me a line if you need something else. Note that some objects are stuck at GPL due to multiple contributors. Unmarked code is (c) 2003-2013 Tom Schouten Other authors are mentioned in the specific files. Some of these objects are from libprim and have stubbed-out code for the LEAF base object library. [1] http://zwizwa.be/pd/pdp [2] http://zwizwa.be/darcs/libprim/ [3] http://zwizwa.be/git/zl pdp-0.14.1+darcs20180201/system/zl/README_API000066400000000000000000000040261266045153600176220ustar00rootroot00000000000000 Abstract API definition. See also the .h corrsponding to the .ap files for expansion into C prototypes. General idea The point of ZL objects is to be wrapped easily in different (dynamic) programming languages. It makes sense to make that process as easy as possible, avoiding a C parsing step by expressing object method descirptions in a more abstract format. The forms in the *.ap files can easily be manipulated using the C preprocessor to generate declarations and wrappers. The *.api files avoid C constructs such as "*" and "struct", and use only identifiers with alphanumeric characters and underscores "_". Note that this means object pointers need to be wrapped in typedefs, an approach which is often frowned upon. To avoid confusion with pointer/integral types, the _p suffix is used in Zl objects. Comma or not? The big decision is between these 2 forms: FUN(t, f, ARG(t1,a1), ARG(t2,a2)) FUN(t, f) ARG(t1,a1) ARG(t2,a2) END The former needs a macro with __VA_ARGS__, the latter has no separators between the arguments, and needs them built into the definition of ARG and FUN. A tale of C preprocessor hacking.. Comma-separated lists can only be mapped to comma-separated list with the same form. This allows 2 C constructs to be used: - Array / structure initializers - Function calls These 2 indirection mechanisms are fairly powerful, but they do are limited due to the presence of the comma, i.e. Note that there is a slight annoyance here: function declarations and calls to not take trailing commas. This means that ARG needs a leading comma, meaning that FUN needs to include the first argument. In practice this doesn't seem to be a problem, since all functions can be grouped by the type of their first operand (object pointer). Implicit object or not? To solve the trailing comma problem, it's probably best to also drop the object argument in the .api definition. Additionally it can get in the way for generic mapping, where the object might be implicit and not part of the representation of the argument lists. pdp-0.14.1+darcs20180201/system/zl/config.h000066400000000000000000000013131266045153600176630ustar00rootroot00000000000000#ifndef _ZL_CONFIG_H_ #define _ZL_CONFIG_H_ #ifdef PD /* Tie ZL into mothership. */ void post(const char *msg, ...); void startpost(const char *fmt, ...); #if 0 #define ZL_LOG(...) startpost("pdp: " __VA_ARGS__) #define ZL_PERROR(...) perror("pdp: " __VA_ARGS__) #else #include #define ZL_LOG(...) fprintf(stderr, __VA_ARGS__) #define ZL_PERROR ZL_LOG #endif #else // #warning ZL running on plain libc #include #include #include static inline void ZL_LOG(const char *msg, ...) { va_list vl; va_start(vl,msg); fprintf(stderr, "zl: "); vfprintf(stderr, msg, vl); fprintf(stderr, "\n"); va_end(vl); } #define ZL_PERROR perror #endif #endif pdp-0.14.1+darcs20180201/system/zl/glx.c000066400000000000000000000240531266045153600172110ustar00rootroot00000000000000/* * Pure Data Packet support file: glx glue code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include //#include #define PRIVATE #include "glx.h" //#include //#include //#include //#include #define D if (0) /* ------------------------- GLX_MESA_swap_control ------------------------- */ #ifndef GLX_MESA_swap_control #define GLX_MESA_swap_control 1 typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void); typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); #define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA) #define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA) #define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control) #endif /* GLX_MESA_swap_control */ static zl_glx *current_context = 0; /* cons */ void zl_glx_init(zl_glx *x) { memset(x, 0, sizeof(*x)); x->tex_width = 1; // smallest nonzero (for mul 2) dummy size x->tex_height = 1; x->format = GL_RGB; // FIXME: This is never set } zl_glx *zl_glx_new(void){ zl_glx *x = malloc(sizeof(*x)); zl_glx_init(x); return x; } /* des */ void zl_glx_cleanup(zl_glx* x) { // XEvent e; if (x->initialized){ ZL_LOG("glXDestroyContext()\n"); glXDestroyContext(x->xdpy->dpy, x->glx_context); x->xdpy = 0; x->initialized = 0; } } void zl_glx_free(zl_glx* x){ if (glIsTexture(x->texture)){ glDeleteTextures(1, &(x->texture)); x->texture = 0; } zl_glx_cleanup(x); free(x); } void zl_glx_swapbuffers(zl_glx *x, zl_xwindow_p xwin) { // ZL_LOG("swapbuffers %x %x", x, xwin); // ZL_LOG("glXSwapBuffers(%p,%p)\n",x->xdpy->dpy, xwin->win); glXSwapBuffers(x->xdpy->dpy, xwin->win); } // FIXME: pbufs? void zl_glx_makecurrent(zl_glx *x, zl_xwindow_p xwin) { if (NULL == xwin) { glXMakeCurrent(x->xdpy->dpy, None, x->glx_context); } else if (x != current_context){ D fprintf(stderr, "glXMakeCurrent(%p,%p,%p)\n", (void*)x->xdpy->dpy, (void*)xwin->win, (void*)x->glx_context); glXMakeCurrent(x->xdpy->dpy, xwin->win, x->glx_context); current_context = x; } } void *zl_glx_image_data(zl_glx* x, zl_xwindow_p xwin, unsigned int w, unsigned int h){ if (!x->initialized) return 0; x->image_width = w; x->image_height = h; int tex_width = x->tex_width; int tex_height = x->tex_height; /* set window context current just to make sure we don't conflict with other contexts */ zl_glx_makecurrent(x, xwin); /* setup texture if necesary */ if ((x->image_width > tex_width) || (x->image_height > tex_height)) { while (x->image_width > tex_width) tex_width *= 2; while (x->image_height > tex_height) tex_height *= 2; if (!glIsTexture(x->texture)){glGenTextures(1, &(x->texture));} glBindTexture(GL_TEXTURE_2D, x->texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); x->tex_width = tex_width; x->tex_height = tex_height; fprintf(stderr, "zl_glx_image_data: creating texture %dx%d", tex_width, tex_height); if (x->data) free (x->data); x->data = malloc(4 * x->image_width * x->image_height); } else { glBindTexture(GL_TEXTURE_2D, x->texture); } return x->data; } void display_texture(void *ctx, int w, int h) { zl_glx *x = ctx; /* upload subtexture */ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, x->image_width, x->image_height, x->format, GL_UNSIGNED_BYTE, x->data); /* enable default texture */ glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, x->texture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* get fractional dimensions */ float fx = (float)x->image_width / (float)x->tex_width; float fy = (float)x->image_height / (float)x->tex_height; /* display texture */ glBegin(GL_QUADS); { glTexCoord2f(fx, fy); glVertex2i(w,0); glTexCoord2f(fx, 0); glVertex2i(w, h); glTexCoord2f(0.0, 0.0); glVertex2i(0, h); glTexCoord2f(0, fy); glVertex2i(0,0); } glEnd(); } void zl_glx_2d_display(zl_glx *x, zl_xwindow_p xwin, void (*draw)(void*,int,int), void *ctx) { /* set window context current just to make sure we don't conflict with other contexts */ zl_glx_makecurrent(x, xwin); /* setup viewport, projection and modelview */ glViewport(0, 0, xwin->winwidth, xwin->winheight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, xwin->winwidth, 0.0, xwin->winheight); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* user drawing routine */ draw(ctx, xwin->winwidth, xwin->winheight); glFlush(); glXSwapBuffers(x->xdpy->dpy, xwin->win); } void zl_glx_image_display(zl_glx *x, zl_xwindow_p xwin) { zl_glx_2d_display(x, xwin, display_texture, x); } int GLXExtensionSupported(Display *dpy, const char *extension) { const char *extensionsString; char *pos; extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy)); pos = strstr(extensionsString, extension); return pos!=NULL && (pos==extensionsString || pos[-1]==' ') && (pos[strlen(extension)]==' ' || pos[strlen(extension)]=='\0'); } // VBLANK config, template from http://forum.openframeworks.cc/index.php?topic=561.0 typedef GLvoid (*glXSwapIntervalSGIFunc) (GLint); typedef GLvoid (*glXSwapIntervalMESAFunc) (GLint); #define TARGET_LINUX void zl_glx_vsync(zl_glx *x, bool sync) { #ifdef TARGET_WIN32 if (sync) { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (1); } else { if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (0); } #endif #ifdef TARGET_OSX long sync = sync ? 1 : 0; CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &sync); #endif #ifdef TARGET_LINUX int interval = sync ? 2 : 0; glXSwapIntervalSGIFunc glXSwapIntervalSGI = 0; glXSwapIntervalMESAFunc glXSwapIntervalMESA = 0; if (GLXExtensionSupported(x->xdpy->dpy, "GLX_MESA_swap_control")) { glXSwapIntervalMESA = (glXSwapIntervalMESAFunc) glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA"); if (glXSwapIntervalMESA) { ZL_LOG("glXSwapIntervalMESA(%d)", interval); glXSwapIntervalMESA (interval); } else { ZL_LOG("Could not get glXSwapIntervalMESA()\n"); } } else if (GLXExtensionSupported(x->xdpy->dpy, "GLX_SGI_swap_control")) { glXSwapIntervalSGI = (glXSwapIntervalSGIFunc) glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI"); if (glXSwapIntervalSGI) { ZL_LOG("glXSwapIntervalSGI(%d,%p)", interval, glXSwapIntervalSGI); glXSwapIntervalSGI (interval); } else { ZL_LOG("Could not get glXSwapIntervalSGI()\n"); } } else { ZL_LOG("can't change vblank settings"); } #endif } int zl_glx_open_on_display(zl_glx *x, zl_xwindow_p w, zl_xdisplay_p d) { static int vis_attr[] = {GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None}; /* store mother */ x->xdpy = d; /* create a glx visual */ if (!(x->vis_info = glXChooseVisual(x->xdpy->dpy, x->xdpy->screen, vis_attr))){ fprintf(stderr, "zl_glx_open_on_display: can't find appropriate visual\n"); goto error; } else { D fprintf(stderr, "zl_glx_open_on_display: using visual 0x%x\n", (unsigned int)x->vis_info->visualid); } /* create the rendering context */ if (!(x->glx_context = glXCreateContext(x->xdpy->dpy, x->vis_info, 0 /*share list*/, GL_TRUE))){ fprintf(stderr, "zl_glx_open_on_display: can't create render context\n"); goto error; } else { D fprintf(stderr, "zl_glx_open_on_display: created render " "context %p on screen %d\n", (void*)x->glx_context, x->xdpy->screen); } /* following is from glxgears.c */ XSetWindowAttributes swa; Colormap cmap; /* create an X colormap since probably not using default visual */ cmap = XCreateColormap(d->dpy, RootWindow(d->dpy, x->vis_info->screen), x->vis_info->visual, AllocNone); swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask; /* Create a window using this visual. This will play nice with zl_xwindow: it will not create a window if there is already one there. */ w->win = XCreateWindow( d->dpy, RootWindow(d->dpy, x->vis_info->screen), w->winxoffset, w->winyoffset, w->winwidth, w->winheight, 0, x->vis_info->depth, InputOutput, x->vis_info->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); x->initialized = 1; return 1; error: return 0; } void handle_error(char *msg){ fprintf(stderr, "%s\n", msg); exit(1); } pdp-0.14.1+darcs20180201/system/zl/glx.h000066400000000000000000000054501266045153600172160ustar00rootroot00000000000000#ifndef _ZL_GLX_H_ #define _ZL_GLX_H_ /* * Pure Data Packet header file: glx glue code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ // x stuff #define GLX_GLXEXT_PROTOTYPES #include "zl/xwindow.h" #include #include #include #include #include // does not work on Darwin //#include /* glx class */ typedef struct zl_glx { zl_xdisplay_p xdpy; //mother display object int initialized; /* texture */ XVisualInfo *vis_info; GLXContext glx_context; GLuint texture; GLsizei tex_width; GLsizei tex_height; GLuint format; /* image */ void *data; int image_width; int image_height; } zl_glx, *zl_glx_p; /* cons */ void zl_glx_init(zl_glx *x); zl_glx *zl_glx_new(void); /* des */ void zl_glx_cleanup(zl_glx* x); void zl_glx_free(zl_glx* x); /* Open an opengl context. Call this before zl_xwindow_config() */ int zl_glx_open_on_display(zl_glx *x, zl_xwindow_p w, zl_xdisplay_p d); /* close an opengl context */ void zl_glx_close(zl_glx* x); /* display a packet */ //void zl_glx_display_packet(zl_glx *x, xwindow *xwin, pf_packet_t packet); /* get texture data buffer */ void *zl_glx_image_data(zl_glx *x, zl_xwindow_p xwin, unsigned int width, unsigned int height); /* display the texture */ void zl_glx_image_display(zl_glx *x, zl_xwindow_p xwin); /* call an OpenGL rendering function */ void zl_glx_2d_display(zl_glx *x, zl_xwindow_p xwin, void (*draw)(void*,int,int), void *ctx); /* opengl specific stuff*/ void zl_glx_swapbuffers(zl_glx *x, zl_xwindow_p xwin); void zl_glx_makecurrent(zl_glx *x, zl_xwindow_p xwin); void zl_glx_vsync(zl_glx *x, bool sync); /* opengl sync module this uses GLX_SGI_video_sync to sync to retrace */ //typedef struct { // xdisplay *xdpy; // Window dummy_window; // GLXContext context; //} glx_sync_t; // glx_sync_t *glx_sync_new(void); // oid glx_sync_free(glx_sync_t *x); // void glx_sync_wait(glx_sync_t *x); // int glx_sync_open_on_display(glx_sync_t *x, xdisplay *xdpy); #endif pdp-0.14.1+darcs20180201/system/zl/pwc-ioctl.h000066400000000000000000000135231266045153600203250ustar00rootroot00000000000000#ifndef PWC_IOCTL_H #define PWC_IOCTL_H /* (C) 2001-2002 Nemosoft Unv. webcam@smcc.demon.nl 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 */ /* This is pwc-ioctl.h belonging to PWC 8.6 */ /* Changes 2001/08/03 Alvarado Added ioctl constants to access methods for changing white balance and red/blue gains */ /* These are private ioctl() commands, specific for the Philips webcams. They contain functions not found in other webcams, and settings not specified in the Video4Linux API. The #define names are built up like follows: VIDIOC VIDeo IOCtl prefix PWC Philps WebCam G optional: Get S optional: Set ... the function */ /* The frame rate is encoded in the video_window.flags parameter using the upper 16 bits, since some flags are defined nowadays. The following defines provide a mask and shift to filter out this value. In 'Snapshot' mode the camera freezes its automatic exposure and colour balance controls. */ #define PWC_FPS_SHIFT 16 #define PWC_FPS_MASK 0x00FF0000 #define PWC_FPS_FRMASK 0x003F0000 #define PWC_FPS_SNAPSHOT 0x00400000 struct pwc_probe { char name[32]; int type; }; /* pwc_whitebalance.mode values */ #define PWC_WB_INDOOR 0 #define PWC_WB_OUTDOOR 1 #define PWC_WB_FL 2 #define PWC_WB_MANUAL 3 #define PWC_WB_AUTO 4 /* Used with VIDIOCPWC[SG]AWB (Auto White Balance). Set mode to one of the PWC_WB_* values above. *red and *blue are the respective gains of these colour components inside the camera; range 0..65535 When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; otherwise undefined. 'read_red' and 'read_blue' are read-only. */ struct pwc_whitebalance { int mode; int manual_red, manual_blue; /* R/W */ int read_red, read_blue; /* R/O */ }; /* 'control_speed' and 'control_delay' are used in automatic whitebalance mode, and tell the camera how fast it should react to changes in lighting, and with how much delay. Valid values are 0..65535. */ struct pwc_wb_speed { int control_speed; int control_delay; }; /* Used with VIDIOCPWC[SG]LED */ struct pwc_leds { int led_on; /* Led on-time; range = 0..25000 */ int led_off; /* Led off-time; range = 0..25000 */ }; /* Restore user settings */ #define VIDIOCPWCRUSER _IO('v', 192) /* Save user settings */ #define VIDIOCPWCSUSER _IO('v', 193) /* Restore factory settings */ #define VIDIOCPWCFACTORY _IO('v', 194) /* You can manipulate the compression factor. A compression preference of 0 means use uncompressed modes when available; 1 is low compression, 2 is medium and 3 is high compression preferred. Of course, the higher the compression, the lower the bandwidth used but more chance of artefacts in the image. The driver automatically chooses a higher compression when the preferred mode is not available. */ /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */ #define VIDIOCPWCSCQUAL _IOW('v', 195, int) /* Get preferred compression quality */ #define VIDIOCPWCGCQUAL _IOR('v', 195, int) /* This is a probe function; since so many devices are supported, it becomes difficult to include all the names in programs that want to check for the enhanced Philips stuff. So in stead, try this PROBE; it returns a structure with the original name, and the corresponding Philips type. To use, fill the structure with zeroes, call PROBE and if that succeeds, compare the name with that returned from VIDIOCGCAP; they should be the same. If so, you can be assured it is a Philips (OEM) cam and the type is valid. */ #define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe) /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ #define VIDIOCPWCSAGC _IOW('v', 200, int) /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */ #define VIDIOCPWCGAGC _IOR('v', 200, int) /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */ #define VIDIOCPWCSSHUTTER _IOW('v', 201, int) /* Color compensation (Auto White Balance) */ #define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance) #define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance) /* Auto WB speed */ #define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed) #define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed) /* LEDs on/off/blink; int range 0..65535 */ #define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds) #define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds) /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */ #define VIDIOCPWCSCONTOUR _IOW('v', 206, int) #define VIDIOCPWCGCONTOUR _IOR('v', 206, int) /* Backlight compensation; 0 = off, otherwise on */ #define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int) #define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int) /* Flickerless mode; = 0 off, otherwise on */ #define VIDIOCPWCSFLICKER _IOW('v', 208, int) #define VIDIOCPWCGFLICKER _IOR('v', 208, int) /* Dynamic noise reduction; 0 off, 3 = high noise reduction */ #define VIDIOCPWCSDYNNOISE _IOW('v', 209, int) #define VIDIOCPWCGDYNNOISE _IOR('v', 209, int) #endif pdp-0.14.1+darcs20180201/system/zl/test.c000066400000000000000000000031621266045153600173740ustar00rootroot00000000000000#include "v4l.h" #include "xwindow.h" #include "xv.h" #include "3Dcontext.h" #include #include #include int test1(void) { struct zl_v4l v4l; zl_v4l_init(&v4l, true); zl_v4l_open(&v4l, "/dev/video0", true); // zl_v4l_open(&v4l, "/dev/video1"); unsigned int fourcc, w,h; zl_v4l_get_format(&v4l, &fourcc, &w, &h); const char *card = zl_v4l_card(&v4l); printf("card = %s\n", card); unsigned char *video_data = NULL; zl_xdisplay *xd = zl_xdisplay_new(":0"); zl_xwindow *xw = zl_xwindow_new(); zl_xv *xv = zl_xv_new(FOURCC_YUV2); zl_xwindow_config(xw, xd); zl_xv_open_on_display(xv, xd, 0); int count = 10; unsigned char *image_buffer = zl_xv_image_data(xv, xw, w, h); int image_buffer_size = w*h * 2; // we know it's FOURCC_YUV2 while (count > 0) { sleep(0); zl_v4l_next(&v4l, &video_data); if (NULL != video_data) { count--; memcpy(image_buffer, video_data, image_buffer_size); zl_xdisplay_route_events(xd); zl_xv_image_display(xv, xw); } } sleep(1); // zl_xdisplay_register_window(xd, xw); // struct zl_xwindow * zl_xdisplay_unregister_window(xd, xw); zl_xwindow_free(xw); zl_xv_free(xv); zl_xdisplay_free(xd); return 0; } void test2(void) { zl_3Dcontext_glx_setup(); // global setup zl_3Dcontext *c = zl_3Dcontext_win_new(); int w = zl_3Dcontext_width(c); int h = zl_3Dcontext_height(c); ZL_LOG("test2: %d x %d\n", w, h); sleep(1); } int main(void) { test1(); test2(); return 0; } pdp-0.14.1+darcs20180201/system/zl/util.h000066400000000000000000000102551266045153600174000ustar00rootroot00000000000000/* util.h - (c) 2004 Tom Schouten. this software is in the public domain. This is supposed to be my low-level data structures toolbox. Defined as inline static to avoid version and symbol clashes. */ #ifndef ZL_UTIL_H #define ZL_UTIL_H #include // linkage #define INLINE inline static // growable array object typedef struct { int size; int elements; void **data; } buf_t; // fixed 2^n size queue object typedef struct { void **data; unsigned int mask; unsigned int read; unsigned int write; } queue_t; typedef buf_t fifo_t; // same /* small utils */ INLINE int imax(int x, int y){return (x > y) ? x : y;} INLINE int imin(int x, int y){return (x < y) ? x : y;} /* protos */ INLINE buf_t *buf_new(int size); ///< create a new growable array INLINE void buf_add(buf_t *x, void *thing); ///< add an element INLINE int buf_lookup(buf_t *x, void *thing); ///< lookup element and return index INLINE int buf_add_to_set(buf_t *x, void *thing); ///< add if not already present INLINE void buf_clear(buf_t *x); INLINE void buf_free(buf_t *x); INLINE void buf_remove(buf_t *x, void *thing); INLINE int buf_allot(buf_t *x, int bytes); ///< allocate memory and return cell index INLINE void stack_clear(fifo_t *x); INLINE void stack_free(fifo_t *x); INLINE int stack_elements(fifo_t *x); INLINE void stack_push(fifo_t *x, void *data); INLINE void *stack_pop(fifo_t *x); INLINE void stack_clear(fifo_t *x); INLINE void stack_free(fifo_t *x); INLINE fifo_t *stack_new(int elements); /* code */ INLINE buf_t *buf_new(int size){ buf_t *x = malloc(sizeof(*x)); x->size = size; x->elements = 0; x->data = malloc(sizeof(void *) * size); return x; } INLINE void buf_add(buf_t *x, void *thing){ if (x->elements == x->size){ x->size *= 2; x->data = realloc(x->data, x->size * sizeof(void *)); } x->data[x->elements++] = thing; } INLINE int buf_lookup(buf_t *x, void *thing){ int i; for (i=0; ielements; i++){ if (x->data[i] == thing) return i; // found } return -1; // not found } // add if not in there INLINE int buf_add_to_set(buf_t *x, void *thing){ int indx = buf_lookup(x, thing); if (indx < 0){ // add if not found indx = x->elements; buf_add(x, thing); } return indx; } INLINE void buf_remove(buf_t *x, void *thing){ int indx = buf_lookup(x, thing); if (indx < 0) return; // not here x->elements--; x->data[indx] = x->data[x->elements]; } INLINE void buf_clear(buf_t *x){x->elements = 0;} INLINE void buf_free(buf_t *x){free (x->data); free(x);} INLINE int buf_allot(buf_t *x, int bytes){ int words = ((bytes-1) / sizeof(int)) - 1; int indx = x->elements; while(words--) buf_add(x, 0); return indx; } INLINE fifo_t *stack_new(int nb_elements){ fifo_t *x = buf_new(nb_elements); return x; } INLINE int stack_elements(fifo_t *x){return x->elements;} INLINE void stack_push(fifo_t *x, void *data){buf_add(x, data);} INLINE void *stack_pop(fifo_t *x){ if (!x->elements) return 0; return x->data[--x->elements]; } INLINE void stack_clear(fifo_t *x){buf_clear(x);} INLINE void stack_free(fifo_t *x){buf_free(x);} #if 0 // FIXME: name conflicts with queue in leaf/queue.h INLINE queue_t *queue_new(int logsize); INLINE void queue_free(queue_t *queue); INLINE void queue_write(queue_t *queue, void *thing); INLINE void *queue_read(queue_t *queue); INLINE unsigned int queue_elements(queue_t *queue); INLINE int queue_full(queue_t *queue); INLINE queue_t *queue_new(int logsize){ queue_t *x = malloc(sizeof(*x)); x->data = malloc(1<mask = (1<read = 0; x->write = 0; return x; } INLINE void queue_free(queue_t *x){ free(x->data); free(x); } INLINE unsigned int queue_elements(queue_t *x){ return (x->write - x->read) & x->mask; } INLINE int queue_full(queue_t *x){ return (x->mask == queue_elements(x)); } INLINE void queue_write(queue_t *x, void *thing){ int i = x->write; x->data[i++] = thing; x->write = i & x->mask; } INLINE void *queue_read(queue_t *x){ int i = x->read; void *thing = x->data[i++]; x->write = i & x->mask; return thing; } #endif #endif pdp-0.14.1+darcs20180201/system/zl/v4l.c000066400000000000000000001132241266045153600171230ustar00rootroot00000000000000/* * Pure Data Packet module. * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * 2012-10-29 : V4L2 support from Pidip's pdp_v4l2 (= fork of pdp_v4l) * Thanks to Yves Degoyon, Lluis Gomez i Bigorda, Gerd Knorr * */ /* NOTE: This code isn't particularly well-written, but it'll have to do for now. I kept most of it as is during porting from pdp_v4l / pdp_v4l2 This code is probably broken on V4L1. If you need it, drop me an email at Overall I'm not sure if it makes sense to keep V4L1 alive.. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "v4l.h" #include #include #include //include it anyway //#ifdef HAVE_PWCV4L #include "pwc-ioctl.h" //#endif #define DO_SANITY_CHECKS 0 /* Formats supported in the _bang method. */ /* FIXME: V4L2: add raw PWC MJPEG decompressor for format [0x32435750] 'PWC2' (Raw Philips Webcam) */ static void v4l_notify_frame(struct zl_v4l *x); static void *v4l_thread(void *_x); /* V4L1 */ #ifdef HAVE_V4L1 static void v4l1_unmap(struct zl_v4l *x) { /* On V4L1 there is only a single buffer. */ if (x->x_buf[0]) { if (x->x_debug) ZL_LOG("v4l: unmapping %p", x->x_buf[0]); if (-1 == munmap(x->x_buf[0], x->x_api.v4l1.mbuf.size)) { ZL_PERROR("munmap"); } } x->x_buf[0] = NULL; } static void v4l1_capture_frame(struct zl_v4l *x) { if (!(ioctl(x->x_tvfd, VIDIOCMCAPTURE, &x->x_api.v4l1.mmap[x->x_frame_wr]) < 0)) return; // OK /* Handle error */ if (errno == EAGAIN) ZL_LOG("v4l: can't sync (no video source?)\n"); else ZL_PERROR("v4l: VIDIOCMCAPTURE"); /* Try again */ if (ioctl(x->x_tvfd, VIDIOCMCAPTURE, &x->x_api.v4l1.mmap[x->x_frame_wr]) < 0) ZL_PERROR("v4l: VIDIOCMCAPTURE2"); ZL_LOG("v4l: frame %d %d, format %d, width %d, height %d", x->x_frame_wr, x->x_api.v4l1.mmap[x->x_frame_wr].frame, x->x_api.v4l1.mmap[x->x_frame_wr].format, x->x_api.v4l1.mmap[x->x_frame_wr].width, x->x_api.v4l1.mmap[x->x_frame_wr].height); // zl_v4l_close(x); // FIXME: don't close from thread } unsigned char *v4l1_image_dequeue(struct zl_v4l *x) { unsigned char *data = (unsigned char *)(x->x_buf[0] + x->x_api.v4l1.mbuf.offsets[x->x_frame_rd]); return data; } static void v4l_notify_frame(struct zl_v4l *x); void v4l1_thread_loop(struct zl_v4l *x) { /* capture with a double buffering scheme */ while (x->x_continue_thread) { /* schedule capture command for next frame */ v4l1_capture_frame(x); /* wait until previous capture is ready */ if (ioctl(x->x_tvfd, VIDIOCSYNC, &x->x_api.v4l1.mmap[x->x_frame_wr].frame) < 0) { ZL_PERROR("v4l: VIDIOCSYNC"); // zl_v4l_close(x); // FIXME: Don't call close in thread break; } /* setup pointers for main thread */ v4l_notify_frame(x); } ZL_LOG("v4l: capture thread quitting" ); } static void v4l1_pwc_agc(struct zl_v4l *x, float gain) { if (x->x_v4l_api != V4L1) { ZL_LOG("v4l: agc message needs V4L1"); return; } gain *= (float)(1<<16); int g = (int)gain; if (g < 0) g = -1; // automatic if (g > (1<<16)) g = (1<<16) - 1; // fixed //ZL_LOG("v4l: setting agc to %d", g); if (ioctl(x->x_tvfd, VIDIOCPWCSAGC, &g)){ ZL_LOG("v4l: pwc: VIDIOCPWCSAGC"); //goto closit; } } static void v4l1_pwc_init(struct zl_v4l *x) { struct pwc_probe probe; int isPhilips = 0; #ifdef HAVE_PWCV4L /* skip test */ isPhilips = 1; #else /* test for pwc */ if (ioctl(x->x_tvfd, VIDIOCPWCPROBE, &probe) == 0) if (!strcmp(x->x_api.v4l1.cap.name, probe.name)) isPhilips = 1; #endif /* don't do pwc specific stuff */ if (!isPhilips) return; ZL_LOG("v4l: detected pwc"); if(ioctl(x->x_tvfd, VIDIOCPWCRUSER)){ ZL_PERROR("v4l: pwc: VIDIOCPWCRUSER"); goto closit; } /* this is a workaround: we disable AGC after restoring user prefs something is wrong with newer cams (like Qickcam 4000 pro) */ if (1) { zl_v4l_pwc_agc(x, 1.0); } if (ioctl(x->x_tvfd, VIDIOCGWIN, &x->x_api.v4l1.win)){ ZL_PERROR("v4l: pwc: VIDIOCGWIN"); goto closit; } if (x->x_api.v4l1.win.flags & PWC_FPS_MASK){ //ZL_LOG("v4l: pwc: camera framerate: %d", (x->x_api.v4l1.win.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT); //ZL_LOG("v4l: pwc: setting camera framerate to %d", x->x_framerate); x->x_api.v4l1.win.flags &= PWC_FPS_MASK; x->x_api.v4l1.win.flags |= ((x->x_fps_num / x->x_fps_den) << PWC_FPS_SHIFT); if (ioctl(x->x_tvfd, VIDIOCSWIN, &x->x_api.v4l1.win)){ ZL_PERROR("v4l: pwc: VIDIOCSWIN"); goto closit; } if (ioctl(x->x_tvfd, VIDIOCGWIN, &x->x_api.v4l1.win)){ ZL_PERROR("v4l: pwc: VIDIOCGWIN"); goto closit; } ZL_LOG("v4l: camera framerate set to %d fps", (x->x_api.v4l1.win.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT); } return; closit: zl_v4l_close_error(x); return; } static void *v4l_thread(void *_x); static void v4l1_open(struct zl_v4l *x, const char *name) { /* if already opened -> close */ if (x->x_initialized) zl_v4l_close(x); ZL_LOG("v4l: opening %s (V4L1)", name); x->x_v4l_api = V4L1; bzero(&x->x_api.v4l1, sizeof(x->x_api.v4l1)); if (x->x_initialized) return; // idempotent /* open a v4l device and allocate a buffer */ int i; unsigned int width, height; if ((x->x_tvfd = open(name, O_RDWR)) < 0) { ZL_LOG("v4l: error:"); perror(name); goto closit; } if (ioctl(x->x_tvfd, VIDIOCGCAP, &x->x_api.v4l1.cap) < 0) { // http://stackoverflow.com/questions/898474/v4l-problem-with-vidiocgcap-ioctl-call perror("get capabilities"); goto closit; } ZL_LOG("v4l: cap: name %s type %d channels %d maxw %d maxh %d minw %d minh %d", x->x_api.v4l1.cap.name, x->x_api.v4l1.cap.type, x->x_api.v4l1.cap.channels, x->x_api.v4l1.cap.maxwidth, x->x_api.v4l1.cap.maxheight, x->x_api.v4l1.cap.minwidth, x->x_api.v4l1.cap.minheight); #if 0 // FIXME: not used x->x_minwidth = pdp_imageproc_legalwidth(x->x_api.v4l1.cap.minwidth); x->x_maxwidth = pdp_imageproc_legalwidth_round_down(x->x_api.v4l1.cap.maxwidth); x->x_minheight = pdp_imageproc_legalheight(x->x_api.v4l1.cap.minheight); x->x_maxheight = pdp_imageproc_legalheight_round_down(x->x_api.v4l1.cap.maxheight); #endif if (ioctl(x->x_tvfd, VIDIOCGPICT, &x->x_api.v4l1.picture) < 0) { perror("VIDIOCGCAP"); goto closit; } ZL_LOG("v4l: picture: brightness %d depth %d palette %d", x->x_api.v4l1.picture.brightness, x->x_api.v4l1.picture.depth, x->x_api.v4l1.picture.palette); /* get channel info */ for (i = 0; i < x->x_api.v4l1.cap.channels; i++) { x->x_api.v4l1.channel.channel = i; if (ioctl(x->x_tvfd, VIDIOCGCHAN, &x->x_api.v4l1.channel) < 0) { perror("VDIOCGCHAN"); goto closit; } ZL_LOG("v4l: channel %d name %s type %d flags %d", x->x_api.v4l1.channel.channel, x->x_api.v4l1.channel.name, x->x_api.v4l1.channel.type, x->x_api.v4l1.channel.flags); } /* switch to the desired channel */ if (x->x_channel >= (unsigned long)x->x_api.v4l1.cap.channels) x->x_channel = x->x_api.v4l1.cap.channels - 1; x->x_api.v4l1.channel.channel = x->x_channel; if (ioctl(x->x_tvfd, VIDIOCGCHAN, &x->x_api.v4l1.channel) < 0) { ZL_PERROR("v4l: warning: VDIOCGCHAN"); ZL_LOG("v4l: cant change to channel %d",x->x_channel); // ignore error // goto closit; } else{ ZL_LOG("v4l: switched to channel %d", x->x_channel); } /* set norm */ x->x_api.v4l1.channel.norm = x->x_norm; if (ioctl(x->x_tvfd, VIDIOCSCHAN, &x->x_api.v4l1.channel) < 0) { ZL_PERROR("v4l: warning: VDIOCSCHAN"); ZL_LOG("v4l: cant change to norm %d",x->x_norm); // ignore error // goto closit; } else { ZL_LOG("v4l: set norm to %u", x->x_norm); } if (x->x_freq > 0){ if (ioctl(x->x_tvfd, VIDIOCSFREQ, &x->x_freq) < 0) perror ("couldn't set frequency :"); } /* get mmap numbers */ if (ioctl(x->x_tvfd, VIDIOCGMBUF, &x->x_api.v4l1.mbuf) < 0) { ZL_PERROR("v4l: VIDIOCGMBUF"); goto closit; } ZL_LOG("v4l: buffer size %d, frames %d, offset %d %d", x->x_api.v4l1.mbuf.size, x->x_api.v4l1.mbuf.frames, x->x_api.v4l1.mbuf.offsets[0], x->x_api.v4l1.mbuf.offsets[1]); bzero(x->x_buf, sizeof(x->x_buf)); if (!(x->x_buf[0] = (unsigned char *) mmap(0, x->x_api.v4l1.mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, x->x_tvfd, 0))) { ZL_PERROR("v4l: mmap"); goto closit; } x->x_nbbuffers = 2; // V4L has only 1 mmapped buffer with 2 frames // FIXME: // pdp_v4l_setlegaldim(x, x->x_width, x->x_height); width = x->x_width; height = x->x_height; for (i = 0; i < ZL_V4L_NBUF; i++) { //x->x_api.v4l1.mmap[i].format = VIDEO_PALETTE_YUV420P; //x->x_api.v4l1.mmap[i].format = VIDEO_PALETTE_UYVY; x->x_api.v4l1.mmap[i].width = width; x->x_api.v4l1.mmap[i].height = height; x->x_api.v4l1.mmap[i].frame = i; } /* fallthrough macro for case statement */ #define TRYPALETTE(_palette) \ x->x_api.v4l1.palette = _palette; \ for (i = 0; i < ZL_V4L_NBUF; i++) x->x_api.v4l1.mmap[i].format = x->x_api.v4l1.palette; \ if (ioctl(x->x_tvfd, VIDIOCMCAPTURE, &x->x_api.v4l1.mmap[x->x_frame_wr]) < 0) \ { \ if (errno == EAGAIN) \ ZL_LOG("v4l: can't sync (no video source?)"); \ if (x->x_format) break; /* only break if not autodetecting */ \ } \ else{ \ ZL_LOG("v4l: using " #_palette); \ goto capture_ok; \ } switch(x->x_format){ default: case 0: case 1: TRYPALETTE(VIDEO_PALETTE_YUV420P); case 2: TRYPALETTE(VIDEO_PALETTE_YUV422); case 3: TRYPALETTE(VIDEO_PALETTE_RGB24); case 4: TRYPALETTE(VIDEO_PALETTE_RGB32); } // none of the formats are supported ZL_PERROR("v4l: VIDIOCMCAPTURE: format not supported"); goto closit; capture_ok: ZL_LOG("v4l: frame %d %d, format %d, width %d, height %d", x->x_frame_wr, x->x_api.v4l1.mmap[x->x_frame_wr].frame, x->x_api.v4l1.mmap[x->x_frame_wr].format, x->x_api.v4l1.mmap[x->x_frame_wr].width, x->x_api.v4l1.mmap[x->x_frame_wr].height); x->x_width = width; x->x_height = height; ZL_LOG("v4l: Opened video connection (%dx%d)",x->x_width,x->x_height); /* do some pwc specific inits */ v4l1_pwc_init(x); x->x_initialized = true; /* create thread */ x->x_continue_thread = 1; sem_init(&x->x_frame_ready_sem, 0, 0); pthread_create(&x->x_thread_id, 0, v4l_thread, x); goto done; closit: zl_v4l_close_error(x); done: return; } #if 0 static void v4l1_audio (struct zl_v4l *x) { if (x->x_v4l_api != V4L1) { ZL_LOG("v4l: audio message needs V4L1"); return; } int i = 0; if (x->x_initialized) { fprintf(stderr," audios : %d\n",x->x_api.v4l1.cap.audios); x->x_api.v4l1.audio.audio = 0; ioctl(x->x_tvfd,VIDIOCGAUDIO, &x->x_api.v4l1.audio); fprintf(stderr," %d (%s): ",i,x->x_api.v4l1.audio.name); if (x->x_api.v4l1.audio.flags & VIDEO_AUDIO_MUTABLE) fprintf(stderr,"muted=%s ", (x->x_api.v4l1.audio.flags & VIDEO_AUDIO_MUTE) ? "yes":"no"); if (x->x_api.v4l1.audio.flags & VIDEO_AUDIO_VOLUME) fprintf(stderr,"volume=%d ",x->x_api.v4l1.audio.volume); if (x->x_api.v4l1.audio.flags & VIDEO_AUDIO_BASS) fprintf(stderr,"bass=%d ",x->x_api.v4l1.audio.bass); if (x->x_api.v4l1.audio.flags & VIDEO_AUDIO_TREBLE) fprintf(stderr,"treble=%d ",x->x_api.v4l1.audio.treble); fprintf(stderr,"\n"); } } #endif #else // !HAVE_V4L1 static inline void v4l1_unmap(struct zl_v4l *x __attribute__((__unused__))) {} static inline void v4l1_capture_frame(struct zl_v4l *x __attribute__((__unused__))) {} #endif /* V4L2 */ #ifdef HAVE_V4L2 unsigned char *v4l2_image_dequeue(struct zl_v4l *x) { return (unsigned char *)( x->x_buf[x->x_frame_rd]); } static void v4l2_unmap(struct zl_v4l *x) { int i; for(i=0; ix_nbbuffers; i++ ) { // if (x->x_debug) ZL_LOG("v4l: unmapping %p (%d)", x->x_buf[i], i); if (x->x_buf[i]) { if (-1 == munmap(x->x_buf[i], x->x_api.v4l2.buffer[i].length)) { ZL_PERROR("munmap"); } } x->x_buf[i] = NULL; } } static void v4l2_capture_frame(struct zl_v4l *x) { x->x_api.v4l2.buffer[x->x_frame_wr].index = x->x_frame_wr; x->x_api.v4l2.buffer[x->x_frame_wr].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; x->x_api.v4l2.buffer[x->x_frame_wr].memory = V4L2_MEMORY_MMAP; if (-1 == ioctl (x->x_tvfd, VIDIOC_DQBUF, &x->x_api.v4l2.buffer[x->x_frame_wr])) { switch (errno) { case EAGAIN: return; case EIO: // could ignore EIO, see spec default: ZL_PERROR("v4l: error reading buffer"); goto error; } } // reenqueing buffer if (-1 == ioctl (x->x_tvfd, VIDIOC_QBUF, &x->x_api.v4l2.buffer[x->x_frame_wr])) { ZL_PERROR("v4l: error queing buffers"); goto error; } return; error: // FIXME: handle error; return; } static int v4l2_format_supported(unsigned long format) { switch(format) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: case v4l2_fourcc('S', '9', '2', '0'): return 1; default: return 0; } } /* Add a timeout to avoid waiting forever. */ static bool v42l_sync_timeout(struct zl_v4l *x) { fd_set fds; struct timeval tv; int ret; FD_ZERO (&fds); FD_SET (x->x_tvfd, &fds); // Timeout. tv.tv_sec = 5; tv.tv_usec = 0; ret = select (x->x_tvfd + 1, &fds, NULL, NULL, &tv); if (-1 == ret) { if (EINTR == errno) goto error; ZL_LOG("v4l: select error"); goto error; } if (0 == ret) { ZL_LOG("v4l: select timeout"); goto error; } /* Check how long we've waited. */ if (0 && x->x_debug) { float dt = tv.tv_usec; dt /= 1000000; dt += tv.tv_sec; dt = 5 - dt; ZL_LOG("v4l: wait %f ms", dt); } return false; error: return true; } void v4l2_thread_loop(struct zl_v4l *x) { enum v4l2_buf_type type; /* Start capturing. */ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (x->x_tvfd, VIDIOC_STREAMON, &type)) { ZL_PERROR("v4l: error starting streaming"); goto error; } ZL_LOG("v4l: capture started"); while (x->x_continue_thread) { /* Don't wait forever for something to happen. */ if (v42l_sync_timeout(x)) goto error; /* Get next frame. Without the sync timeout this will also work, but might wait forever. */ v4l2_capture_frame(x); /* Notify reader */ v4l_notify_frame(x); } /* Stop capturing. */ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (x->x_tvfd, VIDIOC_STREAMOFF, &type)) { ZL_PERROR("v4l: error stopping streaming"); } error: ZL_LOG("v4l: capture thread quitting" ); } // http://v4l.videotechnology.com/dwg/v4l2.html#CONTROL void zl_v4l_control(struct zl_v4l *x, int id, int value) { const int fd = x->x_tvfd; const struct v4l2_queryctrl queryctrl = { .id = id, }; /* Check if it's supported. */ if (-1 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (errno != EINVAL) { perror ("VIDIOC_QUERYCTRL"); goto error; } else { // see /usr/include/linux/videodev2.h // V4L2_CID_CAMERA_CLASS_BASE == 0x00980000 ZL_LOG("v4l: control %08x is not supported", id); perror ("VIDIOC_QUERYCTRL"); } } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { ZL_LOG("v4l: control %d is not supported", id); } else { /* Set the control */ const struct v4l2_control control = { .id = id, .value = value, }; if (-1 == ioctl (fd, VIDIOC_S_CTRL, &control)) { perror ("VIDIOC_S_CTRL"); goto error; } } return; error: return; } static void v4l2_set_format(struct zl_v4l *x, int index) { if (x->x_v4l_api != V4L2) return; typeof(x->x_api.v4l2.format) *format = &x->x_api.v4l2.format; typeof(format->fmt.pix) *pix = &format->fmt.pix; format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; pix->pixelformat = x->x_api.v4l2.fmtdesc[index].pixelformat; pix->field = V4L2_FIELD_ANY; pix->width = x->x_width; pix->height = x->x_height; ZL_LOG("v4l: setting format: index %d, pixel format %c%c%c%c", index, pix->pixelformat & 0xff, (pix->pixelformat >> 8) & 0xff, (pix->pixelformat >> 16) & 0xff, (pix->pixelformat >> 24) & 0xff ); if (-1 == ioctl(x->x_tvfd, VIDIOC_S_FMT, &x->x_api.v4l2.format)) { ZL_LOG("v4l: defaulting to format: pixel format %c%c%c%c", pix->pixelformat & 0xff, (pix->pixelformat >> 8) & 0xff, (pix->pixelformat >> 16) & 0xff, (pix->pixelformat >> 24) & 0xff ); } ZL_LOG("v4l: capture format: width %d, height %d, bytesperline %d, image size %d", pix->width , pix->height, pix->bytesperline, pix->sizeimage ); } static void v4l2_set_timeperframe(struct zl_v4l *x, int tpf_num, int tpf_den) { struct v4l2_streamparm streamparm; streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; streamparm.parm.capture.timeperframe.numerator = tpf_num; streamparm.parm.capture.timeperframe.denominator = tpf_den; ZL_LOG("v4l: timeperframe = %d/%d (requested)", streamparm.parm.capture.timeperframe.numerator, streamparm.parm.capture.timeperframe.denominator); if (-1 == ioctl(x->x_tvfd, VIDIOC_S_PARM, &streamparm)) { ZL_PERROR("v4l: VIDIOC_S_PARM"); } else { /* Actual might differ from requested. */ ZL_LOG("v4l: timeperframe = %d/%d (actual)", streamparm.parm.capture.timeperframe.numerator, streamparm.parm.capture.timeperframe.denominator); } return; } static int v4l2_init_mmap(struct zl_v4l *x) { if (x->x_v4l_api != V4L2) return -1; int i; // get mmap numbers x->x_api.v4l2.requestbuffers.count = x->x_nbbuffers_wanted; x->x_api.v4l2.requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; x->x_api.v4l2.requestbuffers.memory = V4L2_MEMORY_MMAP; if (-1 == ioctl(x->x_tvfd, VIDIOC_REQBUFS, &x->x_api.v4l2.requestbuffers, 0)) { ZL_LOG("v4l: error : couldn't init driver buffers" ); return -1; } ZL_LOG("v4l: got %d buffers type %d memory %d", x->x_api.v4l2.requestbuffers.count, x->x_api.v4l2.requestbuffers.type, x->x_api.v4l2.requestbuffers.memory ); if ( x->x_api.v4l2.requestbuffers.count > ZL_V4L_MAX_BUFFERS ) { ZL_LOG("v4l: this device requires more buffer space" ); return -1; } x->x_nbbuffers = x->x_api.v4l2.requestbuffers.count; ZL_LOG("v4l: using %d buffers", x->x_nbbuffers); for (i = 0; i < x->x_nbbuffers; i++) { x->x_api.v4l2.buffer[i].index = i; x->x_api.v4l2.buffer[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; x->x_api.v4l2.buffer[i].memory = V4L2_MEMORY_MMAP; if (-1 == ioctl(x->x_tvfd, VIDIOC_QUERYBUF, &x->x_api.v4l2.buffer[i], 0)) { ZL_LOG("v4l: error : couldn't query buffer %d", i ); return -1; } x->x_buf[i] = (unsigned char *) mmap(NULL, x->x_api.v4l2.buffer[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, x->x_tvfd, x->x_api.v4l2.buffer[i].m.offset); if (MAP_FAILED == x->x_buf[i]) { ZL_PERROR("v4l: mmap"); return -1; } } ZL_LOG("v4l: mapped %d buffers", x->x_api.v4l2.requestbuffers.count ); for (i = 0; i < x->x_nbbuffers; i++) { x->x_api.v4l2.buffer[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; x->x_api.v4l2.buffer[i].memory = V4L2_MEMORY_MMAP; x->x_api.v4l2.buffer[i].index = i; if (-1 == ioctl (x->x_tvfd, VIDIOC_QBUF, &x->x_api.v4l2.buffer[i])) { ZL_PERROR("v4l: error queing buffers"); return -1; } } ZL_LOG("v4l: queued %d buffers", x->x_api.v4l2.requestbuffers.count ); return 0; } /* This is just for info, since we're not exposing any ranges. For PDP it doesn't matter: if a control doesn't work, it's just ignored except for a log message. */ static bool v4l2_check_control(struct zl_v4l *x, int id) { struct v4l2_queryctrl ctrl = { .id = id }; if (-1 == ioctl(x->x_tvfd, VIDIOC_QUERYCTRL, &ctrl) || (ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { return false; } else if (x->x_debug) { const char *name = zl_v4l_control_name(ctrl.id); ZL_LOG("v4l: control %08x %s", ctrl.id, name); } return true; } static void v4l2_check_controls(struct zl_v4l *x) { #define ZL_V4L_CTRL(id) v4l2_check_control(x, V4L2_CID_##id); ZL_V4L_CTRL_LIST #undef ZL_V4L_CTRL } static void v4l2_open(struct zl_v4l *x, const char *name, bool start_thread) { int i; /* if already opened -> close */ if (x->x_initialized) zl_v4l_close(x); ZL_LOG("v4l: opening %s (V4L2)", name); x->x_v4l_api = V4L2; bzero(&x->x_api.v4l2, sizeof(x->x_api.v4l2)); x->x_device = name; if ((x->x_tvfd = open(name, O_RDWR)) < 0) { ZL_LOG("v4l: error: open %s: %s",name,strerror(errno)); perror(name); goto error; } /* Get capabilities */ typeof (x->x_api.v4l2.capability) *capability = &x->x_api.v4l2.capability; if (ioctl(x->x_tvfd, VIDIOC_QUERYCAP, capability) < 0) { perror("get capabilities"); goto error; } ZL_LOG("v4l: driver info: %s %d.%d.%d / %s @ %s", capability->driver, (capability->version >> 16) & 0xff, (capability->version >> 8) & 0xff, capability->version & 0xff, capability->card, capability->bus_info); /* Get inputs. */ for (i = 0; i < ZL_V4L_MAX_INPUT; i++) { x->x_api.v4l2.input[i].index = i; if (-1 == ioctl(x->x_tvfd, VIDIOC_ENUMINPUT, &x->x_api.v4l2.input[i])) { // perror("get inputs"); break; } else { ZL_LOG("v4l: input %d: %s", i, x->x_api.v4l2.input[i].name); } } if (x->x_debug) ZL_LOG("v4l: device has %d inputs", i); x->x_api.v4l2.ninputs = i; /* Set current input */ if ( x->x_api.v4l2.ninputs > 0 ) { if (ioctl(x->x_tvfd, VIDIOC_S_INPUT, &x->x_curinput) < 0) { ZL_PERROR("v4l: error: VIDIOC_S_INPUT"); ZL_LOG("v4l: cant switch to input %d",x->x_curinput); } else { ZL_LOG("v4l: switched to input %d", x->x_curinput); } } /* Get standards */ for (i = 0; i < ZL_V4L_MAX_NORM; i++) { x->x_api.v4l2.standard[i].index = i; if (-1 == ioctl(x->x_tvfd, VIDIOC_ENUMSTD, &x->x_api.v4l2.standard[i])) { // perror("get standards"); break; } else { ZL_LOG("v4l: standard %d : %s", i, x->x_api.v4l2.standard[i].name ); } } if (x->x_debug) ZL_LOG("v4l: device supports %d standards", i ); x->x_api.v4l2.nstandards = i; /* Set norm if available */ if ( x->x_api.v4l2.nstandards > 0 ) { if (ioctl(x->x_tvfd, VIDIOC_S_STD, &x->x_curstandard) < 0) { ZL_PERROR("v4l: error: VIDIOC_S_STD"); ZL_LOG("v4l: cant switch to standard %d",x->x_curstandard); } else { ZL_LOG("v4l: switched to standard %d", x->x_curstandard); } } /* Set frequency. */ if (x->x_freq > 0) { if (ioctl(x->x_tvfd, VIDIOC_S_FREQUENCY, &x->x_freq) < 0) perror ("couldn't set frequency :"); } /* formats */ int last_supported = -1; for (i = 0; i < ZL_V4L_MAX_FORMAT; i++) { x->x_api.v4l2.fmtdesc[i].index = i; x->x_api.v4l2.fmtdesc[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl(x->x_tvfd, VIDIOC_ENUM_FMT, &x->x_api.v4l2.fmtdesc[i])) { break; } else { if (v4l2_format_supported(x->x_api.v4l2.fmtdesc[i].pixelformat)) { last_supported = i; } ZL_LOG("v4l: format %d: %s", i, x->x_api.v4l2.fmtdesc[i].description ); } } if (x->x_debug) ZL_LOG("v4l: device supports %d formats", i ); x->x_api.v4l2.nfmtdescs = i; /* Use the current format as default and change some parameters. */ if ( x->x_api.v4l2.nfmtdescs > 0 ) { x->x_api.v4l2.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if ((i = ioctl(x->x_tvfd, VIDIOC_G_FMT, &x->x_api.v4l2.format)) < 0) { ZL_PERROR("v4l: error: VIDIOC_G_FMT"); zl_v4l_close_error(x); x->x_initialized = false; } if (last_supported >= 0) { x->x_curformat = last_supported; } ZL_LOG("v4l: setting FOURCC format %08x", x->x_curformat); v4l2_set_format(x, x->x_curformat); } else { ZL_LOG("v4l: error : no available formats : closing..." ); zl_v4l_close_error(x); x->x_initialized = false; return; } /* Get controls */ v4l2_check_controls(x); /* Configure buffers */ if ( v4l2_init_mmap(x) < 0 ) { ZL_LOG("v4l: error : couldn't initialize memory mapping : closing..." ); zl_v4l_close_error(x); x->x_initialized = false; return; } x->x_initialized=true; ZL_LOG("v4l: device initialized" ); /* Set framerate: tpf = 1 / fps */ v4l2_set_timeperframe(x, x->x_fps_den, x->x_fps_num); /* Reset pointers */ x->x_frame_wr = 0; x->x_frame_rd = 0; /* Create thread if requested. */ if (start_thread) { x->x_continue_thread = 1; sem_init(&x->x_frame_ready_sem, 0, 0); pthread_create(&x->x_thread_id, 0, v4l_thread, x); ZL_LOG("v4l: created thread: %p", (void*)x->x_thread_id ); } return; error: zl_v4l_close_error(x); return; } const char *v4l2_card(struct zl_v4l *x) { if (!x->x_initialized) return "none"; return (const char*)x->x_api.v4l2.capability.card; } static void v4l2_input(struct zl_v4l *x, int inpt) { if (!x->x_initialized) { ZL_LOG("v4l: cannot set input: no device opened "); return; } if ((inpt < 0) || (inpt >= x->x_api.v4l2.ninputs)) { ZL_LOG("v4l:input number %d out of range", inpt); return; } if (x->x_initialized) { zl_v4l_close(x); x->x_curinput = inpt; zl_v4l_reopen(x); } } static void v4l2_standard(struct zl_v4l *x, int standrd) { if (!x->x_initialized){ ZL_LOG("v4l: cannot set standard: no device opened "); return; } if ( ( standrd < 0 ) || ( standrd >= x->x_api.v4l2.nstandards ) ) { ZL_LOG("v4l: standard number %d out of range", standrd ); return; } if (x->x_initialized){ zl_v4l_close(x); x->x_curstandard = standrd; zl_v4l_reopen(x); } } #else // !HAVE_V4L2 static void v4l2_unmap(struct zl_v4l *x) {} static void v4l2_capture_frame(struct zl_v4l *x) {} #endif /* Shared */ static void v4l_notify_frame(struct zl_v4l *x) { /* Check if reader is keeping up. */ int nb_frames = x->x_nbbuffers; sem_getvalue(&x->x_frame_ready_sem, &nb_frames); if (nb_frames >= x->x_nbbuffers) { /* Don't let semaphore grow larger than buffer size. For PDP: this happens when Pd thread doesn't bang fast enough. */ // ZL_LOG("v4l: dropped frame"); } else { /* Notify there's a new frame. */ sem_post(&x->x_frame_ready_sem); // ZL_LOG("sem_post: %d", x->x_frame_wr); /* Increment write pointer */ x->x_frame_wr = (x->x_frame_wr + 1) % x->x_nbbuffers; } } int zl_v4l_close(struct zl_v4l *x) { /* Terminate thread if there is one */ if (x->x_continue_thread) { if (x->x_debug) ZL_LOG("v4l: stopping thread"); void *dummy; x->x_continue_thread = 0; pthread_join (x->x_thread_id, &dummy); sem_destroy(&x->x_frame_ready_sem); } /* Unmap memory */ switch (x->x_v4l_api) { #ifdef HAVE_V4L1 case V4L1: v4l1_unmap(x); break; #endif case V4L2: v4l2_unmap(x); break; } /* Close device. */ if (x->x_tvfd >= 0) { ZL_LOG("v4l: closing fd %d", x->x_tvfd); close(x->x_tvfd); x->x_tvfd = -1; } /* Make sure there's no lingering V4L info. */ x->x_initialized = false; bzero(&x->x_api, sizeof(x->x_api)); return 0; } void zl_v4l_close_error(struct zl_v4l *x) { zl_v4l_close(x); } void zl_v4l_capture_frame(struct zl_v4l *x) { switch(x->x_v4l_api) { #ifdef HAVE_V4L1 case V4L1: v4l1_capture_frame(x); break; #endif case V4L2: v4l2_capture_frame(x); break; } } static void *v4l_thread(void *_x) { struct zl_v4l *x = _x; switch(x->x_v4l_api) { #ifdef HAVE_V4L1 case V4L1: v4l1_thread_loop(x); break; #endif case V4L2: v4l2_thread_loop(x); break; } x->x_continue_thread = 0; // make sure we won't wait for thread return NULL; } #define NOT_SUPPORTED() if(0){} void zl_v4l_pwc_agc(struct zl_v4l *x, float gain __attribute__((__unused__))) { switch(x->x_v4l_api) { #ifdef HAVE_V4L1 case V4L1: return v4l1_pwc_agc(x, gain); #endif default: NOT_SUPPORTED(); } } void zl_v4l_reopen(struct zl_v4l *x) { zl_v4l_open(x, x->x_device, x->x_start_thread); } /* The auto-open is not implemented in this file. See pdp_v4l.c */ void zl_v4l_open_if_necessary(struct zl_v4l *x) { if (!x->x_initialized) zl_v4l_reopen(x); } const char *zl_v4l_card(struct zl_v4l *x) { switch(x->x_v4l_api) { case V4L2: return v4l2_card(x); default: NOT_SUPPORTED(); return "unknown"; } } const char *zl_v4l_control_name(int id) { const char *name; switch(id) { #define ZL_V4L_CTRL(id) case V4L2_CID_##id: name = #id; break; ZL_V4L_CTRL_LIST #undef ZL_V4L_CTRL default: name = "unknown"; } return name; } void zl_v4l_set_fps(struct zl_v4l *x, int fps_num, int fps_den) { /* Needs re-open. Can't set when capture is on. */ zl_v4l_close(x); x->x_fps_num = fps_num; x->x_fps_den = fps_den; zl_v4l_reopen(x); } void zl_v4l_open(struct zl_v4l *x, const char *name, bool start_thread) { x->x_device = name; v4l2_open(x, name, start_thread); if (!x->x_initialized) { #ifdef HAVE_V4L1 v4l1_open(x, name); #endif } } void zl_v4l_input(struct zl_v4l *x, int inpt) { switch(x->x_v4l_api) { case V4L2: v4l2_input(x, inpt); break; default: NOT_SUPPORTED(); } } void zl_v4l_standard(struct zl_v4l *x, int standrd) { switch(x->x_v4l_api) { case V4L2: v4l2_standard(x, standrd); break; default: NOT_SUPPORTED(); } } void zl_v4l_freq(struct zl_v4l *x, int freq /* 1/16th of MHz */) { if (!x->x_initialized) { ZL_LOG("v4l: cannot set frequency: no device opened "); return; } x->x_freq = freq; if (x->x_freq <= 0) { ZL_LOG("v4l: freq needs to be positive"); return; } switch(x->x_v4l_api) { #ifdef HAVE_V4l1 case V4L1: if (ioctl(x->x_tvfd, VIDIOCSFREQ, &x->x_freq) < 0) { perror("couldn't set frequency:"); return; } break; #endif #ifdef HAVE_V4L2 case V4L2: if (ioctl(x->x_tvfd, VIDIOC_S_FREQUENCY, &x->x_freq) < 0) { perror("couldn't set frequency:"); return; } break; #endif } ZL_LOG("v4l: tuner frequency set to: %f MHz", ((float)freq) / 16.0f); } void zl_v4l_next(struct zl_v4l *x, unsigned char **newimage, int block) { *newimage = NULL; /* If you want auto-open, call zl_v4l_open_if_necessary() before _next () */ if (!(x->x_initialized)) return; if (!block) { /* do nothing if there is no frame ready */ int val = 0; sem_getvalue(&x->x_frame_ready_sem, &val); if (val == 0) return; /* Because of the previous check, next does not block. */ } sem_wait(&x->x_frame_ready_sem); // ZL_LOG("sem_wait: %d", x->x_frame_rd); /* Get the raw data + set the fourcc tag. */ switch(x->x_v4l_api) { #ifdef HAVE_V4L1 case V4L1: *newimage = v4l1_image_dequeue(x); break; #endif case V4L2: *newimage = v4l2_image_dequeue(x); break; } /* Get ready for next frame */ x->x_frame_rd = (x->x_frame_rd + 1) % x->x_nbbuffers; } void zl_v4l_get_format(struct zl_v4l *x, unsigned int *fourcc, unsigned int *width, unsigned int *height) { *width = x->x_width; *height = x->x_height; *fourcc = 0; switch(x->x_v4l_api) { #ifdef HAVE_V4L1 case V4L1: switch (x->x_api.v4l1.palette) { case VIDEO_PALETTE_YUV420P: *fourcc = V4L2_PIX_FMT_YUV420; break; case VIDEO_PALETTE_RGB24: *fourcc = V4L2_PIX_FMT_RGB24; break; case VIDEO_PALETTE_RGB32: *fourcc = V4L2_PIX_FMT_RGB32; break; case VIDEO_PALETTE_YUV422: *fourcc = V4L2_PIX_FMT_YUYV; break; default: break; } break; #endif #ifdef HAVE_V4L2 case V4L2: *fourcc = x->x_api.v4l2.format.fmt.pix.pixelformat; break; #endif } } /* In PDP, setting the attribute re-opens the connection if it's already open. As a quick hack to avoid duplication these macros go around the setter to do the conditional open/close. */ #define MEMBER_TYPE(member) typeof(((struct zl_v4l *)NULL)->x_##member) #define DEFINE_SETTER_1(member) \ void zl_v4l_set_##member(struct zl_v4l *x, MEMBER_TYPE(member) value) { \ if (value == x->x_##member) return; \ bool do_re = x->x_initialized; \ if (do_re) zl_v4l_close(x); \ x->x_##member = value; \ if (do_re) zl_v4l_reopen(x); \ } DEFINE_SETTER_1(norm) DEFINE_SETTER_1(format) DEFINE_SETTER_1(channel) static DEFINE_SETTER_1(nbbuffers_wanted) void zl_v4l_set_dim(struct zl_v4l *x, unsigned int w, unsigned int h) { if ((w == x->x_width) && (h == x->x_height)) return; bool do_re = x->x_initialized; if (do_re) zl_v4l_close(x); x->x_width = w; x->x_height = h; if (do_re) zl_v4l_reopen(x); } void zl_v4l_set_nb_buf(struct zl_v4l *x, unsigned int nb_buf) { if (nb_buf > ZL_V4L_MAX_BUFFERS) nb_buf = ZL_V4L_MAX_BUFFERS; if (nb_buf < 2) nb_buf = 2; // doesn't make much sense to take less zl_v4l_set_nbbuffers_wanted(x, nb_buf); } void zl_v4l_init(struct zl_v4l *x, bool start_thread) { x->x_initialized = false; x->x_tvfd = -1; x->x_format = 0; // V4L1: unify this x->x_curinput = 0; x->x_curstandard = 0; x->x_curformat = 0; x->x_freq = -1; x->x_frame_wr = 0; x->x_frame_rd = 0; x->x_continue_thread = 0; x->x_width = 320; x->x_height = 240; x->x_device = "/dev/video0"; x->x_channel = 0; x->x_norm = 0; // PAL x->x_freq = -1; //don't set freq by default x->x_fps_num = 30; x->x_fps_den = 1; #if 0 // FIXME: not used x->x_minwidth = pdp_imageproc_legalwidth(0); x->x_maxwidth = pdp_imageproc_legalwidth_round_down(0x7fffffff); x->x_minheight = pdp_imageproc_legalheight(0); x->x_maxheight = pdp_imageproc_legalheight_round_down(0x7fffffff); #endif x->x_start_thread = start_thread; x->x_debug = 1; /* Not sure if this is still necessary. */ x->x_nbbuffers_wanted = 2; } struct zl_v4l *zl_v4l_new(bool start_thread) { struct zl_v4l *x = malloc(sizeof(*x)); zl_v4l_init(x, start_thread); return x; } pdp-0.14.1+darcs20180201/system/zl/v4l.h000066400000000000000000000146461266045153600171400ustar00rootroot00000000000000#ifndef _ZL_V4L_ #define _ZL_V4L_ #include "zl/config.h" #include #include #include // FIXME // #define HAVE_V4L1 #define HAVE_V4L2 #ifdef HAVE_V4L2 #include #else /* Doesn't matter, as long as they are unique. */ #define V4L2_PIX_FMT_YUV420 1 #define V4L2_PIX_FMT_RGB24 2 #define V4L2_PIX_FMT_RGB32 3 #define V4L2_PIX_FMT_YUYV 4 #define V4L2_PIX_FMT_UYVY 5 #define V4L2_PIX_FMT_PAC207 6 #define v4l2_fourcc(...) 7 #endif #ifdef HAVE_V4L1 #ifdef HAVE_LIBV4L1_VIDEODEV_H # include #else //#warning trying to use deprecated V4L-1 API # include #endif #endif /* This was on 8 in Yves' code. Not sure why. 2 is much better, so I leave it configurable, but default set to 2. */ #define ZL_V4L_MAX_BUFFERS 8 #define ZL_V4L_DEVICENO 0 #define ZL_V4L_NBUF 2 #define ZL_V4L_COMPOSITEIN 1 #define ZL_V4L_MAX_INPUT 16 #define ZL_V4L_MAX_NORM 16 #define ZL_V4L_MAX_FORMAT 32 #define ZL_V4L_MAX_CTRL 32 struct zl_v4l { unsigned long x_format; // 0 means autodetect unsigned long x_channel; unsigned long x_norm; bool x_initialized; bool x_open_retry; bool x_start_thread; // start thread on re-open unsigned int x_width; unsigned int x_height; int x_freq; int x_tvfd; int x_frame_wr; // capture thread writes this frame int x_frame_rd; // main thread reads this frame int x_skipnext; int x_mytopmargin, x_mybottommargin; int x_myleftmargin, x_myrightmargin; int x_debug; /* V4L only uses a single mapped region which has 2 halves. V4L2 uses separately mapped buffers. */ int x_nbbuffers_wanted; int x_nbbuffers; unsigned char *x_buf[ZL_V4L_MAX_BUFFERS]; //int x_pdp_image_type; pthread_t x_thread_id; int x_continue_thread; sem_t x_frame_ready_sem; int x_curinput; int x_curstandard; int x_curformat; int x_fps_num; int x_fps_den; /* FIXME: Against ZL principles to keep this external pointer here, so make sure it is an object with infinite extent. */ const char *x_device; /* This uses V4L2 format descs, also for the V4L1 */ unsigned long fourcc; enum { #ifdef HAVE_V4L1 V4L1, #endif #ifdef HAVE_V4L2 V4L2, #endif } x_v4l_api; union { #ifdef HAVE_V4L1 struct { int palette; struct video_tuner tuner; struct video_picture picture; struct video_buffer buffer; struct video_capability cap; struct video_channel channel; struct video_audio audio; struct video_mbuf mbuf; struct video_mmap mmap[ZL_V4L_NBUF]; struct video_window win; } v4l1; #endif #ifdef HAVE_V4L2 struct { int ninputs; int nstandards; int nfmtdescs; struct v4l2_capability capability; struct v4l2_input input[ZL_V4L_MAX_INPUT]; struct v4l2_standard standard[ZL_V4L_MAX_NORM]; struct v4l2_fmtdesc fmtdesc[ZL_V4L_MAX_FORMAT]; struct v4l2_streamparm streamparam; // struct v4l2_queryctrl queryctrl[ZL_V4L_MAX_CTRL]; // struct v4l2_queryctrl queryctrl_priv[ZL_V4L_MAX_CTRL]; struct v4l2_buffer buffer[ZL_V4L_MAX_BUFFERS]; struct v4l2_format format; struct v4l2_requestbuffers requestbuffers; } v4l2; #endif } x_api; }; int zl_v4l_close(struct zl_v4l *x); void zl_v4l_close_error(struct zl_v4l *x); void zl_v4l_control(struct zl_v4l *x, int id, int value); void zl_v4l_pwc_agc(struct zl_v4l *x, float gain); void zl_v4l_open(struct zl_v4l *x, const char *name, bool start_thread); void zl_v4l_reopen(struct zl_v4l *x); void zl_v4l_open_if_necessary(struct zl_v4l *x); void zl_v4l_input(struct zl_v4l *x, int inpt); void zl_v4l_standard(struct zl_v4l *x, int standrd); void zl_v4l_freq(struct zl_v4l *x, int freq /* 1/16th of MHz */); void zl_v4l_next(struct zl_v4l *x, unsigned char **newimage, int block); void zl_v4l_get_format(struct zl_v4l *x, unsigned int *fourcc, unsigned int *width, unsigned int *height); void zl_v4l_set_dim(struct zl_v4l *x, unsigned int w, unsigned int h); void zl_v4l_set_norm(struct zl_v4l *x, unsigned long norm); void zl_v4l_set_format(struct zl_v4l *x, unsigned long format); void zl_v4l_set_channel(struct zl_v4l *x, unsigned long channel); void zl_v4l_set_fps(struct zl_v4l *x, int num, int den); void zl_v4l_init(struct zl_v4l *x, bool start_thread); const char *zl_v4l_card(struct zl_v4l *x); const char *zl_v4l_control_name(int id); /* Useful for abstracting over symbolic names. */ #define ZL_V4L_CTRL_LIST \ ZL_V4L_CTRL(BRIGHTNESS) \ ZL_V4L_CTRL(CONTRAST) \ ZL_V4L_CTRL(SATURATION) \ ZL_V4L_CTRL(HUE) \ ZL_V4L_CTRL(AUDIO_VOLUME) \ ZL_V4L_CTRL(AUDIO_BALANCE) \ ZL_V4L_CTRL(AUDIO_BASS) \ ZL_V4L_CTRL(AUDIO_TREBLE) \ ZL_V4L_CTRL(AUDIO_MUTE) \ ZL_V4L_CTRL(AUDIO_LOUDNESS) \ ZL_V4L_CTRL(BLACK_LEVEL) \ ZL_V4L_CTRL(AUTO_WHITE_BALANCE) \ ZL_V4L_CTRL(DO_WHITE_BALANCE) \ ZL_V4L_CTRL(RED_BALANCE) \ ZL_V4L_CTRL(BLUE_BALANCE) \ ZL_V4L_CTRL(GAMMA) \ ZL_V4L_CTRL(EXPOSURE) \ ZL_V4L_CTRL(AUTOGAIN) \ ZL_V4L_CTRL(GAIN) \ ZL_V4L_CTRL(HFLIP) \ ZL_V4L_CTRL(VFLIP) \ ZL_V4L_CTRL(POWER_LINE_FREQUENCY) \ ZL_V4L_CTRL(HUE_AUTO) \ ZL_V4L_CTRL(WHITE_BALANCE_TEMPERATURE) \ ZL_V4L_CTRL(SHARPNESS) \ ZL_V4L_CTRL(BACKLIGHT_COMPENSATION) \ ZL_V4L_CTRL(CHROMA_AGC) \ ZL_V4L_CTRL(COLOR_KILLER) \ ZL_V4L_CTRL(COLORFX) \ ZL_V4L_CTRL(AUTOBRIGHTNESS) \ ZL_V4L_CTRL(BAND_STOP_FILTER) \ ZL_V4L_CTRL(EXPOSURE_AUTO) \ ZL_V4L_CTRL(EXPOSURE_ABSOLUTE) \ ZL_V4L_CTRL(EXPOSURE_AUTO_PRIORITY) \ ZL_V4L_CTRL(PAN_RELATIVE) \ ZL_V4L_CTRL(TILT_RELATIVE) \ ZL_V4L_CTRL(PAN_RESET) \ ZL_V4L_CTRL(TILT_RESET) \ ZL_V4L_CTRL(PAN_ABSOLUTE) \ ZL_V4L_CTRL(TILT_ABSOLUTE) \ ZL_V4L_CTRL(FOCUS_ABSOLUTE) \ ZL_V4L_CTRL(FOCUS_RELATIVE) \ ZL_V4L_CTRL(FOCUS_AUTO) \ ZL_V4L_CTRL(ZOOM_ABSOLUTE) \ ZL_V4L_CTRL(ZOOM_RELATIVE) \ ZL_V4L_CTRL(ZOOM_CONTINUOUS) \ ZL_V4L_CTRL(PRIVACY) struct zl_v4l *zl_v4l_new(bool start_thread); #define ZL_V4L_CTRL_LIST_REMOVED \ ZL_V4L_CTRL(HCENTER) \ ZL_V4L_CTRL(VCENTER) \ #endif pdp-0.14.1+darcs20180201/system/zl/xdisplay.api000066400000000000000000000003401266045153600205740ustar00rootroot00000000000000/* -*- c -*- */ /* cons / des */ FUN(void, free) END /* windows and events */ FUN(void, register_window) ARG(zl_xwindow_p, w) END FUN(void, unregister_window) ARG(zl_xwindow_p, w) END FUN(void, route_events) END pdp-0.14.1+darcs20180201/system/zl/xv.api000066400000000000000000000014751266045153600174060ustar00rootroot00000000000000/* Abstract API definition. See also xv.h Rationale: Since zl is to be wrapped easily in different languages, it makes sense to make that process as easy as possible, avoiding a C parsing step. The forms below can easily be manipulated using the C preprocessor to generate declarations and wrappers. */ /* Cons / Des */ FUN(void, init) ARG(int, fourcc) END FUN(void, free) END FUN(void, cleanup) END /* open an xv port (and create XvImage) */ FUN(int, open_on_display) ARG(zl_xdisplay_p,d) ARG(int, adaptor) END /* close xv port (and delete XvImage */ FUN(void, close) END /* get XvImage data buffer */ FUN(void_p, image_data) ARG(zl_xwindow_p, xwin) ARG(uint, width) ARG(uint, height) END /* display the XvImage */ FUN(void, image_display) ARG(zl_xwindow_p, xwin) END pdp-0.14.1+darcs20180201/system/zl/xv.c000066400000000000000000000214761266045153600170620ustar00rootroot00000000000000/* * Pure Data Packet system module. - x window glue code (fairly tied to pd and pf) * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ // this code is fairly tied to pd and pf. serves mainly as reusable glue code // for pf_xv, pf_glx, pf_3d_windowcontext, ... #include #include #include // Note sure why this had to be defined.. #define PRIVATE //#include //#include //#include //#include #include "xwindow.h" #include "xv.h" #define D if(1) /************************************* XV ************************************/ /* XvImage image. */ static void zl_xv_destroy_xvimage(zl_xv_p xvid); static void zl_xv_create_xvimage(zl_xv_p xvid, int width, int height); // static void zl_xv_get_dims(zl_xv_p xvid, unsigned int *w, unsigned int *h); /* this was a local function. */ static int errors; static int error_handler(Display __attribute__((unused)) *dpy, XErrorEvent __attribute__((unused)) *e){ errors++; return 0; } static void zl_xv_create_xvimage(zl_xv_p xvid, int width, int height) { // int i; long size; errors = 0; xvid->width = width; xvid->height = height; size = (xvid->width * xvid->height + (((xvid->width>>1)*(xvid->height>>1))<<1)); // don't use shared memory if (!xvid->shm){ no_shm: xvid->data = (unsigned char *)malloc(size + 4); // 4 bytes extra to get word size buffer for word bitflip //for (i=0; idata[i] = i; /* fprintf(stderr, "XvCreateImage(%p,%08x,%08x,%p,%d,%d)", xvid->xdpy->dpy, xvid->xv_port, xvid->xv_format, (char *)xvid->data, xvid->width, xvid->height); */ xvid->xvi = XvCreateImage(xvid->xdpy->dpy, xvid->xv_port, xvid->xv_format, (char *)xvid->data, xvid->width, xvid->height); xvid->last_encoding = -1; if ((!xvid->xvi) || (!xvid->data)) fprintf (stderr, "zl_xv_create_xvimage: error creating xvimage"); return; } // try shared memory else { void *old_handler = XSetErrorHandler(error_handler); // ASSERT! if (xvid->shminfo) { fprintf(stderr, "have shminfo?"); exit(1); } xvid->shminfo = malloc(sizeof(XShmSegmentInfo)); memset(xvid->shminfo, 0, sizeof(XShmSegmentInfo)); /* fprintf(stderr, "XvShmCreateImage(%p,%08x,%08x,%08x,%d,%d,%p)", xvid->xdpy->dpy, xvid->xv_port, xvid->xv_format, 0, xvid->width, xvid->height, xvid->shminfo); */ xvid->xvi = XvShmCreateImage(xvid->xdpy->dpy, xvid->xv_port, xvid->xv_format, 0, xvid->width, xvid->height, xvid->shminfo); if (!xvid->xvi) goto shm_error; if (-1 == (xvid->shminfo->shmid = shmget(IPC_PRIVATE, xvid->xvi->data_size, IPC_CREAT | 0777))) goto shm_error; if (((void *)-1) == (xvid->shminfo->shmaddr = (char *) shmat(xvid->shminfo->shmid, 0, 0))) goto shm_error; xvid->data = xvid->xvi->data = xvid->shminfo->shmaddr; xvid->shminfo->readOnly = False; XShmAttach(xvid->xdpy->dpy, xvid->shminfo); XSync(xvid->xdpy->dpy, False); if (errors) goto shm_error; shmctl(xvid->shminfo->shmid, IPC_RMID, 0); XSetErrorHandler(old_handler); D fprintf(stderr, "xv: using shared memory\n"); return; // ok shm_error: D fprintf(stderr, "xv: can't use shared memory\n"); zl_xv_destroy_xvimage(xvid); XSetErrorHandler(old_handler); xvid->shm = 0; goto no_shm; } } static void zl_xv_destroy_xvimage(zl_xv_p xvid) { if (xvid->xvi) XFree(xvid->xvi); if (xvid->shminfo){ if ((void *)-1 != xvid->shminfo->shmaddr && NULL != xvid->shminfo->shmaddr) shmdt(xvid->shminfo->shmaddr); free(xvid->shminfo); } else { if (xvid->data) free(xvid->data); } xvid->shminfo = 0; xvid->xvi = 0; xvid->data = 0; } /* display */ void zl_xv_image_display(zl_xv_p xvid, zl_xwindow_p xwin){ if (!xvid->initialized) return; /* set aspect ratio here if necessary currently we don't : client responsability */ int a_x = 0; int a_y = 0; int b_x = xvid->width; int b_y = xvid->height; // int offset = 0; int w_w = xwin->winwidth; int w_h = xwin->winheight; D fprintf(stderr, "%d %d %d %d %d %d\n", a_x, a_y, b_x, b_y, w_w, w_h); if (xvid->shminfo){ XvShmPutImage(xvid->xdpy->dpy,xvid->xv_port, xwin->win,xwin->gc,xvid->xvi, a_x, a_y, b_x, b_y, 0,0, w_w, w_h, True); } else { XvPutImage(xvid->xdpy->dpy,xvid->xv_port, xwin->win, xwin->gc, xvid->xvi, a_x, a_y, b_x, b_y, 0,0, w_w, w_h); } XFlush(xvid->xdpy->dpy); } void *zl_xv_image_data(zl_xv_p xvid, zl_xwindow_p __attribute__((unused)) xwin, unsigned int width, unsigned int height){ if (!xvid->initialized) return 0; /* check if xvimage needs to be recreated */ if ((width != xvid->width) || (height != xvid->height)){ zl_xv_destroy_xvimage(xvid); zl_xv_create_xvimage(xvid, width, height); } return xvid->data; } void zl_xv_close(zl_xv_p xvid) { if (xvid->initialized){ if (xvid->xvi) zl_xv_destroy_xvimage(xvid); XvUngrabPort(xvid->xdpy->dpy, xvid->xv_port, CurrentTime); xvid->xv_port = 0; xvid->xdpy = 0; xvid->last_encoding = -1; xvid->initialized = 0; } } void zl_xv_cleanup(zl_xv_p xvid) { // close xv port (and delete XvImage) zl_xv_close(xvid); // no more dynamic data to free } void zl_xv_free(zl_xv_p xvid){ zl_xv_cleanup(xvid); free(xvid); } void zl_xv_init(zl_xv_p xvid, int format) { xvid->xdpy = 0; // xvid->xv_format = FOURCC_I420; // used to be FOURCC_YV12. veejay compat. // xvid->xv_format = FOURCC_YV12; // PDP uses this // xvid->xv_format = 0x32595559; // Microsoft webcam hack xvid->xv_format = format; xvid->xv_port = 0; xvid->shm = 1; // try to use shm //xvid->shm = 0; // don't xvid->shminfo = 0; xvid->width = 320; xvid->height = 240; xvid->data = 0; xvid->xvi = 0; xvid->initialized = 0; xvid->last_encoding = -1; } zl_xv_p zl_xv_new(int format) { zl_xv_p xvid = malloc(sizeof(*xvid)); zl_xv_init(xvid, format); return xvid; } int zl_xv_open_on_display(zl_xv_p xvid, zl_xdisplay_p d, int adaptor_start) { unsigned int ver, rel, req, ev, err, i, j; unsigned int adaptors; // int formats; XvAdaptorInfo *ai; if (xvid->initialized) return 1; if (!d) return 0; xvid->xdpy = d; if (Success != XvQueryExtension(xvid->xdpy->dpy, &ver,&rel,&req,&ev,&err)) return 0; /* find + lock port */ if (Success != XvQueryAdaptors(xvid->xdpy->dpy, DefaultRootWindow(xvid->xdpy->dpy), &adaptors,&ai)) return 0; for (i = adaptor_start; i < adaptors; i++) { if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) { for (j=0; j < ai[i].num_ports; j++){ if (Success != XvGrabPort(xvid->xdpy->dpy, ai[i].base_id+j,CurrentTime)) { D fprintf(stderr,"xv: Xv port %ld on adapter %d: is busy, skipping\n", ai[i].base_id+j, i); } else { xvid->xv_port = ai[i].base_id + j; goto breakout; } } } } breakout: XFree(ai); if (0 == xvid->xv_port) return 0; D fprintf(stderr, "xv: grabbed port %d on adaptor %d\n", xvid->xv_port, i); xvid->initialized = 1; zl_xv_create_xvimage(xvid, xvid->width, xvid->height); return 1; } //static void zl_xv_get_dims(zl_xv_p xvid, unsigned int *w, unsigned int *h) { // if (w) *w = xvid->width; // if (w) *h = xvid->height; //} pdp-0.14.1+darcs20180201/system/zl/xv.h000066400000000000000000000036731266045153600170660ustar00rootroot00000000000000 /* * Pure Data Packet header file: xwindow glue code * Copyright (c) by Tom Schouten * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _zl_xv_h_ #define _zl_xv_h_ struct zl_xv; typedef struct zl_xv zl_xv; typedef struct zl_xv *zl_xv_p; #ifndef PRIVATE #include "xwindow.h" #else // x stuff #include #include #include #include #include #include #include "config.h" #include "xwindow.h" /* xv class */ typedef void zl_xv_class; struct zl_xv { zl_xv_class *type; zl_xdisplay_p xdpy; int xv_format; int xv_port; XvImage *xvi; XShmSegmentInfo *shminfo; // if null, not using shm int shm; // try shm next time void *data; unsigned int width; unsigned int height; int last_encoding; int initialized; }; #endif zl_xv_p zl_xv_new(int fourcc); // image formats for communication with the X Server #define FOURCC_YV12 0x32315659 /* YV12 YUV420P */ #define FOURCC_YUV2 0x32595559 /* YUV2 YUV422 */ #define FOURCC_I420 0x30323449 /* I420 Intel Indeo 4 */ #define FUN(t,f) t zl_xv_##f(zl_xv_p x #define ARG(t,a) , t a #define END ); #include "zl/xv.api" #undef FUN #undef ARG #undef END #endif pdp-0.14.1+darcs20180201/system/zl/xwindow.api000066400000000000000000000036541266045153600204510ustar00rootroot00000000000000/* cons / des */ FUN(void, init) END FUN(void, cleanup) END FUN(void, free) END /* move the pointer */ FUN(void, warppointer) ARG(int, x) ARG(int, y) END FUN(void, warppointer_rel) ARG(float,x) ARG(float,y) END FUN(void,fullscreen) END FUN(void,resize) ARG(int,width) ARG(int,height) END FUN(void, moveresize) ARG(int, xoffset) ARG(int, yoffset) ARG(int, width) ARG(int, height) END FUN(void, move) ARG(int, xoffset) ARG(int, yoffset) END /* fill a tile of the screen */ FUN(void, tile) ARG(int, x_nb_tiles) ARG(int, y_nb_tiles) ARG(int, tile_x) ARG(int, tile_y) END /* enable/disable cursor */ FUN(void, cursor) ARG(int, flag) END /* create zl_xwindow. return code != NULL on succes */ FUN(int, config) ARG(zl_xdisplay_p, d) END /* close window */ FUN(void, close) END /* set title */ FUN(void, title) ARG(char_p, title) END /* clear event queue */ FUN(void, drop_events) END /* Handle events. X11 events are collected through the display connect, which is shared across multiple windows. To collect events for a single window, we perform two operations: flush the display connection's event buffer and sort it into lists for each window, and then allow this list to be queried by the user. To abstract the storage of this list, a callback mechanism is used. */ FUN(void, queue_event) ARG(XEvent_p, e) END FUN(void, for_events) ARG(zl_zwindow_event_fn, handle) ARG(void_p, context) END /* Like zl_xwindow_for_events, but using a state machine to parse the events into something more useful. This is inherited from PDP, but uses just const strings and numbers. */ FUN(void, for_parsed_events) ARG(zl_receiver, handle) ARG(void_p, context) END FUN(int, winwidth) END FUN(int, winheight) END FUN(int, winxoffset) END FUN(int, winyoffset) END /* delegates to zl_xwdiwsplay_route_events() */ FUN(void, route_events) END pdp-0.14.1+darcs20180201/system/zl/xwindow.c000066400000000000000000000466311266045153600201240ustar00rootroot00000000000000/* * Pure Data Packet system module. - x window glue code (fairly tied to pd and pf) * Copyright (c) by Tom Schouten * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as publishd 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* TODO: - rename to zl_ prefix - merge with libprim - merge with pdp_xv */ // this code is fairly tied to pd and pf. serves mainly as reusable glue code // for pf_xv, pf_glx, pf_3d_windowcontext, ... #include //#include // no longer depending on pf //#include //#include //#include #include "config.h" #include #include #include #define PRIVATE #include "xwindow.h" #define D if(0) // TODO: clean this up #define ASSERT(x) \ if (!(x)) { \ fprintf(stderr, "%s:%d: ASSERT(%s)\n", \ __FILE__, __LINE__, #x); \ exit(1); \ } \ /************************************* ZL_XDISPLAY ************************************/ /* For use in libprim */ #ifdef HAVE_LEAF #include static int zl_xdisplay_write(zl_xdisplay *x, port *p) { return port_printf(p, "#", x); } zl_xdisplay_class *zl_xdisplay_type(void) { static zl_xdisplay_class *type = NULL; if (!type) { type = calloc(1, sizeof(*type)); leaf_class_init((leaf_class*)type, (leaf_free_m)zl_xdisplay_free, (leaf_write_m)zl_xdisplay_write); } return type; } static int zl_xwindow_write(zl_xdisplay *x, port *p) { return port_printf(p, "#", x); } zl_xwindow_class *zl_xwindow_type(void) { static zl_xwindow_class *type = NULL; if (!type) { type = calloc(1, sizeof(*type)); leaf_class_init((leaf_class*)type, (leaf_free_m)zl_xwindow_free, (leaf_write_m)zl_xwindow_write); } return type; } #else zl_xdisplay_class *zl_xdisplay_type(void) { return NULL; } zl_xwindow_class *zl_xwindow_type(void) { return NULL; } #endif int zl_xdisplay_errorhandler(Display __attribute__((unused)) *dpy, XErrorEvent __attribute__((unused)) *ev){ fprintf(stderr, "zl_xdisplay_errorhandler\n"); return 0xdeadf00d; } zl_xdisplay_p zl_xdisplay_new(const char *dpy_string) { zl_xdisplay_p d = malloc(sizeof(*d)); /* open display */ d->type = zl_xdisplay_type(); if (!(d->dpy = XOpenDisplay(dpy_string))) { ZL_LOG("x11: can't open display %s\n", dpy_string); free(d); return NULL; } else { //ZL_LOG("x11: open %s OK\n", dpy_string); } /* install error handler */ //XSetErrorHandler(&zl_xdisplay_errorhandler); d->windowlist = buf_new(16); d->screen = DefaultScreen(d->dpy); d->dragbutton = -1; D fprintf (stderr, "x11: using display %s\n", dpy_string); return d; } void zl_xdisplay_free(zl_xdisplay_p d) { XCloseDisplay(d->dpy); ASSERT(0 == d->windowlist->elements); // make sure there are no dangling zl_xwindow objects buf_free(d->windowlist); free(d); } /* some private members */ // static int _windowset_contains(zl_xdisplay_p d, zl_xwindow *w){ // return (buf_lookup(d->windowlist, w) >= 0); //} void zl_xdisplay_register_window(zl_xdisplay_p d, zl_xwindow_p w) { //pf_post("zl_xdisplay: registering window %p", w); buf_add_to_set(d->windowlist, w); //if (!_windowset_contains(d, w)) _windowset_add(d, w); } void zl_xdisplay_unregister_window(zl_xdisplay_p d, zl_xwindow_p w) { //pf_post("zl_xdisplay: unregistering window %p", w); buf_remove(d->windowlist, w); //if (_windowset_contains(d, w)) _windowset_remove(d, w); } // this reads all events from display and passes them on to client // just raw x events. client needs to parse events.. since this is // shared code, we keep it as simple as possible /* These are const strings to enable: - Identification by pointer using tag == ZL_DISPLAY_EV_XXX - Conversion to hashed symbol if target language has a symbol type */ void zl_xdisplay_route_events(zl_xdisplay_p d) { zl_xwindow_p w; int i; XEvent *e = 0; while (XPending(d->dpy)){ if (!e) e = malloc(sizeof(XEvent)); XNextEvent(d->dpy, e); // ZL_LOG("event %x", e); // find zl_xwindow instance for (i = 0; iwindowlist->elements; i++){ w = (zl_xwindow_p )d->windowlist->data[i]; if (w->win == e->xany.window){ if (e->type == ConfigureNotify){ w->winwidth = e->xconfigure.width; w->winheight = e->xconfigure.height; // ZL_LOG("ConfigureNotify %d %d\n", w->winwidth, w->winheight); /* Workaround for weird window sizes 42592x42379 that cause BadValue for XV. */ int max = 4000; if (w->winwidth > max) w->winwidth = max; if (w->winheight> max) w->winheight = max; } zl_xwindow_queue_event(w, e); // ZL_LOG("queue w:%x e:%x", w, e); e = 0; // moved } } } if (e) free(e); } /************************************* ZL_XWINDOW ************************************/ void zl_xwindow_queue_event(zl_xwindow_p x, XEvent *e){ buf_add(x->events, e); } void zl_xwindow_for_events(zl_xwindow_p xwin, zl_zwindow_event_fn handle, void *context) { void *e; while ((e = stack_pop(xwin->events))) { handle(context, e); free(e); } } /* Define the const tag strings. */ #define _ZL_XDISPLAY_EV_IMPL(name) zl_tag ZL_XDISPLAY_EV(name) = #name; ZL_XDISPLAY_EV_LIST(_ZL_XDISPLAY_EV_IMPL) /* There are probably better ways to do this, but we don't have access to the integer, only the tag, so it has to be a switch stmt. */ #define BUT_TAG_N(n, tagn, name) \ case Button##n: \ tagn = ZL_XDISPLAY_EV(name##n); \ break; #define BUT_TAG(ev, tagn, name) do { \ switch(ev) { \ default: \ ZL_FOR_BUTTON(BUT_TAG_N, tagn, name) \ }} while(0) /* Parse the XEvent to something more useful. The "useful" here means in the style used in PDP: tagged lists + button/drag tracking. */ void zl_xwindow_for_parsed_events(zl_xwindow_p xwin, zl_receiver r, void *c) { XEvent *e; /* set dim scalers */ const double inv_x = 1.0f / (double)(xwin->winwidth); const double inv_y = 1.0f / (double)(xwin->winheight); const int bmask = Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask; while ((e = stack_pop(xwin->events))) { // ZL_LOG("pop w:%x e:%x", xwin, e); /* handle event */ double x = inv_x * (double)e->xbutton.x; double y = inv_y * (double)e->xbutton.y; switch(e->type) { case ClientMessage: if ((Atom)e->xclient.data.l[0] == xwin->WM_DELETE_WINDOW) { zl_send(r, c, 0, ZL_XDISPLAY_EV(close)); } break; case KeyPress: case KeyRelease: zl_send(r, c, 1, e->type == KeyPress ? ZL_XDISPLAY_EV(keypress) : ZL_XDISPLAY_EV(keyrelease), (double)e->xkey.keycode); break; case ButtonPress: case ButtonRelease: { zl_tag tag; zl_tag tagn; if (e->type == ButtonPress) { tag = ZL_XDISPLAY_EV(press); BUT_TAG(e->xbutton.button, tagn, press); } else { tag = ZL_XDISPLAY_EV(release); BUT_TAG(e->xbutton.button, tagn, press); } /* send generic event */ zl_send(r, c, 2, tag, x, y); zl_send(r, c, 2, tagn, x, y); /* Keep track of button for MotionNotify. */ xwin->lastbut = e->xbutton.button; break; } case MotionNotify: { if (e->xbutton.state & bmask){ /* button is down: it is a drag event */ zl_tag tag = ZL_XDISPLAY_EV(drag); zl_tag tagn; BUT_TAG(xwin->lastbut, tagn, drag); zl_send(r, c, 2, tag, x, y); zl_send(r, c, 2, tagn, x, y); } else { zl_tag tag = ZL_XDISPLAY_EV(motion); zl_send(r, c, 2, tag, x, y); } break; } // FIXME: should these even get here? case UnmapNotify: { break; } case ConfigureNotify: { break; } default: ZL_LOG("unknown event type %d\n", e->type); break; } free(e); } } void zl_xwindow_drop_events(zl_xwindow_p x) { void handle(void __attribute__((unused)) *x, XEvent __attribute__((unused)) *e) {} zl_xwindow_for_events(x, handle, NULL); } void zl_xwindow_warppointer(zl_xwindow_p xwin, int x, int y) { if (xwin->initialized) { XWarpPointer(xwin->xdisplay->dpy, None, xwin->win, 0, 0, 0, 0, x, y); } } void zl_xwindow_warppointer_rel(zl_xwindow_p xwin, float x, float y) { if (xwin->initialized) { x *= xwin->winwidth; y *= xwin->winheight; zl_xwindow_warppointer(xwin, x, y); } } void zl_xwindow_overrideredirect(zl_xwindow_p xwin, int b) { XSetWindowAttributes new_attr; new_attr.override_redirect = b ? True : False; XChangeWindowAttributes(xwin->xdisplay->dpy, xwin->win, CWOverrideRedirect, &new_attr); //XFlush(xwin->xdisplay->dpy); } void zl_xwindow_moveresize(zl_xwindow_p xwin, int xoffset, int yoffset, int width, int height) { if ((width > 0) && (height > 0)){ xwin->winwidth = width; xwin->winheight = height; xwin->winxoffset = xoffset; xwin->winyoffset = yoffset; if (xwin->initialized){ XMoveResizeWindow(xwin->xdisplay->dpy, xwin->win, xoffset, yoffset, width, height); XFlush(xwin->xdisplay->dpy); } } } void zl_xwindow_fullscreen(zl_xwindow_p xwin) { XWindowAttributes rootwin_attr; /* hmm.. fullscreen and xlib the big puzzle.. if it looks like a hack it is a hack. */ if (xwin->initialized){ XGetWindowAttributes(xwin->xdisplay->dpy, RootWindow(xwin->xdisplay->dpy, xwin->xdisplay->screen), &rootwin_attr ); //zl_xwindow_overrideredirect(xwin, 0); zl_xwindow_moveresize(xwin, 0, 0, rootwin_attr.width, rootwin_attr.height); //zl_xwindow_overrideredirect(xwin, 1); //XRaiseWindow(xwin->xdisplay->dpy, xwin->win); //zl_xwindow_moveresize(xwin, 0, 0, rootwin_attr.width, rootwin_attr.height); //zl_xwindow_overrideredirect(xwin, 0); } } void zl_xwindow_tile(zl_xwindow_p xwin, int x_tiles, int y_tiles, int i, int j) { XWindowAttributes rootwin_attr; // XSetWindowAttributes new_attr; if (xwin->initialized){ int tile_w; int tile_h; XGetWindowAttributes(xwin->xdisplay->dpy, RootWindow(xwin->xdisplay->dpy, xwin->xdisplay->screen), &rootwin_attr ); tile_w = rootwin_attr.width / x_tiles; tile_h = rootwin_attr.height / y_tiles; xwin->winwidth = (x_tiles-1) ? rootwin_attr.width - (x_tiles-1)*tile_w : tile_w; xwin->winheight = (y_tiles-1) ? rootwin_attr.height - (y_tiles-1)*tile_h : tile_h; xwin->winxoffset = i * tile_w; xwin->winyoffset = j * tile_h; //new_attr.override_redirect = True; //XChangeWindowAttributes(xwin->xdisplay->dpy, xwin->win, CWOverrideRedirect, &new_attr ); XMoveResizeWindow(xwin->xdisplay->dpy, xwin->win, xwin->winxoffset, xwin->winyoffset, xwin->winwidth, xwin->winheight); } } /* resize window */ void zl_xwindow_resize(zl_xwindow_p xwin, int width, int height) { if ((width > 0) && (height > 0)){ xwin->winwidth = width; xwin->winheight = height; if (xwin->initialized){ XResizeWindow(xwin->xdisplay->dpy, xwin->win, width, height); XFlush(xwin->xdisplay->dpy); } } //_zl_xwindow_moveresize(xwin, xwin->winxoffset, xwin->winyoffset, width, height); } /* move window */ void zl_xwindow_move(zl_xwindow_p xwin, int xoffset, int yoffset) { zl_xwindow_moveresize(xwin, xoffset, yoffset, xwin->winwidth, xwin->winheight); } /* set an arbitrary cursor image */ void zl_xwindow_cursor_image(zl_xwindow_p xwin, char *data, int width, int height) { if (!xwin->initialized) return; Cursor cursor; Pixmap pm; XColor fg; XColor bg; fg.red = fg.green = fg.blue = 0xffff; bg.red = bg.green = bg.blue = 0x0000; pm = XCreateBitmapFromData(xwin->xdisplay->dpy, xwin->win, data, width, height); cursor = XCreatePixmapCursor(xwin->xdisplay->dpy, pm, pm, &fg, &bg, width/2, height/2); XFreePixmap(xwin->xdisplay->dpy, pm); XDefineCursor(xwin->xdisplay->dpy, xwin->win,cursor); } /* enable / disable cursor */ void zl_xwindow_cursor(zl_xwindow_p xwin, int i){ xwin->cursor = i; if (!xwin->initialized) return; if (i == 0) { char data[] = {0}; zl_xwindow_cursor_image(xwin, data, 1, 1); } else XUndefineCursor(xwin->xdisplay->dpy, xwin->win); } void zl_xwindowitle(zl_xwindow_p xwin, char *title) { if (xwin->initialized) XStoreName(xwin->xdisplay->dpy, xwin->win, title); } /* create zl_xwindow */ int zl_xwindow_config(zl_xwindow_p xwin, zl_xdisplay_p d) { XEvent e; // unsigned int i; /* check if already opened */ if( xwin->initialized ){ fprintf(stderr, "x11: window already created\n"); goto exit; } xwin->xdisplay = d; ASSERT(xwin->xdisplay); /* create a window if xwin doesn't contain one yet: glx init will create its own window */ if (!xwin->win){ xwin->win = XCreateSimpleWindow( xwin->xdisplay->dpy, RootWindow(xwin->xdisplay->dpy, xwin->xdisplay->screen), xwin->winxoffset, xwin->winyoffset, xwin->winwidth, xwin->winheight, 0, BlackPixel(xwin->xdisplay->dpy, xwin->xdisplay->screen), BlackPixel(xwin->xdisplay->dpy, xwin->xdisplay->screen)); D fprintf(stderr, "created window %x on screen %d\n", (unsigned int)xwin->win, xwin->xdisplay->screen); } else { D fprintf(stderr, "reused window %x on screen %d\n", (unsigned int)xwin->win, xwin->xdisplay->screen); } /* enable handling of close window event */ xwin->WM_DELETE_WINDOW = XInternAtom(xwin->xdisplay->dpy, "WM_DELETE_WINDOW", True); (void)XSetWMProtocols(xwin->xdisplay->dpy, xwin->win, &xwin->WM_DELETE_WINDOW, 1); if(!(xwin->win)){ /* clean up mess */ fprintf(stderr, "x11: could not create window.\n"); //XCloseDisplay(xwin->xdisplay->dpy); NOT OWNER xwin->xdisplay = 0; xwin->initialized = 0; goto exit; } /* select input events */ XSelectInput(xwin->xdisplay->dpy, xwin->win, StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | MotionNotify | PointerMotionMask); // | ButtonMotionMask); //XSelectInput(xwin->xdisplay->dpy, xwin->win, StructureNotifyMask); /* set WM_CLASS */ XClassHint chint = {"pf","Pdp"}; XSetClassHint(xwin->xdisplay->dpy, xwin->win, &chint); XSetCommand(xwin->xdisplay->dpy, xwin->win, 0, 0); #if 0 // FIXME: Not sure what to do here... int w = xwin->winwidth; int h = xwin->winheight; ZL_LOG("XSizeHints %dx%d", w, h); XSizeHints shints = { .flags = PBaseSize | PMinSize | PMaxSize, .base_width = w, .base_height = h, .min_width = w, .min_height = h, .max_width = w, .max_height = h, }; XSetWMNormalHints(xwin->xdisplay->dpy, xwin->win, &shints); #endif /* map */ XMapWindow(xwin->xdisplay->dpy, xwin->win); /* create graphics context */ xwin->gc = XCreateGC(xwin->xdisplay->dpy, xwin->win, 0, 0); /* catch events until MapNotify */ for(;;){ XNextEvent(xwin->xdisplay->dpy, &e); fprintf(stderr, "ev: %d\n", e.type); if (e.type == MapNotify) break; if (e.type == ConfigureNotify) { xwin->winwidth = e.xconfigure.width; xwin->winheight = e.xconfigure.height; // fprintf(stderr, "_win: %d x %d\n", e.xconfigure.width, e.xconfigure.height); continue; } ZL_LOG("drop event type %d\n", e.type); } D fprintf(stderr, "mapped window %x\n", (unsigned int)xwin->win); /* we're done initializing */ xwin->initialized = 1; /* disable/enable cursor */ zl_xwindow_cursor(xwin, xwin->cursor); /* set window title */ zl_xwindowitle(xwin, "pf"); zl_xdisplay_register_window(xwin->xdisplay, xwin); exit: return xwin->initialized; } #if 0 static int errors = 0; int xwindow_error_handler(Display *dpy, XErrorEvent *e){ errors++; return 0; } #endif void zl_xwindow_init(zl_xwindow_p xwin) { xwin->xdisplay = 0; xwin->win = 0; xwin->winwidth = 320; xwin->winheight = 240; xwin->winxoffset = 0; xwin->winyoffset = 0; xwin->initialized = 0; xwin->cursor = 0; //xwin->dragbutton = gensym("drag1"); xwin->events = buf_new(16); //XSetErrorHandler(xwindow_error_handler); } zl_xwindow_p zl_xwindow_new(void) { zl_xwindow_p xwin = malloc(sizeof(*xwin)); xwin->type = zl_xwindow_type(); zl_xwindow_init(xwin); return xwin; } void zl_xwindow_close(zl_xwindow_p xwin) { // void *v; zl_xwindow_drop_events(xwin); buf_free(xwin->events); xwin->events = 0; XEvent e; if (xwin->initialized){ XFreeGC(xwin->xdisplay->dpy, xwin->gc); XDestroyWindow(xwin->xdisplay->dpy, xwin->win); while(XPending(xwin->xdisplay->dpy)) XNextEvent(xwin->xdisplay->dpy, &e); zl_xdisplay_unregister_window(xwin->xdisplay, xwin); xwin->xdisplay = 0; xwin->initialized = 0; } } void zl_xwindow_cleanup(zl_xwindow_p x) { // close win zl_xwindow_close(x); // no more dynamic data to free } void zl_xwindow_free(zl_xwindow_p xwin) { zl_xwindow_cleanup(xwin); free(xwin); } int zl_xwindow_winwidth(zl_xwindow *x) { return x->winwidth; } int zl_xwindow_winheight(zl_xwindow *x) { return x->winheight; } int zl_xwindow_winxoffset(zl_xwindow *x) { return x->winxoffset; } int zl_xwindow_winyoffset(zl_xwindow *x) { return x->winyoffset; } // Delegate to display void zl_xwindow_route_events(zl_xwindow *x) { zl_xdisplay_route_events(x->xdisplay); } pdp-0.14.1+darcs20180201/system/zl/xwindow.h000066400000000000000000000100101266045153600201070ustar00rootroot00000000000000#ifndef _ZL_XWINDOW_H_ #define _ZL_XWINDOW_H_ /* * Pure Data Packet header file: zl_xwindow glue code * Copyright (c) by Tom Schouten * * 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,x * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef ZL_XWINDOW_H #define ZL_XWINDOW_H #ifdef HAVE_LEAF #include #else // Stand-alone #define LEAF_CLASS(member) int member[0] #endif // x stuff #include #include #include "zl.h" #include "util.h" // small utility library /* x display class */ typedef struct { LEAF_CLASS(super); } zl_xdisplay_class; /* x window class */ typedef struct { LEAF_CLASS(super); } zl_xwindow_class; struct zl_xdisplay; typedef struct zl_xdisplay zl_xdisplay; typedef struct zl_xdisplay *zl_xdisplay_p; struct zl_xwindow; typedef struct zl_xwindow zl_xwindow; typedef struct zl_xwindow *zl_xwindow_p; #ifdef PRIVATE struct zl_xdisplay { zl_xdisplay_class *type; Display *dpy; // the display connection int screen; // the screen buf_t *windowlist; // all windows belonging to this connection // this contains (id, eventlist) typeof(((XEvent*)0)->xbutton.button) dragbutton; }; struct zl_xwindow { zl_xwindow_class *type; zl_xdisplay_p xdisplay; // the display object Window win; // window reference GC gc; // graphics context Atom WM_DELETE_WINDOW; buf_t *events; int winwidth; // dim states int winheight; int winxoffset; int winyoffset; int initialized; int autocreate; char lastbut; // last button pressed (for drag) //t_symbol *dragbutton; float cursor; }; #endif typedef void (*zl_zwindow_event_fn)(void *context, XEvent *ev); typedef XEvent *XEvent_p; #define ZL_FOR_BUTTON(M, ...) \ M(1, __VA_ARGS__) \ M(2, __VA_ARGS__) \ M(3, __VA_ARGS__) \ M(4, __VA_ARGS__) \ M(5, __VA_ARGS__) #define ZL_BUTTON_EV(n, EV, tag) EV(tag##n) #define ZL_XDISPLAY_DEF_EV_BUT(EV, tag) EV(tag) ZL_FOR_BUTTON(ZL_BUTTON_EV, EV, tag) #define ZL_XDISPLAY_EV_LIST(EV) \ ZL_XDISPLAY_DEF_EV_BUT(EV, drag) \ ZL_XDISPLAY_DEF_EV_BUT(EV, press) \ ZL_XDISPLAY_DEF_EV_BUT(EV, release) \ ZL_XDISPLAY_DEF_EV_BUT(EV, motion) \ EV(close) \ EV(keypress) \ EV(keyrelease) \ #define ZL_XDISPLAY_EV(name) zl_display_ev_##name /* All events are const char, which allows them to be used as static (pointer) references, or to convert to a dynamic hashed string (interned symbol). The macro ZL_DISPLAY_EV_LIST could also be used to define app-specific tag wrappers based on name only. */ #define _ZL_XDISPLAY_EV_DECL(name) extern zl_tag ZL_XDISPLAY_EV(name); ZL_XDISPLAY_EV_LIST(_ZL_XDISPLAY_EV_DECL) zl_xwindow_p zl_xwindow_new(void); zl_xdisplay_p zl_xdisplay_new(const char *dpy); #define FUN(t,f) t zl_xdisplay_##f(zl_xdisplay_p #define ARG(t,a) , t a #define END ); #include "xdisplay.api" #undef FUN #define FUN(t,f) t zl_xwindow_##f(zl_xwindow_p #include "xwindow.api" #undef FUN #undef ARG #undef END zl_xwindow_class *zl_xwindow_type(void); zl_xdisplay_class *zl_xdisplay_type(void); #endif #endif pdp-0.14.1+darcs20180201/system/zl/zl.h000066400000000000000000000021431266045153600170450ustar00rootroot00000000000000#ifndef _ZL_H_ #define _ZL_H_ #include /* ZL uses the "tagged va_list" approach: To facilitate data transfer to a different programming system, it supports a generic data structure modeled after Lisp tagged lists. * Lists are encoded using a standard datastructure: va_lists. This prevents re-invention and makes it very easy to use on both the sending and receiving end. * Tags are encoded as const char *. This allows fast C pointer comparisons and makes bridging to interned symbols (hashed strings) common in dynamically typed languages. */ typedef const char * zl_tag; typedef void (*zl_receiver)(void *ctx, int nb_args, zl_tag tag, va_list args); static inline void zl_send(zl_receiver fn, void *ctx, int nb_args, zl_tag tag, ...) { va_list args; va_start(args, tag); fn(ctx, nb_args, tag, args); va_end(args); } typedef unsigned int uint; /* The _p postfix is for pointers to struct . The main reason to use pointer typedefs is to allow for lexical tricks in .api files. */ typedef void* void_p; typedef char* char_p; #endif pdp-0.14.1+darcs20180201/system/zl/zl.mk000066400000000000000000000016111266045153600172240ustar00rootroot00000000000000.PHONY: all clean run_test all: run_test clean: rm -f *.o test *~ *.so *.a H = $(wildcard *.h) C = $(wildcard *.c) O = $(C:.c=.o) CFLAGS := -O3 -fPIC -ffast-math -I.. -DHAVE_LIBV4L1_VIDEODEV_H -Wall #-Werror %.o: %.c $(H) $(CC) $(CFLAGS) -c $< -o $@ # 2013/10/16 : Still in the process of merging PDP and libprim's dependencies on zl. # Test is only for a subset of the objects: TEST_O := v4l.o xwindow.o xv.o glx.o 3Dcontext_common.o 3Dcontext_glx.o test.o LIBS := -lpthread -L/usr/X11R6/lib -lX11 -lXv -lXext -lGL -lGLU #-llua test: $(TEST_O) $(CC) -o test $(TEST_O) $(LIBS) # $(TEST_LIBS) ?? LIB_C := \ 3Dcontext_common.c \ 3Dcontext_glx.c \ glx.c \ v4l.c \ xv.c \ xwindow.c \ new.c LIB_O := $(LIB_C:.c=.o) libzl.so: $(LIB_O) $(CC) -shared -o $@ $(LIB_O) $(LIBS) zl.a: $(LIB_O) $(AR) -r $@ $(LIB_O) libzl.so: $(LIB_O) $(CC) -shared -o $@ $(LIB_O) $(LIBS) run_test: test ./test pdp-0.14.1+darcs20180201/system/zl_pd/000077500000000000000000000000001266045153600167325ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/system/zl_pd/zl_pd.h000066400000000000000000000033061266045153600202150ustar00rootroot00000000000000#ifndef _ZL_PD_H_ #define _ZL_PD_H_ #include "m_pd.h" #include "zl/zl.h" /* To bridge 2 programming systems, the real hurdle is in impedance-matching the data types and memory model. In ZL this is done by keeping a very simple basic data type: C variable argument lists where tags are reprented using typedef const char *zl_tag; A. List representation ---------------------- There are essentially 2 kinds of list in C that are easy to use inside the language: - Static data initializers. This requires a union (optionally tagged) so has some syntactic overhead. Works for global and local variables. - Variable argument lists. This is a feature supported by the C standard and is very convenient to use as there is no notational overhead. Often converted data is short-lived, allowing data conversion to be implemented with nested C calls. Both are able to side-step malloc() when they are combined with some kind of callback mechanism. B. List tagging --------------- Using const char * as a tag type allows 2 things to be married in a very elegant way: - Pointer-based comparison in C without memory allocation overhead (all string memory allocation is static). - Easy conversion to run-time interned symbols (hashed strings) for dynamic languages. */ /* To further limit complexity, for interfaacing with Pd, ZL uses tagged double lists, easy to convert to pd format. */ static inline void outlet_zl_float_list(t_outlet *o, int nb_double_args, zl_tag tag, va_list args) { t_atom pd_list[nb_double_args]; int i; for (i = 0; i< nb_double_args; i++) { SETFLOAT(&pd_list[i], va_arg(args, double)); } outlet_anything(o, gensym(tag), nb_double_args, pd_list); } #endif pdp-0.14.1+darcs20180201/test/000077500000000000000000000000001266045153600152555ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/test/test-v4l.pd000066400000000000000000000014611266045153600172660ustar00rootroot00000000000000#N canvas 0 29 1438 419 10; #X obj 85 39 loadbang; #X msg 85 66 open /dev/video0; #X obj 296 56 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 298 91 metro 1000; #X msg 355 38 40; #X floatatom 357 65 5 0 0 0 - - -; #X msg 211 153 dim 640 480; #X obj 53 71 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 416 37 1000; #X msg 386 38 200; #X obj 88 106 pdp_v4l_hack; #X obj 76 215 print; #X msg 195 240 dim 640 480; #X obj 87 164 pdp_glx; #X msg 205 202 display :0; #X msg 216 126 dim 320 241; #X connect 0 0 1 0; #X connect 1 0 10 0; #X connect 2 0 3 0; #X connect 3 0 10 0; #X connect 4 0 5 0; #X connect 5 0 3 1; #X connect 6 0 10 0; #X connect 7 0 10 0; #X connect 8 0 5 0; #X connect 9 0 5 0; #X connect 10 0 13 0; #X connect 12 0 13 0; #X connect 14 0 13 0; #X connect 15 0 10 0; pdp-0.14.1+darcs20180201/test/test-xv.pd000066400000000000000000000013411266045153600172130ustar00rootroot00000000000000#N canvas 0 29 718 419 10; #X obj 296 56 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 298 91 metro 1000; #X msg 355 38 40; #X floatatom 357 65 5 0 0 0 - - -; #X msg 211 153 dim 640 480; #X obj 53 71 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 416 37 1000; #X msg 386 38 200; #X obj 76 215 print; #X msg 195 240 dim 640 480; #X msg 205 202 display :0; #X msg 216 126 dim 320 241; #X obj 88 105 pdp_noise; #X obj 87 164 pdp_xv; #X connect 0 0 1 0; #X connect 1 0 12 0; #X connect 2 0 3 0; #X connect 3 0 1 1; #X connect 4 0 12 0; #X connect 5 0 12 0; #X connect 6 0 3 0; #X connect 7 0 3 0; #X connect 9 0 13 0; #X connect 10 0 13 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 13 0 8 0; pdp-0.14.1+darcs20180201/www/000077500000000000000000000000001266045153600151225ustar00rootroot00000000000000pdp-0.14.1+darcs20180201/www/index.html000066400000000000000000000042641266045153600171250ustar00rootroot00000000000000

    Pure Data Packet

    About

    PDP is an extension library for Pure Data, providing video and other media processing functionality. PDP's focus is on images and video, but there is support for matrix processing, 1D and 2D binary cellular automata and opengl rendering (like Gem). PDP runs on Linux and OSX. The OSX version depends on Fink.

    For more image processing objects, streaming objects and a collection of very useful additions to the bare bones PDP functionality, have a look at Yves Degoyon's PiDiP library.

    For documentation, have a look at the 'pdp' subdirectory in pd's 'Pure Documentation'. Most objects are documented with pd style help patches accessible by right clicking on an object. The place to send questions is the Pure Data mailing list.

    Download

    The latest stable PDP tarball release can be found in the PDP section of the Pure Data SourceForge project. The pd-pdp package is currently maintained by Paul Brossier. PDP is written by Tom Schouten and released under the GPL v2.

    Links

  • Pure Data portal
  • PiDiP Is Definitely In Pieces
  • al-Jwarizmi
  • Videoflow / Cruzados BGN
  • Eth0
  • RRADical
  • Veejay / SendVIMS
  • FreeJ
  • EffecTV
  • Packet Forth, the direct descendant of PDP.
  • libprim, a descendant of Packet Forth.