1
0
Fork 0
forked from len0rd/rockbox

Add FS #10214. Initial commit of the original PDa code for the GSoC Pure Data plugin project of Wincent Balin. Stripped some non-sourcefiles and added a rockbox readme that needs a bit more info from Wincent. Is added to CATEGORIES and viewers, but not yet to SUBDIRS (ie doesn't build yet)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21044 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Peter D'Hoye 2009-05-22 21:58:48 +00:00
parent 95fa7f6a2e
commit 513389b4c1
199 changed files with 139349 additions and 1 deletions

View file

@ -54,6 +54,7 @@ mpegplayer,viewers
nim,games
oscilloscope,demos
pacbox,games
pdbox,apps
pegbox,games
pictureflow,demos
plasma,demos

View file

@ -0,0 +1,118 @@
0.6:
- added compilation for blackfin architecture (blackfin.uclinux.org)
- added third outlet for mouseup to gcanvas.
- debian package support (for maemo)
- don't ask quit question
0.5:
- fixed a crasher bug in sfread~.c
0.4:
- added ipod gui communication in m_pd.c (pd_bind) and m_fixed.c
- moved the pd internal objects in a folder called interns
- restructuring of the makefile, you can build a static binary
now with "make static", needed for the iPod part mainly.
- the oscillator tables are precalculated now (faster startup).
see src/makecostable.c for that
- the scheduler is simplified (added an additional scheduler called
m_scheduler_pda(), this is a lot faster now
- changed the "look" of PDa
- The menubar in the patcher window is now optional, its off by default.
- stdin interface added. It is now possible to communicate with pd via the
keyboard even in -nogui mode
- fixed loading and saving of arrays (g_array.c)
- corrected rounding when calculation phase update osc~ and phasor~
(there are better methods to do this, but they are slower)
- fixed tabosc4~
- enabled array drawing
- fixed array saving in subpatch
0.3test2:
- added the O_CREAT flag to sfwrite
- removed the OSC stuff (now in PDa-externals)
0.3test1:
- moved all objects into the extra dir
d_arithmetic: t_float -> t_sample .. exchanged * with mult / with divide
d_fft: t_float -> t_sample
d_global: t_float -> t_sample
d_misc: put print~ into extra folder
d_resample: t_float -> t_sample
g_array: disable editing
fixtof()
t_float -> t_sample (check out the savefn thingy)
g_graph: 1 t_float -> t_sample
g_io: t_float -> t_sample
m_conf: remove calls to setup routines
m_obj.c ftofix
m_pd.h definition of t_sample
double -> t_time
... and more
m_sched.c
double t_time
s_inter: check !!!
s_main: check !!!
0.6:
- added compilation for blackfin architecture (blackfin.uclinux.org)
- added third outlet for mouseup to gcanvas.
- debian package support (for maemo)
- don't ask quit question
0.5:
- fixed a crasher bug in sfread~.c
0.4:
- added ipod gui communication in m_pd.c (pd_bind) and m_fixed.c
- moved the pd internal objects in a folder called interns
- restructuring of the makefile, you can build a static binary
now with "make static", needed for the iPod part mainly.
- the oscillator tables are precalculated now (faster startup).
see src/makecostable.c for that
- the scheduler is simplified (added an additional scheduler called
m_scheduler_pda(), this is a lot faster now
- changed the "look" of PDa
- The menubar in the patcher window is now optional, its off by default.
- stdin interface added. It is now possible to communicate with pd via the
keyboard even in -nogui mode
- fixed loading and saving of arrays (g_array.c)
- corrected rounding when calculation phase update osc~ and phasor~
(there are better methods to do this, but they are slower)
- fixed tabosc4~
- enabled array drawing
- fixed array saving in subpatch
0.3test2:
- added the O_CREAT flag to sfwrite
- removed the OSC stuff (now in PDa-externals)
0.3test1:
- moved all objects into the extra dir
d_arithmetic: t_float -> t_sample .. exchanged * with mult / with divide
d_fft: t_float -> t_sample
d_global: t_float -> t_sample
d_misc: put print~ into extra folder
d_resample: t_float -> t_sample
g_array: disable editing
fixtof()
t_float -> t_sample (check out the savefn thingy)
g_graph: 1 t_float -> t_sample
g_io: t_float -> t_sample
m_conf: remove calls to setup routines
m_obj.c ftofix
m_pd.h definition of t_sample
double -> t_time
... and more
m_sched.c
double t_time
s_inter: check !!!
s_main: check !!!

View file

@ -0,0 +1,60 @@
This software is copyrighted by Miller Puckette and others. The following
terms (the "Standard Improved BSD License") apply to all files associated with
the software unless explicitly disclaimed in individual files:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
This software is copyrighted by Miller Puckette and others. The following
terms (the "Standard Improved BSD License") apply to all files associated with
the software unless explicitly disclaimed in individual files:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,106 @@
PDa - Pure Data for Personal Digital Assistants
===============================================
Based on pd-0.37-4.
This version of Pure Data is based on the original sources by
Miller Puckette, but several part have been changed in order
to run on embedded systems. Most of the changed objects are in
the folder "intern".
This means, that all the signal processing is done with fixed-point
math. The control processing is still in floating point, therefor this
might be a bit slow.
The package is compilable under Linux. I would be glad if someone would
make a version for windows or OSX, but I unfortunately don't have the
time or resource to do so.
In order to compile:
cd src/
make
The default compilation flags are very conservative, you can add
optimization flags through the CFLAGS variable.
e.g
make CFLAGS="-O6"
Will turn on maximum optimization (almost).
If you have tcl/tk installed in the right place this should work out,
if you have problems with that, either adapt the makefile or ask me.
On Debian you just have to install tk8.4-dev to get it going.
Have fun !
Guenter
Additional information:
---------------------------
Instructions for compiling for iPods, using arm-elf-tools-20030314:
cd src
./build.ipod
The tcl/tk interface will not be built for iPods, you can interface with
Pd from the podzilla console or with this GUI for PDa on iPod:
http://ipodlinux.org/Pdpod
PDa - Pure Data for Personal Digital Assistants
===============================================
Based on pd-0.37-4.
This version of Pure Data is based on the original sources by
Miller Puckette, but several part have been changed in order
to run on embedded systems. Most of the changed objects are in
the folder "intern".
This means, that all the signal processing is done with fixed-point
math. The control processing is still in floating point, therefor this
might be a bit slow.
The package is compilable under Linux. I would be glad if someone would
make a version for windows or OSX, but I unfortunately don't have the
time or resource to do so.
In order to compile:
cd src/
make
The default compilation flags are very conservative, you can add
optimization flags through the CFLAGS variable.
e.g
make CFLAGS="-O6"
Will turn on maximum optimization (almost).
If you have tcl/tk installed in the right place this should work out,
if you have problems with that, either adapt the makefile or ask me.
On Debian you just have to install tk8.4-dev to get it going.
Have fun !
Guenter
Additional information:
---------------------------
Instructions for compiling for iPods, using arm-elf-tools-20030314:
cd src
./build.ipod
The tcl/tk interface will not be built for iPods, you can interface with
Pd from the podzilla console or with this GUI for PDa on iPod:
http://ipodlinux.org/Pdpod

View file

@ -0,0 +1,88 @@
This is the README file for Pd, a free real-time computer music software
package resembling Max. You can get Pd for Linux, Windows, Mac OSX, or IRIX
from http://www.crca.ucsd.edu/~msp/software.html or ftp://felix.ucsd.edu.
Installation instructions are in the HTML DOCUMENTATION at:
http://www.crca.ucsd.edu/~msp/Pd_documentation/index.htm
If you download and unpack Pd, you will also find the html documentation
locally in the file, .../pd-whatever/doc/1.manual/index.htm. To unpack Pd:
LINUX (or freeBSD). Download Pd, which will be a ".tar.gz" file; to unpack it,
type "zcat [name].tar.gz | tar xf -" to a shell. This creates a directory with
a name like "pd-0.35". There are also RPMs available.
Microsoft Windows. Pd is distributed as a "zip" file. Unzip this,
creating a directory such as \pd.
IRIX. Download Pd, which will be a "tar.Z" file. You can unpack this by
typing "zcat [name].tar.Z | tar xf -" to a shell.
Macintosh. The web browser will automatically unpack the distributions
into a folder such as "pd-0.35" on your desktop.
If you have qustions about Pd, or if you wish to be notified of releases,
check the Pd mailing list: http://iem.mhsg.ac.at/mailinglists/pd-list/
Many extensions to Pd are available, notably for handling video and 3D
graphics; see the html documentation for pointers.
COPYRIGHT. Except as otherwise noted, all files in the Pd distribution are
Copyright (c) 1997-2001 Miller Puckette and others.
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "LICENSE.txt," included in the Pd distribution.
(Note that tcl/tk, expr, and some other files are copyrighted separately).
ACKNOWLEDGEMENTS. Thanks to Harry Castle, Krzysztof Czaja, Mark Danks,
Christian Feldbauer, Guenter Geiger, Kerry Hagan, Trevor Johnson, Fernando
Lopez-Lezcano, Adam Lindsay, Karl MacMillan, Thomas Musil, Toshinori Ohkouchi,
Winfried Ritsch, Vibeke Sorensen, Rand Steiger, Shahrokh Yadegari, David
Zicarelli, Iohannes Zmoelnig, and probably many others for contributions of
code, documentation, ideas, and expertise. This work has received generous
support from the Intel Research Council.
This is the README file for Pd, a free real-time computer music software
package resembling Max. You can get Pd for Linux, Windows, Mac OSX, or IRIX
from http://www.crca.ucsd.edu/~msp/software.html or ftp://felix.ucsd.edu.
Installation instructions are in the HTML DOCUMENTATION at:
http://www.crca.ucsd.edu/~msp/Pd_documentation/index.htm
If you download and unpack Pd, you will also find the html documentation
locally in the file, .../pd-whatever/doc/1.manual/index.htm. To unpack Pd:
LINUX (or freeBSD). Download Pd, which will be a ".tar.gz" file; to unpack it,
type "zcat [name].tar.gz | tar xf -" to a shell. This creates a directory with
a name like "pd-0.35". There are also RPMs available.
Microsoft Windows. Pd is distributed as a "zip" file. Unzip this,
creating a directory such as \pd.
IRIX. Download Pd, which will be a "tar.Z" file. You can unpack this by
typing "zcat [name].tar.Z | tar xf -" to a shell.
Macintosh. The web browser will automatically unpack the distributions
into a folder such as "pd-0.35" on your desktop.
If you have qustions about Pd, or if you wish to be notified of releases,
check the Pd mailing list: http://iem.mhsg.ac.at/mailinglists/pd-list/
Many extensions to Pd are available, notably for handling video and 3D
graphics; see the html documentation for pointers.
COPYRIGHT. Except as otherwise noted, all files in the Pd distribution are
Copyright (c) 1997-2001 Miller Puckette and others.
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "LICENSE.txt," included in the Pd distribution.
(Note that tcl/tk, expr, and some other files are copyrighted separately).
ACKNOWLEDGEMENTS. Thanks to Harry Castle, Krzysztof Czaja, Mark Danks,
Christian Feldbauer, Guenter Geiger, Kerry Hagan, Trevor Johnson, Fernando
Lopez-Lezcano, Adam Lindsay, Karl MacMillan, Thomas Musil, Toshinori Ohkouchi,
Winfried Ritsch, Vibeke Sorensen, Rand Steiger, Shahrokh Yadegari, David
Zicarelli, Iohannes Zmoelnig, and probably many others for contributions of
code, documentation, ideas, and expertise. This work has received generous
support from the Intel Research Council.

View file

@ -0,0 +1,376 @@
/*
Written by Matt Wright, The Center for New Music and Audio Technologies,
University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03
The Regents of the University of California (Regents).
Permission to use, copy, modify, distribute, and distribute modified versions
of this software and its documentation without fee and without a signed
licensing agreement, is hereby granted, provided that the above copyright
notice, this paragraph and the following two paragraphs appear in all copies,
modifications, and distributions.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
OSC-client.h: library for constructing OpenSoundControl messages.
Derived from SynthControl.h
Author: Matt Wright
Version 0.1: 6/13/97
Version 0.2: 7/21/2000: Support for type-tagged messages
General notes:
This library abstracts away the data format for the OpenSoundControl
protocol. Users of this library can construct OpenSoundControl packets
with a function call interface instead of knowing how to lay out the bits.
All issues of memory allocation are deferred to the user of this library.
There are two data structures that the user must allocate. The first
is the actual buffer that the message will be written into. This buffer
can be any size, but if it's too small there's a possibility that it
will become overfull. The other data structure is called an OSCbuf,
and it holds all the state used by the library as it's constructing
a buffer.
All procedures that have the possibility of an error condition return int,
with 0 indicating no error and nonzero indicating an error. The variable
OSC_errorMessage will be set to point to a string containing an error
message explaining what the problem is.
*/
/* The int4byte type has to be a 4-byte integer. You may have to
change this to long or something else on your system. */
#ifdef __MWERKS__
/* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is
always 4 bytes */
typedef long int4byte;
#else
typedef int int4byte;
#endif
/* OSC_timetag.h */
typedef struct {
int seconds;
int fraction;
} OSCTimeTag;
OSCTimeTag OSCTT_Immediately(void);
OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset);
OSCTimeTag OSCTT_CurrentTime(void);
/* The maximum depth of bundles within bundles within bundles within...
This is the size of a static array. If you exceed this limit you'll
get an error message. */
#define MAX_BUNDLE_NESTING 32
/* Don't ever manipulate the data in the OSCbuf struct directly. (It's
declared here in the header file only so your program will be able to
declare variables of type OSCbuf and have the right amount of memory
be allocated.) */
typedef struct OSCbuf_struct {
char *buffer; /* The buffer to hold the OSC packet */
int size; /* Size of the buffer */
char *bufptr; /* Current position as we fill the buffer */
int state; /* State of partially-constructed message */
int4byte *thisMsgSize; /* Pointer to count field before
currently-being-written message */
int4byte *prevCounts[MAX_BUNDLE_NESTING];
/* Pointers to count field before each currently
open bundle */
int bundleDepth; /* How many sub-sub-bundles are we in now? */
char *typeStringPtr; /* This pointer advances through the type
tag string as you add arguments. */
int gettingFirstUntypedArg; /* nonzero if this message doesn't have
a type tag and we're waiting for the 1st arg */
} OSCbuf;
/* Initialize the given OSCbuf. The user of this module must pass in the
block of memory that this OSCbuf will use for a buffer, and the number of
bytes in that block. (It's the user's job to allocate the memory because
you do it differently in different systems.) */
void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray);
/* Reset the given OSCbuf. Do this after you send out the contents of
the buffer and want to start writing new data into it. */
void OSC_resetBuffer(OSCbuf *buf);
/* Is the buffer empty? (I.e., would it be stupid to send the buffer
contents to the synth?) */
int OSC_isBufferEmpty(OSCbuf *buf);
/* How much space is left in the buffer? */
int OSC_freeSpaceInBuffer(OSCbuf *buf);
/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */
int OSC_isBufferDone(OSCbuf *buf);
/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone()
returns true), call these two procedures to get the OSC packet that's been
assembled and its size in bytes. (And then call OSC_resetBuffer() if you
want to re-use this OSCbuf for the next packet.) */
char *OSC_getPacket(OSCbuf *buf);
int OSC_packetSize(OSCbuf *buf);
/* Here's the basic model for building up OSC messages in an OSCbuf:
- Make sure the OSCbuf has been initialized with OSC_initBuffer().
- To open a bundle, call OSC_openBundle(). You can then write
messages or open new bundles within the bundle you opened.
Call OSC_closeBundle() to close the bundle. Note that a packet
does not have to have a bundle; it can instead consist of just a
single message.
- For each message you want to send:
- Call OSC_writeAddress() with the name of your message. (In
addition to writing your message name into the buffer, this
procedure will also leave space for the size count of this message.)
- Alternately, call OSC_writeAddressAndTypes() with the name of
your message and with a type string listing the types of all the
arguments you will be putting in this message.
- Now write each of the arguments into the buffer, by calling one of:
OSC_writeFloatArg()
OSC_writeFloatArgs()
OSC_writeIntArg()
OSC_writeStringArg()
- Now your message is complete; you can send out the buffer or you can
add another message to it.
*/
int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt);
int OSC_closeBundle(OSCbuf *buf);
int OSC_closeAllBundles(OSCbuf *buf);
int OSC_writeAddress(OSCbuf *buf, char *name);
int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types);
int OSC_writeFloatArg(OSCbuf *buf, float arg);
int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args);
int OSC_writeIntArg(OSCbuf *buf, int4byte arg);
int OSC_writeStringArg(OSCbuf *buf, char *arg);
extern char *OSC_errorMessage;
/* How many bytes will be needed in the OSC format to hold the given
string? The length of the string, plus the null char, plus any padding
needed for 4-byte alignment. */
int OSC_effectiveStringLength(char *string);
/*
Written by Matt Wright, The Center for New Music and Audio Technologies,
University of California, Berkeley. Copyright (c) 1996,97,98,99,2000,01,02,03
The Regents of the University of California (Regents).
Permission to use, copy, modify, distribute, and distribute modified versions
of this software and its documentation without fee and without a signed
licensing agreement, is hereby granted, provided that the above copyright
notice, this paragraph and the following two paragraphs appear in all copies,
modifications, and distributions.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
OSC-client.h: library for constructing OpenSoundControl messages.
Derived from SynthControl.h
Author: Matt Wright
Version 0.1: 6/13/97
Version 0.2: 7/21/2000: Support for type-tagged messages
General notes:
This library abstracts away the data format for the OpenSoundControl
protocol. Users of this library can construct OpenSoundControl packets
with a function call interface instead of knowing how to lay out the bits.
All issues of memory allocation are deferred to the user of this library.
There are two data structures that the user must allocate. The first
is the actual buffer that the message will be written into. This buffer
can be any size, but if it's too small there's a possibility that it
will become overfull. The other data structure is called an OSCbuf,
and it holds all the state used by the library as it's constructing
a buffer.
All procedures that have the possibility of an error condition return int,
with 0 indicating no error and nonzero indicating an error. The variable
OSC_errorMessage will be set to point to a string containing an error
message explaining what the problem is.
*/
/* The int4byte type has to be a 4-byte integer. You may have to
change this to long or something else on your system. */
#ifdef __MWERKS__
/* In Metrowerks you can set ints to be 2 or 4 bytes on 68K, but long is
always 4 bytes */
typedef long int4byte;
#else
typedef int int4byte;
#endif
/* OSC_timetag.h */
typedef struct {
int seconds;
int fraction;
} OSCTimeTag;
OSCTimeTag OSCTT_Immediately(void);
OSCTimeTag OSCTT_PlusSeconds(OSCTimeTag original, float secondsOffset);
OSCTimeTag OSCTT_CurrentTime(void);
/* The maximum depth of bundles within bundles within bundles within...
This is the size of a static array. If you exceed this limit you'll
get an error message. */
#define MAX_BUNDLE_NESTING 32
/* Don't ever manipulate the data in the OSCbuf struct directly. (It's
declared here in the header file only so your program will be able to
declare variables of type OSCbuf and have the right amount of memory
be allocated.) */
typedef struct OSCbuf_struct {
char *buffer; /* The buffer to hold the OSC packet */
int size; /* Size of the buffer */
char *bufptr; /* Current position as we fill the buffer */
int state; /* State of partially-constructed message */
int4byte *thisMsgSize; /* Pointer to count field before
currently-being-written message */
int4byte *prevCounts[MAX_BUNDLE_NESTING];
/* Pointers to count field before each currently
open bundle */
int bundleDepth; /* How many sub-sub-bundles are we in now? */
char *typeStringPtr; /* This pointer advances through the type
tag string as you add arguments. */
int gettingFirstUntypedArg; /* nonzero if this message doesn't have
a type tag and we're waiting for the 1st arg */
} OSCbuf;
/* Initialize the given OSCbuf. The user of this module must pass in the
block of memory that this OSCbuf will use for a buffer, and the number of
bytes in that block. (It's the user's job to allocate the memory because
you do it differently in different systems.) */
void OSC_initBuffer(OSCbuf *buf, int size, char *byteArray);
/* Reset the given OSCbuf. Do this after you send out the contents of
the buffer and want to start writing new data into it. */
void OSC_resetBuffer(OSCbuf *buf);
/* Is the buffer empty? (I.e., would it be stupid to send the buffer
contents to the synth?) */
int OSC_isBufferEmpty(OSCbuf *buf);
/* How much space is left in the buffer? */
int OSC_freeSpaceInBuffer(OSCbuf *buf);
/* Does the buffer contain a valid OSC packet? (Returns nonzero if yes.) */
int OSC_isBufferDone(OSCbuf *buf);
/* When you're ready to send out the buffer (i.e., when OSC_isBufferDone()
returns true), call these two procedures to get the OSC packet that's been
assembled and its size in bytes. (And then call OSC_resetBuffer() if you
want to re-use this OSCbuf for the next packet.) */
char *OSC_getPacket(OSCbuf *buf);
int OSC_packetSize(OSCbuf *buf);
/* Here's the basic model for building up OSC messages in an OSCbuf:
- Make sure the OSCbuf has been initialized with OSC_initBuffer().
- To open a bundle, call OSC_openBundle(). You can then write
messages or open new bundles within the bundle you opened.
Call OSC_closeBundle() to close the bundle. Note that a packet
does not have to have a bundle; it can instead consist of just a
single message.
- For each message you want to send:
- Call OSC_writeAddress() with the name of your message. (In
addition to writing your message name into the buffer, this
procedure will also leave space for the size count of this message.)
- Alternately, call OSC_writeAddressAndTypes() with the name of
your message and with a type string listing the types of all the
arguments you will be putting in this message.
- Now write each of the arguments into the buffer, by calling one of:
OSC_writeFloatArg()
OSC_writeFloatArgs()
OSC_writeIntArg()
OSC_writeStringArg()
- Now your message is complete; you can send out the buffer or you can
add another message to it.
*/
int OSC_openBundle(OSCbuf *buf, OSCTimeTag tt);
int OSC_closeBundle(OSCbuf *buf);
int OSC_closeAllBundles(OSCbuf *buf);
int OSC_writeAddress(OSCbuf *buf, char *name);
int OSC_writeAddressAndTypes(OSCbuf *buf, char *name, char *types);
int OSC_writeFloatArg(OSCbuf *buf, float arg);
int OSC_writeFloatArgs(OSCbuf *buf, int numFloats, float *args);
int OSC_writeIntArg(OSCbuf *buf, int4byte arg);
int OSC_writeStringArg(OSCbuf *buf, char *arg);
extern char *OSC_errorMessage;
/* How many bytes will be needed in the OSC format to hold the given
string? The length of the string, plus the null char, plus any padding
needed for 4-byte alignment. */
int OSC_effectiveStringLength(char *string);

View file

@ -0,0 +1,26 @@
#N canvas 0 0 240 300 10;
#X obj 32 185 dumpOSC 5550;
#X obj 32 217 OSCroute /hello;
#X obj 32 239 print;
#X obj 133 238 print;
#X obj 26 87 sendOSC;
#X msg 50 43 connect localhost 5550;
#X msg 21 13 send /hello PDa;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 1 1 3 0;
#X connect 5 0 4 0;
#X connect 6 0 4 0;
#N canvas 0 0 240 300 10;
#X obj 32 185 dumpOSC 5550;
#X obj 32 217 OSCroute /hello;
#X obj 32 239 print;
#X obj 133 238 print;
#X obj 26 87 sendOSC;
#X msg 50 43 connect localhost 5550;
#X msg 21 13 send /hello PDa;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 1 1 3 0;
#X connect 5 0 4 0;
#X connect 6 0 4 0;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,24 @@
PDa - externals
===============
This is a collection of selected externals for PDa. The externals are
all copyright by their authors, check out the copyright notice in
each of the files.
I have changed some of the files a bit, so the bugs are most likely my
fault. Send feedback and wishes to
geiger <AT> xdv dot org
PDa - externals
===============
This is a collection of selected externals for PDa. The externals are
all copyright by their authors, check out the copyright notice in
each of the files.
I have changed some of the files a bit, so the bugs are most likely my
fault. Send feedback and wishes to
geiger <AT> xdv dot org

View file

@ -0,0 +1,34 @@
#N canvas 428 285 240 300 8;
#X obj 24 78 noise~;
#X obj 15 215 dac~;
#X obj 24 167 biquad~;
#X floatatom 67 76 5 0 0 0 - - -;
#X floatatom 83 111 5 0 0 0 - - -;
#X obj 67 138 bandpass 600 10;
#X text 77 97 bandwidth: 100 = 1 octave;
#X text 67 58 frequency;
#X text 8 11 Calculation of biquad coefficients;
#X text 7 21 ==================================;
#X connect 0 0 2 0;
#X connect 2 0 1 0;
#X connect 2 0 1 1;
#X connect 3 0 5 0;
#X connect 4 0 5 1;
#X connect 5 0 2 0;
#N canvas 428 285 240 300 8;
#X obj 24 78 noise~;
#X obj 15 215 dac~;
#X obj 24 167 biquad~;
#X floatatom 67 76 5 0 0 0 - - -;
#X floatatom 83 111 5 0 0 0 - - -;
#X obj 67 138 bandpass 600 10;
#X text 77 97 bandwidth: 100 = 1 octave;
#X text 67 58 frequency;
#X text 8 11 Calculation of biquad coefficients;
#X text 7 21 ==================================;
#X connect 0 0 2 0;
#X connect 2 0 1 0;
#X connect 2 0 1 1;
#X connect 3 0 5 0;
#X connect 4 0 5 1;
#X connect 5 0 2 0;

View file

@ -0,0 +1,172 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- bandpass ----------------------------*/
static t_class *bandpass_class;
void bandpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = 0.;
t_float b0 = alpha;
t_float b2 = -alpha;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("bandpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void bandpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
bandpass_bang(x);
}
static void *bandpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(bandpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void bandpass_setup(void)
{
bandpass_class = class_new(gensym("bandpass"), (t_newmethod)bandpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(bandpass_class,bandpass_bang);
class_addfloat(bandpass_class,bandpass_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- bandpass ----------------------------*/
static t_class *bandpass_class;
void bandpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = 0.;
t_float b0 = alpha;
t_float b2 = -alpha;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("bandpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void bandpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
bandpass_bang(x);
}
static void *bandpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(bandpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void bandpass_setup(void)
{
bandpass_class = class_new(gensym("bandpass"), (t_newmethod)bandpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(bandpass_class,bandpass_bang);
class_addfloat(bandpass_class,bandpass_float);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,178 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- equ ----------------------------*/
static t_class *equ_class;
void equ_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b0 = 1 + alpha*e_A(x->x_gain);
t_float b1 = -2.*cos(omega);
t_float b2 = 1 - alpha*e_A(x->x_gain);
t_float a0 = 1 + alpha/e_A(x->x_gain);
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha/e_A(x->x_gain);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("equ: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void equ_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
equ_bang(x);
}
static void *equ_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(equ_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void equalizer_setup(void)
{
equ_class = class_new(gensym("equalizer"), (t_newmethod)equ_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(equ_class,equ_bang);
class_addfloat(equ_class,equ_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- equ ----------------------------*/
static t_class *equ_class;
void equ_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b0 = 1 + alpha*e_A(x->x_gain);
t_float b1 = -2.*cos(omega);
t_float b2 = 1 - alpha*e_A(x->x_gain);
t_float a0 = 1 + alpha/e_A(x->x_gain);
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha/e_A(x->x_gain);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("equ: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void equ_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
equ_bang(x);
}
static void *equ_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(equ_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void equalizer_setup(void)
{
equ_class = class_new(gensym("equalizer"), (t_newmethod)equ_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(equ_class,equ_bang);
class_addfloat(equ_class,equ_float);
}

View file

@ -0,0 +1,970 @@
/* ------------------------ fatom ----------------------------- */
#define x_val a_pos.a_w.w_float
#define DEBUG(x)
#include <string.h>
#include <stdio.h>
typedef struct _fatom
{
t_object x_obj;
t_atom a_pos; /* the value of the fatom */
t_symbol* x_send;
t_symbol* x_receive;
t_glist * x_glist; /* value of the current canvas, intialized in _new */
int x_rect_width; /* width of the widget */
int x_rect_height; /* height of the widget */
t_symbol* x_sym; /* symbol for receiving callbacks from GUI */
t_symbol* x_type; /* type of fatom (vslider, hslider, checkbutton) */
t_symbol* x_text; /* associated widget text */
int x_max; /* maximum value of a_pos (x_val) */
int x_min; /* minimum value of a_pos (x_val) */
int x_width; /* width of widget (e.g x_rect_height + 15 for hslider, x_rect_width + 15 for slider) */
t_symbol* x_color;
t_symbol* x_bgcolor;
} t_fatom;
/* widget helper functions */
static void draw_inlets(t_fatom *x, t_glist *glist, int firsttime, int nin, int nout)
{
int n = nin;
int nplus, i;
nplus = (n == 1 ? 1 : n-1);
DEBUG(post("draw inlet");)
for (i = 0; i < n; i++)
{
int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
glist_getcanvas(glist),
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 1,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height,
x, i);
else
sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 1,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height);
}
n = nout;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
glist_getcanvas(glist),
onset, text_ypix(&x->x_obj, glist),
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + 1,
x, i);
else
sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, text_ypix(&x->x_obj, glist),
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + 1);
}
DEBUG(post("draw inlet end");)
}
static void draw_handle(t_fatom *x, t_glist *glist, int firsttime) {
int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH+2);
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xhandle\n",
glist_getcanvas(glist),
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 12,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height-4,
x);
else
sys_vgui(".x%x.c coords %xhandle %d %d %d %d\n",
glist_getcanvas(glist), x,
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 12,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height-4);
}
static void create_widget(t_fatom *x, t_glist *glist)
{
t_canvas *canvas=glist_getcanvas(glist);
if (!strcmp(x->x_type->s_name,"vslider")) {
x->x_rect_width = x->x_width+15;
x->x_rect_height = x->x_max-x->x_min+26;
sys_vgui("scale .x%x.c.s%x \
-sliderlength 10 \
-showvalue 0 \
-length %d \
-resolution 0.01 \
-repeatinterval 20 \
-from %d -to %d \
-width %d \
-bg %s \
-activebackground %s \
-troughcolor %s \
-command fatom_cb%x\n",canvas,x,
x->x_max-x->x_min+14,
x->x_max,
x->x_min,
x->x_width,
x->x_color->s_name,
x->x_color->s_name,
x->x_bgcolor->s_name,
x);
} else if (!strcmp(x->x_type->s_name,"hslider")) {
x->x_rect_width = x->x_max-x->x_min + 24;
x->x_rect_height = x->x_width + 15;
sys_vgui("scale .x%x.c.s%x \
-sliderlength 10 \
-showvalue 0 \
-length %d \
-resolution 0.01 \
-orient horizontal \
-repeatinterval 20 \
-from %d -to %d \
-width %d \
-bg %s \
-activebackground %s \
-troughcolor %s \
-command fatom_cb%x\n",canvas,x,
x->x_max-x->x_min+14,
x->x_min,
x->x_max,
x->x_width,
x->x_color->s_name,
x->x_color->s_name,
x->x_bgcolor->s_name,
x);
} else if (!strcmp(x->x_type->s_name,"checkbutton")) {
x->x_rect_width = 32;
x->x_rect_height = 28;
sys_vgui("checkbutton .x%x.c.s%x \
-command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -text \"%s\" \
-bg %s \
-activebackground %s \
\n",canvas,x,x,x,x,
x->x_text->s_name,
x->x_color->s_name,
x->x_bgcolor->s_name);
} else if (!strcmp(x->x_type->s_name,"hradio")) {
int i;
x->x_rect_width = 8*20;
x->x_rect_height = 25;
for (i=0;i<8;i++) {
sys_vgui("radiobutton .x%x.c.s%x%d \
-command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -value %d\n",canvas,x,i,x,x,x,i);
}
/* TODO pack them */
} else if (!strcmp(x->x_type->s_name,"vradio")) {
int i;
x->x_rect_width = 30;
x->x_rect_height = 20*8+5;
for (i=0;i<8;i++) {
sys_vgui("radiobutton .x%x.c.s%x%d \
-command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -value %d\n",canvas,x,i,x,x,x,i);
}
/* TODO pack them */
} else {
x->x_rect_width = 32;
x->x_rect_height = 140;
sys_vgui("scale .x%x.c.s%x \
-sliderlength 10 \
-showvalue 0 \
-length 131 \
-from 127 -to 0 \
-command fatom_cb%x\n",canvas,x,x);
}
/* set the start value */
if (!strcmp(x->x_type->s_name,"checkbutton")) {
if (x->x_val)
sys_vgui(".x%x.c.s%x select\n",canvas,x,x->x_val);
else
sys_vgui(".x%x.c.s%x deselect\n",canvas,x,x->x_val);
} else
sys_vgui(".x%x.c.s%x set %f\n",canvas,x,x->x_val);
}
static void fatom_drawme(t_fatom *x, t_glist *glist, int firsttime)
{
t_canvas *canvas=glist_getcanvas(glist);// x->x_glist;//glist_getcanvas(glist);
DEBUG(post("drawme %d",firsttime);)
if (firsttime) {
DEBUG(post("glist %x canvas %x",x->x_glist,canvas));
create_widget(x,glist);
x->x_glist = canvas;
sys_vgui(".x%x.c create window %d %d -anchor nw -window .x%x.c.s%x -tags %xS\n",
canvas,text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist)+2,x->x_glist,x,x);
}
else {
sys_vgui(".x%x.c coords %xS \
%d %d\n",
canvas, x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist)+2);
}
draw_inlets(x, glist, firsttime, 1,1);
// draw_handle(x, glist, firsttime);
}
static void fatom_erase(t_fatom* x,t_glist* glist)
{
int n;
DEBUG(post("erase");)
sys_vgui("destroy .x%x.c.s%x\n",glist_getcanvas(glist),x);
sys_vgui(".x%x.c delete %xS\n",glist_getcanvas(glist), x);
/* inlets and outlets */
sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,0);
sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,0);
sys_vgui(".x%x.c delete %xhandle\n",glist_getcanvas(glist),x,0);
}
/* ------------------------ fatom widgetbehaviour----------------------------- */
static void fatom_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_fatom* s = (t_fatom*)z;
width = s->x_rect_width;
height = s->x_rect_height;
*xp1 = text_xpix(&s->x_obj, owner);
*yp1 = text_ypix(&s->x_obj, owner);
*xp2 = text_xpix(&s->x_obj, owner) + width;
*yp2 = text_ypix(&s->x_obj, owner) + height;
}
static void fatom_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_fatom *x = (t_fatom *)z;
DEBUG(post("displace");)
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
if (glist_isvisible(glist))
{
sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_rect_width, text_ypix(&x->x_obj, glist) + x->x_rect_height);
fatom_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
DEBUG(post("displace end");)
}
static void fatom_select(t_gobj *z, t_glist *glist, int state)
{
t_fatom *x = (t_fatom *)z;
if (state) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %xSEL -outline blue\n",
glist_getcanvas(glist),
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_rect_width, text_ypix(&x->x_obj, glist) + x->x_rect_height,
x);
}
else {
sys_vgui(".x%x.c delete %xSEL\n",
glist_getcanvas(glist), x);
}
}
static void fatom_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void fatom_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void fatom_vis(t_gobj *z, t_glist *glist, int vis)
{
t_fatom* s = (t_fatom*)z;
t_rtext *y;
DEBUG(post("vis: %d",vis);)
if (vis) {
#ifdef PD_MINOR_VERSION
y = (t_rtext *) rtext_new(glist, (t_text *)z);
#else
y = (t_rtext *) rtext_new(glist, (t_text *)z,0,0);
#endif
fatom_drawme(s, glist, 1);
}
else {
y = glist_findrtext(glist, (t_text *)z);
fatom_erase(s,glist);
rtext_free(y);
}
}
static void fatom_save(t_gobj *z, t_binbuf *b);
t_widgetbehavior fatom_widgetbehavior;
static void fatom_size(t_fatom* x,t_floatarg w,t_floatarg h) {
x->x_rect_width = w;
x->x_rect_height = h;
}
static void fatom_color(t_fatom* x,t_symbol* col)
{
}
static void fatom_f(t_fatom* x,t_floatarg f)
{
x->x_val = f;
if (x->x_send == &s_)
outlet_float(x->x_obj.ob_outlet,f);
else
if (x->x_send->s_thing) pd_float(x->x_send->s_thing,f);
}
static void fatom_float(t_fatom* x,t_floatarg f)
{
if (glist_isvisible(x->x_glist)) {
if (!strcmp(x->x_type->s_name,"checkbutton")) {
if (x->x_val)
sys_vgui(".x%x.c.s%x select\n",x->x_glist,x,f);
else
sys_vgui(".x%x.c.s%x deselect\n",x->x_glist,x,f);
} else
sys_vgui(".x%x.c.s%x set %f\n",x->x_glist,x,f);
}
fatom_f(x,f);
}
static void fatom_bang(t_fatom* x,t_floatarg f)
{
outlet_float(x->x_obj.ob_outlet,x->x_val);
}
static void fatom_properties(t_gobj *z, t_glist *owner)
{
post("N/I");
}
static void fatom_save(t_gobj *z, t_binbuf *b)
{
t_fatom *x = (t_fatom *)z;
binbuf_addv(b, "ssiiss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix ,
gensym("fatom"),x->x_type);
binbuf_addv(b, ";");
}
static void *fatom_new(t_fatom* x,int argc,t_atom* argv)
{
char buf[256];
int n = 0;
x->x_glist = canvas_getcurrent();
x->x_text = gensym("");
x->x_max = 127;
x->x_min = 0;
x->x_width = 15;
x->x_color = gensym("grey");
x->x_bgcolor = gensym("grey");
x->x_send = &s_;
while (argc) {
if (argv->a_type == A_FLOAT) {
if (n==0) x->x_max = atom_getfloat(argv);
if (n==1) x->x_min = atom_getfloat(argv);
if (n==2) x->x_width = atom_getfloat(argv);
}
if (argv->a_type == A_SYMBOL) {
post("%d: symbol value %s",n,atom_getsymbol(argv)->s_name);
if (n==3) x->x_send = atom_getsymbol(argv);
if (n==4) x->x_color = atom_getsymbol(argv);
if (n==5) x->x_bgcolor = atom_getsymbol(argv);
}
argv++;
argc--;
n++;
}
/* bind to a symbol for slider callback (later make this based on the
filepath ??) */
sprintf(buf,"fatom%x",(t_int)x);
x->x_sym = gensym(buf);
pd_bind(&x->x_obj.ob_pd, x->x_sym);
/* pipe startup code to tk */
sys_vgui("proc fatom_cb%x {v} {\n pd [concat fatom%x f $v \\;]\n }\n",x,x);
outlet_new(&x->x_obj, &s_float);
return (x);
}
static void fatom_setup_common(t_class* class)
{
fatom_widgetbehavior.w_getrectfn = fatom_getrect;
fatom_widgetbehavior.w_displacefn = fatom_displace;
fatom_widgetbehavior.w_selectfn = fatom_select;
fatom_widgetbehavior.w_activatefn = fatom_activate;
fatom_widgetbehavior.w_deletefn = fatom_delete;
fatom_widgetbehavior.w_visfn = fatom_vis;
#if PD_MINOR_VERSION < 37
fatom_widgetbehavior.w_savefn = fatom_save;
fatom_widgetbehavior.w_propertiesfn = NULL;
#endif
fatom_widgetbehavior.w_clickfn = NULL;
class_addfloat(class, (t_method)fatom_float);
class_addbang(class, (t_method)fatom_bang);
class_addmethod(class, (t_method)fatom_f, gensym("f"),
A_FLOAT, 0);
/*
class_addmethod(class, (t_method)fatom_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
class_addmethod(class, (t_method)fatom_color, gensym("color"),
A_SYMBOL, 0);
*/
/*
class_addmethod(class, (t_method)fatom_open, gensym("open"),
A_SYMBOL, 0);
*/
class_setwidget(class,&fatom_widgetbehavior);
#if PD_MINOR_VERSION >= 37
class_setsavefn(class,&fatom_save);
#endif
}
/* ------------------------ fatom ----------------------------- */
#define x_val a_pos.a_w.w_float
#define DEBUG(x)
#include <string.h>
#include <stdio.h>
typedef struct _fatom
{
t_object x_obj;
t_atom a_pos; /* the value of the fatom */
t_symbol* x_send;
t_symbol* x_receive;
t_glist * x_glist; /* value of the current canvas, intialized in _new */
int x_rect_width; /* width of the widget */
int x_rect_height; /* height of the widget */
t_symbol* x_sym; /* symbol for receiving callbacks from GUI */
t_symbol* x_type; /* type of fatom (vslider, hslider, checkbutton) */
t_symbol* x_text; /* associated widget text */
int x_max; /* maximum value of a_pos (x_val) */
int x_min; /* minimum value of a_pos (x_val) */
int x_width; /* width of widget (e.g x_rect_height + 15 for hslider, x_rect_width + 15 for slider) */
t_symbol* x_color;
t_symbol* x_bgcolor;
} t_fatom;
/* widget helper functions */
static void draw_inlets(t_fatom *x, t_glist *glist, int firsttime, int nin, int nout)
{
int n = nin;
int nplus, i;
nplus = (n == 1 ? 1 : n-1);
DEBUG(post("draw inlet");)
for (i = 0; i < n; i++)
{
int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
glist_getcanvas(glist),
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 1,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height,
x, i);
else
sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 1,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height);
}
n = nout;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
glist_getcanvas(glist),
onset, text_ypix(&x->x_obj, glist),
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + 1,
x, i);
else
sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, text_ypix(&x->x_obj, glist),
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + 1);
}
DEBUG(post("draw inlet end");)
}
static void draw_handle(t_fatom *x, t_glist *glist, int firsttime) {
int onset = text_xpix(&x->x_obj, glist) + (x->x_rect_width - IOWIDTH+2);
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xhandle\n",
glist_getcanvas(glist),
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 12,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height-4,
x);
else
sys_vgui(".x%x.c coords %xhandle %d %d %d %d\n",
glist_getcanvas(glist), x,
onset, text_ypix(&x->x_obj, glist) + x->x_rect_height - 12,
onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_rect_height-4);
}
static void create_widget(t_fatom *x, t_glist *glist)
{
t_canvas *canvas=glist_getcanvas(glist);
if (!strcmp(x->x_type->s_name,"vslider")) {
x->x_rect_width = x->x_width+15;
x->x_rect_height = x->x_max-x->x_min+26;
sys_vgui("scale .x%x.c.s%x \
-sliderlength 10 \
-showvalue 0 \
-length %d \
-resolution 0.01 \
-repeatinterval 20 \
-from %d -to %d \
-width %d \
-bg %s \
-activebackground %s \
-troughcolor %s \
-command fatom_cb%x\n",canvas,x,
x->x_max-x->x_min+14,
x->x_max,
x->x_min,
x->x_width,
x->x_color->s_name,
x->x_color->s_name,
x->x_bgcolor->s_name,
x);
} else if (!strcmp(x->x_type->s_name,"hslider")) {
x->x_rect_width = x->x_max-x->x_min + 24;
x->x_rect_height = x->x_width + 15;
sys_vgui("scale .x%x.c.s%x \
-sliderlength 10 \
-showvalue 0 \
-length %d \
-resolution 0.01 \
-orient horizontal \
-repeatinterval 20 \
-from %d -to %d \
-width %d \
-bg %s \
-activebackground %s \
-troughcolor %s \
-command fatom_cb%x\n",canvas,x,
x->x_max-x->x_min+14,
x->x_min,
x->x_max,
x->x_width,
x->x_color->s_name,
x->x_color->s_name,
x->x_bgcolor->s_name,
x);
} else if (!strcmp(x->x_type->s_name,"checkbutton")) {
x->x_rect_width = 32;
x->x_rect_height = 28;
sys_vgui("checkbutton .x%x.c.s%x \
-command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -text \"%s\" \
-bg %s \
-activebackground %s \
\n",canvas,x,x,x,x,
x->x_text->s_name,
x->x_color->s_name,
x->x_bgcolor->s_name);
} else if (!strcmp(x->x_type->s_name,"hradio")) {
int i;
x->x_rect_width = 8*20;
x->x_rect_height = 25;
for (i=0;i<8;i++) {
sys_vgui("radiobutton .x%x.c.s%x%d \
-command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -value %d\n",canvas,x,i,x,x,x,i);
}
/* TODO pack them */
} else if (!strcmp(x->x_type->s_name,"vradio")) {
int i;
x->x_rect_width = 30;
x->x_rect_height = 20*8+5;
for (i=0;i<8;i++) {
sys_vgui("radiobutton .x%x.c.s%x%d \
-command { fatom_cb%x $fatom_val%x} -variable fatom_val%x -value %d\n",canvas,x,i,x,x,x,i);
}
/* TODO pack them */
} else {
x->x_rect_width = 32;
x->x_rect_height = 140;
sys_vgui("scale .x%x.c.s%x \
-sliderlength 10 \
-showvalue 0 \
-length 131 \
-from 127 -to 0 \
-command fatom_cb%x\n",canvas,x,x);
}
/* set the start value */
if (!strcmp(x->x_type->s_name,"checkbutton")) {
if (x->x_val)
sys_vgui(".x%x.c.s%x select\n",canvas,x,x->x_val);
else
sys_vgui(".x%x.c.s%x deselect\n",canvas,x,x->x_val);
} else
sys_vgui(".x%x.c.s%x set %f\n",canvas,x,x->x_val);
}
static void fatom_drawme(t_fatom *x, t_glist *glist, int firsttime)
{
t_canvas *canvas=glist_getcanvas(glist);// x->x_glist;//glist_getcanvas(glist);
DEBUG(post("drawme %d",firsttime);)
if (firsttime) {
DEBUG(post("glist %x canvas %x",x->x_glist,canvas));
create_widget(x,glist);
x->x_glist = canvas;
sys_vgui(".x%x.c create window %d %d -anchor nw -window .x%x.c.s%x -tags %xS\n",
canvas,text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist)+2,x->x_glist,x,x);
}
else {
sys_vgui(".x%x.c coords %xS \
%d %d\n",
canvas, x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist)+2);
}
draw_inlets(x, glist, firsttime, 1,1);
// draw_handle(x, glist, firsttime);
}
static void fatom_erase(t_fatom* x,t_glist* glist)
{
int n;
DEBUG(post("erase");)
sys_vgui("destroy .x%x.c.s%x\n",glist_getcanvas(glist),x);
sys_vgui(".x%x.c delete %xS\n",glist_getcanvas(glist), x);
/* inlets and outlets */
sys_vgui(".x%x.c delete %xi%d\n",glist_getcanvas(glist),x,0);
sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,0);
sys_vgui(".x%x.c delete %xhandle\n",glist_getcanvas(glist),x,0);
}
/* ------------------------ fatom widgetbehaviour----------------------------- */
static void fatom_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_fatom* s = (t_fatom*)z;
width = s->x_rect_width;
height = s->x_rect_height;
*xp1 = text_xpix(&s->x_obj, owner);
*yp1 = text_ypix(&s->x_obj, owner);
*xp2 = text_xpix(&s->x_obj, owner) + width;
*yp2 = text_ypix(&s->x_obj, owner) + height;
}
static void fatom_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_fatom *x = (t_fatom *)z;
DEBUG(post("displace");)
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
if (glist_isvisible(glist))
{
sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_rect_width, text_ypix(&x->x_obj, glist) + x->x_rect_height);
fatom_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
DEBUG(post("displace end");)
}
static void fatom_select(t_gobj *z, t_glist *glist, int state)
{
t_fatom *x = (t_fatom *)z;
if (state) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %xSEL -outline blue\n",
glist_getcanvas(glist),
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_rect_width, text_ypix(&x->x_obj, glist) + x->x_rect_height,
x);
}
else {
sys_vgui(".x%x.c delete %xSEL\n",
glist_getcanvas(glist), x);
}
}
static void fatom_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void fatom_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void fatom_vis(t_gobj *z, t_glist *glist, int vis)
{
t_fatom* s = (t_fatom*)z;
t_rtext *y;
DEBUG(post("vis: %d",vis);)
if (vis) {
#ifdef PD_MINOR_VERSION
y = (t_rtext *) rtext_new(glist, (t_text *)z);
#else
y = (t_rtext *) rtext_new(glist, (t_text *)z,0,0);
#endif
fatom_drawme(s, glist, 1);
}
else {
y = glist_findrtext(glist, (t_text *)z);
fatom_erase(s,glist);
rtext_free(y);
}
}
static void fatom_save(t_gobj *z, t_binbuf *b);
t_widgetbehavior fatom_widgetbehavior;
static void fatom_size(t_fatom* x,t_floatarg w,t_floatarg h) {
x->x_rect_width = w;
x->x_rect_height = h;
}
static void fatom_color(t_fatom* x,t_symbol* col)
{
}
static void fatom_f(t_fatom* x,t_floatarg f)
{
x->x_val = f;
if (x->x_send == &s_)
outlet_float(x->x_obj.ob_outlet,f);
else
if (x->x_send->s_thing) pd_float(x->x_send->s_thing,f);
}
static void fatom_float(t_fatom* x,t_floatarg f)
{
if (glist_isvisible(x->x_glist)) {
if (!strcmp(x->x_type->s_name,"checkbutton")) {
if (x->x_val)
sys_vgui(".x%x.c.s%x select\n",x->x_glist,x,f);
else
sys_vgui(".x%x.c.s%x deselect\n",x->x_glist,x,f);
} else
sys_vgui(".x%x.c.s%x set %f\n",x->x_glist,x,f);
}
fatom_f(x,f);
}
static void fatom_bang(t_fatom* x,t_floatarg f)
{
outlet_float(x->x_obj.ob_outlet,x->x_val);
}
static void fatom_properties(t_gobj *z, t_glist *owner)
{
post("N/I");
}
static void fatom_save(t_gobj *z, t_binbuf *b)
{
t_fatom *x = (t_fatom *)z;
binbuf_addv(b, "ssiiss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix ,
gensym("fatom"),x->x_type);
binbuf_addv(b, ";");
}
static void *fatom_new(t_fatom* x,int argc,t_atom* argv)
{
char buf[256];
int n = 0;
x->x_glist = canvas_getcurrent();
x->x_text = gensym("");
x->x_max = 127;
x->x_min = 0;
x->x_width = 15;
x->x_color = gensym("grey");
x->x_bgcolor = gensym("grey");
x->x_send = &s_;
while (argc) {
if (argv->a_type == A_FLOAT) {
if (n==0) x->x_max = atom_getfloat(argv);
if (n==1) x->x_min = atom_getfloat(argv);
if (n==2) x->x_width = atom_getfloat(argv);
}
if (argv->a_type == A_SYMBOL) {
post("%d: symbol value %s",n,atom_getsymbol(argv)->s_name);
if (n==3) x->x_send = atom_getsymbol(argv);
if (n==4) x->x_color = atom_getsymbol(argv);
if (n==5) x->x_bgcolor = atom_getsymbol(argv);
}
argv++;
argc--;
n++;
}
/* bind to a symbol for slider callback (later make this based on the
filepath ??) */
sprintf(buf,"fatom%x",(t_int)x);
x->x_sym = gensym(buf);
pd_bind(&x->x_obj.ob_pd, x->x_sym);
/* pipe startup code to tk */
sys_vgui("proc fatom_cb%x {v} {\n pd [concat fatom%x f $v \\;]\n }\n",x,x);
outlet_new(&x->x_obj, &s_float);
return (x);
}
static void fatom_setup_common(t_class* class)
{
fatom_widgetbehavior.w_getrectfn = fatom_getrect;
fatom_widgetbehavior.w_displacefn = fatom_displace;
fatom_widgetbehavior.w_selectfn = fatom_select;
fatom_widgetbehavior.w_activatefn = fatom_activate;
fatom_widgetbehavior.w_deletefn = fatom_delete;
fatom_widgetbehavior.w_visfn = fatom_vis;
#if PD_MINOR_VERSION < 37
fatom_widgetbehavior.w_savefn = fatom_save;
fatom_widgetbehavior.w_propertiesfn = NULL;
#endif
fatom_widgetbehavior.w_clickfn = NULL;
class_addfloat(class, (t_method)fatom_float);
class_addbang(class, (t_method)fatom_bang);
class_addmethod(class, (t_method)fatom_f, gensym("f"),
A_FLOAT, 0);
/*
class_addmethod(class, (t_method)fatom_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
class_addmethod(class, (t_method)fatom_color, gensym("color"),
A_SYMBOL, 0);
*/
/*
class_addmethod(class, (t_method)fatom_open, gensym("open"),
A_SYMBOL, 0);
*/
class_setwidget(class,&fatom_widgetbehavior);
#if PD_MINOR_VERSION >= 37
class_setsavefn(class,&fatom_save);
#endif
}

View file

@ -0,0 +1,148 @@
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifndef __GGEE_FILTERS_H__
#define __GGEE_FILTERS_H__
#ifndef M_PI
#define M_PI 3.141593f
#endif
#include <math.h>
#define LN2 0.69314718
#define e_A(g) (pow(10,(g/40.)))
#define e_omega(f,r) (2.0*M_PI*f/r)
#define e_alpha(bw,omega) (sin(omega)*sinh(LN2/2. * bw * omega/sin(omega)))
#define e_beta(a,S) (sqrt((a*a + 1)/(S) - (a-1)*(a-1)))
typedef struct _rbjfilter
{
t_object x_obj;
t_float x_rate;
t_float x_freq;
t_float x_gain;
t_float x_bw;
} t_rbjfilter;
static int check_stability(t_float fb1,
t_float fb2,
t_float ff1,
t_float ff2,
t_float ff3)
{
float discriminant = fb1 * fb1 + 4 * fb2;
if (discriminant < 0) /* imaginary roots -- resonant filter */
{
/* they're conjugates so we just check that the product
is less than one */
if (fb2 >= -1.0f) goto stable;
}
else /* real roots */
{
/* check that the parabola 1 - fb1 x - fb2 x^2 has a
vertex between -1 and 1, and that it's nonnegative
at both ends, which implies both roots are in [1-,1]. */
if (fb1 <= 2.0f && fb1 >= -2.0f &&
1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
goto stable;
}
return 0;
stable:
return 1;
}
#endif
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifndef __GGEE_FILTERS_H__
#define __GGEE_FILTERS_H__
#ifndef M_PI
#define M_PI 3.141593f
#endif
#include <math.h>
#define LN2 0.69314718
#define e_A(g) (pow(10,(g/40.)))
#define e_omega(f,r) (2.0*M_PI*f/r)
#define e_alpha(bw,omega) (sin(omega)*sinh(LN2/2. * bw * omega/sin(omega)))
#define e_beta(a,S) (sqrt((a*a + 1)/(S) - (a-1)*(a-1)))
typedef struct _rbjfilter
{
t_object x_obj;
t_float x_rate;
t_float x_freq;
t_float x_gain;
t_float x_bw;
} t_rbjfilter;
static int check_stability(t_float fb1,
t_float fb2,
t_float ff1,
t_float ff2,
t_float ff3)
{
float discriminant = fb1 * fb1 + 4 * fb2;
if (discriminant < 0) /* imaginary roots -- resonant filter */
{
/* they're conjugates so we just check that the product
is less than one */
if (fb2 >= -1.0f) goto stable;
}
else /* real roots */
{
/* check that the parabola 1 - fb1 x - fb2 x^2 has a
vertex between -1 and 1, and that it's nonnegative
at both ends, which implies both roots are in [1-,1]. */
if (fb1 <= 2.0f && fb1 >= -2.0f &&
1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
goto stable;
}
return 0;
stable:
return 1;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,16 @@
#N canvas 0 0 240 300 8;
#X obj 21 61 gcanvas 80 80;
#X text 14 9 gcanvas .. mouse coordinate enabled canvas;
#X text 13 22 ==========================================;
#X floatatom 21 148 5 0 0 0 - - -;
#X floatatom 94 147 5 0 0 0 - - -;
#X connect 0 0 3 0;
#X connect 0 1 4 0;
#N canvas 0 0 240 300 8;
#X obj 21 61 gcanvas 80 80;
#X text 14 9 gcanvas .. mouse coordinate enabled canvas;
#X text 13 22 ==========================================;
#X floatatom 21 148 5 0 0 0 - - -;
#X floatatom 94 147 5 0 0 0 - - -;
#X connect 0 0 3 0;
#X connect 0 1 4 0;

View file

@ -0,0 +1,758 @@
/* (C) Guenter Geiger <geiger@xdv.org> */
#include "m_pd.h"
#include "g_canvas.h"
/* ------------------------ gcanvas ----------------------------- */
#define BACKGROUNDCOLOR "grey"
#define DEFAULTSIZE 80
static t_class *gcanvas_class;
typedef struct _gcanvas
{
t_object x_obj;
t_glist * x_glist;
t_outlet* out2;
t_outlet* out3;
int x_width;
int x_height;
int x;
int y;
int x_xgrid;
int x_ygrid;
} t_gcanvas;
static void rectangle(void* cv,void* o,char c,int x, int y,int w,int h,char* color) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
}
static void move_object(void* cv,void* o,char c,int x, int y,int w,int h) {
sys_vgui(".x%x.c coords %x%c %d %d %d %d\n",
cv,o,c,x,y,x+w,y+h);
}
static void color_object(void* cv,void* o,char c,char* color) {
sys_vgui(".x%x.c itemconfigure %x%c -fill %s\n", cv,
o, c,color);
}
static void delete_object(void* cv,void* o,char c) {
sys_vgui(".x%x.c delete %x%c\n",
cv, o,c);
}
static void line(void* cv,void* o,char c,int x,int y,int w,int h,char* color) {
sys_vgui(".x%x.c create line \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
}
/* widget helper functions */
void gcanvas_drawme(t_gcanvas *x, t_glist *glist, int firsttime)
{
int i;
if (firsttime) {
rectangle(glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height,BACKGROUNDCOLOR);
for (i=1;i<x->x_xgrid;i++)
line(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height,"red");
for (i=1;i<x->x_ygrid;i++)
line(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0,"blue");
}
else {
move_object(
glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height);
for (i=1;i<x->x_xgrid;i++)
move_object(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height);
for (i=1;i<x->x_ygrid;i++)
move_object(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0);
}
{
/* outlets */
int n = 3;
int nplus, i;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height,
x, i);
else
sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height);
}
/* inlets */
n = 0;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1,
x, i);
else
sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1);
}
}
}
void gcanvas_erase(t_gcanvas* x,t_glist* glist)
{
int n,i;
delete_object(glist_getcanvas(glist),x,'a');
for (i=1;i<x->x_xgrid;i++)
delete_object(glist_getcanvas(glist),x,'b'+ i);
for (i=1;i<x->x_ygrid;i++)
delete_object(glist_getcanvas(glist),x,'B'+ i);
n = 2;
while (n--) {
sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
}
}
/* ------------------------ gcanvas widgetbehaviour----------------------------- */
static void gcanvas_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_gcanvas* s = (t_gcanvas*)z;
width = s->x_width;
height = s->x_height;
*xp1 = s->x_obj.te_xpix;
*yp1 = s->x_obj.te_ypix;
*xp2 = s->x_obj.te_xpix + width;
*yp2 = s->x_obj.te_ypix + height;
}
static void gcanvas_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_gcanvas *x = (t_gcanvas *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
gcanvas_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void gcanvas_select(t_gobj *z, t_glist *glist, int state)
{
t_gcanvas *x = (t_gcanvas *)z;
color_object(glist,x,'a',state ? "blue" : BACKGROUNDCOLOR);
}
static void gcanvas_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void gcanvas_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void gcanvas_vis(t_gobj *z, t_glist *glist, int vis)
{
t_gcanvas* s = (t_gcanvas*)z;
if (vis)
gcanvas_drawme(s, glist, 1);
else
gcanvas_erase(s,glist);
}
/* can we use the normal text save function ?? */
static void gcanvas_save(t_gobj *z, t_binbuf *b)
{
t_gcanvas *x = (t_gcanvas *)z;
binbuf_addv(b, "ssiisiiii", gensym("#X"),gensym("obj"),
(t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
gensym("gcanvas"),x->x_width,x->x_height,
x->x_xgrid,
x->x_ygrid);
binbuf_addv(b, ";");
}
t_widgetbehavior gcanvas_widgetbehavior;
static void gcanvas_motion(t_gcanvas *x, t_floatarg dx, t_floatarg dy)
{
x->x += dx;
x->y += dy;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
}
void gcanvas_key(t_gcanvas *x, t_floatarg f)
{
post("key");
}
static void gcanvas_click(t_gcanvas *x,
t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
t_floatarg doit,int up)
{
glist_grab(x->x_glist, &x->x_obj.te_g, (t_glistmotionfn) gcanvas_motion,
(t_glistkeyfn) NULL, xpos, ypos);
x->x = xpos - x->x_obj.te_xpix;
x->y = ypos - x->x_obj.te_ypix;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
outlet_float(x->out3,0);
}
static int gcanvas_newclick(t_gobj *z, struct _glist *glist,
int xpix, int ypix, int shift, int alt, int dbl, int doit)
{
if (doit)
gcanvas_click((t_gcanvas *)z, (t_floatarg)xpix, (t_floatarg)ypix,
(t_floatarg)shift, 0, (t_floatarg)alt,dbl);
if (dbl) outlet_float(((t_gcanvas*)z)->out3,1);
return (1);
}
void gcanvas_size(t_gcanvas* x,t_floatarg w,t_floatarg h) {
x->x_width = w;
x->x_height = h;
gcanvas_drawme(x, x->x_glist, 0);
}
static void gcanvas_setwidget(void)
{
gcanvas_widgetbehavior.w_getrectfn = gcanvas_getrect;
gcanvas_widgetbehavior.w_displacefn = gcanvas_displace;
gcanvas_widgetbehavior.w_selectfn = gcanvas_select;
gcanvas_widgetbehavior.w_activatefn = gcanvas_activate;
gcanvas_widgetbehavior.w_deletefn = gcanvas_delete;
gcanvas_widgetbehavior.w_visfn = gcanvas_vis;
gcanvas_widgetbehavior.w_clickfn = gcanvas_newclick;
class_setsavefn(gcanvas_class,gcanvas_save);
}
static void *gcanvas_new(t_symbol* s,t_int ac,t_atom* at)
{
t_gcanvas *x = (t_gcanvas *)pd_new(gcanvas_class);
x->x_glist = (t_glist*) canvas_getcurrent();
/* Fetch the width */
x->x_width = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_width = atom_getfloat(at++);
if (x->x_width < 0 || x->x_width > 2000) {
error("gcanvas: unallowed width %f",x->x_width);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the height */
x->x_height = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_height = atom_getfloat(at++);
if (x->x_height < 0 || x->x_height > 2000) {
error("gcanvas: unallowed height %f",x->x_height);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the xgrid */
x->x_xgrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_xgrid = atom_getfloat(at++);
if (x->x_xgrid < 0 || x->x_xgrid > x->x_width/2) {
error("gcanvas: unallowed xgrid %f",x->x_xgrid);
x->x_xgrid = 0;
}
}
/* Fetch the ygrid */
x->x_ygrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_ygrid = atom_getfloat(at++);
if (x->x_ygrid < 0 || x->x_ygrid > x->x_height/2) {
error("gcanvas: unallowed xgrid %f",x->x_ygrid);
x->x_ygrid = 0;
}
}
outlet_new(&x->x_obj, &s_float);
x->out2 = outlet_new(&x->x_obj, &s_float);
x->out3 = outlet_new(&x->x_obj, &s_float);
return (x);
}
void gcanvas_setup(void)
{
gcanvas_class = class_new(gensym("gcanvas"), (t_newmethod)gcanvas_new, 0,
sizeof(t_gcanvas),0, A_GIMME,0);
class_addmethod(gcanvas_class, (t_method)gcanvas_click, gensym("click"),
A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(gcanvas_class, (t_method)gcanvas_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
gcanvas_setwidget();
class_setwidget(gcanvas_class,&gcanvas_widgetbehavior);
}
/* (C) Guenter Geiger <geiger@xdv.org> */
#include "m_pd.h"
#include "g_canvas.h"
/* ------------------------ gcanvas ----------------------------- */
#define BACKGROUNDCOLOR "grey"
#define DEFAULTSIZE 80
static t_class *gcanvas_class;
typedef struct _gcanvas
{
t_object x_obj;
t_glist * x_glist;
t_outlet* out2;
t_outlet* out3;
int x_width;
int x_height;
int x;
int y;
int x_xgrid;
int x_ygrid;
} t_gcanvas;
static void rectangle(void* cv,void* o,char c,int x, int y,int w,int h,char* color) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
}
static void move_object(void* cv,void* o,char c,int x, int y,int w,int h) {
sys_vgui(".x%x.c coords %x%c %d %d %d %d\n",
cv,o,c,x,y,x+w,y+h);
}
static void color_object(void* cv,void* o,char c,char* color) {
sys_vgui(".x%x.c itemconfigure %x%c -fill %s\n", cv,
o, c,color);
}
static void delete_object(void* cv,void* o,char c) {
sys_vgui(".x%x.c delete %x%c\n",
cv, o,c);
}
static void line(void* cv,void* o,char c,int x,int y,int w,int h,char* color) {
sys_vgui(".x%x.c create line \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
}
/* widget helper functions */
void gcanvas_drawme(t_gcanvas *x, t_glist *glist, int firsttime)
{
int i;
if (firsttime) {
rectangle(glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height,BACKGROUNDCOLOR);
for (i=1;i<x->x_xgrid;i++)
line(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height,"red");
for (i=1;i<x->x_ygrid;i++)
line(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0,"blue");
}
else {
move_object(
glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height);
for (i=1;i<x->x_xgrid;i++)
move_object(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height);
for (i=1;i<x->x_ygrid;i++)
move_object(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0);
}
{
/* outlets */
int n = 3;
int nplus, i;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height,
x, i);
else
sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height);
}
/* inlets */
n = 0;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1,
x, i);
else
sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1);
}
}
}
void gcanvas_erase(t_gcanvas* x,t_glist* glist)
{
int n,i;
delete_object(glist_getcanvas(glist),x,'a');
for (i=1;i<x->x_xgrid;i++)
delete_object(glist_getcanvas(glist),x,'b'+ i);
for (i=1;i<x->x_ygrid;i++)
delete_object(glist_getcanvas(glist),x,'B'+ i);
n = 2;
while (n--) {
sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
}
}
/* ------------------------ gcanvas widgetbehaviour----------------------------- */
static void gcanvas_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_gcanvas* s = (t_gcanvas*)z;
width = s->x_width;
height = s->x_height;
*xp1 = s->x_obj.te_xpix;
*yp1 = s->x_obj.te_ypix;
*xp2 = s->x_obj.te_xpix + width;
*yp2 = s->x_obj.te_ypix + height;
}
static void gcanvas_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_gcanvas *x = (t_gcanvas *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
gcanvas_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void gcanvas_select(t_gobj *z, t_glist *glist, int state)
{
t_gcanvas *x = (t_gcanvas *)z;
color_object(glist,x,'a',state ? "blue" : BACKGROUNDCOLOR);
}
static void gcanvas_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void gcanvas_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void gcanvas_vis(t_gobj *z, t_glist *glist, int vis)
{
t_gcanvas* s = (t_gcanvas*)z;
if (vis)
gcanvas_drawme(s, glist, 1);
else
gcanvas_erase(s,glist);
}
/* can we use the normal text save function ?? */
static void gcanvas_save(t_gobj *z, t_binbuf *b)
{
t_gcanvas *x = (t_gcanvas *)z;
binbuf_addv(b, "ssiisiiii", gensym("#X"),gensym("obj"),
(t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
gensym("gcanvas"),x->x_width,x->x_height,
x->x_xgrid,
x->x_ygrid);
binbuf_addv(b, ";");
}
t_widgetbehavior gcanvas_widgetbehavior;
static void gcanvas_motion(t_gcanvas *x, t_floatarg dx, t_floatarg dy)
{
x->x += dx;
x->y += dy;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
}
void gcanvas_key(t_gcanvas *x, t_floatarg f)
{
post("key");
}
static void gcanvas_click(t_gcanvas *x,
t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
t_floatarg doit,int up)
{
glist_grab(x->x_glist, &x->x_obj.te_g, (t_glistmotionfn) gcanvas_motion,
(t_glistkeyfn) NULL, xpos, ypos);
x->x = xpos - x->x_obj.te_xpix;
x->y = ypos - x->x_obj.te_ypix;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
outlet_float(x->out3,0);
}
static int gcanvas_newclick(t_gobj *z, struct _glist *glist,
int xpix, int ypix, int shift, int alt, int dbl, int doit)
{
if (doit)
gcanvas_click((t_gcanvas *)z, (t_floatarg)xpix, (t_floatarg)ypix,
(t_floatarg)shift, 0, (t_floatarg)alt,dbl);
if (dbl) outlet_float(((t_gcanvas*)z)->out3,1);
return (1);
}
void gcanvas_size(t_gcanvas* x,t_floatarg w,t_floatarg h) {
x->x_width = w;
x->x_height = h;
gcanvas_drawme(x, x->x_glist, 0);
}
static void gcanvas_setwidget(void)
{
gcanvas_widgetbehavior.w_getrectfn = gcanvas_getrect;
gcanvas_widgetbehavior.w_displacefn = gcanvas_displace;
gcanvas_widgetbehavior.w_selectfn = gcanvas_select;
gcanvas_widgetbehavior.w_activatefn = gcanvas_activate;
gcanvas_widgetbehavior.w_deletefn = gcanvas_delete;
gcanvas_widgetbehavior.w_visfn = gcanvas_vis;
gcanvas_widgetbehavior.w_clickfn = gcanvas_newclick;
class_setsavefn(gcanvas_class,gcanvas_save);
}
static void *gcanvas_new(t_symbol* s,t_int ac,t_atom* at)
{
t_gcanvas *x = (t_gcanvas *)pd_new(gcanvas_class);
x->x_glist = (t_glist*) canvas_getcurrent();
/* Fetch the width */
x->x_width = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_width = atom_getfloat(at++);
if (x->x_width < 0 || x->x_width > 2000) {
error("gcanvas: unallowed width %f",x->x_width);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the height */
x->x_height = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_height = atom_getfloat(at++);
if (x->x_height < 0 || x->x_height > 2000) {
error("gcanvas: unallowed height %f",x->x_height);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the xgrid */
x->x_xgrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_xgrid = atom_getfloat(at++);
if (x->x_xgrid < 0 || x->x_xgrid > x->x_width/2) {
error("gcanvas: unallowed xgrid %f",x->x_xgrid);
x->x_xgrid = 0;
}
}
/* Fetch the ygrid */
x->x_ygrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_ygrid = atom_getfloat(at++);
if (x->x_ygrid < 0 || x->x_ygrid > x->x_height/2) {
error("gcanvas: unallowed xgrid %f",x->x_ygrid);
x->x_ygrid = 0;
}
}
outlet_new(&x->x_obj, &s_float);
x->out2 = outlet_new(&x->x_obj, &s_float);
x->out3 = outlet_new(&x->x_obj, &s_float);
return (x);
}
void gcanvas_setup(void)
{
gcanvas_class = class_new(gensym("gcanvas"), (t_newmethod)gcanvas_new, 0,
sizeof(t_gcanvas),0, A_GIMME,0);
class_addmethod(gcanvas_class, (t_method)gcanvas_click, gensym("click"),
A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(gcanvas_class, (t_method)gcanvas_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
gcanvas_setwidget();
class_setwidget(gcanvas_class,&gcanvas_widgetbehavior);
}

View file

@ -0,0 +1,174 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- highpass ----------------------------*/
static t_class *highpass_class;
void highpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -(1 + cos(omega));
t_float b0 = -b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highpass_bang(x);
}
static void *highpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void highpass_setup(void)
{
highpass_class = class_new(gensym("highpass"), (t_newmethod)highpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highpass_class,highpass_bang);
class_addfloat(highpass_class,highpass_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- highpass ----------------------------*/
static t_class *highpass_class;
void highpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -(1 + cos(omega));
t_float b0 = -b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highpass_bang(x);
}
static void *highpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void highpass_setup(void)
{
highpass_class = class_new(gensym("highpass"), (t_newmethod)highpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highpass_class,highpass_bang);
class_addfloat(highpass_class,highpass_float);
}

View file

@ -0,0 +1,180 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- highshelf ----------------------------*/
static t_class *highshelf_class;
void highshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw* 0.01);
t_float b0 = A*((A+1) + (A-1)*cs + beta*sn);
t_float b1 =-2.*A*((A-1) + (A+1)*cs);
t_float b2 = A*((A+1) + (A-1)*cs - beta*sn);
t_float a0 = ((A+1) - (A-1)*cs + beta*sn);
t_float a1 = 2.*((A-1) - (A+1)*cs);
t_float a2 = ((A+1) - (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highshelf_bang(x);
}
static void *highshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void highshelf_setup(void)
{
highshelf_class = class_new(gensym("highshelf"), (t_newmethod)highshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highshelf_class,highshelf_bang);
class_addfloat(highshelf_class,highshelf_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- highshelf ----------------------------*/
static t_class *highshelf_class;
void highshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw* 0.01);
t_float b0 = A*((A+1) + (A-1)*cs + beta*sn);
t_float b1 =-2.*A*((A-1) + (A+1)*cs);
t_float b2 = A*((A+1) + (A-1)*cs - beta*sn);
t_float a0 = ((A+1) - (A-1)*cs + beta*sn);
t_float a1 = 2.*((A-1) - (A+1)*cs);
t_float a2 = ((A+1) - (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highshelf_bang(x);
}
static void *highshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void highshelf_setup(void)
{
highshelf_class = class_new(gensym("highshelf"), (t_newmethod)highshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highshelf_class,highshelf_bang);
class_addfloat(highshelf_class,highshelf_float);
}

View file

@ -0,0 +1,452 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include <m_pd.h>
#include <math.h>
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
/* ------------------------ hlshelf ----------------------------- */
#ifndef M_PI
#define M_PI 3.141593f
#endif
#define SRATE 44100.0
#define MAX_GAIN 120.0f
static t_class *hlshelf_class;
typedef struct _hlshelf
{
t_object x_obj;
float s_rate;
float s_gain0;
float s_gain1;
float s_gain2;
float s_ltransfq;
float s_htransfq;
float s_lradians;
float s_hradians;
} t_hlshelf;
int hlshelf_check_stability(t_float fb1,
t_float fb2,
t_float ff1,
t_float ff2,
t_float ff3)
{
float discriminant = fb1 * fb1 + 4 * fb2;
if (discriminant < 0) /* imaginary roots -- resonant filter */
{
/* they're conjugates so we just check that the product
is less than one */
if (fb2 >= -1.0f) goto stable;
}
else /* real roots */
{
/* check that the parabola 1 - fb1 x - fb2 x^2 has a
vertex between -1 and 1, and that it's nonnegative
at both ends, which implies both roots are in [1-,1]. */
if (fb1 <= 2.0f && fb1 >= -2.0f &&
1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
goto stable;
}
return 0;
stable:
return 1;
}
void hlshelf_check(t_hlshelf *x)
{
if(x->s_gain0 - x->s_gain1 > MAX_GAIN) {
x->s_gain0 = x->s_gain1 + MAX_GAIN;
post("setting gain0 to %f",x->s_gain0);
}
if(x->s_gain1 > MAX_GAIN) {
x->s_gain1 = MAX_GAIN;
post("setting gain1 to %f",x->s_gain1);
}
if(x->s_gain2 - x->s_gain1 > MAX_GAIN) {
x->s_gain2 = x->s_gain1 + MAX_GAIN;
post("setting gain2 to %f",x->s_gain2);
}
/* constrain: 0 <= x->s_ltransfq < x->s_htransfq. */
x->s_ltransfq = (x->s_ltransfq < x->s_htransfq) ? x->s_ltransfq : x->s_htransfq - 0.5f;
if (x->s_ltransfq < 0) x->s_ltransfq = 0.0f;
x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
}
void hlshelf_bang(t_hlshelf *x)
{
t_atom at[6];
float c0, c1, c2, d0, d1, d2; /* output coefs */
float a1, a2, b1, b2, g1, g2; /* temp coefs */
double xf;
hlshelf_check(x);
/* low shelf */
xf = 0.5 * 0.115129255 * (double)(x->s_gain0 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
if(xf < -200.) /* exp(x) -> 0 */
{
a1 = 1.0f;
b1 = -1.0f;
g1 = 0.0f;
}
else
{
double t = tan(x->s_lradians);
double e = exp(xf);
double r = t / e;
double kr = t * e;
a1 = (r - 1) / (r + 1);
b1 = (kr - 1) / (kr + 1);
g1 = (kr + 1) / (r + 1);
}
/* high shelf */
xf = 0.5 * 0.115129255 * (double)(x->s_gain2 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
if(xf < -200.) /* exp(x) -> 0 */
{
a2 = -1.0f;
b2 = 1.0f;
g2 = 0.0f;
}
else
{
double t = tan(x->s_hradians);
double e = exp(xf);
double r = t / e;
double kr = t * e;
a2 = (1 - r) / (1 + r);
b2 = (1 - kr) / (1 + kr);
g2 = (1 + kr) / (1 + r);
}
/* form product */
c0 = g1 * g2 * (float)(exp((double)(x->s_gain1) * 0.05f * 2.302585093f)); ;
c1 = a1 + a2;
c2 = a1 * a2;
d0 = 1.0f;
d1 = b1 + b2;
d2 = b1 * b2;
if (!hlshelf_check_stability(-c1/d0,-c2/d0,d0/d0,d1/d0,d2/d0)) {
post("hlshelf: filter unstable -> resetting");
c0=1.;c1=0.;c2=0.;
d0=1.;d1=0.;d2=0.;
}
SETFLOAT(at,-c1/d0);
SETFLOAT(at+1,-c2/d0);
SETFLOAT(at+2,d0/d0);
SETFLOAT(at+3,d1/d0);
SETFLOAT(at+4,d2/d0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void hlshelf_float(t_hlshelf *x,t_floatarg f)
{
x->s_gain0 = f;
hlshelf_bang(x);
}
static void *hlshelf_new(t_symbol* s,t_int argc, t_atom* at)
{
t_hlshelf *x = (t_hlshelf *)pd_new(hlshelf_class);
t_float k0 = atom_getfloat(at);
t_float k1 = atom_getfloat(at+1);
t_float k2 = atom_getfloat(at+2);
t_float f1 = atom_getfloat(at+3);
t_float f2 = atom_getfloat(at+4);
f1 = atom_getfloat(at);
f2 = atom_getfloat(at);
if ((f1 == 0.0f && f2 == 0.0f) || f1 > f2){ /* all gains = 0db */
f1 = 150.0f;
f2 = 5000.0f;
}
if (f1 < 0) f1 = 0.0f;
if (f2 > SRATE) f2 = .5f*SRATE;
x->s_rate = SRATE; /* srate default */
x->s_gain0 = k0;
x->s_gain1 = k1;
x->s_gain2 = k2;
x->s_ltransfq = 0.0f;
x->s_htransfq = SRATE/2;
x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
floatinlet_new(&x->x_obj, &x->s_gain1);
floatinlet_new(&x->x_obj, &x->s_gain2);
floatinlet_new(&x->x_obj, &x->s_ltransfq);
floatinlet_new(&x->x_obj, &x->s_htransfq);
outlet_new(&x->x_obj, &s_list);
return (x);
}
void hlshelf_setup(void)
{
hlshelf_class = class_new(gensym("hlshelf"), (t_newmethod)hlshelf_new, 0,
sizeof(t_hlshelf), 0, A_GIMME, 0);
class_addbang(hlshelf_class,hlshelf_bang);
class_addfloat(hlshelf_class,hlshelf_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include <m_pd.h>
#include <math.h>
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
/* ------------------------ hlshelf ----------------------------- */
#ifndef M_PI
#define M_PI 3.141593f
#endif
#define SRATE 44100.0
#define MAX_GAIN 120.0f
static t_class *hlshelf_class;
typedef struct _hlshelf
{
t_object x_obj;
float s_rate;
float s_gain0;
float s_gain1;
float s_gain2;
float s_ltransfq;
float s_htransfq;
float s_lradians;
float s_hradians;
} t_hlshelf;
int hlshelf_check_stability(t_float fb1,
t_float fb2,
t_float ff1,
t_float ff2,
t_float ff3)
{
float discriminant = fb1 * fb1 + 4 * fb2;
if (discriminant < 0) /* imaginary roots -- resonant filter */
{
/* they're conjugates so we just check that the product
is less than one */
if (fb2 >= -1.0f) goto stable;
}
else /* real roots */
{
/* check that the parabola 1 - fb1 x - fb2 x^2 has a
vertex between -1 and 1, and that it's nonnegative
at both ends, which implies both roots are in [1-,1]. */
if (fb1 <= 2.0f && fb1 >= -2.0f &&
1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
goto stable;
}
return 0;
stable:
return 1;
}
void hlshelf_check(t_hlshelf *x)
{
if(x->s_gain0 - x->s_gain1 > MAX_GAIN) {
x->s_gain0 = x->s_gain1 + MAX_GAIN;
post("setting gain0 to %f",x->s_gain0);
}
if(x->s_gain1 > MAX_GAIN) {
x->s_gain1 = MAX_GAIN;
post("setting gain1 to %f",x->s_gain1);
}
if(x->s_gain2 - x->s_gain1 > MAX_GAIN) {
x->s_gain2 = x->s_gain1 + MAX_GAIN;
post("setting gain2 to %f",x->s_gain2);
}
/* constrain: 0 <= x->s_ltransfq < x->s_htransfq. */
x->s_ltransfq = (x->s_ltransfq < x->s_htransfq) ? x->s_ltransfq : x->s_htransfq - 0.5f;
if (x->s_ltransfq < 0) x->s_ltransfq = 0.0f;
x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
}
void hlshelf_bang(t_hlshelf *x)
{
t_atom at[6];
float c0, c1, c2, d0, d1, d2; /* output coefs */
float a1, a2, b1, b2, g1, g2; /* temp coefs */
double xf;
hlshelf_check(x);
/* low shelf */
xf = 0.5 * 0.115129255 * (double)(x->s_gain0 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
if(xf < -200.) /* exp(x) -> 0 */
{
a1 = 1.0f;
b1 = -1.0f;
g1 = 0.0f;
}
else
{
double t = tan(x->s_lradians);
double e = exp(xf);
double r = t / e;
double kr = t * e;
a1 = (r - 1) / (r + 1);
b1 = (kr - 1) / (kr + 1);
g1 = (kr + 1) / (r + 1);
}
/* high shelf */
xf = 0.5 * 0.115129255 * (double)(x->s_gain2 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */
if(xf < -200.) /* exp(x) -> 0 */
{
a2 = -1.0f;
b2 = 1.0f;
g2 = 0.0f;
}
else
{
double t = tan(x->s_hradians);
double e = exp(xf);
double r = t / e;
double kr = t * e;
a2 = (1 - r) / (1 + r);
b2 = (1 - kr) / (1 + kr);
g2 = (1 + kr) / (1 + r);
}
/* form product */
c0 = g1 * g2 * (float)(exp((double)(x->s_gain1) * 0.05f * 2.302585093f)); ;
c1 = a1 + a2;
c2 = a1 * a2;
d0 = 1.0f;
d1 = b1 + b2;
d2 = b1 * b2;
if (!hlshelf_check_stability(-c1/d0,-c2/d0,d0/d0,d1/d0,d2/d0)) {
post("hlshelf: filter unstable -> resetting");
c0=1.;c1=0.;c2=0.;
d0=1.;d1=0.;d2=0.;
}
SETFLOAT(at,-c1/d0);
SETFLOAT(at+1,-c2/d0);
SETFLOAT(at+2,d0/d0);
SETFLOAT(at+3,d1/d0);
SETFLOAT(at+4,d2/d0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void hlshelf_float(t_hlshelf *x,t_floatarg f)
{
x->s_gain0 = f;
hlshelf_bang(x);
}
static void *hlshelf_new(t_symbol* s,t_int argc, t_atom* at)
{
t_hlshelf *x = (t_hlshelf *)pd_new(hlshelf_class);
t_float k0 = atom_getfloat(at);
t_float k1 = atom_getfloat(at+1);
t_float k2 = atom_getfloat(at+2);
t_float f1 = atom_getfloat(at+3);
t_float f2 = atom_getfloat(at+4);
f1 = atom_getfloat(at);
f2 = atom_getfloat(at);
if ((f1 == 0.0f && f2 == 0.0f) || f1 > f2){ /* all gains = 0db */
f1 = 150.0f;
f2 = 5000.0f;
}
if (f1 < 0) f1 = 0.0f;
if (f2 > SRATE) f2 = .5f*SRATE;
x->s_rate = SRATE; /* srate default */
x->s_gain0 = k0;
x->s_gain1 = k1;
x->s_gain2 = k2;
x->s_ltransfq = 0.0f;
x->s_htransfq = SRATE/2;
x->s_lradians = M_PI * x->s_ltransfq / x->s_rate;
x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate));
floatinlet_new(&x->x_obj, &x->s_gain1);
floatinlet_new(&x->x_obj, &x->s_gain2);
floatinlet_new(&x->x_obj, &x->s_ltransfq);
floatinlet_new(&x->x_obj, &x->s_htransfq);
outlet_new(&x->x_obj, &s_list);
return (x);
}
void hlshelf_setup(void)
{
hlshelf_class = class_new(gensym("hlshelf"), (t_newmethod)hlshelf_new, 0,
sizeof(t_hlshelf), 0, A_GIMME, 0);
class_addbang(hlshelf_class,hlshelf_bang);
class_addfloat(hlshelf_class,hlshelf_float);
}

View file

@ -0,0 +1,434 @@
#include "m_pd.h"
#include "g_canvas.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
/* ------------------------ image ----------------------------- */
static t_class *image_class;
typedef struct _image
{
t_object x_obj;
t_glist * x_glist;
int x_width;
int x_height;
t_symbol* x_fname;
} t_image;
/* widget helper functions */
void image_drawme(t_image *x, t_glist *glist, int firsttime)
{
if (firsttime) {
char fname[MAXPDSTRING];
canvas_makefilename(glist_getcanvas(x->x_glist), x->x_fname->s_name,
fname, MAXPDSTRING);
sys_vgui("image create photo img%x -file %s\n",x,fname);
sys_vgui(".x%x.c create image %d %d -image img%x -tags %xS\n",
glist_getcanvas(glist),text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),x,x);
/* TODO callback from gui
sys_vgui("image_size logo");
*/
}
else {
sys_vgui(".x%x.c coords %xS \
%d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist));
}
}
void image_erase(t_image* x,t_glist* glist)
{
int n;
sys_vgui(".x%x.c delete %xS\n",
glist_getcanvas(glist), x);
}
/* ------------------------ image widgetbehaviour----------------------------- */
static void image_getrect(t_gobj *z, t_glist *glist,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_image* x = (t_image*)z;
width = x->x_width;
height = x->x_height;
*xp1 = text_xpix(&x->x_obj, glist);
*yp1 = text_ypix(&x->x_obj, glist);
*xp2 = text_xpix(&x->x_obj, glist) + width;
*yp2 = text_ypix(&x->x_obj, glist) + height;
}
static void image_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_image *x = (t_image *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height);
image_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void image_select(t_gobj *z, t_glist *glist, int state)
{
t_image *x = (t_image *)z;
if (state) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %xSEL -outline blue\n",
glist_getcanvas(glist),
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height,
x);
}
else {
sys_vgui(".x%x.c delete %xSEL\n",
glist_getcanvas(glist), x);
}
}
static void image_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void image_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void image_vis(t_gobj *z, t_glist *glist, int vis)
{
t_image* s = (t_image*)z;
if (vis)
image_drawme(s, glist, 1);
else
image_erase(s,glist);
}
/* can we use the normal text save function ?? */
static void image_save(t_gobj *z, t_binbuf *b)
{
t_image *x = (t_image *)z;
binbuf_addv(b, "ssiiss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix,
gensym("image"),x->x_fname);
binbuf_addv(b, ";");
}
t_widgetbehavior image_widgetbehavior;
void image_size(t_image* x,t_floatarg w,t_floatarg h) {
x->x_width = w;
x->x_height = h;
}
void image_color(t_image* x,t_symbol* col)
{
/* outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang ..
so color black does the same as bang, but doesn't forward the bang
*/
}
static void image_setwidget(void)
{
image_widgetbehavior.w_getrectfn = image_getrect;
image_widgetbehavior.w_displacefn = image_displace;
image_widgetbehavior.w_selectfn = image_select;
image_widgetbehavior.w_activatefn = image_activate;
image_widgetbehavior.w_deletefn = image_delete;
image_widgetbehavior.w_visfn = image_vis;
#if (PD_VERSION_MINOR > 31)
image_widgetbehavior.w_clickfn = NULL;
image_widgetbehavior.w_propertiesfn = NULL;
#endif
#if PD_MINOR_VERSION < 37
image_widgetbehavior.w_savefn = image_save;
#endif
}
static void *image_new(t_symbol* fname)
{
t_image *x = (t_image *)pd_new(image_class);
x->x_glist = (t_glist*) canvas_getcurrent();
x->x_width = 15;
x->x_height = 15;
x->x_fname = fname;
outlet_new(&x->x_obj, &s_float);
return (x);
}
void image_setup(void)
{
image_class = class_new(gensym("image"), (t_newmethod)image_new, 0,
sizeof(t_image),0, A_DEFSYM,0);
/*
class_addmethod(image_class, (t_method)image_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
class_addmethod(image_class, (t_method)image_color, gensym("color"),
A_SYMBOL, 0);
*/
/*
class_addmethod(image_class, (t_method)image_open, gensym("open"),
A_SYMBOL, 0);
*/
image_setwidget();
class_setwidget(image_class,&image_widgetbehavior);
#if PD_MINOR_VERSION >= 37
class_setsavefn(image_class,&image_save);
#endif
}
#include "m_pd.h"
#include "g_canvas.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
/* ------------------------ image ----------------------------- */
static t_class *image_class;
typedef struct _image
{
t_object x_obj;
t_glist * x_glist;
int x_width;
int x_height;
t_symbol* x_fname;
} t_image;
/* widget helper functions */
void image_drawme(t_image *x, t_glist *glist, int firsttime)
{
if (firsttime) {
char fname[MAXPDSTRING];
canvas_makefilename(glist_getcanvas(x->x_glist), x->x_fname->s_name,
fname, MAXPDSTRING);
sys_vgui("image create photo img%x -file %s\n",x,fname);
sys_vgui(".x%x.c create image %d %d -image img%x -tags %xS\n",
glist_getcanvas(glist),text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),x,x);
/* TODO callback from gui
sys_vgui("image_size logo");
*/
}
else {
sys_vgui(".x%x.c coords %xS \
%d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist));
}
}
void image_erase(t_image* x,t_glist* glist)
{
int n;
sys_vgui(".x%x.c delete %xS\n",
glist_getcanvas(glist), x);
}
/* ------------------------ image widgetbehaviour----------------------------- */
static void image_getrect(t_gobj *z, t_glist *glist,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_image* x = (t_image*)z;
width = x->x_width;
height = x->x_height;
*xp1 = text_xpix(&x->x_obj, glist);
*yp1 = text_ypix(&x->x_obj, glist);
*xp2 = text_xpix(&x->x_obj, glist) + width;
*yp2 = text_ypix(&x->x_obj, glist) + height;
}
static void image_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_image *x = (t_image *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height);
image_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void image_select(t_gobj *z, t_glist *glist, int state)
{
t_image *x = (t_image *)z;
if (state) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %xSEL -outline blue\n",
glist_getcanvas(glist),
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height,
x);
}
else {
sys_vgui(".x%x.c delete %xSEL\n",
glist_getcanvas(glist), x);
}
}
static void image_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void image_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void image_vis(t_gobj *z, t_glist *glist, int vis)
{
t_image* s = (t_image*)z;
if (vis)
image_drawme(s, glist, 1);
else
image_erase(s,glist);
}
/* can we use the normal text save function ?? */
static void image_save(t_gobj *z, t_binbuf *b)
{
t_image *x = (t_image *)z;
binbuf_addv(b, "ssiiss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix,
gensym("image"),x->x_fname);
binbuf_addv(b, ";");
}
t_widgetbehavior image_widgetbehavior;
void image_size(t_image* x,t_floatarg w,t_floatarg h) {
x->x_width = w;
x->x_height = h;
}
void image_color(t_image* x,t_symbol* col)
{
/* outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang ..
so color black does the same as bang, but doesn't forward the bang
*/
}
static void image_setwidget(void)
{
image_widgetbehavior.w_getrectfn = image_getrect;
image_widgetbehavior.w_displacefn = image_displace;
image_widgetbehavior.w_selectfn = image_select;
image_widgetbehavior.w_activatefn = image_activate;
image_widgetbehavior.w_deletefn = image_delete;
image_widgetbehavior.w_visfn = image_vis;
#if (PD_VERSION_MINOR > 31)
image_widgetbehavior.w_clickfn = NULL;
image_widgetbehavior.w_propertiesfn = NULL;
#endif
#if PD_MINOR_VERSION < 37
image_widgetbehavior.w_savefn = image_save;
#endif
}
static void *image_new(t_symbol* fname)
{
t_image *x = (t_image *)pd_new(image_class);
x->x_glist = (t_glist*) canvas_getcurrent();
x->x_width = 15;
x->x_height = 15;
x->x_fname = fname;
outlet_new(&x->x_obj, &s_float);
return (x);
}
void image_setup(void)
{
image_class = class_new(gensym("image"), (t_newmethod)image_new, 0,
sizeof(t_image),0, A_DEFSYM,0);
/*
class_addmethod(image_class, (t_method)image_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
class_addmethod(image_class, (t_method)image_color, gensym("color"),
A_SYMBOL, 0);
*/
/*
class_addmethod(image_class, (t_method)image_open, gensym("open"),
A_SYMBOL, 0);
*/
image_setwidget();
class_setwidget(image_class,&image_widgetbehavior);
#if PD_MINOR_VERSION >= 37
class_setsavefn(image_class,&image_save);
#endif
}

View file

@ -0,0 +1,178 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- lowpass ----------------------------*/
static t_class *lowpass_class;
void lowpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b1 = 1 - cos(omega);
t_float b0 = b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowpass_bang(x);
}
static void *lowpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void lowpass_setup(void)
{
lowpass_class = class_new(gensym("lowpass"), (t_newmethod)lowpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowpass_class,lowpass_bang);
class_addfloat(lowpass_class,lowpass_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- lowpass ----------------------------*/
static t_class *lowpass_class;
void lowpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b1 = 1 - cos(omega);
t_float b0 = b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowpass_bang(x);
}
static void *lowpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void lowpass_setup(void)
{
lowpass_class = class_new(gensym("lowpass"), (t_newmethod)lowpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowpass_class,lowpass_bang);
class_addfloat(lowpass_class,lowpass_float);
}

View file

@ -0,0 +1,182 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- lowshelf ----------------------------*/
static t_class *lowshelf_class;
void lowshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw*0.01);
t_float b0 = A*((A+1) - (A-1)*cs + beta*sn);
t_float b1 = 2.*A*((A-1) - (A+1)*cs);
t_float b2 = A*((A+1) - (A-1)*cs - beta*sn);
t_float a0 = ((A+1) + (A-1)*cs + beta*sn);
t_float a1 = -2.*((A-1) + (A+1)*cs);
t_float a2 = ((A+1) + (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowshelf_bang(x);
}
static void *lowshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void lowshelf_setup(void)
{
lowshelf_class = class_new(gensym("lowshelf"), (t_newmethod)lowshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowshelf_class,lowshelf_bang);
class_addfloat(lowshelf_class,lowshelf_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- lowshelf ----------------------------*/
static t_class *lowshelf_class;
void lowshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw*0.01);
t_float b0 = A*((A+1) - (A-1)*cs + beta*sn);
t_float b1 = 2.*A*((A-1) - (A+1)*cs);
t_float b2 = A*((A+1) - (A-1)*cs - beta*sn);
t_float a0 = ((A+1) + (A-1)*cs + beta*sn);
t_float a1 = -2.*((A-1) + (A+1)*cs);
t_float a2 = ((A+1) + (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowshelf_bang(x);
}
static void *lowshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void lowshelf_setup(void)
{
lowshelf_class = class_new(gensym("lowshelf"), (t_newmethod)lowshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowshelf_class,lowshelf_bang);
class_addfloat(lowshelf_class,lowshelf_float);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
VERSION = 0.2
SOURCE = $(shell ls *.c)
TARGETS = $(SOURCE:.c=.pd_linux)
EXT= pd_linux
AFLAGS = -g -O2 -I./ -DFIXEDPOINT
EFLAGS = -shared -Wl,-export-dynamic
PREFIX = /usr
all: $(TARGETS)
clean:
-rm $(TARGETS)
-rm *.o *~
tar: clean
cd ..;tar czvf PDa-externals-$(VERSION).tgz PDa-externals
upload: tar
scp ../PDa-externals-$(VERSION).tgz gige@xdv.org:~/www/pda/release
install:
install -d $(DESTDIR)/$(PREFIX)/lib/pd/extra
cp $(TARGETS) $(DESTDIR)/$(PREFIX)/lib/pd/extra
%.$(EXT) : %.o
$(CC) -o $@ $(EFLAGS) $+
%.o : %.c
$(CC) -c $(AFLAGS) $(CFLAGS) $+
VERSION = 0.2
SOURCE = $(shell ls *.c)
TARGETS = $(SOURCE:.c=.pd_linux)
EXT= pd_linux
AFLAGS = -g -O2 -I./ -DFIXEDPOINT
EFLAGS = -shared -Wl,-export-dynamic
PREFIX = /usr
all: $(TARGETS)
clean:
-rm $(TARGETS)
-rm *.o *~
tar: clean
cd ..;tar czvf PDa-externals-$(VERSION).tgz PDa-externals
upload: tar
scp ../PDa-externals-$(VERSION).tgz gige@xdv.org:~/www/pda/release
install:
install -d $(DESTDIR)/$(PREFIX)/lib/pd/extra
cp $(TARGETS) $(DESTDIR)/$(PREFIX)/lib/pd/extra
%.$(EXT) : %.o
$(CC) -o $@ $(EFLAGS) $+
%.o : %.c
$(CC) -c $(AFLAGS) $(CFLAGS) $+

View file

@ -0,0 +1,366 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "math.h"
#include <m_pd.h>
/* ----------------------------- moog ----------------------------- */
static t_class *moog_class;
typedef struct _moog
{
t_object x_obj;
t_pd in2;
t_sample x_1,x_2,x_3,x_4;
t_sample y_1,y_2,y_3,y_4;
} t_moog;
static void moog_reset(t_moog *x)
{
x->x_1 = x->x_2 = x->x_3 = x->x_4 = 0;
x->y_1 = x->y_2 = x->y_3 = x->y_4 = 0;
}
static void *moog_new(t_symbol *s, int argc, t_atom *argv)
{
if (argc > 1) post("moog~: extra arguments ignored");
{
t_moog *x = (t_moog *)pd_new(moog_class);
outlet_new(&x->x_obj, &s_signal);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
inlet_new(&x->x_obj, &x->in2, &s_signal, &s_signal);
moog_reset(x);
return (x);
}
}
static t_sample calc_k(t_sample f,t_sample k) {
if (k>itofix(4)) k = itofix(4);
if (k < 0) k = 0;
if (f <= itofix(3800)) return k;
k = k - mult(0.5,(f-idiv(itofix(3800),itofix(4300))));
return k;
}
t_int *moog_perform(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample in;
t_sample pt,pt1;
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =*p;
pt1=mult((pt+1),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,in) + mult(0.3,x1) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,ys1) + mult(0.3,x2) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,ys2) + mult(0.3,x3) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,ys3) + mult(0.3,x4) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
#define CLIP(x) x = ((x) > 1.0 ? (1.0) : (x))
t_int *moog_perf8(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
t_sample temp,temp2;
t_sample pt,pt1;
t_sample in;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =mult(*p, ftofix(0.01*0.0140845)) - ftofix(0.9999999f);
pt1=mult((pt+itofix(1)),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,(in + mult(ftofix(0.3),x1))) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,(ys1 + mult(0.3,x2))) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,(ys2 + mult(0.3,x3))) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,(ys3 + mult(0.3,x4))) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
p++;k++;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
void dsp_add_moog(t_moog *x, t_sample *in1, t_sample *in2, t_sample *in3, t_sample *out, int n)
{
if (n&7)
dsp_add(moog_perform, 6,(t_int)x, in1,in2,in3, out, n);
else
dsp_add(moog_perf8, 6,(t_int) x, in1, in2, in3, out, n);
}
static void moog_dsp(t_moog *x, t_signal **sp)
{
dsp_add_moog(x,sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,sp[0]->s_n);
}
void moog_tilde_setup(void)
{
moog_class = class_new(gensym("moog~"), (t_newmethod)moog_new, 0,
sizeof(t_moog), 0, A_GIMME, 0);
class_addmethod(moog_class, nullfn, gensym("signal"), 0);
class_addmethod(moog_class, (t_method)moog_reset, gensym("reset"), 0);
class_addmethod(moog_class, (t_method)moog_dsp, gensym("dsp"), A_NULL);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "math.h"
#include <m_pd.h>
/* ----------------------------- moog ----------------------------- */
static t_class *moog_class;
typedef struct _moog
{
t_object x_obj;
t_pd in2;
t_sample x_1,x_2,x_3,x_4;
t_sample y_1,y_2,y_3,y_4;
} t_moog;
static void moog_reset(t_moog *x)
{
x->x_1 = x->x_2 = x->x_3 = x->x_4 = 0;
x->y_1 = x->y_2 = x->y_3 = x->y_4 = 0;
}
static void *moog_new(t_symbol *s, int argc, t_atom *argv)
{
if (argc > 1) post("moog~: extra arguments ignored");
{
t_moog *x = (t_moog *)pd_new(moog_class);
outlet_new(&x->x_obj, &s_signal);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
inlet_new(&x->x_obj, &x->in2, &s_signal, &s_signal);
moog_reset(x);
return (x);
}
}
static t_sample calc_k(t_sample f,t_sample k) {
if (k>itofix(4)) k = itofix(4);
if (k < 0) k = 0;
if (f <= itofix(3800)) return k;
k = k - mult(0.5,(f-idiv(itofix(3800),itofix(4300))));
return k;
}
t_int *moog_perform(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample in;
t_sample pt,pt1;
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =*p;
pt1=mult((pt+1),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,in) + mult(0.3,x1) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,ys1) + mult(0.3,x2) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,ys2) + mult(0.3,x3) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,ys3) + mult(0.3,x4) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
#define CLIP(x) x = ((x) > 1.0 ? (1.0) : (x))
t_int *moog_perf8(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
t_sample temp,temp2;
t_sample pt,pt1;
t_sample in;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =mult(*p, ftofix(0.01*0.0140845)) - ftofix(0.9999999f);
pt1=mult((pt+itofix(1)),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,(in + mult(ftofix(0.3),x1))) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,(ys1 + mult(0.3,x2))) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,(ys2 + mult(0.3,x3))) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,(ys3 + mult(0.3,x4))) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
p++;k++;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
void dsp_add_moog(t_moog *x, t_sample *in1, t_sample *in2, t_sample *in3, t_sample *out, int n)
{
if (n&7)
dsp_add(moog_perform, 6,(t_int)x, in1,in2,in3, out, n);
else
dsp_add(moog_perf8, 6,(t_int) x, in1, in2, in3, out, n);
}
static void moog_dsp(t_moog *x, t_signal **sp)
{
dsp_add_moog(x,sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,sp[0]->s_n);
}
void moog_tilde_setup(void)
{
moog_class = class_new(gensym("moog~"), (t_newmethod)moog_new, 0,
sizeof(t_moog), 0, A_GIMME, 0);
class_addmethod(moog_class, nullfn, gensym("signal"), 0);
class_addmethod(moog_class, (t_method)moog_reset, gensym("reset"), 0);
class_addmethod(moog_class, (t_method)moog_dsp, gensym("dsp"), A_NULL);
}

View file

@ -0,0 +1,178 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- notch ----------------------------*/
static t_class *notch_class;
void notch_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -2.*cos(omega);
t_float b0 = 1;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("notch: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void notch_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
notch_bang(x);
}
static void *notch_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(notch_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void notch_setup(void)
{
notch_class = class_new(gensym("notch"), (t_newmethod)notch_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(notch_class,notch_bang);
class_addfloat(notch_class,notch_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- notch ----------------------------*/
static t_class *notch_class;
void notch_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -2.*cos(omega);
t_float b0 = 1;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("notch: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void notch_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
notch_bang(x);
}
static void *notch_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(notch_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void notch_setup(void)
{
notch_class = class_new(gensym("notch"), (t_newmethod)notch_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(notch_class,notch_bang);
class_addfloat(notch_class,notch_float);
}

View file

@ -0,0 +1,430 @@
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* Audio and MIDI I/O, and other scheduling and system stuff. */
/* NOTE: this file describes Pd implementation details which may change
in future releases. The public (stable) API is in m_pd.h. */
/* in s_file.c */
typedef struct _namelist
{
struct _namelist *nl_next;
char *nl_string;
} t_namelist;
t_namelist *namelist_append(t_namelist *listwas, const char *s);
void namelist_free(t_namelist *listwas);
/* s_main.c */
extern int sys_debuglevel;
extern int sys_verbose;
extern int sys_noloadbang;
extern int sys_nogui;
extern char *sys_guicmd;
EXTERN int sys_nearestfontsize(int fontsize);
EXTERN int sys_hostfontsize(int fontsize);
extern int sys_defaultfont;
extern t_symbol *sys_libdir; /* library directory for auxilliary files */
/* s_loader.c */
int sys_load_lib(char *dirname, char *filename);
/* s_audio.c */
#define SENDDACS_NO 0 /* return values for sys_send_dacs() */
#define SENDDACS_YES 1
#define SENDDACS_SLEPT 2
#define DEFDACBLKSIZE 64
extern int sys_schedblocksize; /* audio block size for scheduler */
extern int sys_hipriority; /* real-time flag, true if priority boosted */
extern t_sample *sys_soundout;
extern t_sample *sys_soundin;
extern int sys_inchannels;
extern int sys_outchannels;
extern int sys_advance_samples; /* scheduler advance in samples */
extern int sys_blocksize; /* audio I/O block size in sample frames */
extern float sys_dacsr;
extern int sys_schedadvance;
extern int sys_sleepgrain;
void sys_open_audio(int naudioindev, int *audioindev,
int nchindev, int *chindev,
int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
int srate, int advance, int enable);
void sys_close_audio(void);
/* s_midi.c */
void sys_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec);
/* implemented in the system dependent MIDI code (s_midi_pm.c, etc. ) */
void sys_do_open_midi(int nmidiin, int *midiinvec,
int nmidiout, int *midioutvec);
void sys_close_midi(void);
void midi_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int maxndev, int devdescsize);
int sys_send_dacs(void);
void sys_reportidle(void);
void sys_set_priority(int higher);
void sys_audiobuf(int nbufs);
void sys_getmeters(float *inmax, float *outmax);
void sys_listdevs(void);
void sys_setblocksize(int n);
/* s_midi.c */
#define MAXMIDIINDEV 16 /* max. number of input ports */
#define MAXMIDIOUTDEV 16 /* max. number of output ports */
extern int sys_nmidiin;
extern int sys_nmidiout;
extern int sys_midiindevlist[];
extern int sys_midioutdevlist[];
EXTERN void sys_putmidimess(int portno, int a, int b, int c);
EXTERN void sys_putmidibyte(int portno, int a);
EXTERN void sys_poll_midi(void);
EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime);
EXTERN void sys_midibytein(int portno, int byte);
/* m_sched.c */
EXTERN void sys_log_error(int type);
#define ERR_NOTHING 0
#define ERR_ADCSLEPT 1
#define ERR_DACSLEPT 2
#define ERR_RESYNC 3
#define ERR_DATALATE 4
void sched_set_using_dacs(int flag);
/* s_inter.c */
EXTERN void sys_microsleep(int microsec);
EXTERN void sys_bail(int exitcode);
EXTERN int sys_pollgui(void);
EXTERN_STRUCT _socketreceiver;
#define t_socketreceiver struct _socketreceiver
typedef void (*t_socketnotifier)(void *x);
typedef void (*t_socketreceivefn)(void *x, t_binbuf *b);
EXTERN t_socketreceiver *socketreceiver_new(void *owner,
t_socketnotifier notifier, t_socketreceivefn socketreceivefn, int udp);
EXTERN void socketreceiver_read(t_socketreceiver *x, int fd);
EXTERN void sys_sockerror(char *s);
EXTERN void sys_closesocket(int fd);
typedef void (*t_fdpollfn)(void *ptr, int fd);
EXTERN void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
EXTERN void sys_rmpollfn(int fd);
#ifdef UNIX
void sys_setalarm(int microsec);
void sys_setvirtualalarm( void);
#endif
#define API_ALSA 1
#define API_OSS 2
#define API_MMIO 3
#define API_PORTAUDIO 4
#define API_JACK 5
#ifdef __linux__
#define API_DEFAULT API_OSS
#define API_DEFSTRING "OSS"
#endif
#ifdef MSW
#define API_DEFAULT API_MMIO
#define API_DEFSTRING "MMIO"
#endif
#ifdef MACOSX
#define API_DEFAULT API_PORTAUDIO
#define API_DEFSTRING "portaudio"
#endif
#define DEFAULTAUDIODEV 0
#define MAXAUDIOINDEV 4
#define MAXAUDIOOUTDEV 4
#define DEFMIDIDEV 0
#define DEFAULTSRATE 44100
#ifdef MSW
#define DEFAULTADVANCE 70
#else
#define DEFAULTADVANCE 50
#endif
int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
t_sample *soundout, int framesperbuf, int nbuffers,
int indeviceno, int outdeviceno);
void pa_close_audio(void);
int pa_send_dacs(void);
void sys_reportidle(void);
void pa_listdevs(void);
void pa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
int oss_open_audio(int naudioindev, int *audioindev, int nchindev,
int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
int *choutdev, int rate); /* IOhannes */
void oss_close_audio(void);
int oss_send_dacs(void);
void oss_reportidle(void);
void oss_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
int *choutdev, int rate);
void alsa_close_audio(void);
int alsa_send_dacs(void);
void alsa_reportidle(void);
void alsa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
int jack_open_audio(int wantinchans, int wantoutchans, int srate);
void jack_close_audio(void);
int jack_send_dacs(void);
void jack_reportidle(void);
void jack_listdevs(void);
void mmio_open_audio(int naudioindev, int *audioindev,
int nchindev, int *chindev, int naudiooutdev, int *audiooutdev,
int nchoutdev, int *choutdev, int rate);
void mmio_close_audio( void);
void mmio_reportidle(void);
int mmio_send_dacs(void);
void mmio_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
void sys_listmididevs(void);
void sys_set_audio_api(int whichapi);
void sys_get_audio_apis(char *buf);
extern int sys_audioapi;
void sys_set_audio_state(int onoff);
/* API dependent audio flags and settings */
void oss_set32bit( void);
void linux_alsa_devname(char *devname);
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* Audio and MIDI I/O, and other scheduling and system stuff. */
/* NOTE: this file describes Pd implementation details which may change
in future releases. The public (stable) API is in m_pd.h. */
/* in s_file.c */
typedef struct _namelist
{
struct _namelist *nl_next;
char *nl_string;
} t_namelist;
t_namelist *namelist_append(t_namelist *listwas, const char *s);
void namelist_free(t_namelist *listwas);
/* s_main.c */
extern int sys_debuglevel;
extern int sys_verbose;
extern int sys_noloadbang;
extern int sys_nogui;
extern char *sys_guicmd;
EXTERN int sys_nearestfontsize(int fontsize);
EXTERN int sys_hostfontsize(int fontsize);
extern int sys_defaultfont;
extern t_symbol *sys_libdir; /* library directory for auxilliary files */
/* s_loader.c */
int sys_load_lib(char *dirname, char *filename);
/* s_audio.c */
#define SENDDACS_NO 0 /* return values for sys_send_dacs() */
#define SENDDACS_YES 1
#define SENDDACS_SLEPT 2
#define DEFDACBLKSIZE 64
extern int sys_schedblocksize; /* audio block size for scheduler */
extern int sys_hipriority; /* real-time flag, true if priority boosted */
extern t_sample *sys_soundout;
extern t_sample *sys_soundin;
extern int sys_inchannels;
extern int sys_outchannels;
extern int sys_advance_samples; /* scheduler advance in samples */
extern int sys_blocksize; /* audio I/O block size in sample frames */
extern float sys_dacsr;
extern int sys_schedadvance;
extern int sys_sleepgrain;
void sys_open_audio(int naudioindev, int *audioindev,
int nchindev, int *chindev,
int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev,
int srate, int advance, int enable);
void sys_close_audio(void);
/* s_midi.c */
void sys_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec);
/* implemented in the system dependent MIDI code (s_midi_pm.c, etc. ) */
void sys_do_open_midi(int nmidiin, int *midiinvec,
int nmidiout, int *midioutvec);
void sys_close_midi(void);
void midi_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int maxndev, int devdescsize);
int sys_send_dacs(void);
void sys_reportidle(void);
void sys_set_priority(int higher);
void sys_audiobuf(int nbufs);
void sys_getmeters(float *inmax, float *outmax);
void sys_listdevs(void);
void sys_setblocksize(int n);
/* s_midi.c */
#define MAXMIDIINDEV 16 /* max. number of input ports */
#define MAXMIDIOUTDEV 16 /* max. number of output ports */
extern int sys_nmidiin;
extern int sys_nmidiout;
extern int sys_midiindevlist[];
extern int sys_midioutdevlist[];
EXTERN void sys_putmidimess(int portno, int a, int b, int c);
EXTERN void sys_putmidibyte(int portno, int a);
EXTERN void sys_poll_midi(void);
EXTERN void sys_setmiditimediff(double inbuftime, double outbuftime);
EXTERN void sys_midibytein(int portno, int byte);
/* m_sched.c */
EXTERN void sys_log_error(int type);
#define ERR_NOTHING 0
#define ERR_ADCSLEPT 1
#define ERR_DACSLEPT 2
#define ERR_RESYNC 3
#define ERR_DATALATE 4
void sched_set_using_dacs(int flag);
/* s_inter.c */
EXTERN void sys_microsleep(int microsec);
EXTERN void sys_bail(int exitcode);
EXTERN int sys_pollgui(void);
EXTERN_STRUCT _socketreceiver;
#define t_socketreceiver struct _socketreceiver
typedef void (*t_socketnotifier)(void *x);
typedef void (*t_socketreceivefn)(void *x, t_binbuf *b);
EXTERN t_socketreceiver *socketreceiver_new(void *owner,
t_socketnotifier notifier, t_socketreceivefn socketreceivefn, int udp);
EXTERN void socketreceiver_read(t_socketreceiver *x, int fd);
EXTERN void sys_sockerror(char *s);
EXTERN void sys_closesocket(int fd);
typedef void (*t_fdpollfn)(void *ptr, int fd);
EXTERN void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
EXTERN void sys_rmpollfn(int fd);
#ifdef UNIX
void sys_setalarm(int microsec);
void sys_setvirtualalarm( void);
#endif
#define API_ALSA 1
#define API_OSS 2
#define API_MMIO 3
#define API_PORTAUDIO 4
#define API_JACK 5
#ifdef __linux__
#define API_DEFAULT API_OSS
#define API_DEFSTRING "OSS"
#endif
#ifdef MSW
#define API_DEFAULT API_MMIO
#define API_DEFSTRING "MMIO"
#endif
#ifdef MACOSX
#define API_DEFAULT API_PORTAUDIO
#define API_DEFSTRING "portaudio"
#endif
#define DEFAULTAUDIODEV 0
#define MAXAUDIOINDEV 4
#define MAXAUDIOOUTDEV 4
#define DEFMIDIDEV 0
#define DEFAULTSRATE 44100
#ifdef MSW
#define DEFAULTADVANCE 70
#else
#define DEFAULTADVANCE 50
#endif
int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
t_sample *soundout, int framesperbuf, int nbuffers,
int indeviceno, int outdeviceno);
void pa_close_audio(void);
int pa_send_dacs(void);
void sys_reportidle(void);
void pa_listdevs(void);
void pa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
int oss_open_audio(int naudioindev, int *audioindev, int nchindev,
int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
int *choutdev, int rate); /* IOhannes */
void oss_close_audio(void);
int oss_send_dacs(void);
void oss_reportidle(void);
void oss_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev,
int *choutdev, int rate);
void alsa_close_audio(void);
int alsa_send_dacs(void);
void alsa_reportidle(void);
void alsa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
int jack_open_audio(int wantinchans, int wantoutchans, int srate);
void jack_close_audio(void);
int jack_send_dacs(void);
void jack_reportidle(void);
void jack_listdevs(void);
void mmio_open_audio(int naudioindev, int *audioindev,
int nchindev, int *chindev, int naudiooutdev, int *audiooutdev,
int nchoutdev, int *choutdev, int rate);
void mmio_close_audio( void);
void mmio_reportidle(void);
int mmio_send_dacs(void);
void mmio_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize);
void sys_listmididevs(void);
void sys_set_audio_api(int whichapi);
void sys_get_audio_apis(char *buf);
extern int sys_audioapi;
void sys_set_audio_state(int onoff);
/* API dependent audio flags and settings */
void oss_set32bit( void);
void linux_alsa_devname(char *devname);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
#ifndef SFORMAT_H__
#define SFORMAT_H__
typedef unsigned short uint16;
typedef unsigned long uint32;
#define FORMAT_WAVE 0
#define FORMAT_AIFF 1
#define FORMAT_NEXT 2
/* the NeXTStep sound header structure; can be big or little endian */
typedef struct _nextstep
{
char ns_fileid[4]; /* magic number '.snd' if file is big-endian */
uint32 ns_onset; /* byte offset of first sample */
uint32 ns_length; /* length of sound in bytes */
uint32 ns_format; /* format; see below */
uint32 ns_sr; /* sample rate */
uint32 ns_nchans; /* number of channels */
char ns_info[4]; /* comment */
} t_nextstep;
#define NS_FORMAT_LINEAR_16 3
#define NS_FORMAT_LINEAR_24 4
#define NS_FORMAT_FLOAT 6
#define SCALE (1./(1024. * 1024. * 1024. * 2.))
/* the WAVE header. All Wave files are little endian. We assume
the "fmt" chunk comes first which is usually the case but perhaps not
always; same for AIFF and the "COMM" chunk. */
typedef unsigned word;
typedef unsigned long dword;
typedef struct _wave
{
char w_fileid[4]; /* chunk id 'RIFF' */
uint32 w_chunksize; /* chunk size */
char w_waveid[4]; /* wave chunk id 'WAVE' */
char w_fmtid[4]; /* format chunk id 'fmt ' */
uint32 w_fmtchunksize; /* format chunk size */
uint16 w_fmttag; /* format tag, 1 for PCM */
uint16 w_nchannels; /* number of channels */
uint32 w_samplespersec; /* sample rate in hz */
uint32 w_navgbytespersec; /* average bytes per second */
uint16 w_nblockalign; /* number of bytes per sample */
uint16 w_nbitspersample; /* number of bits in a sample */
char w_datachunkid[4]; /* data chunk id 'data' */
uint32 w_datachunksize; /* length of data chunk */
} t_wave;
#endif
#ifndef SFORMAT_H__
#define SFORMAT_H__
typedef unsigned short uint16;
typedef unsigned long uint32;
#define FORMAT_WAVE 0
#define FORMAT_AIFF 1
#define FORMAT_NEXT 2
/* the NeXTStep sound header structure; can be big or little endian */
typedef struct _nextstep
{
char ns_fileid[4]; /* magic number '.snd' if file is big-endian */
uint32 ns_onset; /* byte offset of first sample */
uint32 ns_length; /* length of sound in bytes */
uint32 ns_format; /* format; see below */
uint32 ns_sr; /* sample rate */
uint32 ns_nchans; /* number of channels */
char ns_info[4]; /* comment */
} t_nextstep;
#define NS_FORMAT_LINEAR_16 3
#define NS_FORMAT_LINEAR_24 4
#define NS_FORMAT_FLOAT 6
#define SCALE (1./(1024. * 1024. * 1024. * 2.))
/* the WAVE header. All Wave files are little endian. We assume
the "fmt" chunk comes first which is usually the case but perhaps not
always; same for AIFF and the "COMM" chunk. */
typedef unsigned word;
typedef unsigned long dword;
typedef struct _wave
{
char w_fileid[4]; /* chunk id 'RIFF' */
uint32 w_chunksize; /* chunk size */
char w_waveid[4]; /* wave chunk id 'WAVE' */
char w_fmtid[4]; /* format chunk id 'fmt ' */
uint32 w_fmtchunksize; /* format chunk size */
uint16 w_fmttag; /* format tag, 1 for PCM */
uint16 w_nchannels; /* number of channels */
uint32 w_samplespersec; /* sample rate in hz */
uint32 w_navgbytespersec; /* average bytes per second */
uint16 w_nblockalign; /* number of bytes per sample */
uint16 w_nbitspersample; /* number of bits in a sample */
char w_datachunkid[4]; /* data chunk id 'data' */
uint32 w_datachunksize; /* length of data chunk */
} t_wave;
#endif

View file

@ -0,0 +1,624 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
void sys_rmpollfn(int fd);
void sys_addpollfn(int fd, void* fn, void *ptr);
/* ------------------------ shell ----------------------------- */
#define INBUFSIZE 1024
static t_class *shell_class;
static void drop_priority(void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
struct sched_param par;
int p1 ,p2, p3;
par.sched_priority = 0;
sched_setscheduler(0,SCHED_OTHER,&par);
#endif
}
typedef struct _shell
{
t_object x_obj;
int x_echo;
char *sr_inbuf;
int sr_inhead;
int sr_intail;
void* x_binbuf;
int fdpipe[2];
int fdinpipe[2];
int pid;
int x_del;
t_outlet* x_done;
t_clock* x_clock;
} t_shell;
static int shell_pid;
void shell_cleanup(t_shell* x)
{
sys_rmpollfn(x->fdpipe[0]);
if (x->fdpipe[0]>0) close(x->fdpipe[0]);
if (x->fdpipe[1]>0) close(x->fdpipe[1]);
if (x->fdinpipe[0]>0) close(x->fdinpipe[0]);
if (x->fdinpipe[1]>0) close(x->fdinpipe[1]);
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
clock_unset(x->x_clock);
}
void shell_check(t_shell* x)
{
int ret;
int status;
ret = waitpid(x->pid,&status,WNOHANG);
if (ret == x->pid) {
shell_cleanup(x);
if (WIFEXITED(status)) {
outlet_float(x->x_done,WEXITSTATUS(status));
}
else outlet_float(x->x_done,0);
}
else {
if (x->x_del < 100) x->x_del+=2; /* increment poll times */
clock_delay(x->x_clock,x->x_del);
}
}
void shell_bang(t_shell *x)
{
post("bang");
}
/* snippet from pd's code */
static void shell_doit(void *z, t_binbuf *b)
{
t_shell *x = (t_shell *)z;
int msg, natom = binbuf_getnatom(b);
t_atom *at = binbuf_getvec(b);
for (msg = 0; msg < natom;)
{
int emsg;
for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
&& at[emsg].a_type != A_SEMI; emsg++)
;
if (emsg > msg)
{
int i;
for (i = msg; i < emsg; i++)
if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
{
pd_error(x, "netreceive: got dollar sign in message");
goto nodice;
}
if (at[msg].a_type == A_FLOAT)
{
if (emsg > msg + 1)
outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
}
else if (at[msg].a_type == A_SYMBOL)
outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
emsg-msg-1, at + msg + 1);
}
nodice:
msg = emsg + 1;
}
}
void shell_read(t_shell *x, int fd)
{
char buf[INBUFSIZE];
t_binbuf* bbuf = binbuf_new();
int i;
int readto =
(x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
int ret;
ret = read(fd, buf,INBUFSIZE-1);
buf[ret] = '\0';
for (i=0;i<ret;i++)
if (buf[i] == '\n') buf[i] = ';';
if (ret < 0)
{
error("shell: pipe read error");
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else if (ret == 0)
{
post("EOF on socket %d\n", fd);
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else
{
int natom;
t_atom *at;
binbuf_text(bbuf, buf, strlen(buf));
natom = binbuf_getnatom(bbuf);
at = binbuf_getvec(bbuf);
shell_doit(x,bbuf);
}
binbuf_free(bbuf);
}
static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at)
{
int i;
char tmp[MAXPDSTRING];
int size = 0;
if (x->fdinpipe[0] == -1) return; /* nothing to send to */
for (i=0;i<ac;i++) {
atom_string(at,tmp+size,MAXPDSTRING - size);
at++;
size=strlen(tmp);
tmp[size++] = ' ';
}
tmp[size-1] = '\0';
post("sending %s",tmp);
write(x->fdinpipe[0],tmp,strlen(tmp));
}
static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
{
int i;
char* argv[20];
t_symbol* sym;
if (!strcmp(s->s_name,"send")) {
post("send");
shell_send(x,s,ac,at);
return;
}
argv[0] = s->s_name;
if (x->fdpipe[0] != -1) {
post("shell: old process still running");
kill(x->pid,SIGKILL);
shell_cleanup(x);
}
if (pipe(x->fdpipe) < 0) {
error("unable to create pipe");
return;
}
if (pipe(x->fdinpipe) < 0) {
error("unable to create input pipe");
return;
}
sys_addpollfn(x->fdpipe[0],shell_read,x);
if (!(x->pid = fork())) {
int status;
char* cmd = getbytes(1024);
char* tcmd = getbytes(1024);
strcpy(cmd,s->s_name);
#if 0
for (i=1;i<=ac;i++) {
argv[i] = getbytes(255);
atom_string(at,argv[i],255);
/* post("argument %s",argv[i]); */
at++;
}
argv[i] = 0;
#endif
for (i=1;i<=ac;i++) {
atom_string(at,tcmd,255);
strcat(cmd," ");
strcat(cmd,tcmd);
at++;
}
/* reassign stdout */
dup2(x->fdpipe[1],1);
dup2(x->fdinpipe[1],0);
/* drop privileges */
drop_priority();
seteuid(getuid()); /* lose setuid priveliges */
post("executing %s",cmd);
system(cmd);
// execvp(s->s_name,argv);
exit(0);
}
x->x_del = 4;
clock_delay(x->x_clock,x->x_del);
if (x->x_echo)
outlet_anything(x->x_obj.ob_outlet, s, ac, at);
}
void shell_free(t_shell* x)
{
binbuf_free(x->x_binbuf);
}
static void *shell_new(void)
{
t_shell *x = (t_shell *)pd_new(shell_class);
x->x_echo = 0;
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
x->sr_inhead = x->sr_intail = 0;
if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
x->x_binbuf = binbuf_new();
outlet_new(&x->x_obj, &s_list);
x->x_done = outlet_new(&x->x_obj, &s_bang);
x->x_clock = clock_new(x, (t_method) shell_check);
return (x);
}
void shell_setup(void)
{
shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
(t_method)shell_free,sizeof(t_shell), 0,0);
class_addbang(shell_class,shell_bang);
class_addanything(shell_class, shell_anything);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
void sys_rmpollfn(int fd);
void sys_addpollfn(int fd, void* fn, void *ptr);
/* ------------------------ shell ----------------------------- */
#define INBUFSIZE 1024
static t_class *shell_class;
static void drop_priority(void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
struct sched_param par;
int p1 ,p2, p3;
par.sched_priority = 0;
sched_setscheduler(0,SCHED_OTHER,&par);
#endif
}
typedef struct _shell
{
t_object x_obj;
int x_echo;
char *sr_inbuf;
int sr_inhead;
int sr_intail;
void* x_binbuf;
int fdpipe[2];
int fdinpipe[2];
int pid;
int x_del;
t_outlet* x_done;
t_clock* x_clock;
} t_shell;
static int shell_pid;
void shell_cleanup(t_shell* x)
{
sys_rmpollfn(x->fdpipe[0]);
if (x->fdpipe[0]>0) close(x->fdpipe[0]);
if (x->fdpipe[1]>0) close(x->fdpipe[1]);
if (x->fdinpipe[0]>0) close(x->fdinpipe[0]);
if (x->fdinpipe[1]>0) close(x->fdinpipe[1]);
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
clock_unset(x->x_clock);
}
void shell_check(t_shell* x)
{
int ret;
int status;
ret = waitpid(x->pid,&status,WNOHANG);
if (ret == x->pid) {
shell_cleanup(x);
if (WIFEXITED(status)) {
outlet_float(x->x_done,WEXITSTATUS(status));
}
else outlet_float(x->x_done,0);
}
else {
if (x->x_del < 100) x->x_del+=2; /* increment poll times */
clock_delay(x->x_clock,x->x_del);
}
}
void shell_bang(t_shell *x)
{
post("bang");
}
/* snippet from pd's code */
static void shell_doit(void *z, t_binbuf *b)
{
t_shell *x = (t_shell *)z;
int msg, natom = binbuf_getnatom(b);
t_atom *at = binbuf_getvec(b);
for (msg = 0; msg < natom;)
{
int emsg;
for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
&& at[emsg].a_type != A_SEMI; emsg++)
;
if (emsg > msg)
{
int i;
for (i = msg; i < emsg; i++)
if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
{
pd_error(x, "netreceive: got dollar sign in message");
goto nodice;
}
if (at[msg].a_type == A_FLOAT)
{
if (emsg > msg + 1)
outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
}
else if (at[msg].a_type == A_SYMBOL)
outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
emsg-msg-1, at + msg + 1);
}
nodice:
msg = emsg + 1;
}
}
void shell_read(t_shell *x, int fd)
{
char buf[INBUFSIZE];
t_binbuf* bbuf = binbuf_new();
int i;
int readto =
(x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
int ret;
ret = read(fd, buf,INBUFSIZE-1);
buf[ret] = '\0';
for (i=0;i<ret;i++)
if (buf[i] == '\n') buf[i] = ';';
if (ret < 0)
{
error("shell: pipe read error");
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else if (ret == 0)
{
post("EOF on socket %d\n", fd);
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else
{
int natom;
t_atom *at;
binbuf_text(bbuf, buf, strlen(buf));
natom = binbuf_getnatom(bbuf);
at = binbuf_getvec(bbuf);
shell_doit(x,bbuf);
}
binbuf_free(bbuf);
}
static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at)
{
int i;
char tmp[MAXPDSTRING];
int size = 0;
if (x->fdinpipe[0] == -1) return; /* nothing to send to */
for (i=0;i<ac;i++) {
atom_string(at,tmp+size,MAXPDSTRING - size);
at++;
size=strlen(tmp);
tmp[size++] = ' ';
}
tmp[size-1] = '\0';
post("sending %s",tmp);
write(x->fdinpipe[0],tmp,strlen(tmp));
}
static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
{
int i;
char* argv[20];
t_symbol* sym;
if (!strcmp(s->s_name,"send")) {
post("send");
shell_send(x,s,ac,at);
return;
}
argv[0] = s->s_name;
if (x->fdpipe[0] != -1) {
post("shell: old process still running");
kill(x->pid,SIGKILL);
shell_cleanup(x);
}
if (pipe(x->fdpipe) < 0) {
error("unable to create pipe");
return;
}
if (pipe(x->fdinpipe) < 0) {
error("unable to create input pipe");
return;
}
sys_addpollfn(x->fdpipe[0],shell_read,x);
if (!(x->pid = fork())) {
int status;
char* cmd = getbytes(1024);
char* tcmd = getbytes(1024);
strcpy(cmd,s->s_name);
#if 0
for (i=1;i<=ac;i++) {
argv[i] = getbytes(255);
atom_string(at,argv[i],255);
/* post("argument %s",argv[i]); */
at++;
}
argv[i] = 0;
#endif
for (i=1;i<=ac;i++) {
atom_string(at,tcmd,255);
strcat(cmd," ");
strcat(cmd,tcmd);
at++;
}
/* reassign stdout */
dup2(x->fdpipe[1],1);
dup2(x->fdinpipe[1],0);
/* drop privileges */
drop_priority();
seteuid(getuid()); /* lose setuid priveliges */
post("executing %s",cmd);
system(cmd);
// execvp(s->s_name,argv);
exit(0);
}
x->x_del = 4;
clock_delay(x->x_clock,x->x_del);
if (x->x_echo)
outlet_anything(x->x_obj.ob_outlet, s, ac, at);
}
void shell_free(t_shell* x)
{
binbuf_free(x->x_binbuf);
}
static void *shell_new(void)
{
t_shell *x = (t_shell *)pd_new(shell_class);
x->x_echo = 0;
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
x->sr_inhead = x->sr_intail = 0;
if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
x->x_binbuf = binbuf_new();
outlet_new(&x->x_obj, &s_list);
x->x_done = outlet_new(&x->x_obj, &s_bang);
x->x_clock = clock_new(x, (t_method) shell_check);
return (x);
}
void shell_setup(void)
{
shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
(t_method)shell_free,sizeof(t_shell), 0,0);
class_addbang(shell_class,shell_bang);
class_addanything(shell_class, shell_anything);
}

View file

@ -0,0 +1,106 @@
#include <stdio.h>
#include "m_pd.h"
#include "g_canvas.h" /* for widgetbehaviour */
#include "fatom.h"
static t_class *slider_class;
static void slider_save(t_gobj *z, t_binbuf *b)
{
t_fatom *x = (t_fatom *)z;
binbuf_addv(b, "ssiisiiisss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix ,
gensym("slider"),x->x_max,x->x_min,x->x_width,x->x_send,x->x_color,x->x_bgcolor);
binbuf_addv(b, ";");
}
static void *slider_new(t_symbol* s,t_int argc, t_atom* argv)
{
t_fatom *x = (t_fatom *)pd_new(slider_class);
x->x_type = gensym("vslider");
return fatom_new(x,argc,argv);
}
t_widgetbehavior slider_widgetbehavior;
void slider_setup(void) {
slider_class = class_new(gensym("slider"), (t_newmethod)slider_new, 0,
sizeof(t_fatom),0,A_GIMME,0);
slider_widgetbehavior.w_getrectfn = fatom_getrect;
slider_widgetbehavior.w_displacefn = fatom_displace;
slider_widgetbehavior.w_selectfn = fatom_select;
slider_widgetbehavior.w_activatefn = fatom_activate;
slider_widgetbehavior.w_deletefn = fatom_delete;
slider_widgetbehavior.w_visfn= fatom_vis;
slider_widgetbehavior.w_clickfn = NULL;
fatom_setup_common(slider_class);
class_setwidget(slider_class,&slider_widgetbehavior);
#if PD_MINOR_VERSION < 37
slider_widgetbehavior.w_savefn = slider_save;
slider_widgetbehavior.w_propertiesfn = NULL;
#else
class_setsavefn(slider_class,&slider_save);
class_setpropertiesfn(slider_class,&fatom_properties);
#endif
}
#include <stdio.h>
#include "m_pd.h"
#include "g_canvas.h" /* for widgetbehaviour */
#include "fatom.h"
static t_class *slider_class;
static void slider_save(t_gobj *z, t_binbuf *b)
{
t_fatom *x = (t_fatom *)z;
binbuf_addv(b, "ssiisiiisss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix ,
gensym("slider"),x->x_max,x->x_min,x->x_width,x->x_send,x->x_color,x->x_bgcolor);
binbuf_addv(b, ";");
}
static void *slider_new(t_symbol* s,t_int argc, t_atom* argv)
{
t_fatom *x = (t_fatom *)pd_new(slider_class);
x->x_type = gensym("vslider");
return fatom_new(x,argc,argv);
}
t_widgetbehavior slider_widgetbehavior;
void slider_setup(void) {
slider_class = class_new(gensym("slider"), (t_newmethod)slider_new, 0,
sizeof(t_fatom),0,A_GIMME,0);
slider_widgetbehavior.w_getrectfn = fatom_getrect;
slider_widgetbehavior.w_displacefn = fatom_displace;
slider_widgetbehavior.w_selectfn = fatom_select;
slider_widgetbehavior.w_activatefn = fatom_activate;
slider_widgetbehavior.w_deletefn = fatom_delete;
slider_widgetbehavior.w_visfn= fatom_vis;
slider_widgetbehavior.w_clickfn = NULL;
fatom_setup_common(slider_class);
class_setwidget(slider_class,&slider_widgetbehavior);
#if PD_MINOR_VERSION < 37
slider_widgetbehavior.w_savefn = slider_save;
slider_widgetbehavior.w_propertiesfn = NULL;
#else
class_setsavefn(slider_class,&slider_save);
class_setpropertiesfn(slider_class,&fatom_properties);
#endif
}

View file

@ -0,0 +1,126 @@
#include "m_pd.h"
#include "g_canvas.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include "fatom.h"
/* can we use the normal text save function ?? */
static t_class *sliderh_class;
static void sliderh_save(t_gobj *z, t_binbuf *b)
{
t_fatom *x = (t_fatom *)z;
binbuf_addv(b, "ssiisiiisss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix ,
gensym("sliderh"),x->x_max,x->x_min,x->x_width,x->x_send,x->x_color,x->x_bgcolor);
binbuf_addv(b, ";");
}
static void *sliderh_new(t_symbol* s, int argc, t_atom* argv)
{
t_fatom *x = (t_fatom *)pd_new(sliderh_class);
x->x_type = gensym("hslider");
return fatom_new(x,argc,argv);
}
t_widgetbehavior sliderh_widgetbehavior;
void sliderh_setup(void) {
sliderh_class = class_new(gensym("sliderh"), (t_newmethod)sliderh_new, 0,
sizeof(t_fatom),0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
fatom_setup_common(sliderh_class);
sliderh_widgetbehavior.w_getrectfn = fatom_getrect;
sliderh_widgetbehavior.w_displacefn= fatom_displace;
sliderh_widgetbehavior.w_selectfn= fatom_select;
sliderh_widgetbehavior.w_activatefn=fatom_activate;
sliderh_widgetbehavior.w_deletefn= fatom_delete;
sliderh_widgetbehavior.w_visfn= fatom_vis;
#if PD_MINOR_VERSION < 37
sliderh_widgetbehavior.w_savefn= sliderh_save;
sliderh_widgetbehavior.w_propertiesfn= NULL;
#endif
sliderh_widgetbehavior.w_clickfn= NULL;
class_setwidget(sliderh_class,&sliderh_widgetbehavior);
#if PD_MINOR_VERSION >= 37
class_setsavefn(sliderh_class,&sliderh_save);
#endif
}
#include "m_pd.h"
#include "g_canvas.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include "fatom.h"
/* can we use the normal text save function ?? */
static t_class *sliderh_class;
static void sliderh_save(t_gobj *z, t_binbuf *b)
{
t_fatom *x = (t_fatom *)z;
binbuf_addv(b, "ssiisiiisss", gensym("#X"),gensym("obj"),
x->x_obj.te_xpix, x->x_obj.te_ypix ,
gensym("sliderh"),x->x_max,x->x_min,x->x_width,x->x_send,x->x_color,x->x_bgcolor);
binbuf_addv(b, ";");
}
static void *sliderh_new(t_symbol* s, int argc, t_atom* argv)
{
t_fatom *x = (t_fatom *)pd_new(sliderh_class);
x->x_type = gensym("hslider");
return fatom_new(x,argc,argv);
}
t_widgetbehavior sliderh_widgetbehavior;
void sliderh_setup(void) {
sliderh_class = class_new(gensym("sliderh"), (t_newmethod)sliderh_new, 0,
sizeof(t_fatom),0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
fatom_setup_common(sliderh_class);
sliderh_widgetbehavior.w_getrectfn = fatom_getrect;
sliderh_widgetbehavior.w_displacefn= fatom_displace;
sliderh_widgetbehavior.w_selectfn= fatom_select;
sliderh_widgetbehavior.w_activatefn=fatom_activate;
sliderh_widgetbehavior.w_deletefn= fatom_delete;
sliderh_widgetbehavior.w_visfn= fatom_vis;
#if PD_MINOR_VERSION < 37
sliderh_widgetbehavior.w_savefn= sliderh_save;
sliderh_widgetbehavior.w_propertiesfn= NULL;
#endif
sliderh_widgetbehavior.w_clickfn= NULL;
class_setwidget(sliderh_class,&sliderh_widgetbehavior);
#if PD_MINOR_VERSION >= 37
class_setsavefn(sliderh_class,&sliderh_save);
#endif
}

View file

@ -0,0 +1,26 @@
#N canvas 0 0 240 300 10;
#X obj 57 84 clip~ -0.1 0.1;
#X obj 58 61 sig~;
#X obj 57 111 snapshot~;
#X floatatom 58 19 5 0 0 0 - - -;
#X floatatom 57 144 5 0 0 0 - - -;
#X obj 58 37 t f b;
#X connect 0 0 2 0;
#X connect 1 0 0 0;
#X connect 2 0 4 0;
#X connect 3 0 5 0;
#X connect 5 0 1 0;
#X connect 5 1 2 0;
#N canvas 0 0 240 300 10;
#X obj 57 84 clip~ -0.1 0.1;
#X obj 58 61 sig~;
#X obj 57 111 snapshot~;
#X floatatom 58 19 5 0 0 0 - - -;
#X floatatom 57 144 5 0 0 0 - - -;
#X obj 58 37 t f b;
#X connect 0 0 2 0;
#X connect 1 0 0 0;
#X connect 2 0 4 0;
#X connect 3 0 5 0;
#X connect 5 0 1 0;
#X connect 5 1 2 0;

View file

@ -0,0 +1,36 @@
#N canvas 0 0 240 300 10;
#X obj 38 93 noise~;
#X obj 44 161 vcf~;
#X obj 48 191 dac~;
#X floatatom 138 33 5 0 0 0 - - -;
#X obj 44 18 osc~ 1;
#X obj 46 75 *~ 800;
#X obj 48 48 +~ 2;
#X obj 106 125 sig~;
#X floatatom 132 77 5 0 0 0 - - -;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 1 0 2 1;
#X connect 3 0 1 2;
#X connect 4 0 6 0;
#X connect 6 0 5 0;
#X connect 7 0 1 1;
#X connect 8 0 7 0;
#N canvas 0 0 240 300 10;
#X obj 38 93 noise~;
#X obj 44 161 vcf~;
#X obj 48 191 dac~;
#X floatatom 138 33 5 0 0 0 - - -;
#X obj 44 18 osc~ 1;
#X obj 46 75 *~ 800;
#X obj 48 48 +~ 2;
#X obj 106 125 sig~;
#X floatatom 132 77 5 0 0 0 - - -;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 1 0 2 1;
#X connect 3 0 1 2;
#X connect 4 0 6 0;
#X connect 6 0 5 0;
#X connect 7 0 1 1;
#X connect 8 0 7 0;

View file

@ -0,0 +1,114 @@
#include "m_pd.h"
static t_class *zerox_class;
typedef struct _zerox
{
t_object x_obj;
t_sample x_f;
t_int x_zeros;
} t_zerox;
static t_int *zerox_perform(t_int *w)
{
t_zerox* x = (t_zerox*)w[1];
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]) ;
if (*in * x->x_f < 0) x->x_zeros++;
n--;
while (n--)
{
float f = *(in++);
x->x_zeros += f * *in < 0;
}
return (w+4);
}
static void zerox_dsp(t_zerox *x, t_signal **sp)
{
dsp_add(zerox_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void zerox_bang(t_zerox* x)
{
outlet_float(x->x_obj.ob_outlet,x->x_zeros);
x->x_zeros=0;
}
static void *zerox_new(void)
{
t_zerox *x = (t_zerox *)pd_new(zerox_class);
outlet_new(&x->x_obj, gensym("float"));
x->x_f = 0;
x->x_zeros=0;
return (x);
}
void zerox_tilde_setup(void)
{
zerox_class = class_new(gensym("zerox~"), (t_newmethod)zerox_new, 0,
sizeof(t_zerox), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(zerox_class, t_zerox, x_f);
class_addmethod(zerox_class, (t_method)zerox_dsp, gensym("dsp"), 0);
class_addbang(zerox_class, (t_method)zerox_bang);
}
#include "m_pd.h"
static t_class *zerox_class;
typedef struct _zerox
{
t_object x_obj;
t_sample x_f;
t_int x_zeros;
} t_zerox;
static t_int *zerox_perform(t_int *w)
{
t_zerox* x = (t_zerox*)w[1];
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]) ;
if (*in * x->x_f < 0) x->x_zeros++;
n--;
while (n--)
{
float f = *(in++);
x->x_zeros += f * *in < 0;
}
return (w+4);
}
static void zerox_dsp(t_zerox *x, t_signal **sp)
{
dsp_add(zerox_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void zerox_bang(t_zerox* x)
{
outlet_float(x->x_obj.ob_outlet,x->x_zeros);
x->x_zeros=0;
}
static void *zerox_new(void)
{
t_zerox *x = (t_zerox *)pd_new(zerox_class);
outlet_new(&x->x_obj, gensym("float"));
x->x_f = 0;
x->x_zeros=0;
return (x);
}
void zerox_tilde_setup(void)
{
zerox_class = class_new(gensym("zerox~"), (t_newmethod)zerox_new, 0,
sizeof(t_zerox), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(zerox_class, t_zerox, x_f);
class_addmethod(zerox_class, (t_method)zerox_dsp, gensym("dsp"), 0);
class_addbang(zerox_class, (t_method)zerox_bang);
}

View file

@ -0,0 +1,252 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct biquadctl
{
t_sample c_x1;
t_sample c_x2;
t_sample c_fb1;
t_sample c_fb2;
t_sample c_ff1;
t_sample c_ff2;
t_sample c_ff3;
} t_biquadctl;
typedef struct sigbiquad
{
t_object x_obj;
float x_f;
t_biquadctl x_cspace;
t_biquadctl *x_ctl;
} t_sigbiquad;
t_class *sigbiquad_class;
static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv);
static void *sigbiquad_new(t_symbol *s, int argc, t_atom *argv)
{
t_sigbiquad *x = (t_sigbiquad *)pd_new(sigbiquad_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x1 = x->x_cspace.c_x2 = 0;
sigbiquad_list(x, s, argc, argv);
x->x_f = 0;
return (x);
}
static t_int *sigbiquad_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_biquadctl *c = (t_biquadctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x1;
t_sample prev = c->c_x2;
t_sample fb1 = c->c_fb1;
t_sample fb2 = c->c_fb2;
t_sample ff1 = c->c_ff1;
t_sample ff2 = c->c_ff2;
t_sample ff3 = c->c_ff3;
for (i = 0; i < n; i++)
{
t_sample output = *in++ + mult(fb1,last) + mult(fb2,prev);
if (PD_BADFLOAT(output))
output = 0;
*out++ = mult(ff1,output) + mult(ff2,last) + mult(ff3,prev);
prev = last;
last = output;
}
c->c_x1 = last;
c->c_x2 = prev;
return (w+5);
}
static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
{
float fb1 = atom_getfloatarg(0, argc, argv);
float fb2 = atom_getfloatarg(1, argc, argv);
float ff1 = atom_getfloatarg(2, argc, argv);
float ff2 = atom_getfloatarg(3, argc, argv);
float ff3 = atom_getfloatarg(4, argc, argv);
float discriminant = fb1 * fb1 + 4 * fb2;
t_biquadctl *c = x->x_ctl;
if (discriminant < 0) /* imaginary roots -- resonant filter */
{
/* they're conjugates so we just check that the product
is less than one */
if (fb2 >= -1.0f) goto stable;
}
else /* real roots */
{
/* check that the parabola 1 - fb1 x - fb2 x^2 has a
vertex between -1 and 1, and that it's nonnegative
at both ends, which implies both roots are in [1-,1]. */
if (fb1 <= 2.0f && fb1 >= -2.0f &&
1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
goto stable;
}
/* if unstable, just bash to zero */
fb1 = fb2 = ff1 = ff2 = ff3 = 0;
stable:
c->c_fb1 = ftofix(fb1);
c->c_fb2 = ftofix(fb2);
c->c_ff1 = ftofix(ff1);
c->c_ff2 = ftofix(ff2);
c->c_ff3 = ftofix(ff3);
}
static void sigbiquad_set(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
{
t_biquadctl *c = x->x_ctl;
c->c_x1 = atom_getfloatarg(0, argc, argv);
c->c_x2 = atom_getfloatarg(1, argc, argv);
}
static void sigbiquad_dsp(t_sigbiquad *x, t_signal **sp)
{
dsp_add(sigbiquad_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void biquad_tilde_setup(void)
{
sigbiquad_class = class_new(gensym("biquad~"), (t_newmethod)sigbiquad_new,
0, sizeof(t_sigbiquad), 0, A_GIMME, 0);
CLASS_MAINSIGNALIN(sigbiquad_class, t_sigbiquad, x_f);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_dsp, gensym("dsp"), 0);
class_addlist(sigbiquad_class, sigbiquad_list);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("set"),
A_GIMME, 0);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("clear"),
A_GIMME, 0);
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct biquadctl
{
t_sample c_x1;
t_sample c_x2;
t_sample c_fb1;
t_sample c_fb2;
t_sample c_ff1;
t_sample c_ff2;
t_sample c_ff3;
} t_biquadctl;
typedef struct sigbiquad
{
t_object x_obj;
float x_f;
t_biquadctl x_cspace;
t_biquadctl *x_ctl;
} t_sigbiquad;
t_class *sigbiquad_class;
static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv);
static void *sigbiquad_new(t_symbol *s, int argc, t_atom *argv)
{
t_sigbiquad *x = (t_sigbiquad *)pd_new(sigbiquad_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x1 = x->x_cspace.c_x2 = 0;
sigbiquad_list(x, s, argc, argv);
x->x_f = 0;
return (x);
}
static t_int *sigbiquad_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_biquadctl *c = (t_biquadctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x1;
t_sample prev = c->c_x2;
t_sample fb1 = c->c_fb1;
t_sample fb2 = c->c_fb2;
t_sample ff1 = c->c_ff1;
t_sample ff2 = c->c_ff2;
t_sample ff3 = c->c_ff3;
for (i = 0; i < n; i++)
{
t_sample output = *in++ + mult(fb1,last) + mult(fb2,prev);
if (PD_BADFLOAT(output))
output = 0;
*out++ = mult(ff1,output) + mult(ff2,last) + mult(ff3,prev);
prev = last;
last = output;
}
c->c_x1 = last;
c->c_x2 = prev;
return (w+5);
}
static void sigbiquad_list(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
{
float fb1 = atom_getfloatarg(0, argc, argv);
float fb2 = atom_getfloatarg(1, argc, argv);
float ff1 = atom_getfloatarg(2, argc, argv);
float ff2 = atom_getfloatarg(3, argc, argv);
float ff3 = atom_getfloatarg(4, argc, argv);
float discriminant = fb1 * fb1 + 4 * fb2;
t_biquadctl *c = x->x_ctl;
if (discriminant < 0) /* imaginary roots -- resonant filter */
{
/* they're conjugates so we just check that the product
is less than one */
if (fb2 >= -1.0f) goto stable;
}
else /* real roots */
{
/* check that the parabola 1 - fb1 x - fb2 x^2 has a
vertex between -1 and 1, and that it's nonnegative
at both ends, which implies both roots are in [1-,1]. */
if (fb1 <= 2.0f && fb1 >= -2.0f &&
1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0)
goto stable;
}
/* if unstable, just bash to zero */
fb1 = fb2 = ff1 = ff2 = ff3 = 0;
stable:
c->c_fb1 = ftofix(fb1);
c->c_fb2 = ftofix(fb2);
c->c_ff1 = ftofix(ff1);
c->c_ff2 = ftofix(ff2);
c->c_ff3 = ftofix(ff3);
}
static void sigbiquad_set(t_sigbiquad *x, t_symbol *s, int argc, t_atom *argv)
{
t_biquadctl *c = x->x_ctl;
c->c_x1 = atom_getfloatarg(0, argc, argv);
c->c_x2 = atom_getfloatarg(1, argc, argv);
}
static void sigbiquad_dsp(t_sigbiquad *x, t_signal **sp)
{
dsp_add(sigbiquad_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void biquad_tilde_setup(void)
{
sigbiquad_class = class_new(gensym("biquad~"), (t_newmethod)sigbiquad_new,
0, sizeof(t_sigbiquad), 0, A_GIMME, 0);
CLASS_MAINSIGNALIN(sigbiquad_class, t_sigbiquad, x_f);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_dsp, gensym("dsp"), 0);
class_addlist(sigbiquad_class, sigbiquad_list);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("set"),
A_GIMME, 0);
class_addmethod(sigbiquad_class, (t_method)sigbiquad_set, gensym("clear"),
A_GIMME, 0);
}

View file

@ -0,0 +1,276 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct bpctl
{
t_sample c_x1;
t_sample c_x2;
t_sample c_coef1;
t_sample c_coef2;
t_sample c_gain;
} t_bpctl;
typedef struct sigbp
{
t_object x_obj;
float x_sr;
float x_freq;
float x_q;
t_bpctl x_cspace;
t_bpctl *x_ctl;
float x_f;
} t_sigbp;
t_class *sigbp_class;
static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q);
static void *sigbp_new(t_floatarg f, t_floatarg q)
{
t_sigbp *x = (t_sigbp *)pd_new(sigbp_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x1 = 0;
x->x_cspace.c_x2 = 0;
sigbp_docoef(x, f, q);
x->x_f = 0;
return (x);
}
static float sigbp_qcos(float f)
{
if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f)
{
float g = f*f;
return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
}
else return (0);
}
static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q)
{
float r, oneminusr, omega;
if (f < 0.001) f = 10;
if (q < 0) q = 0;
x->x_freq = f;
x->x_q = q;
omega = f * (2.0f * 3.14159f) / x->x_sr;
if (q < 0.001) oneminusr = 1.0f;
else oneminusr = omega/q;
if (oneminusr > 1.0f) oneminusr = 1.0f;
r = 1.0f - oneminusr;
x->x_ctl->c_coef1 = ftofix(2.0f * sigbp_qcos(omega) * r);
x->x_ctl->c_coef2 = ftofix(- r * r);
x->x_ctl->c_gain = ftofix(2 * oneminusr * (oneminusr + r * omega));
/* post("r %f, omega %f, coef1 %f, coef2 %f",
r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
}
static void sigbp_ft1(t_sigbp *x, t_floatarg f)
{
sigbp_docoef(x, f, x->x_q);
}
static void sigbp_ft2(t_sigbp *x, t_floatarg q)
{
sigbp_docoef(x, x->x_freq, q);
}
static void sigbp_clear(t_sigbp *x, t_floatarg q)
{
x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0;
}
static t_int *sigbp_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_bpctl *c = (t_bpctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x1;
t_sample prev = c->c_x2;
t_sample coef1 = c->c_coef1;
t_sample coef2 = c->c_coef2;
t_sample gain = c->c_gain;
for (i = 0; i < n; i++)
{
t_sample output = *in++ + mult(coef1,last) + mult(coef2,prev);
*out++ = mult(gain,output);
prev = last;
last = output;
}
if (PD_BADFLOAT(last))
last = 0;
if (PD_BADFLOAT(prev))
prev = 0;
c->c_x1 = last;
c->c_x2 = prev;
return (w+5);
}
static void sigbp_dsp(t_sigbp *x, t_signal **sp)
{
x->x_sr = sp[0]->s_sr;
sigbp_docoef(x, x->x_freq, x->x_q);
dsp_add(sigbp_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void bp_tilde_setup(void)
{
sigbp_class = class_new(gensym("bp~"), (t_newmethod)sigbp_new, 0,
sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, x_f);
class_addmethod(sigbp_class, (t_method)sigbp_dsp, gensym("dsp"), 0);
class_addmethod(sigbp_class, (t_method)sigbp_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(sigbp_class, (t_method)sigbp_ft2,
gensym("ft2"), A_FLOAT, 0);
class_addmethod(sigbp_class, (t_method)sigbp_clear, gensym("clear"), 0);
class_sethelpsymbol(sigbp_class, gensym("lop~-help.pd"));
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct bpctl
{
t_sample c_x1;
t_sample c_x2;
t_sample c_coef1;
t_sample c_coef2;
t_sample c_gain;
} t_bpctl;
typedef struct sigbp
{
t_object x_obj;
float x_sr;
float x_freq;
float x_q;
t_bpctl x_cspace;
t_bpctl *x_ctl;
float x_f;
} t_sigbp;
t_class *sigbp_class;
static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q);
static void *sigbp_new(t_floatarg f, t_floatarg q)
{
t_sigbp *x = (t_sigbp *)pd_new(sigbp_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x1 = 0;
x->x_cspace.c_x2 = 0;
sigbp_docoef(x, f, q);
x->x_f = 0;
return (x);
}
static float sigbp_qcos(float f)
{
if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f)
{
float g = f*f;
return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
}
else return (0);
}
static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q)
{
float r, oneminusr, omega;
if (f < 0.001) f = 10;
if (q < 0) q = 0;
x->x_freq = f;
x->x_q = q;
omega = f * (2.0f * 3.14159f) / x->x_sr;
if (q < 0.001) oneminusr = 1.0f;
else oneminusr = omega/q;
if (oneminusr > 1.0f) oneminusr = 1.0f;
r = 1.0f - oneminusr;
x->x_ctl->c_coef1 = ftofix(2.0f * sigbp_qcos(omega) * r);
x->x_ctl->c_coef2 = ftofix(- r * r);
x->x_ctl->c_gain = ftofix(2 * oneminusr * (oneminusr + r * omega));
/* post("r %f, omega %f, coef1 %f, coef2 %f",
r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
}
static void sigbp_ft1(t_sigbp *x, t_floatarg f)
{
sigbp_docoef(x, f, x->x_q);
}
static void sigbp_ft2(t_sigbp *x, t_floatarg q)
{
sigbp_docoef(x, x->x_freq, q);
}
static void sigbp_clear(t_sigbp *x, t_floatarg q)
{
x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0;
}
static t_int *sigbp_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_bpctl *c = (t_bpctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x1;
t_sample prev = c->c_x2;
t_sample coef1 = c->c_coef1;
t_sample coef2 = c->c_coef2;
t_sample gain = c->c_gain;
for (i = 0; i < n; i++)
{
t_sample output = *in++ + mult(coef1,last) + mult(coef2,prev);
*out++ = mult(gain,output);
prev = last;
last = output;
}
if (PD_BADFLOAT(last))
last = 0;
if (PD_BADFLOAT(prev))
prev = 0;
c->c_x1 = last;
c->c_x2 = prev;
return (w+5);
}
static void sigbp_dsp(t_sigbp *x, t_signal **sp)
{
x->x_sr = sp[0]->s_sr;
sigbp_docoef(x, x->x_freq, x->x_q);
dsp_add(sigbp_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void bp_tilde_setup(void)
{
sigbp_class = class_new(gensym("bp~"), (t_newmethod)sigbp_new, 0,
sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, x_f);
class_addmethod(sigbp_class, (t_method)sigbp_dsp, gensym("dsp"), 0);
class_addmethod(sigbp_class, (t_method)sigbp_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(sigbp_class, (t_method)sigbp_ft2,
gensym("ft2"), A_FLOAT, 0);
class_addmethod(sigbp_class, (t_method)sigbp_clear, gensym("clear"), 0);
class_sethelpsymbol(sigbp_class, gensym("lop~-help.pd"));
}

View file

@ -0,0 +1,116 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *clip_class;
typedef struct _clip
{
t_object x_obj;
float x_f;
t_float x_lo;
t_float x_hi;
} t_clip;
static void *clip_new(t_floatarg lo, t_floatarg hi)
{
t_clip *x = (t_clip *)pd_new(clip_class);
x->x_lo = lo;
x->x_hi = hi;
outlet_new(&x->x_obj, gensym("signal"));
floatinlet_new(&x->x_obj, &x->x_lo);
floatinlet_new(&x->x_obj, &x->x_hi);
x->x_f = 0;
return (x);
}
static t_int *clip_perform(t_int *w)
{
t_clip *x = (t_clip *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
t_sample lo;
t_sample hi;
lo = ftofix(x->x_lo);
hi = ftofix(x->x_hi);
while (n--)
{
t_sample f = *in++;
if (f < lo) f = lo;
if (f > hi) f = hi;
*out++ = f;
}
return (w+5);
}
static void clip_dsp(t_clip *x, t_signal **sp)
{
dsp_add(clip_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void clip_tilde_setup(void)
{
clip_class = class_new(gensym("clip~"), (t_newmethod)clip_new, 0,
sizeof(t_clip), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(clip_class, t_clip, x_f);
class_addmethod(clip_class, (t_method)clip_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *clip_class;
typedef struct _clip
{
t_object x_obj;
float x_f;
t_float x_lo;
t_float x_hi;
} t_clip;
static void *clip_new(t_floatarg lo, t_floatarg hi)
{
t_clip *x = (t_clip *)pd_new(clip_class);
x->x_lo = lo;
x->x_hi = hi;
outlet_new(&x->x_obj, gensym("signal"));
floatinlet_new(&x->x_obj, &x->x_lo);
floatinlet_new(&x->x_obj, &x->x_hi);
x->x_f = 0;
return (x);
}
static t_int *clip_perform(t_int *w)
{
t_clip *x = (t_clip *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
t_sample lo;
t_sample hi;
lo = ftofix(x->x_lo);
hi = ftofix(x->x_hi);
while (n--)
{
t_sample f = *in++;
if (f < lo) f = lo;
if (f > hi) f = hi;
*out++ = f;
}
return (w+5);
}
static void clip_dsp(t_clip *x, t_signal **sp)
{
dsp_add(clip_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void clip_tilde_setup(void)
{
clip_class = class_new(gensym("clip~"), (t_newmethod)clip_new, 0,
sizeof(t_clip), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(clip_class, t_clip, x_f);
class_addmethod(clip_class, (t_method)clip_dsp, gensym("dsp"), 0);
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,122 @@
#include <m_pd.h>
#include <m_fixed.h>
#include "cos_table.h"
/* ------------------------ cos~ ----------------------------- */
#define FRAC ((1<<(fix1-ILOGCOSTABSIZE))-1)
static t_class *cos_class;
typedef struct _cos
{
t_object x_obj;
float x_f;
} t_cos;
static void *cos_new(void)
{
t_cos *x = (t_cos *)pd_new(cos_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *cos_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample *tab = cos_table;
int off;
int frac;
unsigned int phase;
while (n--) {
phase = *in++;
phase &= ((1<<fix1)-1);
off = fixtoi((long long)phase<<ILOGCOSTABSIZE);
frac = phase&(itofix(1)-1);
*out = mult(*(tab + off),itofix(1) - frac) +
mult(*(tab + off + 1),frac);
out++;
}
return (w+4);
}
static void cos_dsp(t_cos *x, t_signal **sp)
{
dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void cos_tilde_setup(void)
{
cos_class = class_new(gensym("cos~"), (t_newmethod)cos_new, 0,
sizeof(t_cos), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(cos_class, t_cos, x_f);
class_addmethod(cos_class, (t_method)cos_dsp, gensym("dsp"), 0);
class_sethelpsymbol(cos_class, gensym("osc~-help.pd"));
}
#include <m_pd.h>
#include <m_fixed.h>
#include "cos_table.h"
/* ------------------------ cos~ ----------------------------- */
#define FRAC ((1<<(fix1-ILOGCOSTABSIZE))-1)
static t_class *cos_class;
typedef struct _cos
{
t_object x_obj;
float x_f;
} t_cos;
static void *cos_new(void)
{
t_cos *x = (t_cos *)pd_new(cos_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *cos_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample *tab = cos_table;
int off;
int frac;
unsigned int phase;
while (n--) {
phase = *in++;
phase &= ((1<<fix1)-1);
off = fixtoi((long long)phase<<ILOGCOSTABSIZE);
frac = phase&(itofix(1)-1);
*out = mult(*(tab + off),itofix(1) - frac) +
mult(*(tab + off + 1),frac);
out++;
}
return (w+4);
}
static void cos_dsp(t_cos *x, t_signal **sp)
{
dsp_add(cos_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void cos_tilde_setup(void)
{
cos_class = class_new(gensym("cos~"), (t_newmethod)cos_new, 0,
sizeof(t_cos), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(cos_class, t_cos, x_f);
class_addmethod(cos_class, (t_method)cos_dsp, gensym("dsp"), 0);
class_sethelpsymbol(cos_class, gensym("osc~-help.pd"));
}

View file

@ -0,0 +1,104 @@
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct dbtopow_tilde
{
t_object x_obj;
float x_f;
} t_dbtopow_tilde;
t_class *dbtopow_tilde_class;
static void *dbtopow_tilde_new(void)
{
t_dbtopow_tilde *x = (t_dbtopow_tilde *)pd_new(dbtopow_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *dbtopow_tilde_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
if (f > 870)
f = 870;
*out = exp((LOGTEN * 0.1) * (f-100.));
}
}
return (w + 4);
}
static void dbtopow_tilde_dsp(t_dbtopow_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(dbtopow_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void dbtopow_tilde_setup(void)
{
dbtopow_tilde_class = class_new(gensym("dbtopow~"), (t_newmethod)dbtopow_tilde_new, 0,
sizeof(t_dbtopow_tilde), 0, 0);
CLASS_MAINSIGNALIN(dbtopow_tilde_class, t_dbtopow_tilde, x_f);
class_addmethod(dbtopow_tilde_class, (t_method)dbtopow_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct dbtopow_tilde
{
t_object x_obj;
float x_f;
} t_dbtopow_tilde;
t_class *dbtopow_tilde_class;
static void *dbtopow_tilde_new(void)
{
t_dbtopow_tilde *x = (t_dbtopow_tilde *)pd_new(dbtopow_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *dbtopow_tilde_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
if (f > 870)
f = 870;
*out = exp((LOGTEN * 0.1) * (f-100.));
}
}
return (w + 4);
}
static void dbtopow_tilde_dsp(t_dbtopow_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(dbtopow_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void dbtopow_tilde_setup(void)
{
dbtopow_tilde_class = class_new(gensym("dbtopow~"), (t_newmethod)dbtopow_tilde_new, 0,
sizeof(t_dbtopow_tilde), 0, 0);
CLASS_MAINSIGNALIN(dbtopow_tilde_class, t_dbtopow_tilde, x_f);
class_addmethod(dbtopow_tilde_class, (t_method)dbtopow_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,106 @@
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct dbtorms_tilde
{
t_object x_obj;
float x_f;
} t_dbtorms_tilde;
t_class *dbtorms_tilde_class;
static void *dbtorms_tilde_new(void)
{
t_dbtorms_tilde *x = (t_dbtorms_tilde *)pd_new(dbtorms_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *dbtorms_tilde_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
if (f > 485)
f = 485;
*out = exp((LOGTEN * 0.05) * (f-100.));
}
}
return (w + 4);
}
static void dbtorms_tilde_dsp(t_dbtorms_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(dbtorms_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void dbtorms_tilde_setup(void)
{
dbtorms_tilde_class = class_new(gensym("dbtorms~"), (t_newmethod)dbtorms_tilde_new, 0,
sizeof(t_dbtorms_tilde), 0, 0);
CLASS_MAINSIGNALIN(dbtorms_tilde_class, t_dbtorms_tilde, x_f);
class_addmethod(dbtorms_tilde_class, (t_method)dbtorms_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct dbtorms_tilde
{
t_object x_obj;
float x_f;
} t_dbtorms_tilde;
t_class *dbtorms_tilde_class;
static void *dbtorms_tilde_new(void)
{
t_dbtorms_tilde *x = (t_dbtorms_tilde *)pd_new(dbtorms_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *dbtorms_tilde_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
if (f > 485)
f = 485;
*out = exp((LOGTEN * 0.05) * (f-100.));
}
}
return (w + 4);
}
static void dbtorms_tilde_dsp(t_dbtorms_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(dbtorms_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void dbtorms_tilde_setup(void)
{
dbtorms_tilde_class = class_new(gensym("dbtorms~"), (t_newmethod)dbtorms_tilde_new, 0,
sizeof(t_dbtorms_tilde), 0, 0);
CLASS_MAINSIGNALIN(dbtorms_tilde_class, t_dbtorms_tilde, x_f);
class_addmethod(dbtorms_tilde_class, (t_method)dbtorms_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,84 @@
#ifndef __DELAY_H__
#define __DELAY_H__
extern t_class *sigdelwrite_class;
typedef struct delwritectl
{
int c_n;
t_sample *c_vec;
int c_phase;
} t_delwritectl;
typedef struct _sigdelwrite
{
t_object x_obj;
t_symbol *x_sym;
t_delwritectl x_cspace;
int x_sortno; /* DSP sort number at which this was last put on chain */
int x_rsortno; /* DSP sort # for first delread or write in chain */
int x_vecsize; /* vector size for delread~ to use */
float x_f;
} t_sigdelwrite;
#define XTRASAMPS 4
#define SAMPBLK 4
/* routine to check that all delwrites/delreads/vds have same vecsize */
static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
{
if (x->x_rsortno != ugen_getsortno())
{
x->x_vecsize = vecsize;
x->x_rsortno = ugen_getsortno();
}
else if (vecsize != x->x_vecsize)
pd_error(x, "delread/delwrite/vd vector size mismatch");
}
#endif
#ifndef __DELAY_H__
#define __DELAY_H__
extern t_class *sigdelwrite_class;
typedef struct delwritectl
{
int c_n;
t_sample *c_vec;
int c_phase;
} t_delwritectl;
typedef struct _sigdelwrite
{
t_object x_obj;
t_symbol *x_sym;
t_delwritectl x_cspace;
int x_sortno; /* DSP sort number at which this was last put on chain */
int x_rsortno; /* DSP sort # for first delread or write in chain */
int x_vecsize; /* vector size for delread~ to use */
float x_f;
} t_sigdelwrite;
#define XTRASAMPS 4
#define SAMPBLK 4
/* routine to check that all delwrites/delreads/vds have same vecsize */
static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
{
if (x->x_rsortno != ugen_getsortno())
{
x->x_vecsize = vecsize;
x->x_rsortno = ugen_getsortno();
}
else if (vecsize != x->x_vecsize)
pd_error(x, "delread/delwrite/vd vector size mismatch");
}
#endif

View file

@ -0,0 +1,200 @@
#include <m_pd.h>
#include <m_fixed.h>
#include "delay.h"
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
static t_class *sigdelread_class;
typedef struct _sigdelread
{
t_object x_obj;
t_symbol *x_sym;
t_float x_deltime; /* delay in msec */
int x_delsamps; /* delay in samples */
t_float x_sr; /* samples per msec */
t_float x_n; /* vector size */
int x_zerodel; /* 0 or vecsize depending on read/write order */
} t_sigdelread;
static void sigdelread_float(t_sigdelread *x, t_float f);
static void *sigdelread_new(t_symbol *s, t_floatarg f)
{
t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
x->x_sym = s;
x->x_sr = 1;
x->x_n = 1;
x->x_zerodel = 0;
sigdelread_float(x, f);
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static void sigdelread_float(t_sigdelread *x, t_float f)
{
int samps;
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_deltime = f;
if (delwriter)
{
int delsize = delwriter->x_cspace.c_n;
x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
+ x->x_n - x->x_zerodel;
if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
}
}
static t_int *sigdelread_perform(t_int *w)
{
t_sample *out = (t_sample *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int delsamps = *(int *)(w[3]);
int n = (int)(w[4]);
int phase = c->c_phase - delsamps, nsamps = c->c_n;
t_sample *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
if (phase < 0) phase += nsamps;
bp = vp + phase;
while (n--)
{
*out++ = *bp++;
if (bp == ep) bp -= nsamps;
}
return (w+5);
}
static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
x->x_n = sp[0]->s_n;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
sigdelread_float(x, x->x_deltime);
dsp_add(sigdelread_perform, 4,
sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
}
else if (*x->x_sym->s_name)
error("delread~: %s: no such delwrite~",x->x_sym->s_name);
}
void delread_tilde_setup(void)
{
sigdelread_class = class_new(gensym("delread~"),
(t_newmethod)sigdelread_new, 0,
sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
gensym("dsp"), 0);
class_addfloat(sigdelread_class, (t_method)sigdelread_float);
}
#include <m_pd.h>
#include <m_fixed.h>
#include "delay.h"
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
static t_class *sigdelread_class;
typedef struct _sigdelread
{
t_object x_obj;
t_symbol *x_sym;
t_float x_deltime; /* delay in msec */
int x_delsamps; /* delay in samples */
t_float x_sr; /* samples per msec */
t_float x_n; /* vector size */
int x_zerodel; /* 0 or vecsize depending on read/write order */
} t_sigdelread;
static void sigdelread_float(t_sigdelread *x, t_float f);
static void *sigdelread_new(t_symbol *s, t_floatarg f)
{
t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
x->x_sym = s;
x->x_sr = 1;
x->x_n = 1;
x->x_zerodel = 0;
sigdelread_float(x, f);
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static void sigdelread_float(t_sigdelread *x, t_float f)
{
int samps;
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_deltime = f;
if (delwriter)
{
int delsize = delwriter->x_cspace.c_n;
x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
+ x->x_n - x->x_zerodel;
if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
}
}
static t_int *sigdelread_perform(t_int *w)
{
t_sample *out = (t_sample *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int delsamps = *(int *)(w[3]);
int n = (int)(w[4]);
int phase = c->c_phase - delsamps, nsamps = c->c_n;
t_sample *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
if (phase < 0) phase += nsamps;
bp = vp + phase;
while (n--)
{
*out++ = *bp++;
if (bp == ep) bp -= nsamps;
}
return (w+5);
}
static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
x->x_n = sp[0]->s_n;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
sigdelread_float(x, x->x_deltime);
dsp_add(sigdelread_perform, 4,
sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
}
else if (*x->x_sym->s_name)
error("delread~: %s: no such delwrite~",x->x_sym->s_name);
}
void delread_tilde_setup(void)
{
sigdelread_class = class_new(gensym("delread~"),
(t_newmethod)sigdelread_new, 0,
sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
gensym("dsp"), 0);
class_addfloat(sigdelread_class, (t_method)sigdelread_float);
}

View file

@ -0,0 +1,168 @@
#include <m_pd.h>
#include <m_fixed.h>
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
#include "delay.h"
t_class *sigdelwrite_class;
static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
{
int nsamps;
t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
if (!*s->s_name) s = gensym("delwrite~");
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
nsamps = msec * sys_getsr() * (float)(0.001f);
if (nsamps < 1) nsamps = 1;
nsamps += ((- nsamps) & (SAMPBLK - 1));
nsamps += DEFDELVS;
x->x_cspace.c_n = nsamps;
x->x_cspace.c_vec =
(t_sample *)getbytes((nsamps + XTRASAMPS) * sizeof(float));
x->x_cspace.c_phase = XTRASAMPS;
x->x_sortno = 0;
x->x_vecsize = 0;
x->x_f = 0;
return (x);
}
static t_int *sigdelwrite_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int n = (int)(w[3]);
int phase = c->c_phase, nsamps = c->c_n;
t_sample *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
phase += n;
while (n--)
{
t_sample f = *in++;
if (PD_BADFLOAT(f))
f = 0;
*bp++ = f;
if (bp == ep)
{
vp[0] = ep[-4];
vp[1] = ep[-3];
vp[2] = ep[-2];
vp[3] = ep[-1];
bp = vp + XTRASAMPS;
phase -= nsamps;
}
}
c->c_phase = phase;
return (w+4);
}
static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
{
dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
x->x_sortno = ugen_getsortno();
sigdelwrite_checkvecsize(x, sp[0]->s_n);
}
static void sigdelwrite_free(t_sigdelwrite *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_cspace.c_vec,
(x->x_cspace.c_n + XTRASAMPS) * sizeof(float));
}
void delwrite_tilde_setup(void)
{
sigdelwrite_class = class_new(gensym("delwrite~"),
(t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
#include "delay.h"
t_class *sigdelwrite_class;
static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
{
int nsamps;
t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
if (!*s->s_name) s = gensym("delwrite~");
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
nsamps = msec * sys_getsr() * (float)(0.001f);
if (nsamps < 1) nsamps = 1;
nsamps += ((- nsamps) & (SAMPBLK - 1));
nsamps += DEFDELVS;
x->x_cspace.c_n = nsamps;
x->x_cspace.c_vec =
(t_sample *)getbytes((nsamps + XTRASAMPS) * sizeof(float));
x->x_cspace.c_phase = XTRASAMPS;
x->x_sortno = 0;
x->x_vecsize = 0;
x->x_f = 0;
return (x);
}
static t_int *sigdelwrite_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int n = (int)(w[3]);
int phase = c->c_phase, nsamps = c->c_n;
t_sample *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
phase += n;
while (n--)
{
t_sample f = *in++;
if (PD_BADFLOAT(f))
f = 0;
*bp++ = f;
if (bp == ep)
{
vp[0] = ep[-4];
vp[1] = ep[-3];
vp[2] = ep[-2];
vp[3] = ep[-1];
bp = vp + XTRASAMPS;
phase -= nsamps;
}
}
c->c_phase = phase;
return (w+4);
}
static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
{
dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
x->x_sortno = ugen_getsortno();
sigdelwrite_checkvecsize(x, sp[0]->s_n);
}
static void sigdelwrite_free(t_sigdelwrite *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_cspace.c_vec,
(x->x_cspace.c_n + XTRASAMPS) * sizeof(float));
}
void delwrite_tilde_setup(void)
{
sigdelwrite_class = class_new(gensym("delwrite~"),
(t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
gensym("dsp"), 0);
}

View file

@ -0,0 +1,254 @@
#define FIXEDPOINT
#include <m_pd.h>
#include <m_fixed.h>
#define MAXOVERLAP 10
#define MAXVSTAKEN 64
typedef struct sigenv
{
t_object x_obj; /* header */
void *x_outlet; /* a "float" outlet */
void *x_clock; /* a "clock" object */
t_sample *x_buf; /* a Hanning window */
int x_phase; /* number of points since last output */
int x_period; /* requested period of output */
int x_realperiod; /* period rounded up to vecsize multiple */
int x_npoints; /* analysis window size in samples */
t_float x_result; /* result to output */
t_sample x_sumbuf[MAXOVERLAP]; /* summing buffer */
t_float x_f;
} t_sigenv;
t_class *sigenv_class;
static void sigenv_tick(t_sigenv *x);
static void *sigenv_new(t_floatarg fnpoints, t_floatarg fperiod)
{
int npoints = fnpoints;
int period = fperiod;
t_sigenv *x;
t_sample *buf;
int i;
if (npoints < 1) npoints = 1024;
if (period < 1) period = npoints/2;
if (period < npoints / MAXOVERLAP + 1)
period = npoints / MAXOVERLAP + 1;
if (!(buf = getbytes(sizeof(t_sample) * (npoints + MAXVSTAKEN))))
{
error("env: couldn't allocate buffer");
return (0);
}
x = (t_sigenv *)pd_new(sigenv_class);
x->x_buf = buf;
x->x_npoints = npoints;
x->x_phase = 0;
x->x_period = period;
for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
for (i = 0; i < npoints; i++)
buf[i] = ftofix((1. - cos((2 * 3.14159 * i) / npoints))/npoints);
for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
x->x_clock = clock_new(x, (t_method)sigenv_tick);
x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
x->x_f = 0;
return (x);
}
static t_int *sigenv_perform(t_int *w)
{
t_sigenv *x = (t_sigenv *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
int count;
t_sample *sump;
in += n;
for (count = x->x_phase, sump = x->x_sumbuf;
count < x->x_npoints; count += x->x_realperiod, sump++)
{
t_sample *hp = x->x_buf + count;
t_sample *fp = in;
t_sample sum = *sump;
int i;
for (i = 0; i < n; i++)
{
fp--;
sum += *hp++ * ((*fp * *fp)>>16)>>16;
}
*sump = sum;
}
sump[0] = 0;
x->x_phase -= n;
if (x->x_phase < 0)
{
x->x_result = x->x_sumbuf[0];
for (count = x->x_realperiod, sump = x->x_sumbuf;
count < x->x_npoints; count += x->x_realperiod, sump++)
sump[0] = sump[1];
sump[0] = 0;
x->x_phase = x->x_realperiod - n;
clock_delay(x->x_clock, 0L);
}
return (w+4);
}
static void sigenv_dsp(t_sigenv *x, t_signal **sp)
{
if (x->x_period % sp[0]->s_n) x->x_realperiod =
x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n);
else x->x_realperiod = x->x_period;
dsp_add(sigenv_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
if (sp[0]->s_n > MAXVSTAKEN) bug("sigenv_dsp");
}
static void sigenv_tick(t_sigenv *x) /* callback function for the clock */
{
outlet_float(x->x_outlet, powtodb(x->x_result*3.051757e-05));
}
static void sigenv_ff(t_sigenv *x) /* cleanup on free */
{
clock_free(x->x_clock);
freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float));
}
void env_tilde_setup(void )
{
sigenv_class = class_new(gensym("env~"), (t_newmethod)sigenv_new,
(t_method)sigenv_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigenv_class, t_sigenv, x_f);
class_addmethod(sigenv_class, (t_method)sigenv_dsp, gensym("dsp"), 0);
}
#define FIXEDPOINT
#include <m_pd.h>
#include <m_fixed.h>
#define MAXOVERLAP 10
#define MAXVSTAKEN 64
typedef struct sigenv
{
t_object x_obj; /* header */
void *x_outlet; /* a "float" outlet */
void *x_clock; /* a "clock" object */
t_sample *x_buf; /* a Hanning window */
int x_phase; /* number of points since last output */
int x_period; /* requested period of output */
int x_realperiod; /* period rounded up to vecsize multiple */
int x_npoints; /* analysis window size in samples */
t_float x_result; /* result to output */
t_sample x_sumbuf[MAXOVERLAP]; /* summing buffer */
t_float x_f;
} t_sigenv;
t_class *sigenv_class;
static void sigenv_tick(t_sigenv *x);
static void *sigenv_new(t_floatarg fnpoints, t_floatarg fperiod)
{
int npoints = fnpoints;
int period = fperiod;
t_sigenv *x;
t_sample *buf;
int i;
if (npoints < 1) npoints = 1024;
if (period < 1) period = npoints/2;
if (period < npoints / MAXOVERLAP + 1)
period = npoints / MAXOVERLAP + 1;
if (!(buf = getbytes(sizeof(t_sample) * (npoints + MAXVSTAKEN))))
{
error("env: couldn't allocate buffer");
return (0);
}
x = (t_sigenv *)pd_new(sigenv_class);
x->x_buf = buf;
x->x_npoints = npoints;
x->x_phase = 0;
x->x_period = period;
for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
for (i = 0; i < npoints; i++)
buf[i] = ftofix((1. - cos((2 * 3.14159 * i) / npoints))/npoints);
for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
x->x_clock = clock_new(x, (t_method)sigenv_tick);
x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
x->x_f = 0;
return (x);
}
static t_int *sigenv_perform(t_int *w)
{
t_sigenv *x = (t_sigenv *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
int count;
t_sample *sump;
in += n;
for (count = x->x_phase, sump = x->x_sumbuf;
count < x->x_npoints; count += x->x_realperiod, sump++)
{
t_sample *hp = x->x_buf + count;
t_sample *fp = in;
t_sample sum = *sump;
int i;
for (i = 0; i < n; i++)
{
fp--;
sum += *hp++ * ((*fp * *fp)>>16)>>16;
}
*sump = sum;
}
sump[0] = 0;
x->x_phase -= n;
if (x->x_phase < 0)
{
x->x_result = x->x_sumbuf[0];
for (count = x->x_realperiod, sump = x->x_sumbuf;
count < x->x_npoints; count += x->x_realperiod, sump++)
sump[0] = sump[1];
sump[0] = 0;
x->x_phase = x->x_realperiod - n;
clock_delay(x->x_clock, 0L);
}
return (w+4);
}
static void sigenv_dsp(t_sigenv *x, t_signal **sp)
{
if (x->x_period % sp[0]->s_n) x->x_realperiod =
x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n);
else x->x_realperiod = x->x_period;
dsp_add(sigenv_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
if (sp[0]->s_n > MAXVSTAKEN) bug("sigenv_dsp");
}
static void sigenv_tick(t_sigenv *x) /* callback function for the clock */
{
outlet_float(x->x_outlet, powtodb(x->x_result*3.051757e-05));
}
static void sigenv_ff(t_sigenv *x) /* cleanup on free */
{
clock_free(x->x_clock);
freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float));
}
void env_tilde_setup(void )
{
sigenv_class = class_new(gensym("env~"), (t_newmethod)sigenv_new,
(t_method)sigenv_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigenv_class, t_sigenv, x_f);
class_addmethod(sigenv_class, (t_method)sigenv_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,88 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct ftom_tilde
{
t_object x_obj;
float x_f;
} t_ftom_tilde;
t_class *ftom_tilde_class;
static void *ftom_tilde_new(void)
{
t_ftom_tilde *x = (t_ftom_tilde *)pd_new(ftom_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *ftom_tilde_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; *in++, out++)
{
t_sample f = *in;
*out = ftofix((fixtof(f) > 0 ? 17.3123405046 * log(.12231220585 * fixtof(f)) : -1500));
}
return (w + 4);
}
static void ftom_tilde_dsp(t_ftom_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(ftom_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void ftom_tilde_setup(void)
{
ftom_tilde_class = class_new(gensym("ftom~"), (t_newmethod)ftom_tilde_new, 0,
sizeof(t_ftom_tilde), 0, 0);
CLASS_MAINSIGNALIN(ftom_tilde_class, t_ftom_tilde, x_f);
class_addmethod(ftom_tilde_class, (t_method)ftom_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct ftom_tilde
{
t_object x_obj;
float x_f;
} t_ftom_tilde;
t_class *ftom_tilde_class;
static void *ftom_tilde_new(void)
{
t_ftom_tilde *x = (t_ftom_tilde *)pd_new(ftom_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *ftom_tilde_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; *in++, out++)
{
t_sample f = *in;
*out = ftofix((fixtof(f) > 0 ? 17.3123405046 * log(.12231220585 * fixtof(f)) : -1500));
}
return (w + 4);
}
static void ftom_tilde_dsp(t_ftom_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(ftom_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void ftom_tilde_setup(void)
{
ftom_tilde_class = class_new(gensym("ftom~"), (t_newmethod)ftom_tilde_new, 0,
sizeof(t_ftom_tilde), 0, 0);
CLASS_MAINSIGNALIN(ftom_tilde_class, t_ftom_tilde, x_f);
class_addmethod(ftom_tilde_class, (t_method)ftom_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,184 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct hipctl
{
t_sample c_x;
t_sample c_coef;
} t_hipctl;
typedef struct sighip
{
t_object x_obj;
float x_sr;
float x_hz;
t_hipctl x_cspace;
t_hipctl *x_ctl;
float x_f;
} t_sighip;
t_class *sighip_class;
static void sighip_ft1(t_sighip *x, t_floatarg f);
static void *sighip_new(t_floatarg f)
{
t_sighip *x = (t_sighip *)pd_new(sighip_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x = 0;
sighip_ft1(x, f);
x->x_f = 0;
return (x);
}
static void sighip_ft1(t_sighip *x, t_floatarg f)
{
t_float coeff;
if (f < 0.001) f = 10;
x->x_hz = f;
coeff = 1 - f * (2 * 3.14159) / x->x_sr;
if (coeff < 0) coeff = 0;
x->x_ctl->c_coef = ftofix(coeff);
}
static t_int *sighip_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_hipctl *c = (t_hipctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x;
t_sample coef = c->c_coef;
for (i = 0; i < n; i++)
{
t_sample new = *in++ + mult(coef,last);
*out++ = new - last;
last = new;
}
if (PD_BADFLOAT(last))
last = 0;
c->c_x = last;
return (w+5);
}
static void sighip_dsp(t_sighip *x, t_signal **sp)
{
x->x_sr = sp[0]->s_sr;
sighip_ft1(x, x->x_hz);
dsp_add(sighip_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
static void sighip_clear(t_sighip *x, t_floatarg q)
{
x->x_cspace.c_x = 0;
}
void hip_tilde_setup(void)
{
sighip_class = class_new(gensym("hip~"), (t_newmethod)sighip_new, 0,
sizeof(t_sighip), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sighip_class, t_sighip, x_f);
class_addmethod(sighip_class, (t_method)sighip_dsp, gensym("dsp"), 0);
class_addmethod(sighip_class, (t_method)sighip_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(sighip_class, (t_method)sighip_clear, gensym("clear"), 0);
class_sethelpsymbol(sighip_class, gensym("lop~-help.pd"));
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct hipctl
{
t_sample c_x;
t_sample c_coef;
} t_hipctl;
typedef struct sighip
{
t_object x_obj;
float x_sr;
float x_hz;
t_hipctl x_cspace;
t_hipctl *x_ctl;
float x_f;
} t_sighip;
t_class *sighip_class;
static void sighip_ft1(t_sighip *x, t_floatarg f);
static void *sighip_new(t_floatarg f)
{
t_sighip *x = (t_sighip *)pd_new(sighip_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x = 0;
sighip_ft1(x, f);
x->x_f = 0;
return (x);
}
static void sighip_ft1(t_sighip *x, t_floatarg f)
{
t_float coeff;
if (f < 0.001) f = 10;
x->x_hz = f;
coeff = 1 - f * (2 * 3.14159) / x->x_sr;
if (coeff < 0) coeff = 0;
x->x_ctl->c_coef = ftofix(coeff);
}
static t_int *sighip_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_hipctl *c = (t_hipctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x;
t_sample coef = c->c_coef;
for (i = 0; i < n; i++)
{
t_sample new = *in++ + mult(coef,last);
*out++ = new - last;
last = new;
}
if (PD_BADFLOAT(last))
last = 0;
c->c_x = last;
return (w+5);
}
static void sighip_dsp(t_sighip *x, t_signal **sp)
{
x->x_sr = sp[0]->s_sr;
sighip_ft1(x, x->x_hz);
dsp_add(sighip_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
static void sighip_clear(t_sighip *x, t_floatarg q)
{
x->x_cspace.c_x = 0;
}
void hip_tilde_setup(void)
{
sighip_class = class_new(gensym("hip~"), (t_newmethod)sighip_new, 0,
sizeof(t_sighip), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sighip_class, t_sighip, x_f);
class_addmethod(sighip_class, (t_method)sighip_dsp, gensym("dsp"), 0);
class_addmethod(sighip_class, (t_method)sighip_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(sighip_class, (t_method)sighip_clear, gensym("clear"), 0);
class_sethelpsymbol(sighip_class, gensym("lop~-help.pd"));
}

View file

@ -0,0 +1,94 @@
#include <stdio.h>
void d_intern_setup() {
fprintf(stderr,"setup\n");
biquad_tilde_setup();
bp_tilde_setup();
clip_tilde_setup();
cos_tilde_setup();
dbtopow_tilde_setup();
dbtorms_tilde_setup();
delread_tilde_setup();
delwrite_tilde_setup();
env_tilde_setup();
ftom_tilde_setup();
hip_tilde_setup();
line_tilde_setup();
lop_tilde_setup();
mtof_tilde_setup();
noise_tilde_setup();
osc_tilde_setup();
phasor_tilde_setup();
powtodb_tilde_setup();
print_tilde_setup();
rmstodb_tilde_setup();
rsqrt_tilde_setup();
samphold_tilde_setup();
sfread_tilde_setup();
sfwrite_tilde_setup();
sig_tilde_setup();
snapshot_tilde_setup();
sqrt_tilde_setup();
tabosc4_tilde_setup();
tabplay_tilde_setup();
tabread4_tilde_setup();
tabread_tilde_setup();
tabread_setup();
tabreceive_tilde_setup();
tabsend_tilde_setup();
tabwrite_tilde_setup();
tabwrite_setup();
threshold_tilde_setup();
vcf_tilde_setup();
vd_tilde_setup();
vline_tilde_setup();
vsnapshot_tilde_setup();
wrap_tilde_setup();
}
#include <stdio.h>
void d_intern_setup() {
fprintf(stderr,"setup\n");
biquad_tilde_setup();
bp_tilde_setup();
clip_tilde_setup();
cos_tilde_setup();
dbtopow_tilde_setup();
dbtorms_tilde_setup();
delread_tilde_setup();
delwrite_tilde_setup();
env_tilde_setup();
ftom_tilde_setup();
hip_tilde_setup();
line_tilde_setup();
lop_tilde_setup();
mtof_tilde_setup();
noise_tilde_setup();
osc_tilde_setup();
phasor_tilde_setup();
powtodb_tilde_setup();
print_tilde_setup();
rmstodb_tilde_setup();
rsqrt_tilde_setup();
samphold_tilde_setup();
sfread_tilde_setup();
sfwrite_tilde_setup();
sig_tilde_setup();
snapshot_tilde_setup();
sqrt_tilde_setup();
tabosc4_tilde_setup();
tabplay_tilde_setup();
tabread4_tilde_setup();
tabread_tilde_setup();
tabread_setup();
tabreceive_tilde_setup();
tabsend_tilde_setup();
tabwrite_tilde_setup();
tabwrite_setup();
threshold_tilde_setup();
vcf_tilde_setup();
vd_tilde_setup();
vline_tilde_setup();
vsnapshot_tilde_setup();
wrap_tilde_setup();
}

View file

@ -0,0 +1,202 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *line_class;
typedef struct _line
{
t_object x_obj;
t_sample x_target;
t_sample x_value;
t_sample x_biginc;
t_sample x_inc;
t_sample x_1overn;
t_sample x_msectodsptick;
t_floatarg x_inletvalue;
t_floatarg x_inletwas;
int x_ticksleft;
int x_retarget;
} t_line;
static t_int *line_perform(t_int *w)
{
t_line *x = (t_line *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample f = x->x_value;
if (x->x_retarget)
{
int nticks = mult(ftofix(x->x_inletwas),x->x_msectodsptick);
if (!nticks) nticks = itofix(1);
x->x_ticksleft = fixtoi(nticks);
x->x_biginc = (x->x_target - x->x_value);
x->x_biginc = idiv(x->x_biginc,nticks);
x->x_inc = mult(x->x_1overn, x->x_biginc);
x->x_retarget = 0;
}
if (x->x_ticksleft)
{
t_sample f = x->x_value;
while (n--) *out++ = f, f += x->x_inc;
x->x_value += x->x_biginc;
x->x_ticksleft--;
}
else
{
x->x_value = x->x_target;
while (n--) *out++ = x->x_value;
}
return (w+4);
}
static void line_float(t_line *x, t_float f)
{
if (x->x_inletvalue <= 0)
{
x->x_target = x->x_value = ftofix(f);
x->x_ticksleft = x->x_retarget = 0;
}
else
{
x->x_target = ftofix(f);
x->x_retarget = 1;
x->x_inletwas = x->x_inletvalue;
x->x_inletvalue = 0;
}
}
static void line_stop(t_line *x)
{
x->x_target = x->x_value;
x->x_ticksleft = x->x_retarget = 0;
}
static void line_dsp(t_line *x, t_signal **sp)
{
dsp_add(line_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
x->x_1overn = ftofix(1)/sp[0]->s_n;
x->x_msectodsptick = idiv(sp[0]->s_sr, (1000 * sp[0]->s_n));
}
static void *line_new(void)
{
t_line *x = (t_line *)pd_new(line_class);
outlet_new(&x->x_obj, gensym("signal"));
floatinlet_new(&x->x_obj, &x->x_inletvalue);
x->x_ticksleft = x->x_retarget = 0;
x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0;
return (x);
}
void line_tilde_setup(void)
{
line_class = class_new(gensym("line~"), line_new, 0,
sizeof(t_line), 0, 0);
class_addfloat(line_class, (t_method)line_float);
class_addmethod(line_class, (t_method)line_dsp, gensym("dsp"), 0);
class_addmethod(line_class, (t_method)line_stop, gensym("stop"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *line_class;
typedef struct _line
{
t_object x_obj;
t_sample x_target;
t_sample x_value;
t_sample x_biginc;
t_sample x_inc;
t_sample x_1overn;
t_sample x_msectodsptick;
t_floatarg x_inletvalue;
t_floatarg x_inletwas;
int x_ticksleft;
int x_retarget;
} t_line;
static t_int *line_perform(t_int *w)
{
t_line *x = (t_line *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample f = x->x_value;
if (x->x_retarget)
{
int nticks = mult(ftofix(x->x_inletwas),x->x_msectodsptick);
if (!nticks) nticks = itofix(1);
x->x_ticksleft = fixtoi(nticks);
x->x_biginc = (x->x_target - x->x_value);
x->x_biginc = idiv(x->x_biginc,nticks);
x->x_inc = mult(x->x_1overn, x->x_biginc);
x->x_retarget = 0;
}
if (x->x_ticksleft)
{
t_sample f = x->x_value;
while (n--) *out++ = f, f += x->x_inc;
x->x_value += x->x_biginc;
x->x_ticksleft--;
}
else
{
x->x_value = x->x_target;
while (n--) *out++ = x->x_value;
}
return (w+4);
}
static void line_float(t_line *x, t_float f)
{
if (x->x_inletvalue <= 0)
{
x->x_target = x->x_value = ftofix(f);
x->x_ticksleft = x->x_retarget = 0;
}
else
{
x->x_target = ftofix(f);
x->x_retarget = 1;
x->x_inletwas = x->x_inletvalue;
x->x_inletvalue = 0;
}
}
static void line_stop(t_line *x)
{
x->x_target = x->x_value;
x->x_ticksleft = x->x_retarget = 0;
}
static void line_dsp(t_line *x, t_signal **sp)
{
dsp_add(line_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
x->x_1overn = ftofix(1)/sp[0]->s_n;
x->x_msectodsptick = idiv(sp[0]->s_sr, (1000 * sp[0]->s_n));
}
static void *line_new(void)
{
t_line *x = (t_line *)pd_new(line_class);
outlet_new(&x->x_obj, gensym("signal"));
floatinlet_new(&x->x_obj, &x->x_inletvalue);
x->x_ticksleft = x->x_retarget = 0;
x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0;
return (x);
}
void line_tilde_setup(void)
{
line_class = class_new(gensym("line~"), line_new, 0,
sizeof(t_line), 0, 0);
class_addfloat(line_class, (t_method)line_float);
class_addmethod(line_class, (t_method)line_dsp, gensym("dsp"), 0);
class_addmethod(line_class, (t_method)line_stop, gensym("stop"), 0);
}

View file

@ -0,0 +1,180 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct lopctl
{
t_sample c_x;
t_sample c_coef;
} t_lopctl;
typedef struct siglop
{
t_object x_obj;
float x_sr;
float x_hz;
t_lopctl x_cspace;
t_lopctl *x_ctl;
float x_f;
} t_siglop;
t_class *siglop_class;
static void siglop_ft1(t_siglop *x, t_floatarg f);
static void *siglop_new(t_floatarg f)
{
t_siglop *x = (t_siglop *)pd_new(siglop_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x = 0;
siglop_ft1(x, f);
x->x_f = 0;
return (x);
}
static void siglop_ft1(t_siglop *x, t_floatarg f)
{
t_float coeff;
if (f < 0.001) f = 10;
x->x_hz = f;
coeff = f * (2 * 3.14159) / x->x_sr;
if (coeff > 1) coeff = 1;
x->x_ctl->c_coef = ftofix(coeff);
}
static void siglop_clear(t_siglop *x, t_floatarg q)
{
x->x_cspace.c_x = 0;
}
static t_int *siglop_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_lopctl *c = (t_lopctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x;
t_sample coef = c->c_coef;
t_sample feedback = ftofix(1) - coef;
for (i = 0; i < n; i++)
last = *out++ = mult(coef, *in++) + mult(feedback,last);
if (PD_BADFLOAT(last))
last = 0;
c->c_x = last;
return (w+5);
}
static void siglop_dsp(t_siglop *x, t_signal **sp)
{
x->x_sr = sp[0]->s_sr;
siglop_ft1(x, x->x_hz);
dsp_add(siglop_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void lop_tilde_setup(void)
{
siglop_class = class_new(gensym("lop~"), (t_newmethod)siglop_new, 0,
sizeof(t_siglop), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(siglop_class, t_siglop, x_f);
class_addmethod(siglop_class, (t_method)siglop_dsp, gensym("dsp"), 0);
class_addmethod(siglop_class, (t_method)siglop_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(siglop_class, (t_method)siglop_clear, gensym("clear"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct lopctl
{
t_sample c_x;
t_sample c_coef;
} t_lopctl;
typedef struct siglop
{
t_object x_obj;
float x_sr;
float x_hz;
t_lopctl x_cspace;
t_lopctl *x_ctl;
float x_f;
} t_siglop;
t_class *siglop_class;
static void siglop_ft1(t_siglop *x, t_floatarg f);
static void *siglop_new(t_floatarg f)
{
t_siglop *x = (t_siglop *)pd_new(siglop_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_sr = 44100;
x->x_ctl = &x->x_cspace;
x->x_cspace.c_x = 0;
siglop_ft1(x, f);
x->x_f = 0;
return (x);
}
static void siglop_ft1(t_siglop *x, t_floatarg f)
{
t_float coeff;
if (f < 0.001) f = 10;
x->x_hz = f;
coeff = f * (2 * 3.14159) / x->x_sr;
if (coeff > 1) coeff = 1;
x->x_ctl->c_coef = ftofix(coeff);
}
static void siglop_clear(t_siglop *x, t_floatarg q)
{
x->x_cspace.c_x = 0;
}
static t_int *siglop_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_lopctl *c = (t_lopctl *)(w[3]);
int n = (t_int)(w[4]);
int i;
t_sample last = c->c_x;
t_sample coef = c->c_coef;
t_sample feedback = ftofix(1) - coef;
for (i = 0; i < n; i++)
last = *out++ = mult(coef, *in++) + mult(feedback,last);
if (PD_BADFLOAT(last))
last = 0;
c->c_x = last;
return (w+5);
}
static void siglop_dsp(t_siglop *x, t_signal **sp)
{
x->x_sr = sp[0]->s_sr;
siglop_ft1(x, x->x_hz);
dsp_add(siglop_perform, 4,
sp[0]->s_vec, sp[1]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void lop_tilde_setup(void)
{
siglop_class = class_new(gensym("lop~"), (t_newmethod)siglop_new, 0,
sizeof(t_siglop), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(siglop_class, t_siglop, x_f);
class_addmethod(siglop_class, (t_method)siglop_dsp, gensym("dsp"), 0);
class_addmethod(siglop_class, (t_method)siglop_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(siglop_class, (t_method)siglop_clear, gensym("clear"), 0);
}

View file

@ -0,0 +1,48 @@
SOURCE = $(shell ls *.c)
TARGETS = $(SOURCE:.c=.pd_linux)
EXT= pd_linux
CFLAGS += -O2 -I../src -DFIXEDPOINT
EFLAGS = -shared -Wl,-export-dynamic
all: $(TARGETS)
clean:
-rm $(TARGETS)
-rm *.o *~
install:
install -d $(DESTDIR)/$(PREFIX)/lib/pd/extra
cp $(TARGETS) $(DESTDIR)/$(PREFIX)/lib/pd/extra
%.$(EXT) : %.o
$(CC) -o $@ $(EFLAGS) $+
SOURCE = $(shell ls *.c)
TARGETS = $(SOURCE:.c=.pd_linux)
EXT= pd_linux
CFLAGS += -O2 -I../src -DFIXEDPOINT
EFLAGS = -shared -Wl,-export-dynamic
all: $(TARGETS)
clean:
-rm $(TARGETS)
-rm *.o *~
install:
install -d $(DESTDIR)/$(PREFIX)/lib/pd/extra
cp $(TARGETS) $(DESTDIR)/$(PREFIX)/lib/pd/extra
%.$(EXT) : %.o
$(CC) -o $@ $(EFLAGS) $+

View file

@ -0,0 +1,98 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct mtof_tilde
{
t_object x_obj;
float x_f;
} t_mtof_tilde;
t_class *mtof_tilde_class;
static void *mtof_tilde_new(void)
{
t_mtof_tilde *x = (t_mtof_tilde *)pd_new(mtof_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *mtof_tilde_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
t_sample f = *in;
if (f <= ftofix(-1500.)) *out = 0;
else
{
if (f > ftofix(1499.)) f = ftofix(1499.);
*out = ftofix(8.17579891564 * exp(.0577622650 * fixtof(f)));
}
}
return (w + 4);
}
static void mtof_tilde_dsp(t_mtof_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(mtof_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void mtof_tilde_setup(void)
{
mtof_tilde_class = class_new(gensym("mtof~"), (t_newmethod)mtof_tilde_new, 0,
sizeof(t_mtof_tilde), 0, 0);
CLASS_MAINSIGNALIN(mtof_tilde_class, t_mtof_tilde, x_f);
class_addmethod(mtof_tilde_class, (t_method)mtof_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct mtof_tilde
{
t_object x_obj;
float x_f;
} t_mtof_tilde;
t_class *mtof_tilde_class;
static void *mtof_tilde_new(void)
{
t_mtof_tilde *x = (t_mtof_tilde *)pd_new(mtof_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *mtof_tilde_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
t_sample f = *in;
if (f <= ftofix(-1500.)) *out = 0;
else
{
if (f > ftofix(1499.)) f = ftofix(1499.);
*out = ftofix(8.17579891564 * exp(.0577622650 * fixtof(f)));
}
}
return (w + 4);
}
static void mtof_tilde_dsp(t_mtof_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(mtof_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void mtof_tilde_setup(void)
{
mtof_tilde_class = class_new(gensym("mtof~"), (t_newmethod)mtof_tilde_new, 0,
sizeof(t_mtof_tilde), 0, 0);
CLASS_MAINSIGNALIN(mtof_tilde_class, t_mtof_tilde, x_f);
class_addmethod(mtof_tilde_class, (t_method)mtof_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,110 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *noise_class;
typedef struct _noise
{
t_object x_obj;
int x_val;
} t_noise;
static void *noise_new(void)
{
t_noise *x = (t_noise *)pd_new(noise_class);
static int init = 307;
x->x_val = (init *= 1319);
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
static t_int *noise_perform(t_int *w)
{
t_sample *out = (t_sample *)(w[1]);
int *vp = (int *)(w[2]);
int n = (int)(w[3]);
int val = *vp;
while (n--)
{
#ifndef FIXEDPOINT
*out++ = ((t_sample)((val & 0x7fffffff) - 0x40000000)) *
(t_sample)(1.0 / 0x40000000);
#else
*out++=val>>(32-fix1);
#endif
val = val * 435898247 + 382842987;
}
*vp = val;
return (w+4);
}
static void noise_dsp(t_noise *x, t_signal **sp)
{
dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
}
void noise_tilde_setup(void)
{
noise_class = class_new(gensym("noise~"), (t_newmethod)noise_new, 0,
sizeof(t_noise), 0, 0);
class_addmethod(noise_class, (t_method)noise_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *noise_class;
typedef struct _noise
{
t_object x_obj;
int x_val;
} t_noise;
static void *noise_new(void)
{
t_noise *x = (t_noise *)pd_new(noise_class);
static int init = 307;
x->x_val = (init *= 1319);
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
static t_int *noise_perform(t_int *w)
{
t_sample *out = (t_sample *)(w[1]);
int *vp = (int *)(w[2]);
int n = (int)(w[3]);
int val = *vp;
while (n--)
{
#ifndef FIXEDPOINT
*out++ = ((t_sample)((val & 0x7fffffff) - 0x40000000)) *
(t_sample)(1.0 / 0x40000000);
#else
*out++=val>>(32-fix1);
#endif
val = val * 435898247 + 382842987;
}
*vp = val;
return (w+4);
}
static void noise_dsp(t_noise *x, t_signal **sp)
{
dsp_add(noise_perform, 3, sp[0]->s_vec, &x->x_val, sp[0]->s_n);
}
void noise_tilde_setup(void)
{
noise_class = class_new(gensym("noise~"), (t_newmethod)noise_new, 0,
sizeof(t_noise), 0, 0);
class_addmethod(noise_class, (t_method)noise_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,174 @@
#include <m_pd.h>
#include <m_fixed.h>
#include "cos_table.h"
/* ------------------------ osc~ ----------------------------- */
static t_class *osc_class, *scalarosc_class;
typedef struct _osc
{
t_object x_obj;
unsigned int x_phase;
t_sample x_conv;
t_sample x_f; /* frequency if scalar */
} t_osc;
static void *osc_new(t_floatarg f)
{
t_osc *x = (t_osc *)pd_new(osc_class);
x->x_f = ftofix(f);
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_phase = 0;
x->x_conv = 0;
return (x);
}
static t_int *osc_perform(t_int *w)
{
t_osc *x = (t_osc *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
t_sample *tab = cos_table;
unsigned int phase = x->x_phase;
int conv = x->x_conv;
int off;
int frac;
while (n--) {
phase+= mult(conv ,(*in++));
phase &= (itofix(1) -1);
off = fixtoi((long long)phase<<ILOGCOSTABSIZE);
#ifdef NO_INTERPOLATION
*out = *(tab+off);
#else
// frac = phase & (itofix(1)-1);
frac = phase & ((1<<ILOGCOSTABSIZE)-1);
frac <<= (fix1-ILOGCOSTABSIZE);
*out = mult(*(tab + off),(itofix(1) - frac)) +
mult(*(tab + off + 1),frac);
#endif
out++;
}
x->x_phase = phase;
return (w+5);
}
static void osc_dsp(t_osc *x, t_signal **sp)
{
post("samplerate %f",sp[0]->s_sr);
x->x_conv = ftofix(1000.)/sp[0]->s_sr;
post("conf %d",x->x_conv);
x->x_conv = mult(x->x_conv + 500,ftofix(0.001));
post("conf %d",x->x_conv);
dsp_add(osc_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void osc_ft1(t_osc *x, t_float f)
{
x->x_phase = ftofix(f); /* *2 ??? */
}
void osc_tilde_setup(void)
{
osc_class = class_new(gensym("osc~"), (t_newmethod)osc_new, 0,
sizeof(t_osc), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(osc_class, t_osc, x_f);
class_addmethod(osc_class, (t_method)osc_dsp, gensym("dsp"), 0);
class_addmethod(osc_class, (t_method)osc_ft1, gensym("ft1"), A_FLOAT, 0);
}
#include <m_pd.h>
#include <m_fixed.h>
#include "cos_table.h"
/* ------------------------ osc~ ----------------------------- */
static t_class *osc_class, *scalarosc_class;
typedef struct _osc
{
t_object x_obj;
unsigned int x_phase;
t_sample x_conv;
t_sample x_f; /* frequency if scalar */
} t_osc;
static void *osc_new(t_floatarg f)
{
t_osc *x = (t_osc *)pd_new(osc_class);
x->x_f = ftofix(f);
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_phase = 0;
x->x_conv = 0;
return (x);
}
static t_int *osc_perform(t_int *w)
{
t_osc *x = (t_osc *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
t_sample *tab = cos_table;
unsigned int phase = x->x_phase;
int conv = x->x_conv;
int off;
int frac;
while (n--) {
phase+= mult(conv ,(*in++));
phase &= (itofix(1) -1);
off = fixtoi((long long)phase<<ILOGCOSTABSIZE);
#ifdef NO_INTERPOLATION
*out = *(tab+off);
#else
// frac = phase & (itofix(1)-1);
frac = phase & ((1<<ILOGCOSTABSIZE)-1);
frac <<= (fix1-ILOGCOSTABSIZE);
*out = mult(*(tab + off),(itofix(1) - frac)) +
mult(*(tab + off + 1),frac);
#endif
out++;
}
x->x_phase = phase;
return (w+5);
}
static void osc_dsp(t_osc *x, t_signal **sp)
{
post("samplerate %f",sp[0]->s_sr);
x->x_conv = ftofix(1000.)/sp[0]->s_sr;
post("conf %d",x->x_conv);
x->x_conv = mult(x->x_conv + 500,ftofix(0.001));
post("conf %d",x->x_conv);
dsp_add(osc_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void osc_ft1(t_osc *x, t_float f)
{
x->x_phase = ftofix(f); /* *2 ??? */
}
void osc_tilde_setup(void)
{
osc_class = class_new(gensym("osc~"), (t_newmethod)osc_new, 0,
sizeof(t_osc), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(osc_class, t_osc, x_f);
class_addmethod(osc_class, (t_method)osc_dsp, gensym("dsp"), 0);
class_addmethod(osc_class, (t_method)osc_ft1, gensym("ft1"), A_FLOAT, 0);
}

View file

@ -0,0 +1,138 @@
#include <m_pd.h>
#include <m_fixed.h>
/* -------------------------- phasor~ ------------------------------ */
static t_class *phasor_class;
typedef struct _phasor
{
t_object x_obj;
unsigned int x_phase;
t_sample x_conv;
t_sample x_f; /* scalar frequency */
} t_phasor;
static void *phasor_new(t_floatarg f)
{
t_phasor *x = (t_phasor *)pd_new(phasor_class);
x->x_f = ftofix(f);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_phase = 0;
x->x_conv = 0;
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
static t_int *phasor_perform(t_int *w)
{
t_phasor *x = (t_phasor *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
unsigned int phase = x->x_phase;
int conv = x->x_conv;
while (n--) {
phase+= mult(conv , (*in++));
phase &= (itofix(1) - 1);
*out++ = phase;
}
x->x_phase = phase;
return (w+5);
}
static void phasor_dsp(t_phasor *x, t_signal **sp)
{
x->x_conv = ftofix(1000.)/sp[0]->s_sr;
x->x_conv = mult(x->x_conv + 500,ftofix(0.001));
dsp_add(phasor_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void phasor_ft1(t_phasor *x, t_float f)
{
x->x_phase = ftofix(f);
}
void phasor_tilde_setup(void)
{
phasor_class = class_new(gensym("phasor~"), (t_newmethod)phasor_new, 0,
sizeof(t_phasor), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(phasor_class, t_phasor, x_f);
class_addmethod(phasor_class, (t_method)phasor_dsp, gensym("dsp"), 0);
class_addmethod(phasor_class, (t_method)phasor_ft1,
gensym("ft1"), A_FLOAT, 0);
class_sethelpsymbol(phasor_class, gensym("osc~-help.pd"));
}
#include <m_pd.h>
#include <m_fixed.h>
/* -------------------------- phasor~ ------------------------------ */
static t_class *phasor_class;
typedef struct _phasor
{
t_object x_obj;
unsigned int x_phase;
t_sample x_conv;
t_sample x_f; /* scalar frequency */
} t_phasor;
static void *phasor_new(t_floatarg f)
{
t_phasor *x = (t_phasor *)pd_new(phasor_class);
x->x_f = ftofix(f);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_phase = 0;
x->x_conv = 0;
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
static t_int *phasor_perform(t_int *w)
{
t_phasor *x = (t_phasor *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
unsigned int phase = x->x_phase;
int conv = x->x_conv;
while (n--) {
phase+= mult(conv , (*in++));
phase &= (itofix(1) - 1);
*out++ = phase;
}
x->x_phase = phase;
return (w+5);
}
static void phasor_dsp(t_phasor *x, t_signal **sp)
{
x->x_conv = ftofix(1000.)/sp[0]->s_sr;
x->x_conv = mult(x->x_conv + 500,ftofix(0.001));
dsp_add(phasor_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void phasor_ft1(t_phasor *x, t_float f)
{
x->x_phase = ftofix(f);
}
void phasor_tilde_setup(void)
{
phasor_class = class_new(gensym("phasor~"), (t_newmethod)phasor_new, 0,
sizeof(t_phasor), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(phasor_class, t_phasor, x_f);
class_addmethod(phasor_class, (t_method)phasor_dsp, gensym("dsp"), 0);
class_addmethod(phasor_class, (t_method)phasor_ft1,
gensym("ft1"), A_FLOAT, 0);
class_sethelpsymbol(phasor_class, gensym("osc~-help.pd"));
}

View file

@ -0,0 +1,106 @@
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct powtodb_tilde
{
t_object x_obj;
float x_f;
} t_powtodb_tilde;
t_class *powtodb_tilde_class;
static void *powtodb_tilde_new(void)
{
t_powtodb_tilde *x = (t_powtodb_tilde *)pd_new(powtodb_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *powtodb_tilde_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
float g = 100 + 10./LOGTEN * log(f);
*out = (g < 0 ? 0 : g);
}
}
return (w + 4);
}
static void powtodb_tilde_dsp(t_powtodb_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(powtodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void powtodb_tilde_setup(void)
{
powtodb_tilde_class = class_new(gensym("powtodb~"), (t_newmethod)powtodb_tilde_new, 0,
sizeof(t_powtodb_tilde), 0, 0);
CLASS_MAINSIGNALIN(powtodb_tilde_class, t_powtodb_tilde, x_f);
class_addmethod(powtodb_tilde_class, (t_method)powtodb_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct powtodb_tilde
{
t_object x_obj;
float x_f;
} t_powtodb_tilde;
t_class *powtodb_tilde_class;
static void *powtodb_tilde_new(void)
{
t_powtodb_tilde *x = (t_powtodb_tilde *)pd_new(powtodb_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *powtodb_tilde_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
float g = 100 + 10./LOGTEN * log(f);
*out = (g < 0 ? 0 : g);
}
}
return (w + 4);
}
static void powtodb_tilde_dsp(t_powtodb_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(powtodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void powtodb_tilde_setup(void)
{
powtodb_tilde_class = class_new(gensym("powtodb~"), (t_newmethod)powtodb_tilde_new, 0,
sizeof(t_powtodb_tilde), 0, 0);
CLASS_MAINSIGNALIN(powtodb_tilde_class, t_powtodb_tilde, x_f);
class_addmethod(powtodb_tilde_class, (t_method)powtodb_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,156 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *print_class;
typedef struct _print
{
t_object x_obj;
float x_f;
t_symbol *x_sym;
int x_count;
} t_print;
static t_int *print_perform(t_int *w)
{
t_print *x = (t_print *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
if (x->x_count)
{
post("%s:", x->x_sym->s_name);
if (n == 1) post("%8g", in[0]);
else if (n == 2) post("%8g %8g", in[0], in[1]);
else if (n == 4) post("%8g %8g %8g %8g",
in[0], in[1], in[2], in[3]);
else while (n > 0)
{
post("%-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g",
fixtof(in[0]),
fixtof(in[1]),
fixtof(in[2]),
fixtof(in[3]),
fixtof(in[4]),
fixtof(in[5]),
fixtof(in[6]),
fixtof(in[7]));
n -= 8;
in += 8;
}
x->x_count--;
}
return (w+4);
}
static void print_dsp(t_print *x, t_signal **sp)
{
dsp_add(print_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void print_float(t_print *x, t_float f)
{
if (f < 0) f = 0;
x->x_count = f;
}
static void print_bang(t_print *x)
{
x->x_count = 1;
}
static void *print_new(t_symbol *s)
{
t_print *x = (t_print *)pd_new(print_class);
x->x_sym = (s->s_name[0]? s : gensym("print~"));
x->x_count = 0;
x->x_f = 0;
return (x);
}
void print_tilde_setup(void)
{
print_class = class_new(gensym("print~"), (t_newmethod)print_new, 0,
sizeof(t_print), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(print_class, t_print, x_f);
class_addmethod(print_class, (t_method)print_dsp, gensym("dsp"), 0);
class_addbang(print_class, print_bang);
class_addfloat(print_class, print_float);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *print_class;
typedef struct _print
{
t_object x_obj;
float x_f;
t_symbol *x_sym;
int x_count;
} t_print;
static t_int *print_perform(t_int *w)
{
t_print *x = (t_print *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
if (x->x_count)
{
post("%s:", x->x_sym->s_name);
if (n == 1) post("%8g", in[0]);
else if (n == 2) post("%8g %8g", in[0], in[1]);
else if (n == 4) post("%8g %8g %8g %8g",
in[0], in[1], in[2], in[3]);
else while (n > 0)
{
post("%-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g",
fixtof(in[0]),
fixtof(in[1]),
fixtof(in[2]),
fixtof(in[3]),
fixtof(in[4]),
fixtof(in[5]),
fixtof(in[6]),
fixtof(in[7]));
n -= 8;
in += 8;
}
x->x_count--;
}
return (w+4);
}
static void print_dsp(t_print *x, t_signal **sp)
{
dsp_add(print_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void print_float(t_print *x, t_float f)
{
if (f < 0) f = 0;
x->x_count = f;
}
static void print_bang(t_print *x)
{
x->x_count = 1;
}
static void *print_new(t_symbol *s)
{
t_print *x = (t_print *)pd_new(print_class);
x->x_sym = (s->s_name[0]? s : gensym("print~"));
x->x_count = 0;
x->x_f = 0;
return (x);
}
void print_tilde_setup(void)
{
print_class = class_new(gensym("print~"), (t_newmethod)print_new, 0,
sizeof(t_print), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(print_class, t_print, x_f);
class_addmethod(print_class, (t_method)print_dsp, gensym("dsp"), 0);
class_addbang(print_class, print_bang);
class_addfloat(print_class, print_float);
}

View file

@ -0,0 +1,104 @@
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct rmstodb_tilde
{
t_object x_obj;
float x_f;
} t_rmstodb_tilde;
t_class *rmstodb_tilde_class;
static void *rmstodb_tilde_new(void)
{
t_rmstodb_tilde *x = (t_rmstodb_tilde *)pd_new(rmstodb_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *rmstodb_tilde_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
float g = 100 + 20./LOGTEN * log(f);
*out = (g < 0 ? 0 : g);
}
}
return (w + 4);
}
static void rmstodb_tilde_dsp(t_rmstodb_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(rmstodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void rmstodb_tilde_setup(void)
{
rmstodb_tilde_class = class_new(gensym("rmstodb~"), (t_newmethod)rmstodb_tilde_new, 0,
sizeof(t_rmstodb_tilde), 0, 0);
CLASS_MAINSIGNALIN(rmstodb_tilde_class, t_rmstodb_tilde, x_f);
class_addmethod(rmstodb_tilde_class, (t_method)rmstodb_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
#define LOGTEN 2.302585092994
typedef struct rmstodb_tilde
{
t_object x_obj;
float x_f;
} t_rmstodb_tilde;
t_class *rmstodb_tilde_class;
static void *rmstodb_tilde_new(void)
{
t_rmstodb_tilde *x = (t_rmstodb_tilde *)pd_new(rmstodb_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *rmstodb_tilde_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
for (; n--; in++, out++)
{
float f = *in;
if (f <= 0) *out = 0;
else
{
float g = 100 + 20./LOGTEN * log(f);
*out = (g < 0 ? 0 : g);
}
}
return (w + 4);
}
static void rmstodb_tilde_dsp(t_rmstodb_tilde *x, t_signal **sp)
{
post("warning: %s not usable yet",__FUNCTION__);
dsp_add(rmstodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void rmstodb_tilde_setup(void)
{
rmstodb_tilde_class = class_new(gensym("rmstodb~"), (t_newmethod)rmstodb_tilde_new, 0,
sizeof(t_rmstodb_tilde), 0, 0);
CLASS_MAINSIGNALIN(rmstodb_tilde_class, t_rmstodb_tilde, x_f);
class_addmethod(rmstodb_tilde_class, (t_method)rmstodb_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,210 @@
#include <m_pd.h>
#include <m_fixed.h>
/* sigrsqrt - reciprocal square root good to 8 mantissa bits */
#define DUMTAB1SIZE 256
#define DUMTAB2SIZE 1024
static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE];
static void init_rsqrt(void)
{
int i;
for (i = 0; i < DUMTAB1SIZE; i++)
{
float f;
long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23;
*(long *)(&f) = l;
rsqrt_exptab[i] = 1./sqrt(f);
}
for (i = 0; i < DUMTAB2SIZE; i++)
{
float f = 1 + (1./DUMTAB2SIZE) * i;
rsqrt_mantissatab[i] = 1./sqrt(f);
}
}
/* these are used in externs like "bonk" */
float q8_rsqrt(float f)
{
long l = *(long *)(&f);
if (f < 0) return (0);
else return (rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff]);
}
float q8_sqrt(float f)
{
long l = *(long *)(&f);
if (f < 0) return (0);
else return (f * rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff]);
}
/* the old names are OK unless we're in IRIX N32 */
#ifndef N32
float qsqrt(float f) {return (q8_sqrt(f)); }
float qrsqrt(float f) {return (q8_rsqrt(f)); }
#endif
typedef struct sigrsqrt
{
t_object x_obj;
float x_f;
} t_sigrsqrt;
static t_class *sigrsqrt_class;
static void *sigrsqrt_new(void)
{
t_sigrsqrt *x = (t_sigrsqrt *)pd_new(sigrsqrt_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigrsqrt_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
while (n--)
{
float f = *in;
long l = *(long *)(in++);
if (f < 0) *out++ = 0;
else
{
float g = rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff];
*out++ = 1.5 * g - 0.5 * g * g * g * f;
}
}
return (w + 4);
}
static void sigrsqrt_dsp(t_sigrsqrt *x, t_signal **sp)
{
dsp_add(sigrsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void rsqrt_tilde_setup(void)
{
init_rsqrt();
sigrsqrt_class = class_new(gensym("rsqrt~"), (t_newmethod)sigrsqrt_new, 0,
sizeof(t_sigrsqrt), 0, 0);
/* an old name for it: */
class_addcreator(sigrsqrt_new, gensym("q8_rsqrt~"), 0);
CLASS_MAINSIGNALIN(sigrsqrt_class, t_sigrsqrt, x_f);
class_addmethod(sigrsqrt_class, (t_method)sigrsqrt_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
/* sigrsqrt - reciprocal square root good to 8 mantissa bits */
#define DUMTAB1SIZE 256
#define DUMTAB2SIZE 1024
static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE];
static void init_rsqrt(void)
{
int i;
for (i = 0; i < DUMTAB1SIZE; i++)
{
float f;
long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23;
*(long *)(&f) = l;
rsqrt_exptab[i] = 1./sqrt(f);
}
for (i = 0; i < DUMTAB2SIZE; i++)
{
float f = 1 + (1./DUMTAB2SIZE) * i;
rsqrt_mantissatab[i] = 1./sqrt(f);
}
}
/* these are used in externs like "bonk" */
float q8_rsqrt(float f)
{
long l = *(long *)(&f);
if (f < 0) return (0);
else return (rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff]);
}
float q8_sqrt(float f)
{
long l = *(long *)(&f);
if (f < 0) return (0);
else return (f * rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff]);
}
/* the old names are OK unless we're in IRIX N32 */
#ifndef N32
float qsqrt(float f) {return (q8_sqrt(f)); }
float qrsqrt(float f) {return (q8_rsqrt(f)); }
#endif
typedef struct sigrsqrt
{
t_object x_obj;
float x_f;
} t_sigrsqrt;
static t_class *sigrsqrt_class;
static void *sigrsqrt_new(void)
{
t_sigrsqrt *x = (t_sigrsqrt *)pd_new(sigrsqrt_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigrsqrt_perform(t_int *w)
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
while (n--)
{
float f = *in;
long l = *(long *)(in++);
if (f < 0) *out++ = 0;
else
{
float g = rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff];
*out++ = 1.5 * g - 0.5 * g * g * g * f;
}
}
return (w + 4);
}
static void sigrsqrt_dsp(t_sigrsqrt *x, t_signal **sp)
{
dsp_add(sigrsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void rsqrt_tilde_setup(void)
{
init_rsqrt();
sigrsqrt_class = class_new(gensym("rsqrt~"), (t_newmethod)sigrsqrt_new, 0,
sizeof(t_sigrsqrt), 0, 0);
/* an old name for it: */
class_addcreator(sigrsqrt_new, gensym("q8_rsqrt~"), 0);
CLASS_MAINSIGNALIN(sigrsqrt_class, t_sigrsqrt, x_f);
class_addmethod(sigrsqrt_class, (t_method)sigrsqrt_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,150 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct sigsamphold
{
t_object x_obj;
t_sample x_f;
t_sample x_lastin;
t_sample x_lastout;
} t_sigsamphold;
t_class *sigsamphold_class;
static void *sigsamphold_new(void)
{
t_sigsamphold *x = (t_sigsamphold *)pd_new(sigsamphold_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
outlet_new(&x->x_obj, gensym("signal"));
x->x_lastin = 0;
x->x_lastout = 0;
x->x_f = 0;
return (x);
}
static t_int *sigsamphold_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
t_sigsamphold *x = (t_sigsamphold *)(w[4]);
int n = (t_int)(w[5]);
int i;
t_sample lastin = x->x_lastin;
t_sample lastout = x->x_lastout;
for (i = 0; i < n; i++, *in1++)
{
t_sample next = *in2++;
if (next < lastin) lastout = *in1;
*out++ = lastout;
lastin = next;
}
x->x_lastin = lastin;
x->x_lastout = lastout;
return (w+6);
}
static void sigsamphold_dsp(t_sigsamphold *x, t_signal **sp)
{
dsp_add(sigsamphold_perform, 5,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
x, sp[0]->s_n);
}
static void sigsamphold_reset(t_sigsamphold *x)
{
x->x_lastin = 0x7fffffff;
}
static void sigsamphold_set(t_sigsamphold *x, t_float f)
{
x->x_lastout = f;
}
void samphold_tilde_setup(void)
{
sigsamphold_class = class_new(gensym("samphold~"),
(t_newmethod)sigsamphold_new, 0, sizeof(t_sigsamphold), 0, 0);
CLASS_MAINSIGNALIN(sigsamphold_class, t_sigsamphold, x_f);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_set,
gensym("set"), A_FLOAT, 0);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_reset,
gensym("reset"), 0);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_dsp,
gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct sigsamphold
{
t_object x_obj;
t_sample x_f;
t_sample x_lastin;
t_sample x_lastout;
} t_sigsamphold;
t_class *sigsamphold_class;
static void *sigsamphold_new(void)
{
t_sigsamphold *x = (t_sigsamphold *)pd_new(sigsamphold_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
outlet_new(&x->x_obj, gensym("signal"));
x->x_lastin = 0;
x->x_lastout = 0;
x->x_f = 0;
return (x);
}
static t_int *sigsamphold_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
t_sigsamphold *x = (t_sigsamphold *)(w[4]);
int n = (t_int)(w[5]);
int i;
t_sample lastin = x->x_lastin;
t_sample lastout = x->x_lastout;
for (i = 0; i < n; i++, *in1++)
{
t_sample next = *in2++;
if (next < lastin) lastout = *in1;
*out++ = lastout;
lastin = next;
}
x->x_lastin = lastin;
x->x_lastout = lastout;
return (w+6);
}
static void sigsamphold_dsp(t_sigsamphold *x, t_signal **sp)
{
dsp_add(sigsamphold_perform, 5,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec,
x, sp[0]->s_n);
}
static void sigsamphold_reset(t_sigsamphold *x)
{
x->x_lastin = 0x7fffffff;
}
static void sigsamphold_set(t_sigsamphold *x, t_float f)
{
x->x_lastout = f;
}
void samphold_tilde_setup(void)
{
sigsamphold_class = class_new(gensym("samphold~"),
(t_newmethod)sigsamphold_new, 0, sizeof(t_sigsamphold), 0, 0);
CLASS_MAINSIGNALIN(sigsamphold_class, t_sigsamphold, x_f);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_set,
gensym("set"), A_FLOAT, 0);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_reset,
gensym("reset"), 0);
class_addmethod(sigsamphold_class, (t_method)sigsamphold_dsp,
gensym("dsp"), 0);
}

View file

@ -0,0 +1,110 @@
#ifndef SFORMAT_H__
#define SFORMAT_H__
typedef unsigned short uint16;
typedef unsigned long uint32;
#define FORMAT_WAVE 0
#define FORMAT_AIFF 1
#define FORMAT_NEXT 2
/* the NeXTStep sound header structure; can be big or little endian */
typedef struct _nextstep
{
char ns_fileid[4]; /* magic number '.snd' if file is big-endian */
uint32 ns_onset; /* byte offset of first sample */
uint32 ns_length; /* length of sound in bytes */
uint32 ns_format; /* format; see below */
uint32 ns_sr; /* sample rate */
uint32 ns_nchans; /* number of channels */
char ns_info[4]; /* comment */
} t_nextstep;
#define NS_FORMAT_LINEAR_16 3
#define NS_FORMAT_LINEAR_24 4
#define NS_FORMAT_FLOAT 6
#define SCALE (1./(1024. * 1024. * 1024. * 2.))
/* the WAVE header. All Wave files are little endian. We assume
the "fmt" chunk comes first which is usually the case but perhaps not
always; same for AIFF and the "COMM" chunk. */
typedef unsigned word;
typedef unsigned long dword;
typedef struct _wave
{
char w_fileid[4]; /* chunk id 'RIFF' */
uint32 w_chunksize; /* chunk size */
char w_waveid[4]; /* wave chunk id 'WAVE' */
char w_fmtid[4]; /* format chunk id 'fmt ' */
uint32 w_fmtchunksize; /* format chunk size */
uint16 w_fmttag; /* format tag, 1 for PCM */
uint16 w_nchannels; /* number of channels */
uint32 w_samplespersec; /* sample rate in hz */
uint32 w_navgbytespersec; /* average bytes per second */
uint16 w_nblockalign; /* number of bytes per sample */
uint16 w_nbitspersample; /* number of bits in a sample */
char w_datachunkid[4]; /* data chunk id 'data' */
uint32 w_datachunksize; /* length of data chunk */
} t_wave;
#endif
#ifndef SFORMAT_H__
#define SFORMAT_H__
typedef unsigned short uint16;
typedef unsigned long uint32;
#define FORMAT_WAVE 0
#define FORMAT_AIFF 1
#define FORMAT_NEXT 2
/* the NeXTStep sound header structure; can be big or little endian */
typedef struct _nextstep
{
char ns_fileid[4]; /* magic number '.snd' if file is big-endian */
uint32 ns_onset; /* byte offset of first sample */
uint32 ns_length; /* length of sound in bytes */
uint32 ns_format; /* format; see below */
uint32 ns_sr; /* sample rate */
uint32 ns_nchans; /* number of channels */
char ns_info[4]; /* comment */
} t_nextstep;
#define NS_FORMAT_LINEAR_16 3
#define NS_FORMAT_LINEAR_24 4
#define NS_FORMAT_FLOAT 6
#define SCALE (1./(1024. * 1024. * 1024. * 2.))
/* the WAVE header. All Wave files are little endian. We assume
the "fmt" chunk comes first which is usually the case but perhaps not
always; same for AIFF and the "COMM" chunk. */
typedef unsigned word;
typedef unsigned long dword;
typedef struct _wave
{
char w_fileid[4]; /* chunk id 'RIFF' */
uint32 w_chunksize; /* chunk size */
char w_waveid[4]; /* wave chunk id 'WAVE' */
char w_fmtid[4]; /* format chunk id 'fmt ' */
uint32 w_fmtchunksize; /* format chunk size */
uint16 w_fmttag; /* format tag, 1 for PCM */
uint16 w_nchannels; /* number of channels */
uint32 w_samplespersec; /* sample rate in hz */
uint32 w_navgbytespersec; /* average bytes per second */
uint16 w_nblockalign; /* number of bytes per sample */
uint16 w_nbitspersample; /* number of bits in a sample */
char w_datachunkid[4]; /* data chunk id 'data' */
uint32 w_datachunksize; /* length of data chunk */
} t_wave;
#endif

View file

@ -0,0 +1,576 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <m_pd.h>
#include <m_fixed.h>
#include "g_canvas.h"
/* ------------------------ sfread~ ----------------------------- */
#include "sformat.h"
static t_class *sfread_class;
typedef struct _sfread
{
t_object x_obj;
void* x_mapaddr;
int x_fd;
int x_play;
int x_channels;
long long x_size;
int x_loop;
t_time x_pos;
t_sample x_skip;
t_sample x_speed;
t_glist * x_glist;
t_outlet *x_bangout;
} t_sfread;
void sfread_open(t_sfread *x,t_symbol *filename)
{
struct stat fstate;
char fname[MAXPDSTRING];
if (filename == &s_) {
post("sfread: open without filename");
return;
}
canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
fname, MAXPDSTRING);
/* close the old file */
if (x->x_mapaddr) munmap(x->x_mapaddr,x->x_size);
if (x->x_fd >= 0) close(x->x_fd);
if ((x->x_fd = open(fname,O_RDONLY)) < 0)
{
error("can't open %s",fname);
x->x_play = 0;
x->x_mapaddr = NULL;
return;
}
/* get the size */
fstat(x->x_fd,&fstate);
x->x_size = fstate.st_size;
/* map the file into memory */
if (!(x->x_mapaddr = mmap(NULL,x->x_size,PROT_READ,MAP_PRIVATE,x->x_fd,0)))
{
error("can't mmap %s",fname);
return;
}
}
#define MAX_CHANS 4
static t_int *sfread_perform(t_int *w)
{
t_sfread* x = (t_sfread*)(w[1]);
short* buf = x->x_mapaddr;
t_time tmp;
int c = x->x_channels;
t_time pos = x->x_pos;
t_sample speed = x->x_speed;
t_time end = itofix(x->x_size/sizeof(short)/c);
int i,n;
t_sample* out[MAX_CHANS];
for (i=0;i<c;i++)
out[i] = (t_sample *)(w[3+i]);
n = (int)(w[3+c]);
/* loop */
if (pos > end)
pos = end;
if (pos + n*speed >= end) { // playing forward end
if (!x->x_loop) {
x->x_play=0;
}
pos = x->x_skip;
}
tmp = n*speed;
if (pos + n*speed <= 0) { // playing backwards end
if (!x->x_loop) {
x->x_play=0;
}
pos = end;
}
if (x->x_play && x->x_mapaddr) {
t_time aoff = fixtoi(pos)*c;
while (n--) {
long frac = (long long)((1<<fix1)-1)&pos;
for (i=0;i<c;i++) {
t_sample bs = *(buf+aoff+i)<<(fix1-16);
t_sample cs = *(buf+aoff+i+1)<<(fix1-16);
*out[i]++ = bs + mult((cs - bs),frac);
}
pos += speed;
aoff = fixtoi(pos)*c;
if (aoff > end) {
if (x->x_loop) pos = x->x_skip;
else break;
}
if (aoff < x->x_skip) {
if (x->x_loop) pos = end;
else break;
}
}
/* Fill with zero in case of end */
n++;
while (n--)
for (i=0;i<c;i++)
*out[i]++ = 0;
}
else {
while (n--) {
for (i=0;i<c;i++)
*out[i]++ = 0.;
}
}
x->x_pos = pos;
return (w+c+4);
}
static void sfread_float(t_sfread *x, t_floatarg f)
{
int t = f;
if (t && x->x_mapaddr) {
x->x_play=1;
}
else {
x->x_play=0;
}
}
static void sfread_loop(t_sfread *x, t_floatarg f)
{
x->x_loop = f;
}
static void sfread_size(t_sfread* x)
{
t_atom a;
SETFLOAT(&a,x->x_size*0.5/x->x_channels);
outlet_list(x->x_bangout, gensym("size"),1,&a);
}
static void sfread_state(t_sfread* x)
{
t_atom a;
SETFLOAT(&a,x->x_play);
outlet_list(x->x_bangout, gensym("state"),1,&a);
}
static void sfread_bang(t_sfread* x)
{
x->x_pos = x->x_skip;
sfread_float(x,1.0);
}
static void sfread_dsp(t_sfread *x, t_signal **sp)
{
/* post("sfread: dsp"); */
switch (x->x_channels) {
case 1:
dsp_add(sfread_perform, 4, x, sp[0]->s_vec,
sp[1]->s_vec, sp[0]->s_n);
break;
case 2:
dsp_add(sfread_perform, 5, x, sp[0]->s_vec,
sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n);
break;
case 4:
dsp_add(sfread_perform, 6, x, sp[0]->s_vec,
sp[1]->s_vec,sp[2]->s_vec,
sp[3]->s_vec,sp[4]->s_vec,
sp[0]->s_n);
break;
}
}
static void sfread_speed(t_sfread* x, t_floatarg f)
{
x->x_speed = ftofix(f);
}
static void sfread_offset(t_sfread* x, t_floatarg f)
{
x->x_pos = (int)f;
}
static void *sfread_new(t_floatarg chan,t_floatarg skip)
{
t_sfread *x = (t_sfread *)pd_new(sfread_class);
t_int c = chan;
x->x_glist = (t_glist*) canvas_getcurrent();
if (c<1 || c > MAX_CHANS) c = 1;
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
x->x_fd = -1;
x->x_mapaddr = NULL;
x->x_size = 0;
x->x_loop = 0;
x->x_channels = c;
x->x_mapaddr=NULL;
x->x_pos = 0;
x->x_skip = 0;
x->x_speed = ftofix(1.0);
x->x_play = 0;
while (c--) {
outlet_new(&x->x_obj, gensym("signal"));
}
x->x_bangout = outlet_new(&x->x_obj, &s_float);
return (x);
}
void sfread_tilde_setup(void)
{
/* sfread */
sfread_class = class_new(gensym("sfread~"), (t_newmethod)sfread_new, 0,
sizeof(t_sfread), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addmethod(sfread_class, nullfn, gensym("signal"), 0);
class_addmethod(sfread_class, (t_method) sfread_dsp, gensym("dsp"), 0);
class_addmethod(sfread_class, (t_method) sfread_open, gensym("open"), A_SYMBOL,A_NULL);
class_addmethod(sfread_class, (t_method) sfread_size, gensym("size"), 0);
class_addmethod(sfread_class, (t_method) sfread_offset, gensym("ft1"), A_FLOAT, A_NULL);
class_addmethod(sfread_class, (t_method) sfread_speed, gensym("ft2"), A_FLOAT, A_NULL);
class_addmethod(sfread_class, (t_method) sfread_state, gensym("state"), 0);
class_addfloat(sfread_class, sfread_float);
class_addbang(sfread_class,sfread_bang);
class_addmethod(sfread_class,(t_method)sfread_loop,gensym("loop"),A_FLOAT,A_NULL);
}
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <m_pd.h>
#include <m_fixed.h>
#include "g_canvas.h"
/* ------------------------ sfread~ ----------------------------- */
#include "sformat.h"
static t_class *sfread_class;
typedef struct _sfread
{
t_object x_obj;
void* x_mapaddr;
int x_fd;
int x_play;
int x_channels;
long long x_size;
int x_loop;
t_time x_pos;
t_sample x_skip;
t_sample x_speed;
t_glist * x_glist;
t_outlet *x_bangout;
} t_sfread;
void sfread_open(t_sfread *x,t_symbol *filename)
{
struct stat fstate;
char fname[MAXPDSTRING];
if (filename == &s_) {
post("sfread: open without filename");
return;
}
canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
fname, MAXPDSTRING);
/* close the old file */
if (x->x_mapaddr) munmap(x->x_mapaddr,x->x_size);
if (x->x_fd >= 0) close(x->x_fd);
if ((x->x_fd = open(fname,O_RDONLY)) < 0)
{
error("can't open %s",fname);
x->x_play = 0;
x->x_mapaddr = NULL;
return;
}
/* get the size */
fstat(x->x_fd,&fstate);
x->x_size = fstate.st_size;
/* map the file into memory */
if (!(x->x_mapaddr = mmap(NULL,x->x_size,PROT_READ,MAP_PRIVATE,x->x_fd,0)))
{
error("can't mmap %s",fname);
return;
}
}
#define MAX_CHANS 4
static t_int *sfread_perform(t_int *w)
{
t_sfread* x = (t_sfread*)(w[1]);
short* buf = x->x_mapaddr;
t_time tmp;
int c = x->x_channels;
t_time pos = x->x_pos;
t_sample speed = x->x_speed;
t_time end = itofix(x->x_size/sizeof(short)/c);
int i,n;
t_sample* out[MAX_CHANS];
for (i=0;i<c;i++)
out[i] = (t_sample *)(w[3+i]);
n = (int)(w[3+c]);
/* loop */
if (pos > end)
pos = end;
if (pos + n*speed >= end) { // playing forward end
if (!x->x_loop) {
x->x_play=0;
}
pos = x->x_skip;
}
tmp = n*speed;
if (pos + n*speed <= 0) { // playing backwards end
if (!x->x_loop) {
x->x_play=0;
}
pos = end;
}
if (x->x_play && x->x_mapaddr) {
t_time aoff = fixtoi(pos)*c;
while (n--) {
long frac = (long long)((1<<fix1)-1)&pos;
for (i=0;i<c;i++) {
t_sample bs = *(buf+aoff+i)<<(fix1-16);
t_sample cs = *(buf+aoff+i+1)<<(fix1-16);
*out[i]++ = bs + mult((cs - bs),frac);
}
pos += speed;
aoff = fixtoi(pos)*c;
if (aoff > end) {
if (x->x_loop) pos = x->x_skip;
else break;
}
if (aoff < x->x_skip) {
if (x->x_loop) pos = end;
else break;
}
}
/* Fill with zero in case of end */
n++;
while (n--)
for (i=0;i<c;i++)
*out[i]++ = 0;
}
else {
while (n--) {
for (i=0;i<c;i++)
*out[i]++ = 0.;
}
}
x->x_pos = pos;
return (w+c+4);
}
static void sfread_float(t_sfread *x, t_floatarg f)
{
int t = f;
if (t && x->x_mapaddr) {
x->x_play=1;
}
else {
x->x_play=0;
}
}
static void sfread_loop(t_sfread *x, t_floatarg f)
{
x->x_loop = f;
}
static void sfread_size(t_sfread* x)
{
t_atom a;
SETFLOAT(&a,x->x_size*0.5/x->x_channels);
outlet_list(x->x_bangout, gensym("size"),1,&a);
}
static void sfread_state(t_sfread* x)
{
t_atom a;
SETFLOAT(&a,x->x_play);
outlet_list(x->x_bangout, gensym("state"),1,&a);
}
static void sfread_bang(t_sfread* x)
{
x->x_pos = x->x_skip;
sfread_float(x,1.0);
}
static void sfread_dsp(t_sfread *x, t_signal **sp)
{
/* post("sfread: dsp"); */
switch (x->x_channels) {
case 1:
dsp_add(sfread_perform, 4, x, sp[0]->s_vec,
sp[1]->s_vec, sp[0]->s_n);
break;
case 2:
dsp_add(sfread_perform, 5, x, sp[0]->s_vec,
sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n);
break;
case 4:
dsp_add(sfread_perform, 6, x, sp[0]->s_vec,
sp[1]->s_vec,sp[2]->s_vec,
sp[3]->s_vec,sp[4]->s_vec,
sp[0]->s_n);
break;
}
}
static void sfread_speed(t_sfread* x, t_floatarg f)
{
x->x_speed = ftofix(f);
}
static void sfread_offset(t_sfread* x, t_floatarg f)
{
x->x_pos = (int)f;
}
static void *sfread_new(t_floatarg chan,t_floatarg skip)
{
t_sfread *x = (t_sfread *)pd_new(sfread_class);
t_int c = chan;
x->x_glist = (t_glist*) canvas_getcurrent();
if (c<1 || c > MAX_CHANS) c = 1;
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
x->x_fd = -1;
x->x_mapaddr = NULL;
x->x_size = 0;
x->x_loop = 0;
x->x_channels = c;
x->x_mapaddr=NULL;
x->x_pos = 0;
x->x_skip = 0;
x->x_speed = ftofix(1.0);
x->x_play = 0;
while (c--) {
outlet_new(&x->x_obj, gensym("signal"));
}
x->x_bangout = outlet_new(&x->x_obj, &s_float);
return (x);
}
void sfread_tilde_setup(void)
{
/* sfread */
sfread_class = class_new(gensym("sfread~"), (t_newmethod)sfread_new, 0,
sizeof(t_sfread), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addmethod(sfread_class, nullfn, gensym("signal"), 0);
class_addmethod(sfread_class, (t_method) sfread_dsp, gensym("dsp"), 0);
class_addmethod(sfread_class, (t_method) sfread_open, gensym("open"), A_SYMBOL,A_NULL);
class_addmethod(sfread_class, (t_method) sfread_size, gensym("size"), 0);
class_addmethod(sfread_class, (t_method) sfread_offset, gensym("ft1"), A_FLOAT, A_NULL);
class_addmethod(sfread_class, (t_method) sfread_speed, gensym("ft2"), A_FLOAT, A_NULL);
class_addmethod(sfread_class, (t_method) sfread_state, gensym("state"), 0);
class_addfloat(sfread_class, sfread_float);
class_addbang(sfread_class,sfread_bang);
class_addmethod(sfread_class,(t_method)sfread_loop,gensym("loop"),A_FLOAT,A_NULL);
}

View file

@ -0,0 +1,480 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <m_pd.h>
#include <m_fixed.h>
#include "g_canvas.h"
#define BLOCKTIME 10
#define MAX_CHANS 4
#include "sformat.h"
static t_class *sfwrite_class;
typedef struct _sfwrite
{
t_object x_obj;
t_symbol* filename;
int x_file;
t_int rec;
t_int x_channels;
uint32 size;
t_glist * x_glist;
t_int x_blocked;
t_int x_blockwarn;
} t_sfwrite;
static void sfwrite_wave_setup(t_sfwrite* x,t_wave* w)
{
strncpy(w->w_fileid,"RIFF",4); /* chunk id 'RIFF' */
w->w_chunksize = x->size + sizeof(t_wave) -8; /* chunk size */
strncpy(w->w_waveid,"WAVE",4); /* wave chunk id 'WAVE' */
strncpy(w->w_fmtid,"fmt ",4); /* format chunk id 'fmt '*/
w->w_fmtchunksize = 16; /* format chunk size */
w->w_fmttag = 1; /* format tag, 1 for PCM */
w->w_nchannels = x->x_channels; /* number of channels */
w->w_samplespersec = 44100; /* sample rate in hz */
w->w_navgbytespersec = 44100*x->x_channels*2; /* average bytes per second */
w->w_nblockalign = 4; /* number of bytes per sample */
w->w_nbitspersample = 16; /* number of bits in a sample */
strncpy(w->w_datachunkid,"data",4); /* data chunk id 'data'*/
w->w_datachunksize = x->size; /* length of data chunk */
}
static void sfwrite_close(t_sfwrite *x)
{
if (x->x_file > 0) {
t_wave w;
sfwrite_wave_setup(x,&w);
lseek(x->x_file,0,SEEK_SET);
write(x->x_file,&w,sizeof(w));
close(x->x_file);
}
x->x_file = -1;
}
static void sfwrite_open(t_sfwrite *x,t_symbol *filename)
{
char fname[MAXPDSTRING];
if (filename == &s_) {
post("sfwrite: open without filename");
return;
}
canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
fname, MAXPDSTRING);
x->x_blocked = 0;
x->filename = filename;
post("sfwrite: filename = %s",x->filename->s_name);
sfwrite_close(x);
if ((x->x_file = open(fname,O_RDWR | O_CREAT,0664)) < 0)
{
error("can't create %s",fname);
return;
}
/* skip the header */
lseek(x->x_file,sizeof(t_wave),SEEK_SET);
x->size = 0;
}
static void sfwrite_block(t_sfwrite *x, t_floatarg f)
{
x->x_blockwarn = f;
}
static void sfwrite_float(t_sfwrite *x, t_floatarg f)
{
int t = f;
if (t) {
post("sfwrite: start", f);
x->rec=1;
}
else {
post("sfwrite: stop", f);
x->rec=0;
}
}
static short out[4*64];
static t_int *sfwrite_perform(t_int *w)
{
t_sfwrite* x = (t_sfwrite*)(w[1]);
t_sample * in[4];
int c = x->x_channels;
int i,num,n;
short* tout = out;
int ret;
int timebefore,timeafter;
double late;
for (i=0;i < c;i++) {
in[i] = (t_sample *)(w[2+i]);
}
n = num = (int)(w[2+c]);
/* loop */
if (x->rec && x->x_file) {
while (n--) {
for (i=0;i<c;i++) {
*tout++ = (*(in[i])++)>>(fix1-16);
}
}
timebefore = sys_getrealtime();
if ((ret =write(x->x_file,out,sizeof(short)*num*c)) < (signed int)sizeof(short)*num*c) {
post("sfwrite: short write %d",ret);
}
timeafter = sys_getrealtime();
late = timeafter - timebefore;
#if 0
/* OK, we let only 10 ms block here */
if (late > BLOCKTIME && x->x_blockwarn) {
post("sfwrite blocked %f ms",late*1000);
x->x_blocked++;
if (x->x_blocked > x->x_blockwarn) {
x->rec = 0;
post("maximum blockcount %d reached, recording stopped (set blockcount with \"block <num>\"",x->x_blockwarn);
}
}
#endif
x->size +=64*x->x_channels*sizeof(short) ;
}
return (w+3+c);
}
static void sfwrite_dsp(t_sfwrite *x, t_signal **sp)
{
switch (x->x_channels) {
case 1:
dsp_add(sfwrite_perform, 3, x, sp[0]->s_vec,
sp[0]->s_n);
break;
case 2:
dsp_add(sfwrite_perform, 4, x, sp[0]->s_vec,
sp[1]->s_vec, sp[0]->s_n);
break;
case 4:
dsp_add(sfwrite_perform, 6, x, sp[0]->s_vec,
sp[1]->s_vec,
sp[2]->s_vec,
sp[3]->s_vec,
sp[0]->s_n);
break;
}
}
static void sfwrite_free(t_sfwrite* x)
{
sfwrite_close(x);
}
static void *sfwrite_new(t_floatarg chan)
{
t_sfwrite *x = (t_sfwrite *)pd_new(sfwrite_class);
t_int c = chan;
if (c<1 || c > MAX_CHANS) c = 1;
x->x_glist = (t_glist*) canvas_getcurrent();
x->x_channels = c--;
x->x_file=0;
x->rec = 0;
x->size = 0;
x->x_blocked = 0;
x->x_blockwarn = 10;
while (c--) {
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
}
return (x);
}
void sfwrite_tilde_setup(void)
{
sfwrite_class = class_new(gensym("sfwrite~"), (t_newmethod)sfwrite_new, (t_method)sfwrite_free,
sizeof(t_sfwrite), 0,A_DEFFLOAT,0);
class_addmethod(sfwrite_class,nullfn,gensym("signal"), 0);
class_addmethod(sfwrite_class, (t_method) sfwrite_dsp, gensym("dsp"), 0);
class_addmethod(sfwrite_class, (t_method) sfwrite_open, gensym("open"), A_SYMBOL,A_NULL);
class_addmethod(sfwrite_class, (t_method) sfwrite_close, gensym("close"), 0);
class_addmethod(sfwrite_class, (t_method)sfwrite_block,gensym("block"),A_DEFFLOAT,0);
class_addfloat(sfwrite_class, sfwrite_float);
}
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <m_pd.h>
#include <m_fixed.h>
#include "g_canvas.h"
#define BLOCKTIME 10
#define MAX_CHANS 4
#include "sformat.h"
static t_class *sfwrite_class;
typedef struct _sfwrite
{
t_object x_obj;
t_symbol* filename;
int x_file;
t_int rec;
t_int x_channels;
uint32 size;
t_glist * x_glist;
t_int x_blocked;
t_int x_blockwarn;
} t_sfwrite;
static void sfwrite_wave_setup(t_sfwrite* x,t_wave* w)
{
strncpy(w->w_fileid,"RIFF",4); /* chunk id 'RIFF' */
w->w_chunksize = x->size + sizeof(t_wave) -8; /* chunk size */
strncpy(w->w_waveid,"WAVE",4); /* wave chunk id 'WAVE' */
strncpy(w->w_fmtid,"fmt ",4); /* format chunk id 'fmt '*/
w->w_fmtchunksize = 16; /* format chunk size */
w->w_fmttag = 1; /* format tag, 1 for PCM */
w->w_nchannels = x->x_channels; /* number of channels */
w->w_samplespersec = 44100; /* sample rate in hz */
w->w_navgbytespersec = 44100*x->x_channels*2; /* average bytes per second */
w->w_nblockalign = 4; /* number of bytes per sample */
w->w_nbitspersample = 16; /* number of bits in a sample */
strncpy(w->w_datachunkid,"data",4); /* data chunk id 'data'*/
w->w_datachunksize = x->size; /* length of data chunk */
}
static void sfwrite_close(t_sfwrite *x)
{
if (x->x_file > 0) {
t_wave w;
sfwrite_wave_setup(x,&w);
lseek(x->x_file,0,SEEK_SET);
write(x->x_file,&w,sizeof(w));
close(x->x_file);
}
x->x_file = -1;
}
static void sfwrite_open(t_sfwrite *x,t_symbol *filename)
{
char fname[MAXPDSTRING];
if (filename == &s_) {
post("sfwrite: open without filename");
return;
}
canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
fname, MAXPDSTRING);
x->x_blocked = 0;
x->filename = filename;
post("sfwrite: filename = %s",x->filename->s_name);
sfwrite_close(x);
if ((x->x_file = open(fname,O_RDWR | O_CREAT,0664)) < 0)
{
error("can't create %s",fname);
return;
}
/* skip the header */
lseek(x->x_file,sizeof(t_wave),SEEK_SET);
x->size = 0;
}
static void sfwrite_block(t_sfwrite *x, t_floatarg f)
{
x->x_blockwarn = f;
}
static void sfwrite_float(t_sfwrite *x, t_floatarg f)
{
int t = f;
if (t) {
post("sfwrite: start", f);
x->rec=1;
}
else {
post("sfwrite: stop", f);
x->rec=0;
}
}
static short out[4*64];
static t_int *sfwrite_perform(t_int *w)
{
t_sfwrite* x = (t_sfwrite*)(w[1]);
t_sample * in[4];
int c = x->x_channels;
int i,num,n;
short* tout = out;
int ret;
int timebefore,timeafter;
double late;
for (i=0;i < c;i++) {
in[i] = (t_sample *)(w[2+i]);
}
n = num = (int)(w[2+c]);
/* loop */
if (x->rec && x->x_file) {
while (n--) {
for (i=0;i<c;i++) {
*tout++ = (*(in[i])++)>>(fix1-16);
}
}
timebefore = sys_getrealtime();
if ((ret =write(x->x_file,out,sizeof(short)*num*c)) < (signed int)sizeof(short)*num*c) {
post("sfwrite: short write %d",ret);
}
timeafter = sys_getrealtime();
late = timeafter - timebefore;
#if 0
/* OK, we let only 10 ms block here */
if (late > BLOCKTIME && x->x_blockwarn) {
post("sfwrite blocked %f ms",late*1000);
x->x_blocked++;
if (x->x_blocked > x->x_blockwarn) {
x->rec = 0;
post("maximum blockcount %d reached, recording stopped (set blockcount with \"block <num>\"",x->x_blockwarn);
}
}
#endif
x->size +=64*x->x_channels*sizeof(short) ;
}
return (w+3+c);
}
static void sfwrite_dsp(t_sfwrite *x, t_signal **sp)
{
switch (x->x_channels) {
case 1:
dsp_add(sfwrite_perform, 3, x, sp[0]->s_vec,
sp[0]->s_n);
break;
case 2:
dsp_add(sfwrite_perform, 4, x, sp[0]->s_vec,
sp[1]->s_vec, sp[0]->s_n);
break;
case 4:
dsp_add(sfwrite_perform, 6, x, sp[0]->s_vec,
sp[1]->s_vec,
sp[2]->s_vec,
sp[3]->s_vec,
sp[0]->s_n);
break;
}
}
static void sfwrite_free(t_sfwrite* x)
{
sfwrite_close(x);
}
static void *sfwrite_new(t_floatarg chan)
{
t_sfwrite *x = (t_sfwrite *)pd_new(sfwrite_class);
t_int c = chan;
if (c<1 || c > MAX_CHANS) c = 1;
x->x_glist = (t_glist*) canvas_getcurrent();
x->x_channels = c--;
x->x_file=0;
x->rec = 0;
x->size = 0;
x->x_blocked = 0;
x->x_blockwarn = 10;
while (c--) {
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
}
return (x);
}
void sfwrite_tilde_setup(void)
{
sfwrite_class = class_new(gensym("sfwrite~"), (t_newmethod)sfwrite_new, (t_method)sfwrite_free,
sizeof(t_sfwrite), 0,A_DEFFLOAT,0);
class_addmethod(sfwrite_class,nullfn,gensym("signal"), 0);
class_addmethod(sfwrite_class, (t_method) sfwrite_dsp, gensym("dsp"), 0);
class_addmethod(sfwrite_class, (t_method) sfwrite_open, gensym("open"), A_SYMBOL,A_NULL);
class_addmethod(sfwrite_class, (t_method) sfwrite_close, gensym("close"), 0);
class_addmethod(sfwrite_class, (t_method)sfwrite_block,gensym("block"),A_DEFFLOAT,0);
class_addfloat(sfwrite_class, sfwrite_float);
}

View file

@ -0,0 +1,134 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *sig_tilde_class;
typedef struct _sig
{
t_object x_obj;
t_sample x_f;
} t_sig;
static t_int *sig_tilde_perform(t_int *w)
{
t_sample f = *(t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
while (n--)
*out++ = f;
return (w+4);
}
static t_int *sig_tilde_perf8(t_int *w)
{
t_sample f = *(t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
for (; n; n -= 8, out += 8)
{
out[0] = f;
out[1] = f;
out[2] = f;
out[3] = f;
out[4] = f;
out[5] = f;
out[6] = f;
out[7] = f;
}
return (w+4);
}
static void sig_tilde_float(t_sig *x, t_float f)
{
x->x_f = ftofix(f);
}
static void sig_tilde_dsp(t_sig *x, t_signal **sp)
{
dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n);
}
static void *sig_tilde_new(t_floatarg f)
{
t_sig *x = (t_sig *)pd_new(sig_tilde_class);
x->x_f = ftofix(f);
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
void sig_tilde_setup(void)
{
sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0,
sizeof(t_sig), 0, A_DEFFLOAT, 0);
class_addfloat(sig_tilde_class, (t_method)sig_tilde_float);
class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *sig_tilde_class;
typedef struct _sig
{
t_object x_obj;
t_sample x_f;
} t_sig;
static t_int *sig_tilde_perform(t_int *w)
{
t_sample f = *(t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
while (n--)
*out++ = f;
return (w+4);
}
static t_int *sig_tilde_perf8(t_int *w)
{
t_sample f = *(t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
for (; n; n -= 8, out += 8)
{
out[0] = f;
out[1] = f;
out[2] = f;
out[3] = f;
out[4] = f;
out[5] = f;
out[6] = f;
out[7] = f;
}
return (w+4);
}
static void sig_tilde_float(t_sig *x, t_float f)
{
x->x_f = ftofix(f);
}
static void sig_tilde_dsp(t_sig *x, t_signal **sp)
{
dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n);
}
static void *sig_tilde_new(t_floatarg f)
{
t_sig *x = (t_sig *)pd_new(sig_tilde_class);
x->x_f = ftofix(f);
outlet_new(&x->x_obj, gensym("signal"));
return (x);
}
void sig_tilde_setup(void)
{
sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0,
sizeof(t_sig), 0, A_DEFFLOAT, 0);
class_addfloat(sig_tilde_class, (t_method)sig_tilde_float);
class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,114 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *snapshot_tilde_class;
typedef struct _snapshot
{
t_object x_obj;
t_sample x_value;
float x_f;
} t_snapshot;
static void *snapshot_tilde_new(void)
{
t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class);
x->x_value = 0;
outlet_new(&x->x_obj, &s_float);
x->x_f = 0;
return (x);
}
static t_int *snapshot_tilde_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
*out = *in;
return (w+3);
}
static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp)
{
dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1),
&x->x_value);
}
static void snapshot_tilde_bang(t_snapshot *x)
{
outlet_float(x->x_obj.ob_outlet, fixtof(x->x_value));
}
static void snapshot_tilde_set(t_snapshot *x, t_floatarg f)
{
x->x_value = ftofix(f);
}
void snapshot_tilde_setup(void)
{
snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0,
sizeof(t_snapshot), 0, 0);
CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f);
class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set,
gensym("set"), A_DEFFLOAT, 0);
class_addbang(snapshot_tilde_class, snapshot_tilde_bang);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *snapshot_tilde_class;
typedef struct _snapshot
{
t_object x_obj;
t_sample x_value;
float x_f;
} t_snapshot;
static void *snapshot_tilde_new(void)
{
t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class);
x->x_value = 0;
outlet_new(&x->x_obj, &s_float);
x->x_f = 0;
return (x);
}
static t_int *snapshot_tilde_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
*out = *in;
return (w+3);
}
static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp)
{
dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1),
&x->x_value);
}
static void snapshot_tilde_bang(t_snapshot *x)
{
outlet_float(x->x_obj.ob_outlet, fixtof(x->x_value));
}
static void snapshot_tilde_set(t_snapshot *x, t_floatarg f)
{
x->x_value = ftofix(f);
}
void snapshot_tilde_setup(void)
{
snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0,
sizeof(t_snapshot), 0, 0);
CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f);
class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set,
gensym("set"), A_DEFFLOAT, 0);
class_addbang(snapshot_tilde_class, snapshot_tilde_bang);
}

View file

@ -0,0 +1,154 @@
#define DUMTAB1SIZE 256
#define DUMTAB2SIZE 1024
#include<m_pd.h>
#include<m_fixed.h>
/* sigsqrt - square root good to 8 mantissa bits */
static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE];
static void init_rsqrt(void)
{
int i;
for (i = 0; i < DUMTAB1SIZE; i++)
{
float f;
long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23;
*(long *)(&f) = l;
rsqrt_exptab[i] = 1./sqrt(f);
}
for (i = 0; i < DUMTAB2SIZE; i++)
{
float f = 1 + (1./DUMTAB2SIZE) * i;
rsqrt_mantissatab[i] = 1./sqrt(f);
}
}
typedef struct sigsqrt
{
t_object x_obj;
float x_f;
} t_sigsqrt;
static t_class *sigsqrt_class;
static void *sigsqrt_new(void)
{
t_sigsqrt *x = (t_sigsqrt *)pd_new(sigsqrt_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
t_int *sigsqrt_perform(t_int *w) /* not static; also used in d_fft.c */
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
while (n--)
{
float f = *in;
long l = *(long *)(in++);
if (f < 0) *out++ = 0;
else
{
float g = rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff];
*out++ = f * (1.5 * g - 0.5 * g * g * g * f);
}
}
return (w + 4);
}
static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp)
{
dsp_add(sigsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void sqrt_tilde_setup(void)
{
init_rsqrt();
sigsqrt_class = class_new(gensym("sqrt~"), (t_newmethod)sigsqrt_new, 0,
sizeof(t_sigsqrt), 0, 0);
class_addcreator(sigsqrt_new, gensym("q8_sqrt~"), 0); /* old name */
CLASS_MAINSIGNALIN(sigsqrt_class, t_sigsqrt, x_f);
class_addmethod(sigsqrt_class, (t_method)sigsqrt_dsp, gensym("dsp"), 0);
}
#define DUMTAB1SIZE 256
#define DUMTAB2SIZE 1024
#include<m_pd.h>
#include<m_fixed.h>
/* sigsqrt - square root good to 8 mantissa bits */
static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE];
static void init_rsqrt(void)
{
int i;
for (i = 0; i < DUMTAB1SIZE; i++)
{
float f;
long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23;
*(long *)(&f) = l;
rsqrt_exptab[i] = 1./sqrt(f);
}
for (i = 0; i < DUMTAB2SIZE; i++)
{
float f = 1 + (1./DUMTAB2SIZE) * i;
rsqrt_mantissatab[i] = 1./sqrt(f);
}
}
typedef struct sigsqrt
{
t_object x_obj;
float x_f;
} t_sigsqrt;
static t_class *sigsqrt_class;
static void *sigsqrt_new(void)
{
t_sigsqrt *x = (t_sigsqrt *)pd_new(sigsqrt_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
t_int *sigsqrt_perform(t_int *w) /* not static; also used in d_fft.c */
{
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
t_int n = *(t_int *)(w+3);
while (n--)
{
float f = *in;
long l = *(long *)(in++);
if (f < 0) *out++ = 0;
else
{
float g = rsqrt_exptab[(l >> 23) & 0xff] *
rsqrt_mantissatab[(l >> 13) & 0x3ff];
*out++ = f * (1.5 * g - 0.5 * g * g * g * f);
}
}
return (w + 4);
}
static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp)
{
dsp_add(sigsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void sqrt_tilde_setup(void)
{
init_rsqrt();
sigsqrt_class = class_new(gensym("sqrt~"), (t_newmethod)sigsqrt_new, 0,
sizeof(t_sigsqrt), 0, 0);
class_addcreator(sigsqrt_new, gensym("q8_sqrt~"), 0); /* old name */
CLASS_MAINSIGNALIN(sigsqrt_class, t_sigsqrt, x_f);
class_addmethod(sigsqrt_class, (t_method)sigsqrt_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,264 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabosc4_tilde_class;
typedef struct _tabosc4_tilde
{
t_object x_obj;
int x_fnpoints;
int x_lognpoints;
t_sample *x_vec;
t_symbol *x_arrayname;
t_sample x_f;
unsigned int x_phase;
t_sample x_conv;
} t_tabosc4_tilde;
static void *tabosc4_tilde_new(t_symbol *s)
{
t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
x->x_fnpoints = 512;
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_f = 0;
post("new done");
return (x);
}
static t_int *tabosc4_tilde_perform(t_int *w)
{
t_tabosc4_tilde *x = (t_tabosc4_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
t_sample *tab = x->x_vec;
unsigned int phase = x->x_phase;
int conv = x->x_conv;
int off;
int frac;
int logp = x->x_lognpoints;
if (!tab) goto zero;
while (n--) {
t_sample f2;
phase+= mult(conv ,(*in++));
phase &= (itofix(1) -1);
off = fixtoi((long long)phase<<logp);
#ifdef NO_INTERPOLATION
*out = *(tab+off);
#else
frac = phase & ((1<<logp)-1);
frac <<= (fix1-logp);
f2 = (off == x->x_fnpoints) ?
mult(*(tab),frac) :
mult(*(tab + off + 1),frac);
*out = mult(*(tab + off),(itofix(1) - frac)) + f2;
#endif
out++;
}
x->x_phase = phase;
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s)
{
t_garray *a;
int npoints, pointsinarray;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name)
pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &pointsinarray, &x->x_vec))
{
pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else
{
int i;
x->x_fnpoints = pointsinarray;
x->x_lognpoints = ilog2(pointsinarray);
post("tabosc~: using %d (log %d) points of array",x->x_fnpoints,x->x_lognpoints);
garray_usedindsp(a);
}
}
static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f)
{
x->x_phase = f;
}
static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp)
{
x->x_conv = ftofix(1000.)/sp[0]->s_sr;
x->x_conv = mult(x->x_conv + 500,ftofix(0.001));
tabosc4_tilde_set(x, x->x_arrayname);
dsp_add(tabosc4_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void tabosc4_tilde_setup(void)
{
tabosc4_tilde_class = class_new(gensym("tabosc4~"),
(t_newmethod)tabosc4_tilde_new, 0,
sizeof(t_tabosc4_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabosc4_tilde_class, t_tabosc4_tilde, x_f);
class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_set,
gensym("set"), A_SYMBOL, 0);
class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_ft1,
gensym("ft1"), A_FLOAT, 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabosc4_tilde_class;
typedef struct _tabosc4_tilde
{
t_object x_obj;
int x_fnpoints;
int x_lognpoints;
t_sample *x_vec;
t_symbol *x_arrayname;
t_sample x_f;
unsigned int x_phase;
t_sample x_conv;
} t_tabosc4_tilde;
static void *tabosc4_tilde_new(t_symbol *s)
{
t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
x->x_fnpoints = 512;
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_f = 0;
post("new done");
return (x);
}
static t_int *tabosc4_tilde_perform(t_int *w)
{
t_tabosc4_tilde *x = (t_tabosc4_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
t_sample *tab = x->x_vec;
unsigned int phase = x->x_phase;
int conv = x->x_conv;
int off;
int frac;
int logp = x->x_lognpoints;
if (!tab) goto zero;
while (n--) {
t_sample f2;
phase+= mult(conv ,(*in++));
phase &= (itofix(1) -1);
off = fixtoi((long long)phase<<logp);
#ifdef NO_INTERPOLATION
*out = *(tab+off);
#else
frac = phase & ((1<<logp)-1);
frac <<= (fix1-logp);
f2 = (off == x->x_fnpoints) ?
mult(*(tab),frac) :
mult(*(tab + off + 1),frac);
*out = mult(*(tab + off),(itofix(1) - frac)) + f2;
#endif
out++;
}
x->x_phase = phase;
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s)
{
t_garray *a;
int npoints, pointsinarray;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name)
pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &pointsinarray, &x->x_vec))
{
pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else
{
int i;
x->x_fnpoints = pointsinarray;
x->x_lognpoints = ilog2(pointsinarray);
post("tabosc~: using %d (log %d) points of array",x->x_fnpoints,x->x_lognpoints);
garray_usedindsp(a);
}
}
static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f)
{
x->x_phase = f;
}
static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp)
{
x->x_conv = ftofix(1000.)/sp[0]->s_sr;
x->x_conv = mult(x->x_conv + 500,ftofix(0.001));
tabosc4_tilde_set(x, x->x_arrayname);
dsp_add(tabosc4_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void tabosc4_tilde_setup(void)
{
tabosc4_tilde_class = class_new(gensym("tabosc4~"),
(t_newmethod)tabosc4_tilde_new, 0,
sizeof(t_tabosc4_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabosc4_tilde_class, t_tabosc4_tilde, x_f);
class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_set,
gensym("set"), A_SYMBOL, 0);
class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_ft1,
gensym("ft1"), A_FLOAT, 0);
}

View file

@ -0,0 +1,264 @@
#define FIXEDPOINT
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabplay_tilde_class;
typedef struct _tabplay_tilde
{
t_object x_obj;
t_outlet *x_bangout;
int x_phase;
int x_nsampsintab;
int x_limit;
t_sample *x_vec;
t_symbol *x_arrayname;
t_clock *x_clock;
} t_tabplay_tilde;
static void tabplay_tilde_tick(t_tabplay_tilde *x);
static void *tabplay_tilde_new(t_symbol *s)
{
t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class);
x->x_clock = clock_new(x, (t_method)tabplay_tilde_tick);
x->x_phase = 0x7fffffff;
x->x_limit = 0;
x->x_arrayname = s;
outlet_new(&x->x_obj, &s_signal);
x->x_bangout = outlet_new(&x->x_obj, &s_bang);
return (x);
}
static t_int *tabplay_tilde_perform(t_int *w)
{
t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]);
t_sample *out = (t_sample *)(w[2]), *fp;
int n = (int)(w[3]), phase = x->x_phase,
endphase = (x->x_nsampsintab < x->x_limit ?
x->x_nsampsintab : x->x_limit), nxfer, n3;
if (!x->x_vec || phase >= endphase)
goto zero;
nxfer = endphase - phase;
fp = x->x_vec + phase;
if (nxfer > n)
nxfer = n;
n3 = n - nxfer;
phase += nxfer;
while (nxfer--)
*out++ = *fp++;
if (phase >= endphase)
{
clock_delay(x->x_clock, 0);
x->x_phase = 0x7fffffff;
while (n3--)
*out++ = 0;
}
else x->x_phase = phase;
return (w+4);
zero:
while (n--) *out++ = 0;
return (w+4);
}
void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name) pd_error(x, "tabplay~: %s: no such array",
x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
{
error("%s: bad template for tabplay~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp)
{
tabplay_tilde_set(x, x->x_arrayname);
dsp_add(tabplay_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s,
int argc, t_atom *argv)
{
long start = atom_getfloatarg(0, argc, argv);
long length = atom_getfloatarg(1, argc, argv);
if (start < 0) start = 0;
if (length <= 0)
x->x_limit = 0x7fffffff;
else
x->x_limit = start + length;
x->x_phase = start;
}
static void tabplay_tilde_stop(t_tabplay_tilde *x)
{
x->x_phase = 0x7fffffff;
}
static void tabplay_tilde_tick(t_tabplay_tilde *x)
{
outlet_bang(x->x_bangout);
}
static void tabplay_tilde_free(t_tabplay_tilde *x)
{
clock_free(x->x_clock);
}
void tabplay_tilde_setup(void)
{
tabplay_tilde_class = class_new(gensym("tabplay~"),
(t_newmethod)tabplay_tilde_new, (t_method)tabplay_tilde_free,
sizeof(t_tabplay_tilde), 0, A_DEFSYM, 0);
class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_stop,
gensym("stop"), 0);
class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_set,
gensym("set"), A_DEFSYM, 0);
class_addlist(tabplay_tilde_class, tabplay_tilde_list);
}
#define FIXEDPOINT
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabplay_tilde_class;
typedef struct _tabplay_tilde
{
t_object x_obj;
t_outlet *x_bangout;
int x_phase;
int x_nsampsintab;
int x_limit;
t_sample *x_vec;
t_symbol *x_arrayname;
t_clock *x_clock;
} t_tabplay_tilde;
static void tabplay_tilde_tick(t_tabplay_tilde *x);
static void *tabplay_tilde_new(t_symbol *s)
{
t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class);
x->x_clock = clock_new(x, (t_method)tabplay_tilde_tick);
x->x_phase = 0x7fffffff;
x->x_limit = 0;
x->x_arrayname = s;
outlet_new(&x->x_obj, &s_signal);
x->x_bangout = outlet_new(&x->x_obj, &s_bang);
return (x);
}
static t_int *tabplay_tilde_perform(t_int *w)
{
t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]);
t_sample *out = (t_sample *)(w[2]), *fp;
int n = (int)(w[3]), phase = x->x_phase,
endphase = (x->x_nsampsintab < x->x_limit ?
x->x_nsampsintab : x->x_limit), nxfer, n3;
if (!x->x_vec || phase >= endphase)
goto zero;
nxfer = endphase - phase;
fp = x->x_vec + phase;
if (nxfer > n)
nxfer = n;
n3 = n - nxfer;
phase += nxfer;
while (nxfer--)
*out++ = *fp++;
if (phase >= endphase)
{
clock_delay(x->x_clock, 0);
x->x_phase = 0x7fffffff;
while (n3--)
*out++ = 0;
}
else x->x_phase = phase;
return (w+4);
zero:
while (n--) *out++ = 0;
return (w+4);
}
void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name) pd_error(x, "tabplay~: %s: no such array",
x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
{
error("%s: bad template for tabplay~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp)
{
tabplay_tilde_set(x, x->x_arrayname);
dsp_add(tabplay_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s,
int argc, t_atom *argv)
{
long start = atom_getfloatarg(0, argc, argv);
long length = atom_getfloatarg(1, argc, argv);
if (start < 0) start = 0;
if (length <= 0)
x->x_limit = 0x7fffffff;
else
x->x_limit = start + length;
x->x_phase = start;
}
static void tabplay_tilde_stop(t_tabplay_tilde *x)
{
x->x_phase = 0x7fffffff;
}
static void tabplay_tilde_tick(t_tabplay_tilde *x)
{
outlet_bang(x->x_bangout);
}
static void tabplay_tilde_free(t_tabplay_tilde *x)
{
clock_free(x->x_clock);
}
void tabplay_tilde_setup(void)
{
tabplay_tilde_class = class_new(gensym("tabplay~"),
(t_newmethod)tabplay_tilde_new, (t_method)tabplay_tilde_free,
sizeof(t_tabplay_tilde), 0, A_DEFSYM, 0);
class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_stop,
gensym("stop"), 0);
class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_set,
gensym("set"), A_DEFSYM, 0);
class_addlist(tabplay_tilde_class, tabplay_tilde_list);
}

View file

@ -0,0 +1,104 @@
#include <m_pd.h>
/* ---------- tabread: control, non-interpolating ------------------------ */
static t_class *tabread_class;
typedef struct _tabread
{
t_object x_obj;
t_symbol *x_arrayname;
} t_tabread;
static void tabread_float(t_tabread *x, t_float f)
{
t_garray *a;
int npoints;
t_sample *vec;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
pd_error(x, "%s: no such array", x->x_arrayname->s_name);
else if (!garray_getfloatarray(a, &npoints, &vec))
pd_error(x, "%s: bad template for tabread", x->x_arrayname->s_name);
else
{
int n = f;
if (n < 0) n = 0;
else if (n >= npoints) n = npoints - 1;
outlet_float(x->x_obj.ob_outlet, (npoints ? fixtof(vec[n]) : 0));
}
}
static void tabread_set(t_tabread *x, t_symbol *s)
{
x->x_arrayname = s;
}
static void *tabread_new(t_symbol *s)
{
t_tabread *x = (t_tabread *)pd_new(tabread_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, &s_float);
return (x);
}
void tabread_setup(void)
{
tabread_class = class_new(gensym("tabread"), (t_newmethod)tabread_new,
0, sizeof(t_tabread), 0, A_DEFSYM, 0);
class_addfloat(tabread_class, (t_method)tabread_float);
class_addmethod(tabread_class, (t_method)tabread_set, gensym("set"),
A_SYMBOL, 0);
}
#include <m_pd.h>
/* ---------- tabread: control, non-interpolating ------------------------ */
static t_class *tabread_class;
typedef struct _tabread
{
t_object x_obj;
t_symbol *x_arrayname;
} t_tabread;
static void tabread_float(t_tabread *x, t_float f)
{
t_garray *a;
int npoints;
t_sample *vec;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
pd_error(x, "%s: no such array", x->x_arrayname->s_name);
else if (!garray_getfloatarray(a, &npoints, &vec))
pd_error(x, "%s: bad template for tabread", x->x_arrayname->s_name);
else
{
int n = f;
if (n < 0) n = 0;
else if (n >= npoints) n = npoints - 1;
outlet_float(x->x_obj.ob_outlet, (npoints ? fixtof(vec[n]) : 0));
}
}
static void tabread_set(t_tabread *x, t_symbol *s)
{
x->x_arrayname = s;
}
static void *tabread_new(t_symbol *s)
{
t_tabread *x = (t_tabread *)pd_new(tabread_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, &s_float);
return (x);
}
void tabread_setup(void)
{
tabread_class = class_new(gensym("tabread"), (t_newmethod)tabread_new,
0, sizeof(t_tabread), 0, A_DEFSYM, 0);
class_addfloat(tabread_class, (t_method)tabread_float);
class_addmethod(tabread_class, (t_method)tabread_set, gensym("set"),
A_SYMBOL, 0);
}

View file

@ -0,0 +1,210 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabread4_tilde_class;
typedef struct _tabread4_tilde
{
t_object x_obj;
int x_npoints;
t_sample *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tabread4_tilde;
static void *tabread4_tilde_new(t_symbol *s)
{
t_tabread4_tilde *x = (t_tabread4_tilde *)pd_new(tabread4_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *tabread4_tilde_perform(t_int *w)
{
t_tabread4_tilde *x = (t_tabread4_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
int maxindex;
t_sample *buf = x->x_vec, *fp;
int i;
maxindex = x->x_npoints - 3;
if (!buf) goto zero;
for (i = 0; i < n; i++)
{
t_time findex = ((long long) mult((*in++),ftofix(44.1)));
int index = fixtoi(findex);
t_sample frac;
// post("%d: index %d f %lld",index,findex,*in);
if (index < 1)
index = 1, frac = 0;
else if (index > maxindex)
index = maxindex, frac = 1;
else frac = findex - itofix(index);
fp = buf + index;
*out++ = fp[0] + mult(frac,fp[1]-fp[0]);
}
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tabread4_tilde_set(t_tabread4_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name)
error("tabread4~: %s: no such array", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
{
error("%s: bad template for tabread4~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabread4_tilde_dsp(t_tabread4_tilde *x, t_signal **sp)
{
tabread4_tilde_set(x, x->x_arrayname);
dsp_add(tabread4_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void tabread4_tilde_free(t_tabread4_tilde *x)
{
}
void tabread4_tilde_setup(void)
{
tabread4_tilde_class = class_new(gensym("tabread4~"),
(t_newmethod)tabread4_tilde_new, (t_method)tabread4_tilde_free,
sizeof(t_tabread4_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabread4_tilde_class, t_tabread4_tilde, x_f);
class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_set,
gensym("set"), A_SYMBOL, 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabread4_tilde_class;
typedef struct _tabread4_tilde
{
t_object x_obj;
int x_npoints;
t_sample *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tabread4_tilde;
static void *tabread4_tilde_new(t_symbol *s)
{
t_tabread4_tilde *x = (t_tabread4_tilde *)pd_new(tabread4_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *tabread4_tilde_perform(t_int *w)
{
t_tabread4_tilde *x = (t_tabread4_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
int maxindex;
t_sample *buf = x->x_vec, *fp;
int i;
maxindex = x->x_npoints - 3;
if (!buf) goto zero;
for (i = 0; i < n; i++)
{
t_time findex = ((long long) mult((*in++),ftofix(44.1)));
int index = fixtoi(findex);
t_sample frac;
// post("%d: index %d f %lld",index,findex,*in);
if (index < 1)
index = 1, frac = 0;
else if (index > maxindex)
index = maxindex, frac = 1;
else frac = findex - itofix(index);
fp = buf + index;
*out++ = fp[0] + mult(frac,fp[1]-fp[0]);
}
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tabread4_tilde_set(t_tabread4_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name)
error("tabread4~: %s: no such array", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
{
error("%s: bad template for tabread4~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabread4_tilde_dsp(t_tabread4_tilde *x, t_signal **sp)
{
tabread4_tilde_set(x, x->x_arrayname);
dsp_add(tabread4_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void tabread4_tilde_free(t_tabread4_tilde *x)
{
}
void tabread4_tilde_setup(void)
{
tabread4_tilde_class = class_new(gensym("tabread4~"),
(t_newmethod)tabread4_tilde_new, (t_method)tabread4_tilde_free,
sizeof(t_tabread4_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabread4_tilde_class, t_tabread4_tilde, x_f);
class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_set,
gensym("set"), A_SYMBOL, 0);
}

View file

@ -0,0 +1,194 @@
#define FIXEDPOINT
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabread_tilde_class;
typedef struct _tabread_tilde
{
t_object x_obj;
int x_npoints;
t_sample *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tabread_tilde;
static void *tabread_tilde_new(t_symbol *s)
{
t_tabread_tilde *x = (t_tabread_tilde *)pd_new(tabread_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *tabread_tilde_perform(t_int *w)
{
t_tabread_tilde *x = (t_tabread_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
int maxindex;
t_sample *buf = x->x_vec, *fp;
int i;
maxindex = x->x_npoints - 1;
if (!buf) goto zero;
for (i = 0; i < n; i++)
{
int index = ((long long) mult((*in++),ftofix(44.1)) >> fix1);
if (index < 0)
index = 0;
else if (index > maxindex)
index = maxindex;
*out++ = buf[index];
}
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tabread_tilde_set(t_tabread_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name)
error("tabread~: %s: no such array", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
{
error("%s: bad template for tabread~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabread_tilde_dsp(t_tabread_tilde *x, t_signal **sp)
{
tabread_tilde_set(x, x->x_arrayname);
dsp_add(tabread_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void tabread_tilde_free(t_tabread_tilde *x)
{
}
void tabread_tilde_setup(void)
{
tabread_tilde_class = class_new(gensym("tabread~"),
(t_newmethod)tabread_tilde_new, (t_method)tabread_tilde_free,
sizeof(t_tabread_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabread_tilde_class, t_tabread_tilde, x_f);
class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_set,
gensym("set"), A_SYMBOL, 0);
}
#define FIXEDPOINT
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabread_tilde_class;
typedef struct _tabread_tilde
{
t_object x_obj;
int x_npoints;
t_sample *x_vec;
t_symbol *x_arrayname;
float x_f;
} t_tabread_tilde;
static void *tabread_tilde_new(t_symbol *s)
{
t_tabread_tilde *x = (t_tabread_tilde *)pd_new(tabread_tilde_class);
x->x_arrayname = s;
x->x_vec = 0;
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *tabread_tilde_perform(t_int *w)
{
t_tabread_tilde *x = (t_tabread_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
int maxindex;
t_sample *buf = x->x_vec, *fp;
int i;
maxindex = x->x_npoints - 1;
if (!buf) goto zero;
for (i = 0; i < n; i++)
{
int index = ((long long) mult((*in++),ftofix(44.1)) >> fix1);
if (index < 0)
index = 0;
else if (index > maxindex)
index = maxindex;
*out++ = buf[index];
}
return (w+5);
zero:
while (n--) *out++ = 0;
return (w+5);
}
void tabread_tilde_set(t_tabread_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name)
error("tabread~: %s: no such array", x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
{
error("%s: bad template for tabread~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabread_tilde_dsp(t_tabread_tilde *x, t_signal **sp)
{
tabread_tilde_set(x, x->x_arrayname);
dsp_add(tabread_tilde_perform, 4, x,
sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
static void tabread_tilde_free(t_tabread_tilde *x)
{
}
void tabread_tilde_setup(void)
{
tabread_tilde_class = class_new(gensym("tabread~"),
(t_newmethod)tabread_tilde_new, (t_method)tabread_tilde_free,
sizeof(t_tabread_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabread_tilde_class, t_tabread_tilde, x_f);
class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_set,
gensym("set"), A_SYMBOL, 0);
}

View file

@ -0,0 +1,122 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabreceive_class;
typedef struct _tabreceive
{
t_object x_obj;
t_sample *x_vec;
t_symbol *x_arrayname;
} t_tabreceive;
static t_int *tabreceive_perform(t_int *w)
{
t_tabreceive *x = (t_tabreceive *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = w[3];
t_sample *from = x->x_vec;
if (from) while (n--) *out++ = *from++;
else while (n--) *out++ = 0;
return (w+4);
}
static void tabreceive_dsp(t_tabreceive *x, t_signal **sp)
{
t_garray *a;
int vecsize;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*x->x_arrayname->s_name)
error("tabsend~: %s: no such array", x->x_arrayname->s_name);
}
else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
error("%s: bad template for tabreceive~", x->x_arrayname->s_name);
else
{
int n = sp[0]->s_n;
if (n < vecsize) vecsize = n;
garray_usedindsp(a);
dsp_add(tabreceive_perform, 3, x, sp[0]->s_vec, vecsize);
}
}
static void *tabreceive_new(t_symbol *s)
{
t_tabreceive *x = (t_tabreceive *)pd_new(tabreceive_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, &s_signal);
return (x);
}
void tabreceive_tilde_setup(void)
{
tabreceive_class = class_new(gensym("tabreceive~"),
(t_newmethod)tabreceive_new, 0,
sizeof(t_tabreceive), 0, A_DEFSYM, 0);
class_addmethod(tabreceive_class, (t_method)tabreceive_dsp,
gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabreceive_class;
typedef struct _tabreceive
{
t_object x_obj;
t_sample *x_vec;
t_symbol *x_arrayname;
} t_tabreceive;
static t_int *tabreceive_perform(t_int *w)
{
t_tabreceive *x = (t_tabreceive *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = w[3];
t_sample *from = x->x_vec;
if (from) while (n--) *out++ = *from++;
else while (n--) *out++ = 0;
return (w+4);
}
static void tabreceive_dsp(t_tabreceive *x, t_signal **sp)
{
t_garray *a;
int vecsize;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*x->x_arrayname->s_name)
error("tabsend~: %s: no such array", x->x_arrayname->s_name);
}
else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
error("%s: bad template for tabreceive~", x->x_arrayname->s_name);
else
{
int n = sp[0]->s_n;
if (n < vecsize) vecsize = n;
garray_usedindsp(a);
dsp_add(tabreceive_perform, 3, x, sp[0]->s_vec, vecsize);
}
}
static void *tabreceive_new(t_symbol *s)
{
t_tabreceive *x = (t_tabreceive *)pd_new(tabreceive_class);
x->x_arrayname = s;
outlet_new(&x->x_obj, &s_signal);
return (x);
}
void tabreceive_tilde_setup(void)
{
tabreceive_class = class_new(gensym("tabreceive~"),
(t_newmethod)tabreceive_new, 0,
sizeof(t_tabreceive), 0, A_DEFSYM, 0);
class_addmethod(tabreceive_class, (t_method)tabreceive_dsp,
gensym("dsp"), 0);
}

View file

@ -0,0 +1,196 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabsend_class;
typedef struct _tabsend
{
t_object x_obj;
t_sample *x_vec;
int x_graphperiod;
int x_graphcount;
t_symbol *x_arrayname;
t_clock *x_clock;
float x_f;
} t_tabsend;
static void tabsend_tick(t_tabsend *x);
static void *tabsend_new(t_symbol *s)
{
t_tabsend *x = (t_tabsend *)pd_new(tabsend_class);
x->x_graphcount = 0;
x->x_arrayname = s;
x->x_clock = clock_new(x, (t_method)tabsend_tick);
x->x_f = 0;
return (x);
}
static t_int *tabsend_perform(t_int *w)
{
t_tabsend *x = (t_tabsend *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = w[3];
t_sample *dest = x->x_vec;
int i = x->x_graphcount;
if (!x->x_vec) goto bad;
while (n--)
{
t_sample f = *in++;
if (PD_BADFLOAT(f))
f = 0;
*dest++ = f;
}
if (!i--)
{
clock_delay(x->x_clock, 0);
i = x->x_graphperiod;
}
x->x_graphcount = i;
bad:
return (w+4);
}
static void tabsend_dsp(t_tabsend *x, t_signal **sp)
{
int i, vecsize;
t_garray *a;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*x->x_arrayname->s_name)
error("tabsend~: %s: no such array", x->x_arrayname->s_name);
}
else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
error("%s: bad template for tabsend~", x->x_arrayname->s_name);
else
{
int n = sp[0]->s_n;
int ticksper = sp[0]->s_sr/n;
if (ticksper < 1) ticksper = 1;
x->x_graphperiod = ticksper;
if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
if (n < vecsize) vecsize = n;
garray_usedindsp(a);
dsp_add(tabsend_perform, 3, x, sp[0]->s_vec, vecsize);
}
}
static void tabsend_tick(t_tabsend *x)
{
t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
if (!a) bug("tabsend_tick");
else garray_redraw(a);
}
static void tabsend_free(t_tabsend *x)
{
clock_free(x->x_clock);
}
void tabsend_tilde_setup(void)
{
tabsend_class = class_new(gensym("tabsend~"), (t_newmethod)tabsend_new,
(t_method)tabsend_free, sizeof(t_tabsend), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabsend_class, t_tabsend, x_f);
class_addmethod(tabsend_class, (t_method)tabsend_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabsend_class;
typedef struct _tabsend
{
t_object x_obj;
t_sample *x_vec;
int x_graphperiod;
int x_graphcount;
t_symbol *x_arrayname;
t_clock *x_clock;
float x_f;
} t_tabsend;
static void tabsend_tick(t_tabsend *x);
static void *tabsend_new(t_symbol *s)
{
t_tabsend *x = (t_tabsend *)pd_new(tabsend_class);
x->x_graphcount = 0;
x->x_arrayname = s;
x->x_clock = clock_new(x, (t_method)tabsend_tick);
x->x_f = 0;
return (x);
}
static t_int *tabsend_perform(t_int *w)
{
t_tabsend *x = (t_tabsend *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = w[3];
t_sample *dest = x->x_vec;
int i = x->x_graphcount;
if (!x->x_vec) goto bad;
while (n--)
{
t_sample f = *in++;
if (PD_BADFLOAT(f))
f = 0;
*dest++ = f;
}
if (!i--)
{
clock_delay(x->x_clock, 0);
i = x->x_graphperiod;
}
x->x_graphcount = i;
bad:
return (w+4);
}
static void tabsend_dsp(t_tabsend *x, t_signal **sp)
{
int i, vecsize;
t_garray *a;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*x->x_arrayname->s_name)
error("tabsend~: %s: no such array", x->x_arrayname->s_name);
}
else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
error("%s: bad template for tabsend~", x->x_arrayname->s_name);
else
{
int n = sp[0]->s_n;
int ticksper = sp[0]->s_sr/n;
if (ticksper < 1) ticksper = 1;
x->x_graphperiod = ticksper;
if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
if (n < vecsize) vecsize = n;
garray_usedindsp(a);
dsp_add(tabsend_perform, 3, x, sp[0]->s_vec, vecsize);
}
}
static void tabsend_tick(t_tabsend *x)
{
t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
if (!a) bug("tabsend_tick");
else garray_redraw(a);
}
static void tabsend_free(t_tabsend *x)
{
clock_free(x->x_clock);
}
void tabsend_tilde_setup(void)
{
tabsend_class = class_new(gensym("tabsend~"), (t_newmethod)tabsend_new,
(t_method)tabsend_free, sizeof(t_tabsend), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabsend_class, t_tabsend, x_f);
class_addmethod(tabsend_class, (t_method)tabsend_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,168 @@
#include <m_pd.h>
/* ------------------ tabwrite: control ------------------------ */
static t_class *tabwrite_class;
typedef struct _tabwrite
{
t_object x_obj;
t_symbol *x_arrayname;
t_clock *x_clock;
float x_ft1;
double x_updtime;
int x_set;
} t_tabwrite;
static void tabwrite_tick(t_tabwrite *x)
{
t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
if (!a) bug("tabwrite_tick");
else garray_redraw(a);
x->x_set = 0;
x->x_updtime = clock_getsystime();
}
static void tabwrite_float(t_tabwrite *x, t_float f)
{
int i, vecsize;
t_garray *a;
t_sample *vec;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
pd_error(x, "%s: no such array", x->x_arrayname->s_name);
else if (!garray_getfloatarray(a, &vecsize, &vec))
pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name);
else
{
int n = x->x_ft1;
double timesince = clock_gettimesince(x->x_updtime);
if (n < 0) n = 0;
else if (n >= vecsize) n = vecsize-1;
vec[n] = ftofix(f);
if (timesince > 1000)
{
tabwrite_tick(x);
}
else
{
if (x->x_set == 0)
{
clock_delay(x->x_clock, 1000 - timesince);
x->x_set = 1;
}
}
}
}
static void tabwrite_set(t_tabwrite *x, t_symbol *s)
{
x->x_arrayname = s;
}
static void tabwrite_free(t_tabwrite *x)
{
clock_free(x->x_clock);
}
static void *tabwrite_new(t_symbol *s)
{
t_tabwrite *x = (t_tabwrite *)pd_new(tabwrite_class);
x->x_ft1 = 0;
x->x_arrayname = s;
x->x_updtime = clock_getsystime();
x->x_clock = clock_new(x, (t_method)tabwrite_tick);
floatinlet_new(&x->x_obj, &x->x_ft1);
return (x);
}
void tabwrite_setup(void)
{
tabwrite_class = class_new(gensym("tabwrite"), (t_newmethod)tabwrite_new,
(t_method)tabwrite_free, sizeof(t_tabwrite), 0, A_DEFSYM, 0);
class_addfloat(tabwrite_class, (t_method)tabwrite_float);
class_addmethod(tabwrite_class, (t_method)tabwrite_set, gensym("set"), A_SYMBOL, 0);
}
#include <m_pd.h>
/* ------------------ tabwrite: control ------------------------ */
static t_class *tabwrite_class;
typedef struct _tabwrite
{
t_object x_obj;
t_symbol *x_arrayname;
t_clock *x_clock;
float x_ft1;
double x_updtime;
int x_set;
} t_tabwrite;
static void tabwrite_tick(t_tabwrite *x)
{
t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
if (!a) bug("tabwrite_tick");
else garray_redraw(a);
x->x_set = 0;
x->x_updtime = clock_getsystime();
}
static void tabwrite_float(t_tabwrite *x, t_float f)
{
int i, vecsize;
t_garray *a;
t_sample *vec;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
pd_error(x, "%s: no such array", x->x_arrayname->s_name);
else if (!garray_getfloatarray(a, &vecsize, &vec))
pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name);
else
{
int n = x->x_ft1;
double timesince = clock_gettimesince(x->x_updtime);
if (n < 0) n = 0;
else if (n >= vecsize) n = vecsize-1;
vec[n] = ftofix(f);
if (timesince > 1000)
{
tabwrite_tick(x);
}
else
{
if (x->x_set == 0)
{
clock_delay(x->x_clock, 1000 - timesince);
x->x_set = 1;
}
}
}
}
static void tabwrite_set(t_tabwrite *x, t_symbol *s)
{
x->x_arrayname = s;
}
static void tabwrite_free(t_tabwrite *x)
{
clock_free(x->x_clock);
}
static void *tabwrite_new(t_symbol *s)
{
t_tabwrite *x = (t_tabwrite *)pd_new(tabwrite_class);
x->x_ft1 = 0;
x->x_arrayname = s;
x->x_updtime = clock_getsystime();
x->x_clock = clock_new(x, (t_method)tabwrite_tick);
floatinlet_new(&x->x_obj, &x->x_ft1);
return (x);
}
void tabwrite_setup(void)
{
tabwrite_class = class_new(gensym("tabwrite"), (t_newmethod)tabwrite_new,
(t_method)tabwrite_free, sizeof(t_tabwrite), 0, A_DEFSYM, 0);
class_addfloat(tabwrite_class, (t_method)tabwrite_float);
class_addmethod(tabwrite_class, (t_method)tabwrite_set, gensym("set"), A_SYMBOL, 0);
}

View file

@ -0,0 +1,264 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabwrite_tilde_class;
typedef struct _tabwrite_tilde
{
t_object x_obj;
int x_phase;
int x_nsampsintab;
t_sample *x_vec;
t_symbol *x_arrayname;
t_clock *x_clock;
float x_f;
} t_tabwrite_tilde;
static void tabwrite_tilde_tick(t_tabwrite_tilde *x);
static void *tabwrite_tilde_new(t_symbol *s)
{
t_tabwrite_tilde *x = (t_tabwrite_tilde *)pd_new(tabwrite_tilde_class);
x->x_clock = clock_new(x, (t_method)tabwrite_tilde_tick);
x->x_phase = 0x7fffffff;
x->x_arrayname = s;
x->x_f = 0;
return (x);
}
static t_int *tabwrite_tilde_perform(t_int *w)
{
t_tabwrite_tilde *x = (t_tabwrite_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
if (!x->x_vec) goto bad;
if (endphase > phase)
{
int nxfer = endphase - phase;
t_sample *fp = x->x_vec + phase;
if (nxfer > n) nxfer = n;
phase += nxfer;
while (nxfer--)
{
t_sample f = *in++;
*fp++ = f;
}
if (phase >= endphase)
{
clock_delay(x->x_clock, 0);
phase = 0x7fffffff;
}
x->x_phase = phase;
}
bad:
return (w+4);
}
void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name) pd_error(x, "tabwrite~: %s: no such array",
x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
{
error("%s: bad template for tabwrite~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabwrite_tilde_dsp(t_tabwrite_tilde *x, t_signal **sp)
{
tabwrite_tilde_set(x, x->x_arrayname);
dsp_add(tabwrite_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void tabwrite_tilde_bang(t_tabwrite_tilde *x)
{
x->x_phase = 0;
}
static void tabwrite_tilde_float(t_tabwrite_tilde *x,t_float n)
{
if (n < x->x_nsampsintab)
x->x_phase = n;
else
x->x_phase = 0;
}
static void tabwrite_tilde_stop(t_tabwrite_tilde *x)
{
if (x->x_phase != 0x7fffffff)
{
tabwrite_tilde_tick(x);
x->x_phase = 0x7fffffff;
}
}
static void tabwrite_tilde_tick(t_tabwrite_tilde *x)
{
t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
if (!a) bug("tabwrite_tilde_tick");
else garray_redraw(a);
}
static void tabwrite_tilde_free(t_tabwrite_tilde *x)
{
clock_free(x->x_clock);
}
void tabwrite_tilde_setup(void)
{
tabwrite_tilde_class = class_new(gensym("tabwrite~"),
(t_newmethod)tabwrite_tilde_new, (t_method)tabwrite_tilde_free,
sizeof(t_tabwrite_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabwrite_tilde_class, t_tabwrite_tilde, x_f);
class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_set,
gensym("set"), A_SYMBOL, 0);
class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_stop,
gensym("stop"), 0);
class_addbang(tabwrite_tilde_class, tabwrite_tilde_bang);
class_addfloat(tabwrite_tilde_class, tabwrite_tilde_float);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *tabwrite_tilde_class;
typedef struct _tabwrite_tilde
{
t_object x_obj;
int x_phase;
int x_nsampsintab;
t_sample *x_vec;
t_symbol *x_arrayname;
t_clock *x_clock;
float x_f;
} t_tabwrite_tilde;
static void tabwrite_tilde_tick(t_tabwrite_tilde *x);
static void *tabwrite_tilde_new(t_symbol *s)
{
t_tabwrite_tilde *x = (t_tabwrite_tilde *)pd_new(tabwrite_tilde_class);
x->x_clock = clock_new(x, (t_method)tabwrite_tilde_tick);
x->x_phase = 0x7fffffff;
x->x_arrayname = s;
x->x_f = 0;
return (x);
}
static t_int *tabwrite_tilde_perform(t_int *w)
{
t_tabwrite_tilde *x = (t_tabwrite_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
if (!x->x_vec) goto bad;
if (endphase > phase)
{
int nxfer = endphase - phase;
t_sample *fp = x->x_vec + phase;
if (nxfer > n) nxfer = n;
phase += nxfer;
while (nxfer--)
{
t_sample f = *in++;
*fp++ = f;
}
if (phase >= endphase)
{
clock_delay(x->x_clock, 0);
phase = 0x7fffffff;
}
x->x_phase = phase;
}
bad:
return (w+4);
}
void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s)
{
t_garray *a;
x->x_arrayname = s;
if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
{
if (*s->s_name) pd_error(x, "tabwrite~: %s: no such array",
x->x_arrayname->s_name);
x->x_vec = 0;
}
else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
{
error("%s: bad template for tabwrite~", x->x_arrayname->s_name);
x->x_vec = 0;
}
else garray_usedindsp(a);
}
static void tabwrite_tilde_dsp(t_tabwrite_tilde *x, t_signal **sp)
{
tabwrite_tilde_set(x, x->x_arrayname);
dsp_add(tabwrite_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void tabwrite_tilde_bang(t_tabwrite_tilde *x)
{
x->x_phase = 0;
}
static void tabwrite_tilde_float(t_tabwrite_tilde *x,t_float n)
{
if (n < x->x_nsampsintab)
x->x_phase = n;
else
x->x_phase = 0;
}
static void tabwrite_tilde_stop(t_tabwrite_tilde *x)
{
if (x->x_phase != 0x7fffffff)
{
tabwrite_tilde_tick(x);
x->x_phase = 0x7fffffff;
}
}
static void tabwrite_tilde_tick(t_tabwrite_tilde *x)
{
t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
if (!a) bug("tabwrite_tilde_tick");
else garray_redraw(a);
}
static void tabwrite_tilde_free(t_tabwrite_tilde *x)
{
clock_free(x->x_clock);
}
void tabwrite_tilde_setup(void)
{
tabwrite_tilde_class = class_new(gensym("tabwrite~"),
(t_newmethod)tabwrite_tilde_new, (t_method)tabwrite_tilde_free,
sizeof(t_tabwrite_tilde), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(tabwrite_tilde_class, t_tabwrite_tilde, x_f);
class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_set,
gensym("set"), A_SYMBOL, 0);
class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_stop,
gensym("stop"), 0);
class_addbang(tabwrite_tilde_class, tabwrite_tilde_bang);
class_addfloat(tabwrite_tilde_class, tabwrite_tilde_float);
}

View file

@ -0,0 +1,270 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *threshold_tilde_class;
typedef struct _threshold_tilde
{
t_object x_obj;
t_outlet *x_outlet1; /* bang out for high thresh */
t_outlet *x_outlet2; /* bang out for low thresh */
t_clock *x_clock; /* wakeup for message output */
float x_f; /* scalar inlet */
int x_state; /* 1 = high, 0 = low */
t_sample x_hithresh; /* value of high threshold */
t_sample x_lothresh; /* value of low threshold */
float x_deadwait; /* msec remaining in dead period */
float x_msecpertick; /* msec per DSP tick */
float x_hideadtime; /* hi dead time in msec */
float x_lodeadtime; /* lo dead time in msec */
} t_threshold_tilde;
static void threshold_tilde_tick(t_threshold_tilde *x);
static void threshold_tilde_set(t_threshold_tilde *x,
t_floatarg hithresh, t_floatarg hideadtime,
t_floatarg lothresh, t_floatarg lodeadtime);
static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh,
t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime)
{
t_threshold_tilde *x = (t_threshold_tilde *)
pd_new(threshold_tilde_class);
x->x_state = 0; /* low state */
x->x_deadwait = 0; /* no dead time */
x->x_clock = clock_new(x, (t_method)threshold_tilde_tick);
x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
x->x_outlet2 = outlet_new(&x->x_obj, &s_bang);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_msecpertick = 0.;
x->x_f = 0;
threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime);
return (x);
}
/* "set" message to specify thresholds and dead times */
static void threshold_tilde_set(t_threshold_tilde *x,
t_floatarg hithresh, t_floatarg hideadtime,
t_floatarg lothresh, t_floatarg lodeadtime)
{
if (lothresh > hithresh)
lothresh = hithresh;
x->x_hithresh = ftofix(hithresh);
x->x_hideadtime = hideadtime;
x->x_lothresh = ftofix(lothresh);
x->x_lodeadtime = lodeadtime;
}
/* number in inlet sets state -- note incompatible with JMAX which used
"int" message for this, impossible here because of auto signal conversion */
static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f)
{
x->x_state = (f != 0);
x->x_deadwait = 0;
}
static void threshold_tilde_tick(t_threshold_tilde *x)
{
if (x->x_state)
outlet_bang(x->x_outlet1);
else outlet_bang(x->x_outlet2);
}
static t_int *threshold_tilde_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_threshold_tilde *x = (t_threshold_tilde *)(w[2]);
int n = (t_int)(w[3]);
if (x->x_deadwait > 0)
x->x_deadwait -= x->x_msecpertick;
else if (x->x_state)
{
/* we're high; look for low sample */
for (; n--; in1++)
{
if (*in1 < x->x_lothresh)
{
clock_delay(x->x_clock, 0L);
x->x_state = 0;
x->x_deadwait = x->x_lodeadtime;
goto done;
}
}
}
else
{
/* we're low; look for high sample */
for (; n--; in1++)
{
if (*in1 >= x->x_hithresh)
{
clock_delay(x->x_clock, 0L);
x->x_state = 1;
x->x_deadwait = x->x_hideadtime;
goto done;
}
}
}
done:
return (w+4);
}
void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp)
{
x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr;
dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
}
static void threshold_tilde_ff(t_threshold_tilde *x)
{
clock_free(x->x_clock);
}
void threshold_tilde_setup( void)
{
threshold_tilde_class = class_new(gensym("threshold~"),
(t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff,
sizeof(t_threshold_tilde), 0,
A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f);
class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set,
gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp,
gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *threshold_tilde_class;
typedef struct _threshold_tilde
{
t_object x_obj;
t_outlet *x_outlet1; /* bang out for high thresh */
t_outlet *x_outlet2; /* bang out for low thresh */
t_clock *x_clock; /* wakeup for message output */
float x_f; /* scalar inlet */
int x_state; /* 1 = high, 0 = low */
t_sample x_hithresh; /* value of high threshold */
t_sample x_lothresh; /* value of low threshold */
float x_deadwait; /* msec remaining in dead period */
float x_msecpertick; /* msec per DSP tick */
float x_hideadtime; /* hi dead time in msec */
float x_lodeadtime; /* lo dead time in msec */
} t_threshold_tilde;
static void threshold_tilde_tick(t_threshold_tilde *x);
static void threshold_tilde_set(t_threshold_tilde *x,
t_floatarg hithresh, t_floatarg hideadtime,
t_floatarg lothresh, t_floatarg lodeadtime);
static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh,
t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime)
{
t_threshold_tilde *x = (t_threshold_tilde *)
pd_new(threshold_tilde_class);
x->x_state = 0; /* low state */
x->x_deadwait = 0; /* no dead time */
x->x_clock = clock_new(x, (t_method)threshold_tilde_tick);
x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
x->x_outlet2 = outlet_new(&x->x_obj, &s_bang);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
x->x_msecpertick = 0.;
x->x_f = 0;
threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime);
return (x);
}
/* "set" message to specify thresholds and dead times */
static void threshold_tilde_set(t_threshold_tilde *x,
t_floatarg hithresh, t_floatarg hideadtime,
t_floatarg lothresh, t_floatarg lodeadtime)
{
if (lothresh > hithresh)
lothresh = hithresh;
x->x_hithresh = ftofix(hithresh);
x->x_hideadtime = hideadtime;
x->x_lothresh = ftofix(lothresh);
x->x_lodeadtime = lodeadtime;
}
/* number in inlet sets state -- note incompatible with JMAX which used
"int" message for this, impossible here because of auto signal conversion */
static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f)
{
x->x_state = (f != 0);
x->x_deadwait = 0;
}
static void threshold_tilde_tick(t_threshold_tilde *x)
{
if (x->x_state)
outlet_bang(x->x_outlet1);
else outlet_bang(x->x_outlet2);
}
static t_int *threshold_tilde_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_threshold_tilde *x = (t_threshold_tilde *)(w[2]);
int n = (t_int)(w[3]);
if (x->x_deadwait > 0)
x->x_deadwait -= x->x_msecpertick;
else if (x->x_state)
{
/* we're high; look for low sample */
for (; n--; in1++)
{
if (*in1 < x->x_lothresh)
{
clock_delay(x->x_clock, 0L);
x->x_state = 0;
x->x_deadwait = x->x_lodeadtime;
goto done;
}
}
}
else
{
/* we're low; look for high sample */
for (; n--; in1++)
{
if (*in1 >= x->x_hithresh)
{
clock_delay(x->x_clock, 0L);
x->x_state = 1;
x->x_deadwait = x->x_hideadtime;
goto done;
}
}
}
done:
return (w+4);
}
void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp)
{
x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr;
dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
}
static void threshold_tilde_ff(t_threshold_tilde *x)
{
clock_free(x->x_clock);
}
void threshold_tilde_setup( void)
{
threshold_tilde_class = class_new(gensym("threshold~"),
(t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff,
sizeof(t_threshold_tilde), 0,
A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f);
class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set,
gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1,
gensym("ft1"), A_FLOAT, 0);
class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp,
gensym("dsp"), 0);
}

View file

@ -0,0 +1,238 @@
#include <m_pd.h>
#include <m_fixed.h>
#include "cos_table.h"
/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
/* GG: complex resonator with signal frequency control
this time using the bigger cos_table without interpolation
really have to switch to a separate fixpoint format sometime
*/
typedef struct vcfctl
{
t_sample c_re;
t_sample c_im;
t_sample c_q;
t_sample c_isr;
} t_vcfctl;
typedef struct sigvcf
{
t_object x_obj;
t_vcfctl x_cspace;
t_vcfctl *x_ctl;
float x_f;
} t_sigvcf;
t_class *sigvcf_class;
static void *sigvcf_new(t_floatarg q)
{
t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_ctl = &x->x_cspace;
x->x_cspace.c_re = 0;
x->x_cspace.c_im = 0;
x->x_cspace.c_q = ftofix(q);
x->x_cspace.c_isr = 0;
x->x_f = 0;
return (x);
}
static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
{
x->x_ctl->c_q = (f > 0 ? ftofix(f) : 0);
}
static t_int *sigvcf_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
t_sample *out1 = (t_sample *)(w[3]);
t_sample *out2 = (t_sample *)(w[4]);
t_vcfctl *c = (t_vcfctl *)(w[5]);
int n = (t_int)(w[6]);
int i;
t_sample re = c->c_re, re2;
t_sample im = c->c_im;
t_sample q = c->c_q;
t_sample qinv = (q > 0 ? idiv(ftofix(1.0),q) : 0);
t_sample ampcorrect = ftofix(2.0f) - idiv(ftofix(2.0f) , (q + ftofix(2.0f)));
t_sample isr = c->c_isr;
t_sample coefr, coefi;
t_sample *tab = cos_table;
t_sample oneminusr,cfindx,cf,r;
for (i = 0; i < n; i++)
{
cf = mult(*in2++,isr);
if (cf < 0) cf = 0;
cfindx = mult(cf,ftofix(0.15915494))>>(fix1-ILOGCOSTABSIZE); /* 1/2*PI */
r = (qinv > 0 ? ftofix(1.01) - mult(cf,qinv) : 0);
if (r < 0) r = 0;
oneminusr = ftofix(1.02f) - r; /* hand adapted */
/* r*cos(cf) */
coefr = mult(r,tab[cfindx]);
/* r*sin(cf) */
cfindx-=(ICOSTABSIZE>>2);
cfindx += cfindx < 0 ? ICOSTABSIZE:0;
coefi = mult(r,tab[cfindx]);
re2 = re;
*out1++ = re = mult(ampcorrect,mult(oneminusr,*in1++))
+ mult(coefr,re2) - mult(coefi, im);
*out2++ = im = mult(coefi,re2) + mult(coefr,im);
}
c->c_re = re;
c->c_im = im;
return (w+7);
}
static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
{
/* TODO sr is hardcoded */
x->x_ctl->c_isr = ftofix(0.0001424758);
// idiv(ftofix(6.28318),ftofix(sp[0]->s_sr));
post("%f",fixtof(x->x_ctl->c_isr));
dsp_add(sigvcf_perform, 6,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void vcf_tilde_setup(void)
{
sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0,
sizeof(t_sigvcf), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f);
class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0);
class_addmethod(sigvcf_class, (t_method)sigvcf_ft1,
gensym("ft1"), A_FLOAT, 0);
class_sethelpsymbol(sigvcf_class, gensym("lop~-help.pd"));
}
#include <m_pd.h>
#include <m_fixed.h>
#include "cos_table.h"
/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
/* GG: complex resonator with signal frequency control
this time using the bigger cos_table without interpolation
really have to switch to a separate fixpoint format sometime
*/
typedef struct vcfctl
{
t_sample c_re;
t_sample c_im;
t_sample c_q;
t_sample c_isr;
} t_vcfctl;
typedef struct sigvcf
{
t_object x_obj;
t_vcfctl x_cspace;
t_vcfctl *x_ctl;
float x_f;
} t_sigvcf;
t_class *sigvcf_class;
static void *sigvcf_new(t_floatarg q)
{
t_sigvcf *x = (t_sigvcf *)pd_new(sigvcf_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_ctl = &x->x_cspace;
x->x_cspace.c_re = 0;
x->x_cspace.c_im = 0;
x->x_cspace.c_q = ftofix(q);
x->x_cspace.c_isr = 0;
x->x_f = 0;
return (x);
}
static void sigvcf_ft1(t_sigvcf *x, t_floatarg f)
{
x->x_ctl->c_q = (f > 0 ? ftofix(f) : 0);
}
static t_int *sigvcf_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
t_sample *out1 = (t_sample *)(w[3]);
t_sample *out2 = (t_sample *)(w[4]);
t_vcfctl *c = (t_vcfctl *)(w[5]);
int n = (t_int)(w[6]);
int i;
t_sample re = c->c_re, re2;
t_sample im = c->c_im;
t_sample q = c->c_q;
t_sample qinv = (q > 0 ? idiv(ftofix(1.0),q) : 0);
t_sample ampcorrect = ftofix(2.0f) - idiv(ftofix(2.0f) , (q + ftofix(2.0f)));
t_sample isr = c->c_isr;
t_sample coefr, coefi;
t_sample *tab = cos_table;
t_sample oneminusr,cfindx,cf,r;
for (i = 0; i < n; i++)
{
cf = mult(*in2++,isr);
if (cf < 0) cf = 0;
cfindx = mult(cf,ftofix(0.15915494))>>(fix1-ILOGCOSTABSIZE); /* 1/2*PI */
r = (qinv > 0 ? ftofix(1.01) - mult(cf,qinv) : 0);
if (r < 0) r = 0;
oneminusr = ftofix(1.02f) - r; /* hand adapted */
/* r*cos(cf) */
coefr = mult(r,tab[cfindx]);
/* r*sin(cf) */
cfindx-=(ICOSTABSIZE>>2);
cfindx += cfindx < 0 ? ICOSTABSIZE:0;
coefi = mult(r,tab[cfindx]);
re2 = re;
*out1++ = re = mult(ampcorrect,mult(oneminusr,*in1++))
+ mult(coefr,re2) - mult(coefi, im);
*out2++ = im = mult(coefi,re2) + mult(coefr,im);
}
c->c_re = re;
c->c_im = im;
return (w+7);
}
static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
{
/* TODO sr is hardcoded */
x->x_ctl->c_isr = ftofix(0.0001424758);
// idiv(ftofix(6.28318),ftofix(sp[0]->s_sr));
post("%f",fixtof(x->x_ctl->c_isr));
dsp_add(sigvcf_perform, 6,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,
x->x_ctl, sp[0]->s_n);
}
void vcf_tilde_setup(void)
{
sigvcf_class = class_new(gensym("vcf~"), (t_newmethod)sigvcf_new, 0,
sizeof(t_sigvcf), 0, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigvcf_class, t_sigvcf, x_f);
class_addmethod(sigvcf_class, (t_method)sigvcf_dsp, gensym("dsp"), 0);
class_addmethod(sigvcf_class, (t_method)sigvcf_ft1,
gensym("ft1"), A_FLOAT, 0);
class_sethelpsymbol(sigvcf_class, gensym("lop~-help.pd"));
}

View file

@ -0,0 +1,184 @@
#include <m_pd.h>
#include <m_fixed.h>
#include "delay.h"
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
static t_class *sigvd_class;
typedef struct _sigvd
{
t_object x_obj;
t_symbol *x_sym;
t_sample x_sr; /* samples per msec */
int x_zerodel; /* 0 or vecsize depending on read/write order */
float x_f;
} t_sigvd;
static void *sigvd_new(t_symbol *s)
{
t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
if (!*s->s_name) s = gensym("vd~");
x->x_sym = s;
x->x_sr = 1;
x->x_zerodel = 0;
outlet_new(&x->x_obj, &s_signal);
x->x_f = 0;
return (x);
}
static t_int *sigvd_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_delwritectl *ctl = (t_delwritectl *)(w[3]);
t_sigvd *x = (t_sigvd *)(w[4]);
int n = (int)(w[5]);
int nsamps = ctl->c_n;
int fn = n;
t_sample limit = nsamps - n - 1;
t_sample *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
t_sample zerodel = x->x_zerodel;
while (n--)
{
t_time delsamps = ((long long) mult((*in++),ftofix(44.1)));//- itofix(zerodel);
int index = fixtoi(delsamps);
t_sample frac;
// post("%d: index %d f %lld",index,findex,*in);
frac = delsamps - itofix(index);
index+=fn;
if (index < 1 ) index += nsamps ;
if (index > limit) index-= nsamps;
bp = wp - index;
if (bp < vp + 2) bp += nsamps;
*out++ = bp[-1] + mult(frac,bp[-1]-bp[0]);
wp++;
}
return (w+6);
}
static void sigvd_dsp(t_sigvd *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
dsp_add(sigvd_perform, 5,
sp[0]->s_vec, sp[1]->s_vec,
&delwriter->x_cspace, x, sp[0]->s_n);
}
else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
}
void vd_tilde_setup(void)
{
sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
sizeof(t_sigvd), 0, A_DEFSYM, 0);
class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
}
#include <m_pd.h>
#include <m_fixed.h>
#include "delay.h"
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
static t_class *sigvd_class;
typedef struct _sigvd
{
t_object x_obj;
t_symbol *x_sym;
t_sample x_sr; /* samples per msec */
int x_zerodel; /* 0 or vecsize depending on read/write order */
float x_f;
} t_sigvd;
static void *sigvd_new(t_symbol *s)
{
t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
if (!*s->s_name) s = gensym("vd~");
x->x_sym = s;
x->x_sr = 1;
x->x_zerodel = 0;
outlet_new(&x->x_obj, &s_signal);
x->x_f = 0;
return (x);
}
static t_int *sigvd_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
t_delwritectl *ctl = (t_delwritectl *)(w[3]);
t_sigvd *x = (t_sigvd *)(w[4]);
int n = (int)(w[5]);
int nsamps = ctl->c_n;
int fn = n;
t_sample limit = nsamps - n - 1;
t_sample *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
t_sample zerodel = x->x_zerodel;
while (n--)
{
t_time delsamps = ((long long) mult((*in++),ftofix(44.1)));//- itofix(zerodel);
int index = fixtoi(delsamps);
t_sample frac;
// post("%d: index %d f %lld",index,findex,*in);
frac = delsamps - itofix(index);
index+=fn;
if (index < 1 ) index += nsamps ;
if (index > limit) index-= nsamps;
bp = wp - index;
if (bp < vp + 2) bp += nsamps;
*out++ = bp[-1] + mult(frac,bp[-1]-bp[0]);
wp++;
}
return (w+6);
}
static void sigvd_dsp(t_sigvd *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
dsp_add(sigvd_perform, 5,
sp[0]->s_vec, sp[1]->s_vec,
&delwriter->x_cspace, x, sp[0]->s_n);
}
else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
}
void vd_tilde_setup(void)
{
sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
sizeof(t_sigvd), 0, A_DEFSYM, 0);
class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
}

View file

@ -0,0 +1,368 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *vline_tilde_class;
typedef struct _vseg
{
t_time s_targettime;
t_time s_starttime;
t_sample s_target;
struct _vseg *s_next;
} t_vseg;
typedef struct _vline
{
t_object x_obj;
t_sample x_value;
t_sample x_inc;
t_time x_referencetime;
t_time x_samppermsec;
t_time x_msecpersamp;
t_time x_targettime;
t_sample x_target;
float x_inlet1;
float x_inlet2;
t_vseg *x_list;
} t_vline;
static t_int *vline_tilde_perform(t_int *w)
{
t_vline *x = (t_vline *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]), i;
t_sample f = x->x_value;
t_sample inc = x->x_inc;
t_time msecpersamp = x->x_msecpersamp;
t_time samppermsec = x->x_samppermsec;
t_time timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp;
t_vseg *s = x->x_list;
for (i = 0; i < n; i++)
{
t_time timenext = timenow + msecpersamp;
checknext:
if (s)
{
/* has starttime elapsed? If so update value and increment */
if (s->s_starttime < timenext)
{
if (x->x_targettime <= timenext)
f = x->x_target, inc = 0;
/* if zero-length segment bash output value */
if (s->s_targettime <= s->s_starttime)
{
f = s->s_target;
inc = 0;
}
else
{
t_time incpermsec = div((s->s_target - f),
(s->s_targettime - s->s_starttime));
f = mult(f + incpermsec,(timenext - s->s_starttime));
inc = mult(incpermsec,msecpersamp);
}
x->x_inc = inc;
x->x_target = s->s_target;
x->x_targettime = s->s_targettime;
x->x_list = s->s_next;
t_freebytes(s, sizeof(*s));
s = x->x_list;
goto checknext;
}
}
if (x->x_targettime <= timenext)
f = x->x_target, inc = 0;
*out++ = f;
f = f + inc;
timenow = timenext;
}
x->x_value = f;
return (w+4);
}
static void vline_tilde_stop(t_vline *x)
{
t_vseg *s1, *s2;
for (s1 = x->x_list; s1; s1 = s2)
s2 = s1->s_next, t_freebytes(s1, sizeof(*s1));
x->x_list = 0;
x->x_inc = 0;
x->x_inlet1 = x->x_inlet2 = 0;
}
static void vline_tilde_float(t_vline *x, t_float f)
{
t_time timenow = clock_gettimesince(x->x_referencetime);
t_sample inlet1 = (x->x_inlet1 < 0 ? 0 : (t_sample)x->x_inlet1);
t_sample inlet2 = (t_sample) x->x_inlet2;
t_time starttime = timenow + inlet2;
t_vseg *s1, *s2, *deletefrom = 0,
*snew = (t_vseg *)t_getbytes(sizeof(*snew));
if (PD_BADFLOAT(f))
f = 0;
/* negative delay input means stop and jump immediately to new value */
if (inlet2 < 0)
{
vline_tilde_stop(x);
x->x_value = ftofix(f);
return;
}
/* check if we supplant the first item in the list. We supplant
an item by having an earlier starttime, or an equal starttime unless
the equal one was instantaneous and the new one isn't (in which case
we'll do a jump-and-slide starting at that time.) */
if (!x->x_list || x->x_list->s_starttime > starttime ||
(x->x_list->s_starttime == starttime &&
(x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0)))
{
deletefrom = x->x_list;
x->x_list = snew;
}
else
{
for (s1 = x->x_list; s2 = s1->s_next; s1 = s2)
{
if (s2->s_starttime > starttime ||
(s2->s_starttime == starttime &&
(s2->s_targettime > s2->s_starttime || inlet1 <= 0)))
{
deletefrom = s2;
s1->s_next = snew;
goto didit;
}
}
s1->s_next = snew;
deletefrom = 0;
didit: ;
}
while (deletefrom)
{
s1 = deletefrom->s_next;
t_freebytes(deletefrom, sizeof(*deletefrom));
deletefrom = s1;
}
snew->s_next = 0;
snew->s_target = f;
snew->s_starttime = starttime;
snew->s_targettime = starttime + inlet1;
x->x_inlet1 = x->x_inlet2 = 0;
}
static void vline_tilde_dsp(t_vline *x, t_signal **sp)
{
dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
x->x_samppermsec = idiv(ftofix(sp[0]->s_sr),ftofix(1000));
x->x_msecpersamp = idiv(ftofix(1000),ftofix(sp[0]->s_sr));
}
static void *vline_tilde_new(void)
{
t_vline *x = (t_vline *)pd_new(vline_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
floatinlet_new(&x->x_obj, &x->x_inlet1);
floatinlet_new(&x->x_obj, &x->x_inlet2);
x->x_inlet1 = x->x_inlet2 = 0;
x->x_value = x->x_inc = 0;
x->x_referencetime = clock_getlogicaltime();
x->x_list = 0;
x->x_samppermsec = 0;
return (x);
}
void vline_tilde_setup(void)
{
vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new,
(t_method)vline_tilde_stop, sizeof(t_vline), 0, 0);
class_addfloat(vline_tilde_class, (t_method)vline_tilde_float);
class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop,
gensym("stop"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *vline_tilde_class;
typedef struct _vseg
{
t_time s_targettime;
t_time s_starttime;
t_sample s_target;
struct _vseg *s_next;
} t_vseg;
typedef struct _vline
{
t_object x_obj;
t_sample x_value;
t_sample x_inc;
t_time x_referencetime;
t_time x_samppermsec;
t_time x_msecpersamp;
t_time x_targettime;
t_sample x_target;
float x_inlet1;
float x_inlet2;
t_vseg *x_list;
} t_vline;
static t_int *vline_tilde_perform(t_int *w)
{
t_vline *x = (t_vline *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]), i;
t_sample f = x->x_value;
t_sample inc = x->x_inc;
t_time msecpersamp = x->x_msecpersamp;
t_time samppermsec = x->x_samppermsec;
t_time timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp;
t_vseg *s = x->x_list;
for (i = 0; i < n; i++)
{
t_time timenext = timenow + msecpersamp;
checknext:
if (s)
{
/* has starttime elapsed? If so update value and increment */
if (s->s_starttime < timenext)
{
if (x->x_targettime <= timenext)
f = x->x_target, inc = 0;
/* if zero-length segment bash output value */
if (s->s_targettime <= s->s_starttime)
{
f = s->s_target;
inc = 0;
}
else
{
t_time incpermsec = div((s->s_target - f),
(s->s_targettime - s->s_starttime));
f = mult(f + incpermsec,(timenext - s->s_starttime));
inc = mult(incpermsec,msecpersamp);
}
x->x_inc = inc;
x->x_target = s->s_target;
x->x_targettime = s->s_targettime;
x->x_list = s->s_next;
t_freebytes(s, sizeof(*s));
s = x->x_list;
goto checknext;
}
}
if (x->x_targettime <= timenext)
f = x->x_target, inc = 0;
*out++ = f;
f = f + inc;
timenow = timenext;
}
x->x_value = f;
return (w+4);
}
static void vline_tilde_stop(t_vline *x)
{
t_vseg *s1, *s2;
for (s1 = x->x_list; s1; s1 = s2)
s2 = s1->s_next, t_freebytes(s1, sizeof(*s1));
x->x_list = 0;
x->x_inc = 0;
x->x_inlet1 = x->x_inlet2 = 0;
}
static void vline_tilde_float(t_vline *x, t_float f)
{
t_time timenow = clock_gettimesince(x->x_referencetime);
t_sample inlet1 = (x->x_inlet1 < 0 ? 0 : (t_sample)x->x_inlet1);
t_sample inlet2 = (t_sample) x->x_inlet2;
t_time starttime = timenow + inlet2;
t_vseg *s1, *s2, *deletefrom = 0,
*snew = (t_vseg *)t_getbytes(sizeof(*snew));
if (PD_BADFLOAT(f))
f = 0;
/* negative delay input means stop and jump immediately to new value */
if (inlet2 < 0)
{
vline_tilde_stop(x);
x->x_value = ftofix(f);
return;
}
/* check if we supplant the first item in the list. We supplant
an item by having an earlier starttime, or an equal starttime unless
the equal one was instantaneous and the new one isn't (in which case
we'll do a jump-and-slide starting at that time.) */
if (!x->x_list || x->x_list->s_starttime > starttime ||
(x->x_list->s_starttime == starttime &&
(x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0)))
{
deletefrom = x->x_list;
x->x_list = snew;
}
else
{
for (s1 = x->x_list; s2 = s1->s_next; s1 = s2)
{
if (s2->s_starttime > starttime ||
(s2->s_starttime == starttime &&
(s2->s_targettime > s2->s_starttime || inlet1 <= 0)))
{
deletefrom = s2;
s1->s_next = snew;
goto didit;
}
}
s1->s_next = snew;
deletefrom = 0;
didit: ;
}
while (deletefrom)
{
s1 = deletefrom->s_next;
t_freebytes(deletefrom, sizeof(*deletefrom));
deletefrom = s1;
}
snew->s_next = 0;
snew->s_target = f;
snew->s_starttime = starttime;
snew->s_targettime = starttime + inlet1;
x->x_inlet1 = x->x_inlet2 = 0;
}
static void vline_tilde_dsp(t_vline *x, t_signal **sp)
{
dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
x->x_samppermsec = idiv(ftofix(sp[0]->s_sr),ftofix(1000));
x->x_msecpersamp = idiv(ftofix(1000),ftofix(sp[0]->s_sr));
}
static void *vline_tilde_new(void)
{
t_vline *x = (t_vline *)pd_new(vline_tilde_class);
outlet_new(&x->x_obj, gensym("signal"));
floatinlet_new(&x->x_obj, &x->x_inlet1);
floatinlet_new(&x->x_obj, &x->x_inlet2);
x->x_inlet1 = x->x_inlet2 = 0;
x->x_value = x->x_inc = 0;
x->x_referencetime = clock_getlogicaltime();
x->x_list = 0;
x->x_samppermsec = 0;
return (x);
}
void vline_tilde_setup(void)
{
vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new,
(t_method)vline_tilde_stop, sizeof(t_vline), 0, 0);
class_addfloat(vline_tilde_class, (t_method)vline_tilde_float);
class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp,
gensym("dsp"), 0);
class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop,
gensym("stop"), 0);
}

View file

@ -0,0 +1,176 @@
#include <m_pd.h>
#include <m_fixed.h>
static t_class *vsnapshot_tilde_class;
typedef struct _vsnapshot
{
t_object x_obj;
int x_n;
int x_gotone;
t_sample *x_vec;
float x_f;
float x_sampspermsec;
double x_time;
} t_vsnapshot;
static void *vsnapshot_tilde_new(void)
{
t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class);
outlet_new(&x->x_obj, &s_float);
x->x_f = 0;
x->x_n = 0;
x->x_vec = 0;
x->x_gotone = 0;
return (x);
}
static t_int *vsnapshot_tilde_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_vsnapshot *x = (t_vsnapshot *)(w[2]);
t_sample *out = x->x_vec;
int n = x->x_n, i;
for (i = 0; i < n; i++)
out[i] = in[i];
x->x_time = clock_getlogicaltime();
x->x_gotone = 1;
return (w+3);
}
static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp)
{
int n = sp[0]->s_n;
if (n != x->x_n)
{
if (x->x_vec)
t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample));
x->x_gotone = 0;
x->x_n = n;
}
x->x_sampspermsec = sp[0]->s_sr / 1000;
dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x);
}
static void vsnapshot_tilde_bang(t_vsnapshot *x)
{
float val;
if (x->x_gotone)
{
int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec;
if (indx < 0)
indx = 0;
else if (indx >= x->x_n)
indx = x->x_n - 1;
val = x->x_vec[indx];
}
else val = 0;
outlet_float(x->x_obj.ob_outlet, val);
}
static void vsnapshot_tilde_ff(t_vsnapshot *x)
{
if (x->x_vec)
t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
}
void vsnapshot_tilde_setup(void)
{
vsnapshot_tilde_class = class_new(gensym("vsnapshot~"),
vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff,
sizeof(t_vsnapshot), 0, 0);
CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f);
class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0);
class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang);
}
#include <m_pd.h>
#include <m_fixed.h>
static t_class *vsnapshot_tilde_class;
typedef struct _vsnapshot
{
t_object x_obj;
int x_n;
int x_gotone;
t_sample *x_vec;
float x_f;
float x_sampspermsec;
double x_time;
} t_vsnapshot;
static void *vsnapshot_tilde_new(void)
{
t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class);
outlet_new(&x->x_obj, &s_float);
x->x_f = 0;
x->x_n = 0;
x->x_vec = 0;
x->x_gotone = 0;
return (x);
}
static t_int *vsnapshot_tilde_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_vsnapshot *x = (t_vsnapshot *)(w[2]);
t_sample *out = x->x_vec;
int n = x->x_n, i;
for (i = 0; i < n; i++)
out[i] = in[i];
x->x_time = clock_getlogicaltime();
x->x_gotone = 1;
return (w+3);
}
static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp)
{
int n = sp[0]->s_n;
if (n != x->x_n)
{
if (x->x_vec)
t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample));
x->x_gotone = 0;
x->x_n = n;
}
x->x_sampspermsec = sp[0]->s_sr / 1000;
dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x);
}
static void vsnapshot_tilde_bang(t_vsnapshot *x)
{
float val;
if (x->x_gotone)
{
int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec;
if (indx < 0)
indx = 0;
else if (indx >= x->x_n)
indx = x->x_n - 1;
val = x->x_vec[indx];
}
else val = 0;
outlet_float(x->x_obj.ob_outlet, val);
}
static void vsnapshot_tilde_ff(t_vsnapshot *x)
{
if (x->x_vec)
t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
}
void vsnapshot_tilde_setup(void)
{
vsnapshot_tilde_class = class_new(gensym("vsnapshot~"),
vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff,
sizeof(t_vsnapshot), 0, 0);
CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f);
class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0);
class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang);
}

View file

@ -0,0 +1,104 @@
#include <m_pd.h>
#include <m_fixed.h>
typedef struct wrap
{
t_object x_obj;
float x_f;
} t_sigwrap;
t_class *sigwrap_class;
static void *sigwrap_new(void)
{
t_sigwrap *x = (t_sigwrap *)pd_new(sigwrap_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigwrap_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2);
t_int n = *(t_int *)(w+3);
while (n--)
{
t_sample f = *in++;
#ifndef FIXEDPOINT
int k = f;
if (f > 0) *out++ = f-k;
else *out++ = f - (k-1);
#else
int k = ftofix(1.) - 1;
*out = f&k;
#endif
}
return (w + 4);
}
static void sigwrap_dsp(t_sigwrap *x, t_signal **sp)
{
dsp_add(sigwrap_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void wrap_tilde_setup(void)
{
sigwrap_class = class_new(gensym("wrap~"), (t_newmethod)sigwrap_new, 0,
sizeof(t_sigwrap), 0, 0);
CLASS_MAINSIGNALIN(sigwrap_class, t_sigwrap, x_f);
class_addmethod(sigwrap_class, (t_method)sigwrap_dsp, gensym("dsp"), 0);
}
#include <m_pd.h>
#include <m_fixed.h>
typedef struct wrap
{
t_object x_obj;
float x_f;
} t_sigwrap;
t_class *sigwrap_class;
static void *sigwrap_new(void)
{
t_sigwrap *x = (t_sigwrap *)pd_new(sigwrap_class);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigwrap_perform(t_int *w)
{
t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2);
t_int n = *(t_int *)(w+3);
while (n--)
{
t_sample f = *in++;
#ifndef FIXEDPOINT
int k = f;
if (f > 0) *out++ = f-k;
else *out++ = f - (k-1);
#else
int k = ftofix(1.) - 1;
*out = f&k;
#endif
}
return (w + 4);
}
static void sigwrap_dsp(t_sigwrap *x, t_signal **sp)
{
dsp_add(sigwrap_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void wrap_tilde_setup(void)
{
sigwrap_class = class_new(gensym("wrap~"), (t_newmethod)sigwrap_new, 0,
sizeof(t_sigwrap), 0, 0);
CLASS_MAINSIGNALIN(sigwrap_class, t_sigwrap, x_f);
class_addmethod(sigwrap_class, (t_method)sigwrap_dsp, gensym("dsp"), 0);
}

View file

@ -0,0 +1,10 @@
# The compiler for iPod has a bug with -O6, thats why we try to compile twice
make CFLAGS="-O6 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi " -k ipod
make CFLAGS="-O2 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi" ipod
# The compiler for iPod has a bug with -O6, thats why we try to compile twice
make CFLAGS="-O6 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi " -k ipod
make CFLAGS="-O2 -ffast-math -fexpensive-optimizations -mcpu=arm7tdmi" ipod

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,368 @@
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* The dac~ and adc~ routines.
*/
#include "m_pd.h"
#include "s_stuff.h"
/* ----------------------------- dac~ --------------------------- */
static t_class *dac_class;
typedef struct _dac
{
t_object x_obj;
t_int x_n;
t_int *x_vec;
float x_f;
} t_dac;
static void *dac_new(t_symbol *s, int argc, t_atom *argv)
{
t_dac *x = (t_dac *)pd_new(dac_class);
t_atom defarg[2], *ap;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETFLOAT(&defarg[0], 1);
SETFLOAT(&defarg[1], 2);
}
x->x_n = argc;
x->x_vec = (t_int *)getbytes(argc * sizeof(*x->x_vec));
for (i = 0; i < argc; i++)
x->x_vec[i] = atom_getintarg(i, argc, argv);
for (i = 1; i < argc; i++)
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->x_f = 0;
return (x);
}
static void dac_dsp(t_dac *x, t_signal **sp)
{
t_int i, *ip;
t_signal **sp2;
for (i = x->x_n, ip = x->x_vec, sp2 = sp; i--; ip++, sp2++)
{
int ch = *ip - 1;
if ((*sp2)->s_n != DEFDACBLKSIZE)
error("dac~: bad vector size");
else if (ch >= 0 && ch < sys_get_outchannels())
dsp_add(plus_perform, 4, sys_soundout + DEFDACBLKSIZE*ch,
(*sp2)->s_vec, sys_soundout + DEFDACBLKSIZE*ch, DEFDACBLKSIZE);
}
}
static void dac_free(t_dac *x)
{
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
}
static void dac_setup(void)
{
dac_class = class_new(gensym("dac~"), (t_newmethod)dac_new,
(t_method)dac_free, sizeof(t_dac), 0, A_GIMME, 0);
CLASS_MAINSIGNALIN(dac_class, t_dac, x_f);
class_addmethod(dac_class, (t_method)dac_dsp, gensym("dsp"), A_CANT, 0);
class_sethelpsymbol(dac_class, gensym("adc~_dac~"));
}
/* ----------------------------- adc~ --------------------------- */
static t_class *adc_class;
typedef struct _adc
{
t_object x_obj;
t_int x_n;
t_int *x_vec;
} t_adc;
static void *adc_new(t_symbol *s, int argc, t_atom *argv)
{
t_adc *x = (t_adc *)pd_new(adc_class);
t_atom defarg[2], *ap;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETFLOAT(&defarg[0], 1);
SETFLOAT(&defarg[1], 2);
}
x->x_n = argc;
x->x_vec = (t_int *)getbytes(argc * sizeof(*x->x_vec));
for (i = 0; i < argc; i++)
x->x_vec[i] = atom_getintarg(i, argc, argv);
for (i = 0; i < argc; i++)
outlet_new(&x->x_obj, &s_signal);
return (x);
}
t_int *copy_perform(t_int *w)
{
t_float *in1 = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
int n = (int)(w[3]);
while (n--) *out++ = *in1++;
return (w+4);
}
t_int *copy_perf8(t_int *w)
{
t_float *in1 = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
int n = (int)(w[3]);
for (; n; n -= 8, in1 += 8, out += 8)
{
float f0 = in1[0];
float f1 = in1[1];
float f2 = in1[2];
float f3 = in1[3];
float f4 = in1[4];
float f5 = in1[5];
float f6 = in1[6];
float f7 = in1[7];
out[0] = f0;
out[1] = f1;
out[2] = f2;
out[3] = f3;
out[4] = f4;
out[5] = f5;
out[6] = f6;
out[7] = f7;
}
return (w+4);
}
void dsp_add_copy(t_sample *in, t_sample *out, int n)
{
if (n&7)
dsp_add(copy_perform, 3, in, out, n);
else
dsp_add(copy_perf8, 3, in, out, n);
}
static void adc_dsp(t_adc *x, t_signal **sp)
{
t_int i, *ip;
t_signal **sp2;
for (i = x->x_n, ip = x->x_vec, sp2 = sp; i--; ip++, sp2++)
{
int ch = *ip - 1;
if ((*sp2)->s_n != DEFDACBLKSIZE)
error("adc~: bad vector size");
else if (ch >= 0 && ch < sys_get_inchannels())
dsp_add_copy(sys_soundin + DEFDACBLKSIZE*ch,
(*sp2)->s_vec, DEFDACBLKSIZE);
else dsp_add_zero((*sp2)->s_vec, DEFDACBLKSIZE);
}
}
static void adc_free(t_adc *x)
{
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
}
static void adc_setup(void)
{
adc_class = class_new(gensym("adc~"), (t_newmethod)adc_new,
(t_method)adc_free, sizeof(t_adc), 0, A_GIMME, 0);
class_addmethod(adc_class, (t_method)adc_dsp, gensym("dsp"), A_CANT, 0);
class_sethelpsymbol(adc_class, gensym("adc~_dac~"));
}
void d_dac_setup(void)
{
dac_setup();
adc_setup();
}
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* The dac~ and adc~ routines.
*/
#include "m_pd.h"
#include "s_stuff.h"
/* ----------------------------- dac~ --------------------------- */
static t_class *dac_class;
typedef struct _dac
{
t_object x_obj;
t_int x_n;
t_int *x_vec;
float x_f;
} t_dac;
static void *dac_new(t_symbol *s, int argc, t_atom *argv)
{
t_dac *x = (t_dac *)pd_new(dac_class);
t_atom defarg[2], *ap;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETFLOAT(&defarg[0], 1);
SETFLOAT(&defarg[1], 2);
}
x->x_n = argc;
x->x_vec = (t_int *)getbytes(argc * sizeof(*x->x_vec));
for (i = 0; i < argc; i++)
x->x_vec[i] = atom_getintarg(i, argc, argv);
for (i = 1; i < argc; i++)
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->x_f = 0;
return (x);
}
static void dac_dsp(t_dac *x, t_signal **sp)
{
t_int i, *ip;
t_signal **sp2;
for (i = x->x_n, ip = x->x_vec, sp2 = sp; i--; ip++, sp2++)
{
int ch = *ip - 1;
if ((*sp2)->s_n != DEFDACBLKSIZE)
error("dac~: bad vector size");
else if (ch >= 0 && ch < sys_get_outchannels())
dsp_add(plus_perform, 4, sys_soundout + DEFDACBLKSIZE*ch,
(*sp2)->s_vec, sys_soundout + DEFDACBLKSIZE*ch, DEFDACBLKSIZE);
}
}
static void dac_free(t_dac *x)
{
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
}
static void dac_setup(void)
{
dac_class = class_new(gensym("dac~"), (t_newmethod)dac_new,
(t_method)dac_free, sizeof(t_dac), 0, A_GIMME, 0);
CLASS_MAINSIGNALIN(dac_class, t_dac, x_f);
class_addmethod(dac_class, (t_method)dac_dsp, gensym("dsp"), A_CANT, 0);
class_sethelpsymbol(dac_class, gensym("adc~_dac~"));
}
/* ----------------------------- adc~ --------------------------- */
static t_class *adc_class;
typedef struct _adc
{
t_object x_obj;
t_int x_n;
t_int *x_vec;
} t_adc;
static void *adc_new(t_symbol *s, int argc, t_atom *argv)
{
t_adc *x = (t_adc *)pd_new(adc_class);
t_atom defarg[2], *ap;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETFLOAT(&defarg[0], 1);
SETFLOAT(&defarg[1], 2);
}
x->x_n = argc;
x->x_vec = (t_int *)getbytes(argc * sizeof(*x->x_vec));
for (i = 0; i < argc; i++)
x->x_vec[i] = atom_getintarg(i, argc, argv);
for (i = 0; i < argc; i++)
outlet_new(&x->x_obj, &s_signal);
return (x);
}
t_int *copy_perform(t_int *w)
{
t_float *in1 = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
int n = (int)(w[3]);
while (n--) *out++ = *in1++;
return (w+4);
}
t_int *copy_perf8(t_int *w)
{
t_float *in1 = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
int n = (int)(w[3]);
for (; n; n -= 8, in1 += 8, out += 8)
{
float f0 = in1[0];
float f1 = in1[1];
float f2 = in1[2];
float f3 = in1[3];
float f4 = in1[4];
float f5 = in1[5];
float f6 = in1[6];
float f7 = in1[7];
out[0] = f0;
out[1] = f1;
out[2] = f2;
out[3] = f3;
out[4] = f4;
out[5] = f5;
out[6] = f6;
out[7] = f7;
}
return (w+4);
}
void dsp_add_copy(t_sample *in, t_sample *out, int n)
{
if (n&7)
dsp_add(copy_perform, 3, in, out, n);
else
dsp_add(copy_perf8, 3, in, out, n);
}
static void adc_dsp(t_adc *x, t_signal **sp)
{
t_int i, *ip;
t_signal **sp2;
for (i = x->x_n, ip = x->x_vec, sp2 = sp; i--; ip++, sp2++)
{
int ch = *ip - 1;
if ((*sp2)->s_n != DEFDACBLKSIZE)
error("adc~: bad vector size");
else if (ch >= 0 && ch < sys_get_inchannels())
dsp_add_copy(sys_soundin + DEFDACBLKSIZE*ch,
(*sp2)->s_vec, DEFDACBLKSIZE);
else dsp_add_zero((*sp2)->s_vec, DEFDACBLKSIZE);
}
}
static void adc_free(t_adc *x)
{
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
}
static void adc_setup(void)
{
adc_class = class_new(gensym("adc~"), (t_newmethod)adc_new,
(t_method)adc_free, sizeof(t_adc), 0, A_GIMME, 0);
class_addmethod(adc_class, (t_method)adc_dsp, gensym("dsp"), A_CANT, 0);
class_sethelpsymbol(adc_class, gensym("adc~_dac~"));
}
void d_dac_setup(void)
{
dac_setup();
adc_setup();
}

View file

@ -0,0 +1,638 @@
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* send~, delread~, throw~, catch~ */
#include "m_pd.h"
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
/* ----------------------------- delwrite~ ----------------------------- */
static t_class *sigdelwrite_class;
typedef struct delwritectl
{
int c_n;
float *c_vec;
int c_phase;
} t_delwritectl;
typedef struct _sigdelwrite
{
t_object x_obj;
t_symbol *x_sym;
t_delwritectl x_cspace;
int x_sortno; /* DSP sort number at which this was last put on chain */
int x_rsortno; /* DSP sort # for first delread or write in chain */
int x_vecsize; /* vector size for delread~ to use */
float x_f;
} t_sigdelwrite;
#define XTRASAMPS 4
#define SAMPBLK 4
/* routine to check that all delwrites/delreads/vds have same vecsize */
static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
{
/*
LATER this should really check sample rate and blocking, once that is
supported. Probably we don't actually care about vecsize.
For now just suppress this check... */
#if 0
if (x->x_rsortno != ugen_getsortno())
{
x->x_vecsize = vecsize;
x->x_rsortno = ugen_getsortno();
}
else if (vecsize != x->x_vecsize)
pd_error(x, "delread/delwrite/vd vector size mismatch");
#endif
}
static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
{
int nsamps;
t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
if (!*s->s_name) s = gensym("delwrite~");
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
nsamps = msec * sys_getsr() * (float)(0.001f);
if (nsamps < 1) nsamps = 1;
nsamps += ((- nsamps) & (SAMPBLK - 1));
nsamps += DEFDELVS;
x->x_cspace.c_n = nsamps;
x->x_cspace.c_vec =
(float *)getbytes((nsamps + XTRASAMPS) * sizeof(float));
x->x_cspace.c_phase = XTRASAMPS;
x->x_sortno = 0;
x->x_vecsize = 0;
x->x_f = 0;
return (x);
}
static t_int *sigdelwrite_perform(t_int *w)
{
t_float *in = (t_float *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int n = (int)(w[3]);
int phase = c->c_phase, nsamps = c->c_n;
float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
phase += n;
while (n--)
{
float f = *in++;
if (PD_BIGORSMALL(f))
f = 0;
*bp++ = f;
if (bp == ep)
{
vp[0] = ep[-4];
vp[1] = ep[-3];
vp[2] = ep[-2];
vp[3] = ep[-1];
bp = vp + XTRASAMPS;
phase -= nsamps;
}
}
c->c_phase = phase;
return (w+4);
}
static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
{
dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
x->x_sortno = ugen_getsortno();
sigdelwrite_checkvecsize(x, sp[0]->s_n);
}
static void sigdelwrite_free(t_sigdelwrite *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_cspace.c_vec,
(x->x_cspace.c_n + XTRASAMPS) * sizeof(float));
}
static void sigdelwrite_setup(void)
{
sigdelwrite_class = class_new(gensym("delwrite~"),
(t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
gensym("dsp"), 0);
}
/* ----------------------------- delread~ ----------------------------- */
static t_class *sigdelread_class;
typedef struct _sigdelread
{
t_object x_obj;
t_symbol *x_sym;
t_float x_deltime; /* delay in msec */
int x_delsamps; /* delay in samples */
t_float x_sr; /* samples per msec */
t_float x_n; /* vector size */
int x_zerodel; /* 0 or vecsize depending on read/write order */
} t_sigdelread;
static void sigdelread_float(t_sigdelread *x, t_float f);
static void *sigdelread_new(t_symbol *s, t_floatarg f)
{
t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
x->x_sym = s;
x->x_sr = 1;
x->x_n = 1;
x->x_zerodel = 0;
sigdelread_float(x, f);
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static void sigdelread_float(t_sigdelread *x, t_float f)
{
int samps;
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_deltime = f;
if (delwriter)
{
int delsize = delwriter->x_cspace.c_n;
x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
+ x->x_n - x->x_zerodel;
if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
}
}
static t_int *sigdelread_perform(t_int *w)
{
t_float *out = (t_float *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int delsamps = *(int *)(w[3]);
int n = (int)(w[4]);
int phase = c->c_phase - delsamps, nsamps = c->c_n;
float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
if (phase < 0) phase += nsamps;
bp = vp + phase;
while (n--)
{
*out++ = *bp++;
if (bp == ep) bp -= nsamps;
}
return (w+5);
}
static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
x->x_n = sp[0]->s_n;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
sigdelread_float(x, x->x_deltime);
dsp_add(sigdelread_perform, 4,
sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
}
else if (*x->x_sym->s_name)
error("delread~: %s: no such delwrite~",x->x_sym->s_name);
}
static void sigdelread_setup(void)
{
sigdelread_class = class_new(gensym("delread~"),
(t_newmethod)sigdelread_new, 0,
sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
gensym("dsp"), 0);
class_addfloat(sigdelread_class, (t_method)sigdelread_float);
}
/* ----------------------------- vd~ ----------------------------- */
static t_class *sigvd_class;
typedef struct _sigvd
{
t_object x_obj;
t_symbol *x_sym;
t_float x_sr; /* samples per msec */
int x_zerodel; /* 0 or vecsize depending on read/write order */
float x_f;
} t_sigvd;
static void *sigvd_new(t_symbol *s)
{
t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
if (!*s->s_name) s = gensym("vd~");
x->x_sym = s;
x->x_sr = 1;
x->x_zerodel = 0;
outlet_new(&x->x_obj, &s_signal);
x->x_f = 0;
return (x);
}
static t_int *sigvd_perform(t_int *w)
{
t_float *in = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
t_delwritectl *ctl = (t_delwritectl *)(w[3]);
t_sigvd *x = (t_sigvd *)(w[4]);
int n = (int)(w[5]);
int nsamps = ctl->c_n;
float limit = nsamps - n - 1;
float fn = n-1;
float *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
float zerodel = x->x_zerodel;
while (n--)
{
float delsamps = x->x_sr * *in++ - zerodel, frac;
int idelsamps;
float a, b, c, d, cminusb;
if (delsamps < 1.00001f) delsamps = 1.00001f;
if (delsamps > limit) delsamps = limit;
delsamps += fn;
fn = fn - 1.0f;
idelsamps = delsamps;
frac = delsamps - (float)idelsamps;
bp = wp - idelsamps;
if (bp < vp + 4) bp += nsamps;
d = bp[-3];
c = bp[-2];
b = bp[-1];
a = bp[0];
cminusb = c-b;
*out++ = b + frac * (
cminusb - 0.1666667f * (1.-frac) * (
(d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
)
);
}
return (w+6);
}
static void sigvd_dsp(t_sigvd *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
dsp_add(sigvd_perform, 5,
sp[0]->s_vec, sp[1]->s_vec,
&delwriter->x_cspace, x, sp[0]->s_n);
}
else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
}
static void sigvd_setup(void)
{
sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
sizeof(t_sigvd), 0, A_DEFSYM, 0);
class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
}
/* ----------------------- global setup routine ---------------- */
void d_delay_setup(void)
{
sigdelwrite_setup();
sigdelread_setup();
sigvd_setup();
}
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* send~, delread~, throw~, catch~ */
#include "m_pd.h"
extern int ugen_getsortno(void);
#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
/* ----------------------------- delwrite~ ----------------------------- */
static t_class *sigdelwrite_class;
typedef struct delwritectl
{
int c_n;
float *c_vec;
int c_phase;
} t_delwritectl;
typedef struct _sigdelwrite
{
t_object x_obj;
t_symbol *x_sym;
t_delwritectl x_cspace;
int x_sortno; /* DSP sort number at which this was last put on chain */
int x_rsortno; /* DSP sort # for first delread or write in chain */
int x_vecsize; /* vector size for delread~ to use */
float x_f;
} t_sigdelwrite;
#define XTRASAMPS 4
#define SAMPBLK 4
/* routine to check that all delwrites/delreads/vds have same vecsize */
static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
{
/*
LATER this should really check sample rate and blocking, once that is
supported. Probably we don't actually care about vecsize.
For now just suppress this check... */
#if 0
if (x->x_rsortno != ugen_getsortno())
{
x->x_vecsize = vecsize;
x->x_rsortno = ugen_getsortno();
}
else if (vecsize != x->x_vecsize)
pd_error(x, "delread/delwrite/vd vector size mismatch");
#endif
}
static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
{
int nsamps;
t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
if (!*s->s_name) s = gensym("delwrite~");
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
nsamps = msec * sys_getsr() * (float)(0.001f);
if (nsamps < 1) nsamps = 1;
nsamps += ((- nsamps) & (SAMPBLK - 1));
nsamps += DEFDELVS;
x->x_cspace.c_n = nsamps;
x->x_cspace.c_vec =
(float *)getbytes((nsamps + XTRASAMPS) * sizeof(float));
x->x_cspace.c_phase = XTRASAMPS;
x->x_sortno = 0;
x->x_vecsize = 0;
x->x_f = 0;
return (x);
}
static t_int *sigdelwrite_perform(t_int *w)
{
t_float *in = (t_float *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int n = (int)(w[3]);
int phase = c->c_phase, nsamps = c->c_n;
float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
phase += n;
while (n--)
{
float f = *in++;
if (PD_BIGORSMALL(f))
f = 0;
*bp++ = f;
if (bp == ep)
{
vp[0] = ep[-4];
vp[1] = ep[-3];
vp[2] = ep[-2];
vp[3] = ep[-1];
bp = vp + XTRASAMPS;
phase -= nsamps;
}
}
c->c_phase = phase;
return (w+4);
}
static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
{
dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
x->x_sortno = ugen_getsortno();
sigdelwrite_checkvecsize(x, sp[0]->s_n);
}
static void sigdelwrite_free(t_sigdelwrite *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_cspace.c_vec,
(x->x_cspace.c_n + XTRASAMPS) * sizeof(float));
}
static void sigdelwrite_setup(void)
{
sigdelwrite_class = class_new(gensym("delwrite~"),
(t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
gensym("dsp"), 0);
}
/* ----------------------------- delread~ ----------------------------- */
static t_class *sigdelread_class;
typedef struct _sigdelread
{
t_object x_obj;
t_symbol *x_sym;
t_float x_deltime; /* delay in msec */
int x_delsamps; /* delay in samples */
t_float x_sr; /* samples per msec */
t_float x_n; /* vector size */
int x_zerodel; /* 0 or vecsize depending on read/write order */
} t_sigdelread;
static void sigdelread_float(t_sigdelread *x, t_float f);
static void *sigdelread_new(t_symbol *s, t_floatarg f)
{
t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
x->x_sym = s;
x->x_sr = 1;
x->x_n = 1;
x->x_zerodel = 0;
sigdelread_float(x, f);
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static void sigdelread_float(t_sigdelread *x, t_float f)
{
int samps;
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_deltime = f;
if (delwriter)
{
int delsize = delwriter->x_cspace.c_n;
x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
+ x->x_n - x->x_zerodel;
if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
}
}
static t_int *sigdelread_perform(t_int *w)
{
t_float *out = (t_float *)(w[1]);
t_delwritectl *c = (t_delwritectl *)(w[2]);
int delsamps = *(int *)(w[3]);
int n = (int)(w[4]);
int phase = c->c_phase - delsamps, nsamps = c->c_n;
float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
if (phase < 0) phase += nsamps;
bp = vp + phase;
while (n--)
{
*out++ = *bp++;
if (bp == ep) bp -= nsamps;
}
return (w+5);
}
static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
x->x_n = sp[0]->s_n;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
sigdelread_float(x, x->x_deltime);
dsp_add(sigdelread_perform, 4,
sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
}
else if (*x->x_sym->s_name)
error("delread~: %s: no such delwrite~",x->x_sym->s_name);
}
static void sigdelread_setup(void)
{
sigdelread_class = class_new(gensym("delread~"),
(t_newmethod)sigdelread_new, 0,
sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
gensym("dsp"), 0);
class_addfloat(sigdelread_class, (t_method)sigdelread_float);
}
/* ----------------------------- vd~ ----------------------------- */
static t_class *sigvd_class;
typedef struct _sigvd
{
t_object x_obj;
t_symbol *x_sym;
t_float x_sr; /* samples per msec */
int x_zerodel; /* 0 or vecsize depending on read/write order */
float x_f;
} t_sigvd;
static void *sigvd_new(t_symbol *s)
{
t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
if (!*s->s_name) s = gensym("vd~");
x->x_sym = s;
x->x_sr = 1;
x->x_zerodel = 0;
outlet_new(&x->x_obj, &s_signal);
x->x_f = 0;
return (x);
}
static t_int *sigvd_perform(t_int *w)
{
t_float *in = (t_float *)(w[1]);
t_float *out = (t_float *)(w[2]);
t_delwritectl *ctl = (t_delwritectl *)(w[3]);
t_sigvd *x = (t_sigvd *)(w[4]);
int n = (int)(w[5]);
int nsamps = ctl->c_n;
float limit = nsamps - n - 1;
float fn = n-1;
float *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
float zerodel = x->x_zerodel;
while (n--)
{
float delsamps = x->x_sr * *in++ - zerodel, frac;
int idelsamps;
float a, b, c, d, cminusb;
if (delsamps < 1.00001f) delsamps = 1.00001f;
if (delsamps > limit) delsamps = limit;
delsamps += fn;
fn = fn - 1.0f;
idelsamps = delsamps;
frac = delsamps - (float)idelsamps;
bp = wp - idelsamps;
if (bp < vp + 4) bp += nsamps;
d = bp[-3];
c = bp[-2];
b = bp[-1];
a = bp[0];
cminusb = c-b;
*out++ = b + frac * (
cminusb - 0.1666667f * (1.-frac) * (
(d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
)
);
}
return (w+6);
}
static void sigvd_dsp(t_sigvd *x, t_signal **sp)
{
t_sigdelwrite *delwriter =
(t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
x->x_sr = sp[0]->s_sr * 0.001;
if (delwriter)
{
sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
0 : delwriter->x_vecsize);
dsp_add(sigvd_perform, 5,
sp[0]->s_vec, sp[1]->s_vec,
&delwriter->x_cspace, x, sp[0]->s_n);
}
else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
}
static void sigvd_setup(void)
{
sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
sizeof(t_sigvd), 0, A_DEFSYM, 0);
class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
}
/* ----------------------- global setup routine ---------------- */
void d_delay_setup(void)
{
sigdelwrite_setup();
sigdelread_setup();
sigvd_setup();
}

View file

@ -0,0 +1,688 @@
/* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include "m_pd.h"
/* ------------------------ fft~ and ifft~ -------------------------------- */
static t_class *sigfft_class, *sigifft_class;
typedef struct fft
{
t_object x_obj;
float x_f;
} t_sigfft;
static void *sigfft_new(void)
{
t_sigfft *x = (t_sigfft *)pd_new(sigfft_class);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->x_f = 0;
return (x);
}
static void *sigifft_new(void)
{
t_sigfft *x = (t_sigfft *)pd_new(sigifft_class);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->x_f = 0;
return (x);
}
static t_int *sigfft_swap(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
int n = w[3];
for (;n--; in1++, in2++)
{
float f = *in1;
*in1 = *in2;
*in2 = f;
}
return (w+4);
}
static t_int *sigfft_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
int n = w[3];
mayer_fft(n, in1, in2);
return (w+4);
}
static t_int *sigifft_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
int n = w[3];
mayer_ifft(n, in1, in2);
return (w+4);
}
static void sigfft_dspx(t_sigfft *x, t_signal **sp, t_int *(*f)(t_int *w))
{
int n = sp[0]->s_n;
t_sample *in1 = sp[0]->s_vec;
t_sample *in2 = sp[1]->s_vec;
t_sample *out1 = sp[2]->s_vec;
t_sample *out2 = sp[3]->s_vec;
if (out1 == in2 && out2 == in1)
dsp_add(sigfft_swap, 3, out1, out2, n);
else if (out1 == in2)
{
dsp_add(copy_perform, 3, in2, out2, n);
dsp_add(copy_perform, 3, in1, out1, n);
}
else
{
if (out1 != in1) dsp_add(copy_perform, 3, in1, out1, n);
if (out2 != in2) dsp_add(copy_perform, 3, in2, out2, n);
}
dsp_add(f, 3, sp[2]->s_vec, sp[3]->s_vec, n);
}
static void sigfft_dsp(t_sigfft *x, t_signal **sp)
{
sigfft_dspx(x, sp, sigfft_perform);
}
static void sigifft_dsp(t_sigfft *x, t_signal **sp)
{
sigfft_dspx(x, sp, sigifft_perform);
}
static void sigfft_setup(void)
{
sigfft_class = class_new(gensym("fft~"), sigfft_new, 0,
sizeof(t_sigfft), 0, 0);
CLASS_MAINSIGNALIN(sigfft_class, t_sigfft, x_f);
class_addmethod(sigfft_class, (t_method)sigfft_dsp, gensym("dsp"), 0);
sigifft_class = class_new(gensym("ifft~"), sigifft_new, 0,
sizeof(t_sigfft), 0, 0);
CLASS_MAINSIGNALIN(sigifft_class, t_sigfft, x_f);
class_addmethod(sigifft_class, (t_method)sigifft_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigifft_class, gensym("fft~"));
}
/* ----------------------- rfft~ -------------------------------- */
static t_class *sigrfft_class;
typedef struct rfft
{
t_object x_obj;
float x_f;
} t_sigrfft;
static void *sigrfft_new(void)
{
t_sigrfft *x = (t_sigrfft *)pd_new(sigrfft_class);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigrfft_flip(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = w[3];
while (n--) *(--out) = *in++;
*(--out) = 0; /* to hell with it */
return (w+4);
}
static t_int *sigrfft_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
int n = w[2];
mayer_realfft(n, in);
return (w+3);
}
static void sigrfft_dsp(t_sigrfft *x, t_signal **sp)
{
int n = sp[0]->s_n, n2 = (n>>1);
t_sample *in1 = sp[0]->s_vec;
t_sample *out1 = sp[1]->s_vec;
t_sample *out2 = sp[2]->s_vec;
if (n < 4)
{
error("fft: minimum 4 points");
return;
}
if (in1 == out2) /* this probably never happens */
{
dsp_add(sigrfft_perform, 2, out2, n);
dsp_add(copy_perform, 3, out2, out1, n2);
dsp_add(sigrfft_flip, 3, out2 + (n2+1), out2 + n2, n2-1);
}
else
{
if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n);
dsp_add(sigrfft_perform, 2, out1, n);
dsp_add(sigrfft_flip, 3, out1 + (n2+1), out2 + n2, n2-1);
}
dsp_add_zero(out1 + n2, n2);
dsp_add_zero(out2 + n2, n2);
}
static void sigrfft_setup(void)
{
sigrfft_class = class_new(gensym("rfft~"), sigrfft_new, 0,
sizeof(t_sigrfft), 0, 0);
CLASS_MAINSIGNALIN(sigrfft_class, t_sigrfft, x_f);
class_addmethod(sigrfft_class, (t_method)sigrfft_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigrfft_class, gensym("fft~"));
}
/* ----------------------- rifft~ -------------------------------- */
static t_class *sigrifft_class;
typedef struct rifft
{
t_object x_obj;
float x_f;
} t_sigrifft;
static void *sigrifft_new(void)
{
t_sigrifft *x = (t_sigrifft *)pd_new(sigrifft_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigrifft_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
int n = w[2];
mayer_realifft(n, in);
return (w+3);
}
static void sigrifft_dsp(t_sigrifft *x, t_signal **sp)
{
int n = sp[0]->s_n, n2 = (n>>1);
t_sample *in1 = sp[0]->s_vec;
t_sample *in2 = sp[1]->s_vec;
t_sample *out1 = sp[2]->s_vec;
if (n < 4)
{
error("fft: minimum 4 points");
return;
}
if (in2 == out1)
{
dsp_add(sigrfft_flip, 3, out1+1, out1 + n, (n2-1));
dsp_add(copy_perform, 3, in1, out1, n2);
}
else
{
if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n2);
dsp_add(sigrfft_flip, 3, in2+1, out1 + n, n2-1);
}
dsp_add(sigrifft_perform, 2, out1, n);
}
static void sigrifft_setup(void)
{
sigrifft_class = class_new(gensym("rifft~"), sigrifft_new, 0,
sizeof(t_sigrifft), 0, 0);
CLASS_MAINSIGNALIN(sigrifft_class, t_sigrifft, x_f);
class_addmethod(sigrifft_class, (t_method)sigrifft_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigrifft_class, gensym("fft~"));
}
/* ----------------------- framp~ -------------------------------- */
#if 0
static t_class *sigframp_class;
typedef struct framp
{
t_object x_obj;
float x_f;
} t_sigframp;
static void *sigframp_new(void)
{
t_sigframp *x = (t_sigframp *)pd_new(sigframp_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigframp_perform(t_int *w)
{
float *inreal = (t_float *)(w[1]);
float *inimag = (t_float *)(w[2]);
float *outfreq = (t_float *)(w[3]);
float *outamp = (t_float *)(w[4]);
float lastreal = 0, currentreal = inreal[0], nextreal = inreal[1];
float lastimag = 0, currentimag = inimag[0], nextimag = inimag[1];
int n = w[5];
int m = n + 1;
float fbin = 1, oneovern2 = 1.f/((float)n * (float)n);
inreal += 2;
inimag += 2;
*outamp++ = *outfreq++ = 0;
n -= 2;
while (n--)
{
float re, im, pow, freq;
lastreal = currentreal;
currentreal = nextreal;
nextreal = *inreal++;
lastimag = currentimag;
currentimag = nextimag;
nextimag = *inimag++;
re = currentreal - 0.5f * (lastreal + nextreal);
im = currentimag - 0.5f * (lastimag + nextimag);
pow = re * re + im * im;
if (pow > 1e-19)
{
float detune = ((lastreal - nextreal) * re +
(lastimag - nextimag) * im) / (2.0f * pow);
if (detune > 2 || detune < -2) freq = pow = 0;
else freq = fbin + detune;
}
else freq = pow = 0;
*outfreq++ = freq;
*outamp++ = oneovern2 * pow;
fbin += 1.0f;
}
while (m--) *outamp++ = *outfreq++ = 0;
return (w+6);
}
t_int *sigsqrt_perform(t_int *w);
static void sigframp_dsp(t_sigframp *x, t_signal **sp)
{
int n = sp[0]->s_n, n2 = (n>>1);
if (n < 4)
{
error("framp: minimum 4 points");
return;
}
dsp_add(sigframp_perform, 5, sp[0]->s_vec, sp[1]->s_vec,
sp[2]->s_vec, sp[3]->s_vec, n2);
dsp_add(sigsqrt_perform, 3, sp[3]->s_vec, sp[3]->s_vec, n2);
}
static void sigframp_setup(void)
{
sigframp_class = class_new(gensym("framp~"), sigframp_new, 0,
sizeof(t_sigframp), 0, 0);
CLASS_MAINSIGNALIN(sigframp_class, t_sigframp, x_f);
class_addmethod(sigframp_class, (t_method)sigframp_dsp, gensym("dsp"), 0);
}
#endif
/* ------------------------ global setup routine ------------------------- */
void d_fft_setup(void)
{
sigfft_setup();
sigrfft_setup();
sigrifft_setup();
// sigframp_setup();
}
/* Copyright (c) 1997-1999 Miller Puckette and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include "m_pd.h"
/* ------------------------ fft~ and ifft~ -------------------------------- */
static t_class *sigfft_class, *sigifft_class;
typedef struct fft
{
t_object x_obj;
float x_f;
} t_sigfft;
static void *sigfft_new(void)
{
t_sigfft *x = (t_sigfft *)pd_new(sigfft_class);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->x_f = 0;
return (x);
}
static void *sigifft_new(void)
{
t_sigfft *x = (t_sigfft *)pd_new(sigifft_class);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
x->x_f = 0;
return (x);
}
static t_int *sigfft_swap(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
int n = w[3];
for (;n--; in1++, in2++)
{
float f = *in1;
*in1 = *in2;
*in2 = f;
}
return (w+4);
}
static t_int *sigfft_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
int n = w[3];
mayer_fft(n, in1, in2);
return (w+4);
}
static t_int *sigifft_perform(t_int *w)
{
t_sample *in1 = (t_sample *)(w[1]);
t_sample *in2 = (t_sample *)(w[2]);
int n = w[3];
mayer_ifft(n, in1, in2);
return (w+4);
}
static void sigfft_dspx(t_sigfft *x, t_signal **sp, t_int *(*f)(t_int *w))
{
int n = sp[0]->s_n;
t_sample *in1 = sp[0]->s_vec;
t_sample *in2 = sp[1]->s_vec;
t_sample *out1 = sp[2]->s_vec;
t_sample *out2 = sp[3]->s_vec;
if (out1 == in2 && out2 == in1)
dsp_add(sigfft_swap, 3, out1, out2, n);
else if (out1 == in2)
{
dsp_add(copy_perform, 3, in2, out2, n);
dsp_add(copy_perform, 3, in1, out1, n);
}
else
{
if (out1 != in1) dsp_add(copy_perform, 3, in1, out1, n);
if (out2 != in2) dsp_add(copy_perform, 3, in2, out2, n);
}
dsp_add(f, 3, sp[2]->s_vec, sp[3]->s_vec, n);
}
static void sigfft_dsp(t_sigfft *x, t_signal **sp)
{
sigfft_dspx(x, sp, sigfft_perform);
}
static void sigifft_dsp(t_sigfft *x, t_signal **sp)
{
sigfft_dspx(x, sp, sigifft_perform);
}
static void sigfft_setup(void)
{
sigfft_class = class_new(gensym("fft~"), sigfft_new, 0,
sizeof(t_sigfft), 0, 0);
CLASS_MAINSIGNALIN(sigfft_class, t_sigfft, x_f);
class_addmethod(sigfft_class, (t_method)sigfft_dsp, gensym("dsp"), 0);
sigifft_class = class_new(gensym("ifft~"), sigifft_new, 0,
sizeof(t_sigfft), 0, 0);
CLASS_MAINSIGNALIN(sigifft_class, t_sigfft, x_f);
class_addmethod(sigifft_class, (t_method)sigifft_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigifft_class, gensym("fft~"));
}
/* ----------------------- rfft~ -------------------------------- */
static t_class *sigrfft_class;
typedef struct rfft
{
t_object x_obj;
float x_f;
} t_sigrfft;
static void *sigrfft_new(void)
{
t_sigrfft *x = (t_sigrfft *)pd_new(sigrfft_class);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigrfft_flip(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = w[3];
while (n--) *(--out) = *in++;
*(--out) = 0; /* to hell with it */
return (w+4);
}
static t_int *sigrfft_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
int n = w[2];
mayer_realfft(n, in);
return (w+3);
}
static void sigrfft_dsp(t_sigrfft *x, t_signal **sp)
{
int n = sp[0]->s_n, n2 = (n>>1);
t_sample *in1 = sp[0]->s_vec;
t_sample *out1 = sp[1]->s_vec;
t_sample *out2 = sp[2]->s_vec;
if (n < 4)
{
error("fft: minimum 4 points");
return;
}
if (in1 == out2) /* this probably never happens */
{
dsp_add(sigrfft_perform, 2, out2, n);
dsp_add(copy_perform, 3, out2, out1, n2);
dsp_add(sigrfft_flip, 3, out2 + (n2+1), out2 + n2, n2-1);
}
else
{
if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n);
dsp_add(sigrfft_perform, 2, out1, n);
dsp_add(sigrfft_flip, 3, out1 + (n2+1), out2 + n2, n2-1);
}
dsp_add_zero(out1 + n2, n2);
dsp_add_zero(out2 + n2, n2);
}
static void sigrfft_setup(void)
{
sigrfft_class = class_new(gensym("rfft~"), sigrfft_new, 0,
sizeof(t_sigrfft), 0, 0);
CLASS_MAINSIGNALIN(sigrfft_class, t_sigrfft, x_f);
class_addmethod(sigrfft_class, (t_method)sigrfft_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigrfft_class, gensym("fft~"));
}
/* ----------------------- rifft~ -------------------------------- */
static t_class *sigrifft_class;
typedef struct rifft
{
t_object x_obj;
float x_f;
} t_sigrifft;
static void *sigrifft_new(void)
{
t_sigrifft *x = (t_sigrifft *)pd_new(sigrifft_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigrifft_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
int n = w[2];
mayer_realifft(n, in);
return (w+3);
}
static void sigrifft_dsp(t_sigrifft *x, t_signal **sp)
{
int n = sp[0]->s_n, n2 = (n>>1);
t_sample *in1 = sp[0]->s_vec;
t_sample *in2 = sp[1]->s_vec;
t_sample *out1 = sp[2]->s_vec;
if (n < 4)
{
error("fft: minimum 4 points");
return;
}
if (in2 == out1)
{
dsp_add(sigrfft_flip, 3, out1+1, out1 + n, (n2-1));
dsp_add(copy_perform, 3, in1, out1, n2);
}
else
{
if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n2);
dsp_add(sigrfft_flip, 3, in2+1, out1 + n, n2-1);
}
dsp_add(sigrifft_perform, 2, out1, n);
}
static void sigrifft_setup(void)
{
sigrifft_class = class_new(gensym("rifft~"), sigrifft_new, 0,
sizeof(t_sigrifft), 0, 0);
CLASS_MAINSIGNALIN(sigrifft_class, t_sigrifft, x_f);
class_addmethod(sigrifft_class, (t_method)sigrifft_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigrifft_class, gensym("fft~"));
}
/* ----------------------- framp~ -------------------------------- */
#if 0
static t_class *sigframp_class;
typedef struct framp
{
t_object x_obj;
float x_f;
} t_sigframp;
static void *sigframp_new(void)
{
t_sigframp *x = (t_sigframp *)pd_new(sigframp_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->x_f = 0;
return (x);
}
static t_int *sigframp_perform(t_int *w)
{
float *inreal = (t_float *)(w[1]);
float *inimag = (t_float *)(w[2]);
float *outfreq = (t_float *)(w[3]);
float *outamp = (t_float *)(w[4]);
float lastreal = 0, currentreal = inreal[0], nextreal = inreal[1];
float lastimag = 0, currentimag = inimag[0], nextimag = inimag[1];
int n = w[5];
int m = n + 1;
float fbin = 1, oneovern2 = 1.f/((float)n * (float)n);
inreal += 2;
inimag += 2;
*outamp++ = *outfreq++ = 0;
n -= 2;
while (n--)
{
float re, im, pow, freq;
lastreal = currentreal;
currentreal = nextreal;
nextreal = *inreal++;
lastimag = currentimag;
currentimag = nextimag;
nextimag = *inimag++;
re = currentreal - 0.5f * (lastreal + nextreal);
im = currentimag - 0.5f * (lastimag + nextimag);
pow = re * re + im * im;
if (pow > 1e-19)
{
float detune = ((lastreal - nextreal) * re +
(lastimag - nextimag) * im) / (2.0f * pow);
if (detune > 2 || detune < -2) freq = pow = 0;
else freq = fbin + detune;
}
else freq = pow = 0;
*outfreq++ = freq;
*outamp++ = oneovern2 * pow;
fbin += 1.0f;
}
while (m--) *outamp++ = *outfreq++ = 0;
return (w+6);
}
t_int *sigsqrt_perform(t_int *w);
static void sigframp_dsp(t_sigframp *x, t_signal **sp)
{
int n = sp[0]->s_n, n2 = (n>>1);
if (n < 4)
{
error("framp: minimum 4 points");
return;
}
dsp_add(sigframp_perform, 5, sp[0]->s_vec, sp[1]->s_vec,
sp[2]->s_vec, sp[3]->s_vec, n2);
dsp_add(sigsqrt_perform, 3, sp[3]->s_vec, sp[3]->s_vec, n2);
}
static void sigframp_setup(void)
{
sigframp_class = class_new(gensym("framp~"), sigframp_new, 0,
sizeof(t_sigframp), 0, 0);
CLASS_MAINSIGNALIN(sigframp_class, t_sigframp, x_f);
class_addmethod(sigframp_class, (t_method)sigframp_dsp, gensym("dsp"), 0);
}
#endif
/* ------------------------ global setup routine ------------------------- */
void d_fft_setup(void)
{
sigfft_setup();
sigrfft_setup();
sigrifft_setup();
// sigframp_setup();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,616 @@
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* send~, receive~, throw~, catch~ */
#include "m_pd.h"
#include <string.h>
#define DEFSENDVS 64 /* LATER get send to get this from canvas */
/* ----------------------------- send~ ----------------------------- */
static t_class *sigsend_class;
typedef struct _sigsend
{
t_object x_obj;
t_symbol *x_sym;
int x_n;
t_sample *x_vec;
float x_f;
} t_sigsend;
static void *sigsend_new(t_symbol *s)
{
t_sigsend *x = (t_sigsend *)pd_new(sigsend_class);
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
x->x_n = DEFSENDVS;
x->x_vec = (t_sample *)getbytes(DEFSENDVS * sizeof(t_sample));
memset((char *)(x->x_vec), 0, DEFSENDVS * sizeof(t_sample));
x->x_f = 0;
return (x);
}
static t_int *sigsend_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
while (n--)
{
*out = (PD_BIGORSMALL(*in) ? 0 : *in);
out++;
in++;
}
return (w+4);
}
static void sigsend_dsp(t_sigsend *x, t_signal **sp)
{
if (x->x_n == sp[0]->s_n)
dsp_add(sigsend_perform, 3, sp[0]->s_vec, x->x_vec, sp[0]->s_n);
else error("sigsend %s: unexpected vector size", x->x_sym->s_name);
}
static void sigsend_free(t_sigsend *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_vec, x->x_n * sizeof(float));
}
static void sigsend_setup(void)
{
sigsend_class = class_new(gensym("send~"), (t_newmethod)sigsend_new,
(t_method)sigsend_free, sizeof(t_sigsend), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)sigsend_new, gensym("s~"), A_DEFSYM, 0);
CLASS_MAINSIGNALIN(sigsend_class, t_sigsend, x_f);
class_addmethod(sigsend_class, (t_method)sigsend_dsp, gensym("dsp"), 0);
}
/* ----------------------------- receive~ ----------------------------- */
static t_class *sigreceive_class;
typedef struct _sigreceive
{
t_object x_obj;
t_symbol *x_sym;
t_sample *x_wherefrom;
int x_n;
} t_sigreceive;
static void *sigreceive_new(t_symbol *s)
{
t_sigreceive *x = (t_sigreceive *)pd_new(sigreceive_class);
x->x_n = DEFSENDVS; /* LATER find our vector size correctly */
x->x_sym = s;
x->x_wherefrom = 0;
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static t_int *sigreceive_perform(t_int *w)
{
t_sigreceive *x = (t_sigreceive *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample *in = x->x_wherefrom;
if (in)
{
while (n--)
*out++ = *in++;
}
else
{
while (n--)
*out++ = 0;
}
return (w+4);
}
static void sigreceive_set(t_sigreceive *x, t_symbol *s)
{
t_sigsend *sender = (t_sigsend *)pd_findbyclass((x->x_sym = s),
sigsend_class);
if (sender)
{
if (sender->x_n == x->x_n)
x->x_wherefrom = sender->x_vec;
else
{
pd_error(x, "receive~ %s: vector size mismatch", x->x_sym->s_name);
x->x_wherefrom = 0;
}
}
else
{
pd_error(x, "receive~ %s: no matching send", x->x_sym->s_name);
x->x_wherefrom = 0;
}
}
static void sigreceive_dsp(t_sigreceive *x, t_signal **sp)
{
if (sp[0]->s_n != x->x_n)
{
pd_error(x, "receive~ %s: vector size mismatch", x->x_sym->s_name);
}
else
{
sigreceive_set(x, x->x_sym);
dsp_add(sigreceive_perform, 3,
x, sp[0]->s_vec, sp[0]->s_n);
}
}
static void sigreceive_setup(void)
{
sigreceive_class = class_new(gensym("receive~"),
(t_newmethod)sigreceive_new, 0,
sizeof(t_sigreceive), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)sigreceive_new, gensym("r~"), A_DEFSYM, 0);
class_addmethod(sigreceive_class, (t_method)sigreceive_set, gensym("set"),
A_SYMBOL, 0);
class_addmethod(sigreceive_class, (t_method)sigreceive_dsp, gensym("dsp"),
0);
class_sethelpsymbol(sigreceive_class, gensym("send~"));
}
/* ----------------------------- catch~ ----------------------------- */
static t_class *sigcatch_class;
typedef struct _sigcatch
{
t_object x_obj;
t_symbol *x_sym;
int x_n;
t_sample *x_vec;
} t_sigcatch;
static void *sigcatch_new(t_symbol *s)
{
t_sigcatch *x = (t_sigcatch *)pd_new(sigcatch_class);
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
x->x_n = DEFSENDVS;
x->x_vec = (t_sample *)getbytes(DEFSENDVS * sizeof(t_sample));
memset((char *)(x->x_vec), 0, DEFSENDVS * sizeof(t_sample));
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static t_int *sigcatch_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
while (n--) *out++ = *in, *in++ = 0;
return (w+4);
}
static void sigcatch_dsp(t_sigcatch *x, t_signal **sp)
{
if (x->x_n == sp[0]->s_n)
dsp_add(sigcatch_perform, 3, x->x_vec, sp[0]->s_vec, sp[0]->s_n);
else error("sigcatch %s: unexpected vector size", x->x_sym->s_name);
}
static void sigcatch_free(t_sigcatch *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_vec, x->x_n * sizeof(float));
}
static void sigcatch_setup(void)
{
sigcatch_class = class_new(gensym("catch~"), (t_newmethod)sigcatch_new,
(t_method)sigcatch_free, sizeof(t_sigcatch), CLASS_NOINLET, A_DEFSYM, 0);
class_addmethod(sigcatch_class, (t_method)sigcatch_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigcatch_class, gensym("throw~"));
}
/* ----------------------------- throw~ ----------------------------- */
static t_class *sigthrow_class;
typedef struct _sigthrow
{
t_object x_obj;
t_symbol *x_sym;
t_sample *x_whereto;
int x_n;
t_float x_f;
} t_sigthrow;
static void *sigthrow_new(t_symbol *s)
{
t_sigthrow *x = (t_sigthrow *)pd_new(sigthrow_class);
x->x_sym = s;
x->x_whereto = 0;
x->x_n = DEFSENDVS;
x->x_f = 0;
return (x);
}
static t_int *sigthrow_perform(t_int *w)
{
t_sigthrow *x = (t_sigthrow *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample *out = x->x_whereto;
if (out)
{
while (n--)
{
*out += (PD_BIGORSMALL(*in) ? 0 : *in);
out++;
in++;
}
}
return (w+4);
}
static void sigthrow_set(t_sigthrow *x, t_symbol *s)
{
t_sigcatch *catcher = (t_sigcatch *)pd_findbyclass((x->x_sym = s),
sigcatch_class);
if (catcher)
{
if (catcher->x_n == x->x_n)
x->x_whereto = catcher->x_vec;
else
{
pd_error(x, "throw~ %s: vector size mismatch", x->x_sym->s_name);
x->x_whereto = 0;
}
}
else
{
pd_error(x, "throw~ %s: no matching catch", x->x_sym->s_name);
x->x_whereto = 0;
}
}
static void sigthrow_dsp(t_sigthrow *x, t_signal **sp)
{
if (sp[0]->s_n != x->x_n)
{
pd_error(x, "throw~ %s: vector size mismatch", x->x_sym->s_name);
}
else
{
sigthrow_set(x, x->x_sym);
dsp_add(sigthrow_perform, 3,
x, sp[0]->s_vec, sp[0]->s_n);
}
}
static void sigthrow_setup(void)
{
sigthrow_class = class_new(gensym("throw~"), (t_newmethod)sigthrow_new, 0,
sizeof(t_sigthrow), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)sigthrow_new, gensym("r~"), A_DEFSYM, 0);
class_addmethod(sigthrow_class, (t_method)sigthrow_set, gensym("set"),
A_SYMBOL, 0);
CLASS_MAINSIGNALIN(sigthrow_class, t_sigthrow, x_f);
class_addmethod(sigthrow_class, (t_method)sigthrow_dsp, gensym("dsp"), 0);
}
/* ----------------------- global setup routine ---------------- */
void d_global_setup(void)
{
sigsend_setup();
sigreceive_setup();
sigcatch_setup();
sigthrow_setup();
}
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* send~, receive~, throw~, catch~ */
#include "m_pd.h"
#include <string.h>
#define DEFSENDVS 64 /* LATER get send to get this from canvas */
/* ----------------------------- send~ ----------------------------- */
static t_class *sigsend_class;
typedef struct _sigsend
{
t_object x_obj;
t_symbol *x_sym;
int x_n;
t_sample *x_vec;
float x_f;
} t_sigsend;
static void *sigsend_new(t_symbol *s)
{
t_sigsend *x = (t_sigsend *)pd_new(sigsend_class);
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
x->x_n = DEFSENDVS;
x->x_vec = (t_sample *)getbytes(DEFSENDVS * sizeof(t_sample));
memset((char *)(x->x_vec), 0, DEFSENDVS * sizeof(t_sample));
x->x_f = 0;
return (x);
}
static t_int *sigsend_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
while (n--)
{
*out = (PD_BIGORSMALL(*in) ? 0 : *in);
out++;
in++;
}
return (w+4);
}
static void sigsend_dsp(t_sigsend *x, t_signal **sp)
{
if (x->x_n == sp[0]->s_n)
dsp_add(sigsend_perform, 3, sp[0]->s_vec, x->x_vec, sp[0]->s_n);
else error("sigsend %s: unexpected vector size", x->x_sym->s_name);
}
static void sigsend_free(t_sigsend *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_vec, x->x_n * sizeof(float));
}
static void sigsend_setup(void)
{
sigsend_class = class_new(gensym("send~"), (t_newmethod)sigsend_new,
(t_method)sigsend_free, sizeof(t_sigsend), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)sigsend_new, gensym("s~"), A_DEFSYM, 0);
CLASS_MAINSIGNALIN(sigsend_class, t_sigsend, x_f);
class_addmethod(sigsend_class, (t_method)sigsend_dsp, gensym("dsp"), 0);
}
/* ----------------------------- receive~ ----------------------------- */
static t_class *sigreceive_class;
typedef struct _sigreceive
{
t_object x_obj;
t_symbol *x_sym;
t_sample *x_wherefrom;
int x_n;
} t_sigreceive;
static void *sigreceive_new(t_symbol *s)
{
t_sigreceive *x = (t_sigreceive *)pd_new(sigreceive_class);
x->x_n = DEFSENDVS; /* LATER find our vector size correctly */
x->x_sym = s;
x->x_wherefrom = 0;
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static t_int *sigreceive_perform(t_int *w)
{
t_sigreceive *x = (t_sigreceive *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample *in = x->x_wherefrom;
if (in)
{
while (n--)
*out++ = *in++;
}
else
{
while (n--)
*out++ = 0;
}
return (w+4);
}
static void sigreceive_set(t_sigreceive *x, t_symbol *s)
{
t_sigsend *sender = (t_sigsend *)pd_findbyclass((x->x_sym = s),
sigsend_class);
if (sender)
{
if (sender->x_n == x->x_n)
x->x_wherefrom = sender->x_vec;
else
{
pd_error(x, "receive~ %s: vector size mismatch", x->x_sym->s_name);
x->x_wherefrom = 0;
}
}
else
{
pd_error(x, "receive~ %s: no matching send", x->x_sym->s_name);
x->x_wherefrom = 0;
}
}
static void sigreceive_dsp(t_sigreceive *x, t_signal **sp)
{
if (sp[0]->s_n != x->x_n)
{
pd_error(x, "receive~ %s: vector size mismatch", x->x_sym->s_name);
}
else
{
sigreceive_set(x, x->x_sym);
dsp_add(sigreceive_perform, 3,
x, sp[0]->s_vec, sp[0]->s_n);
}
}
static void sigreceive_setup(void)
{
sigreceive_class = class_new(gensym("receive~"),
(t_newmethod)sigreceive_new, 0,
sizeof(t_sigreceive), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)sigreceive_new, gensym("r~"), A_DEFSYM, 0);
class_addmethod(sigreceive_class, (t_method)sigreceive_set, gensym("set"),
A_SYMBOL, 0);
class_addmethod(sigreceive_class, (t_method)sigreceive_dsp, gensym("dsp"),
0);
class_sethelpsymbol(sigreceive_class, gensym("send~"));
}
/* ----------------------------- catch~ ----------------------------- */
static t_class *sigcatch_class;
typedef struct _sigcatch
{
t_object x_obj;
t_symbol *x_sym;
int x_n;
t_sample *x_vec;
} t_sigcatch;
static void *sigcatch_new(t_symbol *s)
{
t_sigcatch *x = (t_sigcatch *)pd_new(sigcatch_class);
pd_bind(&x->x_obj.ob_pd, s);
x->x_sym = s;
x->x_n = DEFSENDVS;
x->x_vec = (t_sample *)getbytes(DEFSENDVS * sizeof(t_sample));
memset((char *)(x->x_vec), 0, DEFSENDVS * sizeof(t_sample));
outlet_new(&x->x_obj, &s_signal);
return (x);
}
static t_int *sigcatch_perform(t_int *w)
{
t_sample *in = (t_sample *)(w[1]);
t_sample *out = (t_sample *)(w[2]);
int n = (int)(w[3]);
while (n--) *out++ = *in, *in++ = 0;
return (w+4);
}
static void sigcatch_dsp(t_sigcatch *x, t_signal **sp)
{
if (x->x_n == sp[0]->s_n)
dsp_add(sigcatch_perform, 3, x->x_vec, sp[0]->s_vec, sp[0]->s_n);
else error("sigcatch %s: unexpected vector size", x->x_sym->s_name);
}
static void sigcatch_free(t_sigcatch *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
freebytes(x->x_vec, x->x_n * sizeof(float));
}
static void sigcatch_setup(void)
{
sigcatch_class = class_new(gensym("catch~"), (t_newmethod)sigcatch_new,
(t_method)sigcatch_free, sizeof(t_sigcatch), CLASS_NOINLET, A_DEFSYM, 0);
class_addmethod(sigcatch_class, (t_method)sigcatch_dsp, gensym("dsp"), 0);
class_sethelpsymbol(sigcatch_class, gensym("throw~"));
}
/* ----------------------------- throw~ ----------------------------- */
static t_class *sigthrow_class;
typedef struct _sigthrow
{
t_object x_obj;
t_symbol *x_sym;
t_sample *x_whereto;
int x_n;
t_float x_f;
} t_sigthrow;
static void *sigthrow_new(t_symbol *s)
{
t_sigthrow *x = (t_sigthrow *)pd_new(sigthrow_class);
x->x_sym = s;
x->x_whereto = 0;
x->x_n = DEFSENDVS;
x->x_f = 0;
return (x);
}
static t_int *sigthrow_perform(t_int *w)
{
t_sigthrow *x = (t_sigthrow *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
int n = (int)(w[3]);
t_sample *out = x->x_whereto;
if (out)
{
while (n--)
{
*out += (PD_BIGORSMALL(*in) ? 0 : *in);
out++;
in++;
}
}
return (w+4);
}
static void sigthrow_set(t_sigthrow *x, t_symbol *s)
{
t_sigcatch *catcher = (t_sigcatch *)pd_findbyclass((x->x_sym = s),
sigcatch_class);
if (catcher)
{
if (catcher->x_n == x->x_n)
x->x_whereto = catcher->x_vec;
else
{
pd_error(x, "throw~ %s: vector size mismatch", x->x_sym->s_name);
x->x_whereto = 0;
}
}
else
{
pd_error(x, "throw~ %s: no matching catch", x->x_sym->s_name);
x->x_whereto = 0;
}
}
static void sigthrow_dsp(t_sigthrow *x, t_signal **sp)
{
if (sp[0]->s_n != x->x_n)
{
pd_error(x, "throw~ %s: vector size mismatch", x->x_sym->s_name);
}
else
{
sigthrow_set(x, x->x_sym);
dsp_add(sigthrow_perform, 3,
x, sp[0]->s_vec, sp[0]->s_n);
}
}
static void sigthrow_setup(void)
{
sigthrow_class = class_new(gensym("throw~"), (t_newmethod)sigthrow_new, 0,
sizeof(t_sigthrow), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)sigthrow_new, gensym("r~"), A_DEFSYM, 0);
class_addmethod(sigthrow_class, (t_method)sigthrow_set, gensym("set"),
A_SYMBOL, 0);
CLASS_MAINSIGNALIN(sigthrow_class, t_sigthrow, x_f);
class_addmethod(sigthrow_class, (t_method)sigthrow_dsp, gensym("dsp"), 0);
}
/* ----------------------- global setup routine ---------------- */
void d_global_setup(void)
{
sigsend_setup();
sigreceive_setup();
sigcatch_setup();
sigthrow_setup();
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,100 @@
/* Tables for fixed point lookup with 18 bit precision*/
static int fsintab[TRIG_TAB_SIZE]= {
262144,
185363,
100318,
51141,
25694,
12862,
6433,
3216,
1608,
804,
402,
201,
100,
50,
25,
12,
6,
3,
0,
0,
0,
0 };
static int fcostab[TRIG_TAB_SIZE]= {
0,
185363,
242189,
257106,
260881,
261828,
262065,
262124,
262139,
262142,
262143,
262143,
262143,
262143,
262143,
262143,
262143,
262143,
0,
0,
0,
0 };
/* Tables for fixed point lookup with 18 bit precision*/
static int fsintab[TRIG_TAB_SIZE]= {
262144,
185363,
100318,
51141,
25694,
12862,
6433,
3216,
1608,
804,
402,
201,
100,
50,
25,
12,
6,
3,
0,
0,
0,
0 };
static int fcostab[TRIG_TAB_SIZE]= {
0,
185363,
242189,
257106,
260881,
261828,
262065,
262124,
262139,
262142,
262143,
262143,
262143,
262143,
262143,
262143,
262143,
262143,
0,
0,
0,
0 };

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,838 @@
/*
** FFT and FHT routines
** Copyright 1988, 1993; Ron Mayer
**
** mayer_fht(fz,n);
** Does a hartley transform of "n" points in the array "fz".
** mayer_fft(n,real,imag)
** Does a fourier transform of "n" points of the "real" and
** "imag" arrays.
** mayer_ifft(n,real,imag)
** Does an inverse fourier transform of "n" points of the "real"
** and "imag" arrays.
** mayer_realfft(n,real)
** Does a real-valued fourier transform of "n" points of the
** "real" array. The real part of the transform ends
** up in the first half of the array and the imaginary part of the
** transform ends up in the second half of the array.
** mayer_realifft(n,real)
** The inverse of the realfft() routine above.
**
**
** NOTE: This routine uses at least 2 patented algorithms, and may be
** under the restrictions of a bunch of different organizations.
** Although I wrote it completely myself, it is kind of a derivative
** of a routine I once authored and released under the GPL, so it
** may fall under the free software foundation's restrictions;
** it was worked on as a Stanford Univ project, so they claim
** some rights to it; it was further optimized at work here, so
** I think this company claims parts of it. The patents are
** held by R. Bracewell (the FHT algorithm) and O. Buneman (the
** trig generator), both at Stanford Univ.
** If it were up to me, I'd say go do whatever you want with it;
** but it would be polite to give credit to the following people
** if you use this anywhere:
** Euler - probable inventor of the fourier transform.
** Gauss - probable inventor of the FFT.
** Hartley - probable inventor of the hartley transform.
** Buneman - for a really cool trig generator
** Mayer(me) - for authoring this particular version and
** including all the optimizations in one package.
** Thanks,
** Ron Mayer; mayer@acuson.com
**
*/
/* This is a slightly modified version of Mayer's contribution; write
* msp@ucsd.edu for the original code. Kudos to Mayer for a fine piece
* of work. -msp
*/
#ifdef MSW
#pragma warning( disable : 4305 ) /* uncast const double to float */
#pragma warning( disable : 4244 ) /* uncast double to float */
#pragma warning( disable : 4101 ) /* unused local variables */
#endif
#define REAL float
#define GOOD_TRIG
#ifdef GOOD_TRIG
#else
#define FAST_TRIG
#endif
#if defined(GOOD_TRIG)
#define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
#define TRIG_VARS \
int t_lam=0;
#define TRIG_INIT(k,c,s) \
{ \
int i; \
for (i=2 ; i<=k ; i++) \
{coswrk[i]=costab[i];sinwrk[i]=sintab[i];} \
t_lam = 0; \
c = 1; \
s = 0; \
}
#define TRIG_NEXT(k,c,s) \
{ \
int i,j; \
(t_lam)++; \
for (i=0 ; !((1<<i)&t_lam) ; i++); \
i = k-i; \
s = sinwrk[i]; \
c = coswrk[i]; \
if (i>1) \
{ \
for (j=k-i+2 ; (1<<j)&t_lam ; j++); \
j = k - j; \
sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \
coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \
} \
}
#define TRIG_RESET(k,c,s)
#endif
#if defined(FAST_TRIG)
#define TRIG_VARS \
REAL t_c,t_s;
#define TRIG_INIT(k,c,s) \
{ \
t_c = costab[k]; \
t_s = sintab[k]; \
c = 1; \
s = 0; \
}
#define TRIG_NEXT(k,c,s) \
{ \
REAL t = c; \
c = t*t_c - s*t_s; \
s = t*t_s + s*t_c; \
}
#define TRIG_RESET(k,c,s)
#endif
static REAL halsec[20]=
{
0,
0,
.54119610014619698439972320536638942006107206337801,
.50979557910415916894193980398784391368261849190893,
.50241928618815570551167011928012092247859337193963,
.50060299823519630134550410676638239611758632599591,
.50015063602065098821477101271097658495974913010340,
.50003765191554772296778139077905492847503165398345,
.50000941253588775676512870469186533538523133757983,
.50000235310628608051401267171204408939326297376426,
.50000058827484117879868526730916804925780637276181,
.50000014706860214875463798283871198206179118093251,
.50000003676714377807315864400643020315103490883972,
.50000000919178552207366560348853455333939112569380,
.50000000229794635411562887767906868558991922348920,
.50000000057448658687873302235147272458812263401372
};
static REAL costab[20]=
{
.00000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768847,
.92387953251128675612818318939678828682241662586364,
.98078528040323044912618223613423903697393373089333,
.99518472667219688624483695310947992157547486872985,
.99879545620517239271477160475910069444320361470461,
.99969881869620422011576564966617219685006108125772,
.99992470183914454092164649119638322435060646880221,
.99998117528260114265699043772856771617391725094433,
.99999529380957617151158012570011989955298763362218,
.99999882345170190992902571017152601904826792288976,
.99999970586288221916022821773876567711626389934930,
.99999992646571785114473148070738785694820115568892,
.99999998161642929380834691540290971450507605124278,
.99999999540410731289097193313960614895889430318945,
.99999999885102682756267330779455410840053741619428
};
static REAL sintab[20]=
{
1.0000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768846,
.38268343236508977172845998403039886676134456248561,
.19509032201612826784828486847702224092769161775195,
.09801714032956060199419556388864184586113667316749,
.04906767432741801425495497694268265831474536302574,
.02454122852291228803173452945928292506546611923944,
.01227153828571992607940826195100321214037231959176,
.00613588464915447535964023459037258091705788631738,
.00306795676296597627014536549091984251894461021344,
.00153398018628476561230369715026407907995486457522,
.00076699031874270452693856835794857664314091945205,
.00038349518757139558907246168118138126339502603495,
.00019174759731070330743990956198900093346887403385,
.00009587379909597734587051721097647635118706561284,
.00004793689960306688454900399049465887274686668768
};
static REAL coswrk[20]=
{
.00000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768847,
.92387953251128675612818318939678828682241662586364,
.98078528040323044912618223613423903697393373089333,
.99518472667219688624483695310947992157547486872985,
.99879545620517239271477160475910069444320361470461,
.99969881869620422011576564966617219685006108125772,
.99992470183914454092164649119638322435060646880221,
.99998117528260114265699043772856771617391725094433,
.99999529380957617151158012570011989955298763362218,
.99999882345170190992902571017152601904826792288976,
.99999970586288221916022821773876567711626389934930,
.99999992646571785114473148070738785694820115568892,
.99999998161642929380834691540290971450507605124278,
.99999999540410731289097193313960614895889430318945,
.99999999885102682756267330779455410840053741619428
};
static REAL sinwrk[20]=
{
1.0000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768846,
.38268343236508977172845998403039886676134456248561,
.19509032201612826784828486847702224092769161775195,
.09801714032956060199419556388864184586113667316749,
.04906767432741801425495497694268265831474536302574,
.02454122852291228803173452945928292506546611923944,
.01227153828571992607940826195100321214037231959176,
.00613588464915447535964023459037258091705788631738,
.00306795676296597627014536549091984251894461021344,
.00153398018628476561230369715026407907995486457522,
.00076699031874270452693856835794857664314091945205,
.00038349518757139558907246168118138126339502603495,
.00019174759731070330743990956198900093346887403385,
.00009587379909597734587051721097647635118706561284,
.00004793689960306688454900399049465887274686668768
};
#define SQRT2_2 0.70710678118654752440084436210484
#define SQRT2 2*0.70710678118654752440084436210484
void mayer_fht(REAL *fz, int n)
{
/* REAL a,b;
REAL c1,s1,s2,c2,s3,c3,s4,c4;
REAL f0,g0,f1,g1,f2,g2,f3,g3; */
int k,k1,k2,k3,k4,kx;
REAL *fi,*fn,*gi;
TRIG_VARS;
for (k1=1,k2=0;k1<n;k1++)
{
REAL aa;
for (k=n>>1; (!((k2^=k)&k)); k>>=1);
if (k1>k2)
{
aa=fz[k1];fz[k1]=fz[k2];fz[k2]=aa;
}
}
for ( k=0 ; (1<<k)<n ; k++ );
k &= 1;
if (k==0)
{
for (fi=fz,fn=fz+n;fi<fn;fi+=4)
{
REAL f0,f1,f2,f3;
f1 = fi[0 ]-fi[1 ];
f0 = fi[0 ]+fi[1 ];
f3 = fi[2 ]-fi[3 ];
f2 = fi[2 ]+fi[3 ];
fi[2 ] = (f0-f2);
fi[0 ] = (f0+f2);
fi[3 ] = (f1-f3);
fi[1 ] = (f1+f3);
}
}
else
{
for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8)
{
REAL bs1,bc1,bs2,bc2,bs3,bc3,bs4,bc4,
bg0,bf0,bf1,bg1,bf2,bg2,bf3,bg3;
bc1 = fi[0 ] - gi[0 ];
bs1 = fi[0 ] + gi[0 ];
bc2 = fi[2 ] - gi[2 ];
bs2 = fi[2 ] + gi[2 ];
bc3 = fi[4 ] - gi[4 ];
bs3 = fi[4 ] + gi[4 ];
bc4 = fi[6 ] - gi[6 ];
bs4 = fi[6 ] + gi[6 ];
bf1 = (bs1 - bs2);
bf0 = (bs1 + bs2);
bg1 = (bc1 - bc2);
bg0 = (bc1 + bc2);
bf3 = (bs3 - bs4);
bf2 = (bs3 + bs4);
bg3 = SQRT2*bc4;
bg2 = SQRT2*bc3;
fi[4 ] = bf0 - bf2;
fi[0 ] = bf0 + bf2;
fi[6 ] = bf1 - bf3;
fi[2 ] = bf1 + bf3;
gi[4 ] = bg0 - bg2;
gi[0 ] = bg0 + bg2;
gi[6 ] = bg1 - bg3;
gi[2 ] = bg1 + bg3;
}
}
if (n<16) return;
do
{
REAL s1,c1;
int ii;
k += 2;
k1 = 1 << k;
k2 = k1 << 1;
k4 = k2 << 1;
k3 = k2 + k1;
kx = k1 >> 1;
fi = fz;
gi = fi + kx;
fn = fz + n;
do
{
REAL g0,f0,f1,g1,f2,g2,f3,g3;
f1 = fi[0 ] - fi[k1];
f0 = fi[0 ] + fi[k1];
f3 = fi[k2] - fi[k3];
f2 = fi[k2] + fi[k3];
fi[k2] = f0 - f2;
fi[0 ] = f0 + f2;
fi[k3] = f1 - f3;
fi[k1] = f1 + f3;
g1 = gi[0 ] - gi[k1];
g0 = gi[0 ] + gi[k1];
g3 = SQRT2 * gi[k3];
g2 = SQRT2 * gi[k2];
gi[k2] = g0 - g2;
gi[0 ] = g0 + g2;
gi[k3] = g1 - g3;
gi[k1] = g1 + g3;
gi += k4;
fi += k4;
} while (fi<fn);
TRIG_INIT(k,c1,s1);
for (ii=1;ii<kx;ii++)
{
REAL c2,s2;
TRIG_NEXT(k,c1,s1);
c2 = c1*c1 - s1*s1;
s2 = 2*(c1*s1);
fn = fz + n;
fi = fz +ii;
gi = fz +k1-ii;
do
{
REAL a,b,g0,f0,f1,g1,f2,g2,f3,g3;
b = s2*fi[k1] - c2*gi[k1];
a = c2*fi[k1] + s2*gi[k1];
f1 = fi[0 ] - a;
f0 = fi[0 ] + a;
g1 = gi[0 ] - b;
g0 = gi[0 ] + b;
b = s2*fi[k3] - c2*gi[k3];
a = c2*fi[k3] + s2*gi[k3];
f3 = fi[k2] - a;
f2 = fi[k2] + a;
g3 = gi[k2] - b;
g2 = gi[k2] + b;
b = s1*f2 - c1*g3;
a = c1*f2 + s1*g3;
fi[k2] = f0 - a;
fi[0 ] = f0 + a;
gi[k3] = g1 - b;
gi[k1] = g1 + b;
b = c1*g2 - s1*f3;
a = s1*g2 + c1*f3;
gi[k2] = g0 - a;
gi[0 ] = g0 + a;
fi[k3] = f1 - b;
fi[k1] = f1 + b;
gi += k4;
fi += k4;
} while (fi<fn);
}
TRIG_RESET(k,c1,s1);
} while (k4<n);
}
void mayer_fft(int n, REAL *real, REAL *imag)
{
REAL a,b,c,d;
REAL q,r,s,t;
int i,j,k;
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i]; b = real[j]; q=a+b; r=a-b;
c = imag[i]; d = imag[j]; s=c+d; t=c-d;
real[i] = (q+t)*.5; real[j] = (q-t)*.5;
imag[i] = (s-r)*.5; imag[j] = (s+r)*.5;
}
mayer_fht(real,n);
mayer_fht(imag,n);
}
void mayer_ifft(int n, REAL *real, REAL *imag)
{
REAL a,b,c,d;
REAL q,r,s,t;
int i,j,k;
mayer_fht(real,n);
mayer_fht(imag,n);
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i]; b = real[j]; q=a+b; r=a-b;
c = imag[i]; d = imag[j]; s=c+d; t=c-d;
imag[i] = (s+r)*0.5; imag[j] = (s-r)*0.5;
real[i] = (q-t)*0.5; real[j] = (q+t)*0.5;
}
}
void mayer_realfft(int n, REAL *real)
{
REAL a,b,c,d;
int i,j,k;
mayer_fht(real,n);
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i];
b = real[j];
real[j] = (a-b)*0.5;
real[i] = (a+b)*0.5;
}
}
void mayer_realifft(int n, REAL *real)
{
REAL a,b,c,d;
int i,j,k;
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i];
b = real[j];
real[j] = (a-b);
real[i] = (a+b);
}
mayer_fht(real,n);
}
/*
** FFT and FHT routines
** Copyright 1988, 1993; Ron Mayer
**
** mayer_fht(fz,n);
** Does a hartley transform of "n" points in the array "fz".
** mayer_fft(n,real,imag)
** Does a fourier transform of "n" points of the "real" and
** "imag" arrays.
** mayer_ifft(n,real,imag)
** Does an inverse fourier transform of "n" points of the "real"
** and "imag" arrays.
** mayer_realfft(n,real)
** Does a real-valued fourier transform of "n" points of the
** "real" array. The real part of the transform ends
** up in the first half of the array and the imaginary part of the
** transform ends up in the second half of the array.
** mayer_realifft(n,real)
** The inverse of the realfft() routine above.
**
**
** NOTE: This routine uses at least 2 patented algorithms, and may be
** under the restrictions of a bunch of different organizations.
** Although I wrote it completely myself, it is kind of a derivative
** of a routine I once authored and released under the GPL, so it
** may fall under the free software foundation's restrictions;
** it was worked on as a Stanford Univ project, so they claim
** some rights to it; it was further optimized at work here, so
** I think this company claims parts of it. The patents are
** held by R. Bracewell (the FHT algorithm) and O. Buneman (the
** trig generator), both at Stanford Univ.
** If it were up to me, I'd say go do whatever you want with it;
** but it would be polite to give credit to the following people
** if you use this anywhere:
** Euler - probable inventor of the fourier transform.
** Gauss - probable inventor of the FFT.
** Hartley - probable inventor of the hartley transform.
** Buneman - for a really cool trig generator
** Mayer(me) - for authoring this particular version and
** including all the optimizations in one package.
** Thanks,
** Ron Mayer; mayer@acuson.com
**
*/
/* This is a slightly modified version of Mayer's contribution; write
* msp@ucsd.edu for the original code. Kudos to Mayer for a fine piece
* of work. -msp
*/
#ifdef MSW
#pragma warning( disable : 4305 ) /* uncast const double to float */
#pragma warning( disable : 4244 ) /* uncast double to float */
#pragma warning( disable : 4101 ) /* unused local variables */
#endif
#define REAL float
#define GOOD_TRIG
#ifdef GOOD_TRIG
#else
#define FAST_TRIG
#endif
#if defined(GOOD_TRIG)
#define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
#define TRIG_VARS \
int t_lam=0;
#define TRIG_INIT(k,c,s) \
{ \
int i; \
for (i=2 ; i<=k ; i++) \
{coswrk[i]=costab[i];sinwrk[i]=sintab[i];} \
t_lam = 0; \
c = 1; \
s = 0; \
}
#define TRIG_NEXT(k,c,s) \
{ \
int i,j; \
(t_lam)++; \
for (i=0 ; !((1<<i)&t_lam) ; i++); \
i = k-i; \
s = sinwrk[i]; \
c = coswrk[i]; \
if (i>1) \
{ \
for (j=k-i+2 ; (1<<j)&t_lam ; j++); \
j = k - j; \
sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]); \
coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]); \
} \
}
#define TRIG_RESET(k,c,s)
#endif
#if defined(FAST_TRIG)
#define TRIG_VARS \
REAL t_c,t_s;
#define TRIG_INIT(k,c,s) \
{ \
t_c = costab[k]; \
t_s = sintab[k]; \
c = 1; \
s = 0; \
}
#define TRIG_NEXT(k,c,s) \
{ \
REAL t = c; \
c = t*t_c - s*t_s; \
s = t*t_s + s*t_c; \
}
#define TRIG_RESET(k,c,s)
#endif
static REAL halsec[20]=
{
0,
0,
.54119610014619698439972320536638942006107206337801,
.50979557910415916894193980398784391368261849190893,
.50241928618815570551167011928012092247859337193963,
.50060299823519630134550410676638239611758632599591,
.50015063602065098821477101271097658495974913010340,
.50003765191554772296778139077905492847503165398345,
.50000941253588775676512870469186533538523133757983,
.50000235310628608051401267171204408939326297376426,
.50000058827484117879868526730916804925780637276181,
.50000014706860214875463798283871198206179118093251,
.50000003676714377807315864400643020315103490883972,
.50000000919178552207366560348853455333939112569380,
.50000000229794635411562887767906868558991922348920,
.50000000057448658687873302235147272458812263401372
};
static REAL costab[20]=
{
.00000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768847,
.92387953251128675612818318939678828682241662586364,
.98078528040323044912618223613423903697393373089333,
.99518472667219688624483695310947992157547486872985,
.99879545620517239271477160475910069444320361470461,
.99969881869620422011576564966617219685006108125772,
.99992470183914454092164649119638322435060646880221,
.99998117528260114265699043772856771617391725094433,
.99999529380957617151158012570011989955298763362218,
.99999882345170190992902571017152601904826792288976,
.99999970586288221916022821773876567711626389934930,
.99999992646571785114473148070738785694820115568892,
.99999998161642929380834691540290971450507605124278,
.99999999540410731289097193313960614895889430318945,
.99999999885102682756267330779455410840053741619428
};
static REAL sintab[20]=
{
1.0000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768846,
.38268343236508977172845998403039886676134456248561,
.19509032201612826784828486847702224092769161775195,
.09801714032956060199419556388864184586113667316749,
.04906767432741801425495497694268265831474536302574,
.02454122852291228803173452945928292506546611923944,
.01227153828571992607940826195100321214037231959176,
.00613588464915447535964023459037258091705788631738,
.00306795676296597627014536549091984251894461021344,
.00153398018628476561230369715026407907995486457522,
.00076699031874270452693856835794857664314091945205,
.00038349518757139558907246168118138126339502603495,
.00019174759731070330743990956198900093346887403385,
.00009587379909597734587051721097647635118706561284,
.00004793689960306688454900399049465887274686668768
};
static REAL coswrk[20]=
{
.00000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768847,
.92387953251128675612818318939678828682241662586364,
.98078528040323044912618223613423903697393373089333,
.99518472667219688624483695310947992157547486872985,
.99879545620517239271477160475910069444320361470461,
.99969881869620422011576564966617219685006108125772,
.99992470183914454092164649119638322435060646880221,
.99998117528260114265699043772856771617391725094433,
.99999529380957617151158012570011989955298763362218,
.99999882345170190992902571017152601904826792288976,
.99999970586288221916022821773876567711626389934930,
.99999992646571785114473148070738785694820115568892,
.99999998161642929380834691540290971450507605124278,
.99999999540410731289097193313960614895889430318945,
.99999999885102682756267330779455410840053741619428
};
static REAL sinwrk[20]=
{
1.0000000000000000000000000000000000000000000000000,
.70710678118654752440084436210484903928483593768846,
.38268343236508977172845998403039886676134456248561,
.19509032201612826784828486847702224092769161775195,
.09801714032956060199419556388864184586113667316749,
.04906767432741801425495497694268265831474536302574,
.02454122852291228803173452945928292506546611923944,
.01227153828571992607940826195100321214037231959176,
.00613588464915447535964023459037258091705788631738,
.00306795676296597627014536549091984251894461021344,
.00153398018628476561230369715026407907995486457522,
.00076699031874270452693856835794857664314091945205,
.00038349518757139558907246168118138126339502603495,
.00019174759731070330743990956198900093346887403385,
.00009587379909597734587051721097647635118706561284,
.00004793689960306688454900399049465887274686668768
};
#define SQRT2_2 0.70710678118654752440084436210484
#define SQRT2 2*0.70710678118654752440084436210484
void mayer_fht(REAL *fz, int n)
{
/* REAL a,b;
REAL c1,s1,s2,c2,s3,c3,s4,c4;
REAL f0,g0,f1,g1,f2,g2,f3,g3; */
int k,k1,k2,k3,k4,kx;
REAL *fi,*fn,*gi;
TRIG_VARS;
for (k1=1,k2=0;k1<n;k1++)
{
REAL aa;
for (k=n>>1; (!((k2^=k)&k)); k>>=1);
if (k1>k2)
{
aa=fz[k1];fz[k1]=fz[k2];fz[k2]=aa;
}
}
for ( k=0 ; (1<<k)<n ; k++ );
k &= 1;
if (k==0)
{
for (fi=fz,fn=fz+n;fi<fn;fi+=4)
{
REAL f0,f1,f2,f3;
f1 = fi[0 ]-fi[1 ];
f0 = fi[0 ]+fi[1 ];
f3 = fi[2 ]-fi[3 ];
f2 = fi[2 ]+fi[3 ];
fi[2 ] = (f0-f2);
fi[0 ] = (f0+f2);
fi[3 ] = (f1-f3);
fi[1 ] = (f1+f3);
}
}
else
{
for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8)
{
REAL bs1,bc1,bs2,bc2,bs3,bc3,bs4,bc4,
bg0,bf0,bf1,bg1,bf2,bg2,bf3,bg3;
bc1 = fi[0 ] - gi[0 ];
bs1 = fi[0 ] + gi[0 ];
bc2 = fi[2 ] - gi[2 ];
bs2 = fi[2 ] + gi[2 ];
bc3 = fi[4 ] - gi[4 ];
bs3 = fi[4 ] + gi[4 ];
bc4 = fi[6 ] - gi[6 ];
bs4 = fi[6 ] + gi[6 ];
bf1 = (bs1 - bs2);
bf0 = (bs1 + bs2);
bg1 = (bc1 - bc2);
bg0 = (bc1 + bc2);
bf3 = (bs3 - bs4);
bf2 = (bs3 + bs4);
bg3 = SQRT2*bc4;
bg2 = SQRT2*bc3;
fi[4 ] = bf0 - bf2;
fi[0 ] = bf0 + bf2;
fi[6 ] = bf1 - bf3;
fi[2 ] = bf1 + bf3;
gi[4 ] = bg0 - bg2;
gi[0 ] = bg0 + bg2;
gi[6 ] = bg1 - bg3;
gi[2 ] = bg1 + bg3;
}
}
if (n<16) return;
do
{
REAL s1,c1;
int ii;
k += 2;
k1 = 1 << k;
k2 = k1 << 1;
k4 = k2 << 1;
k3 = k2 + k1;
kx = k1 >> 1;
fi = fz;
gi = fi + kx;
fn = fz + n;
do
{
REAL g0,f0,f1,g1,f2,g2,f3,g3;
f1 = fi[0 ] - fi[k1];
f0 = fi[0 ] + fi[k1];
f3 = fi[k2] - fi[k3];
f2 = fi[k2] + fi[k3];
fi[k2] = f0 - f2;
fi[0 ] = f0 + f2;
fi[k3] = f1 - f3;
fi[k1] = f1 + f3;
g1 = gi[0 ] - gi[k1];
g0 = gi[0 ] + gi[k1];
g3 = SQRT2 * gi[k3];
g2 = SQRT2 * gi[k2];
gi[k2] = g0 - g2;
gi[0 ] = g0 + g2;
gi[k3] = g1 - g3;
gi[k1] = g1 + g3;
gi += k4;
fi += k4;
} while (fi<fn);
TRIG_INIT(k,c1,s1);
for (ii=1;ii<kx;ii++)
{
REAL c2,s2;
TRIG_NEXT(k,c1,s1);
c2 = c1*c1 - s1*s1;
s2 = 2*(c1*s1);
fn = fz + n;
fi = fz +ii;
gi = fz +k1-ii;
do
{
REAL a,b,g0,f0,f1,g1,f2,g2,f3,g3;
b = s2*fi[k1] - c2*gi[k1];
a = c2*fi[k1] + s2*gi[k1];
f1 = fi[0 ] - a;
f0 = fi[0 ] + a;
g1 = gi[0 ] - b;
g0 = gi[0 ] + b;
b = s2*fi[k3] - c2*gi[k3];
a = c2*fi[k3] + s2*gi[k3];
f3 = fi[k2] - a;
f2 = fi[k2] + a;
g3 = gi[k2] - b;
g2 = gi[k2] + b;
b = s1*f2 - c1*g3;
a = c1*f2 + s1*g3;
fi[k2] = f0 - a;
fi[0 ] = f0 + a;
gi[k3] = g1 - b;
gi[k1] = g1 + b;
b = c1*g2 - s1*f3;
a = s1*g2 + c1*f3;
gi[k2] = g0 - a;
gi[0 ] = g0 + a;
fi[k3] = f1 - b;
fi[k1] = f1 + b;
gi += k4;
fi += k4;
} while (fi<fn);
}
TRIG_RESET(k,c1,s1);
} while (k4<n);
}
void mayer_fft(int n, REAL *real, REAL *imag)
{
REAL a,b,c,d;
REAL q,r,s,t;
int i,j,k;
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i]; b = real[j]; q=a+b; r=a-b;
c = imag[i]; d = imag[j]; s=c+d; t=c-d;
real[i] = (q+t)*.5; real[j] = (q-t)*.5;
imag[i] = (s-r)*.5; imag[j] = (s+r)*.5;
}
mayer_fht(real,n);
mayer_fht(imag,n);
}
void mayer_ifft(int n, REAL *real, REAL *imag)
{
REAL a,b,c,d;
REAL q,r,s,t;
int i,j,k;
mayer_fht(real,n);
mayer_fht(imag,n);
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i]; b = real[j]; q=a+b; r=a-b;
c = imag[i]; d = imag[j]; s=c+d; t=c-d;
imag[i] = (s+r)*0.5; imag[j] = (s-r)*0.5;
real[i] = (q-t)*0.5; real[j] = (q+t)*0.5;
}
}
void mayer_realfft(int n, REAL *real)
{
REAL a,b,c,d;
int i,j,k;
mayer_fht(real,n);
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i];
b = real[j];
real[j] = (a-b)*0.5;
real[i] = (a+b)*0.5;
}
}
void mayer_realifft(int n, REAL *real)
{
REAL a,b,c,d;
int i,j,k;
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i];
b = real[j];
real[j] = (a-b);
real[i] = (a+b);
}
mayer_fht(real,n);
}

View file

@ -0,0 +1,524 @@
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* miscellaneous: print~; more to come.
*/
#include "m_pd.h"
#include <stdio.h>
#include <string.h>
/* ------------------------- print~ -------------------------- */
static t_class *print_class;
typedef struct _print
{
t_object x_obj;
float x_f;
t_symbol *x_sym;
int x_count;
} t_print;
static t_int *print_perform(t_int *w)
{
t_print *x = (t_print *)(w[1]);
t_float *in = (t_float *)(w[2]);
int n = (int)(w[3]);
if (x->x_count)
{
post("%s:", x->x_sym->s_name);
if (n == 1) post("%8g", in[0]);
else if (n == 2) post("%8g %8g", in[0], in[1]);
else if (n == 4) post("%8g %8g %8g %8g",
in[0], in[1], in[2], in[3]);
else while (n > 0)
{
post("%-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g",
in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]);
n -= 8;
in += 8;
}
x->x_count--;
}
return (w+4);
}
static void print_dsp(t_print *x, t_signal **sp)
{
dsp_add(print_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void print_float(t_print *x, t_float f)
{
if (f < 0) f = 0;
x->x_count = f;
}
static void print_bang(t_print *x)
{
x->x_count = 1;
}
static void *print_new(t_symbol *s)
{
t_print *x = (t_print *)pd_new(print_class);
x->x_sym = (s->s_name[0]? s : gensym("print~"));
x->x_count = 0;
x->x_f = 0;
return (x);
}
static void print_setup(void)
{
print_class = class_new(gensym("print~"), (t_newmethod)print_new, 0,
sizeof(t_print), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(print_class, t_print, x_f);
class_addmethod(print_class, (t_method)print_dsp, gensym("dsp"), 0);
class_addbang(print_class, print_bang);
class_addfloat(print_class, print_float);
}
/* ------------------------- scope~ -------------------------- */
/* this has been replaced by arrays; to be deleted later */
#include "g_canvas.h"
static t_class *scope_class;
#define SCOPESIZE 256
typedef struct _scope
{
t_object x_obj;
t_sample x_samps[SCOPESIZE];
int x_phase;
int x_drawn;
void *x_canvas;
} t_scope;
static t_int *scope_perform(t_int *w)
{
t_scope *x = (t_scope *)(w[1]);
t_float *in = (t_float *)(w[2]);
int n = (int)(w[3]), phase = x->x_phase;
while (n--)
{
x->x_samps[phase] = *in++;
phase = (phase + 1) & (SCOPESIZE-1);
}
x->x_phase = phase;
return (w+4);
}
static void scope_dsp(t_scope *x, t_signal **sp)
{
dsp_add(scope_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void scope_erase(t_scope *x)
{
if (x->x_drawn) sys_vgui(".x%x.c delete gumbo\n", x->x_canvas);
}
#define X1 10.
#define X2 20.
#define YC 5.
static void scope_bang(t_scope *x)
{
int n, phase;
char hugebuf[10000], *s = hugebuf;
scope_erase(x);
sys_vgui(".x%x.c create line 10c 5c 20c 5c -tags gumbo\n", x->x_canvas);
sprintf(s, ".x%x.c create line ", (t_int)x->x_canvas);
s += strlen(s);
for (n = 0, phase = x->x_phase;
n < SCOPESIZE; phase = ((phase+1) & (SCOPESIZE-1)), n++)
{
sprintf(s, "%fc %fc ", X1 + (X2 - X1) * (float)n * (1./SCOPESIZE),
YC - 5 * x->x_samps[phase]);
s += strlen(s);
/* post("phase %d", phase); */
}
sprintf(s, "-tags gumbo\n");
sys_gui(hugebuf);
x->x_drawn = 1;
}
static void scope_free(t_scope *x)
{
scope_erase(x);
}
static void *scope_new(t_symbol *s)
{
t_scope *x = (t_scope *)pd_new(scope_class);
error("scope: this is now obsolete; use arrays and tabwrite~ instead");
x->x_phase = 0;
x->x_drawn = 0;
x->x_canvas = canvas_getcurrent();
return (x);
}
static void scope_setup(void)
{
scope_class = class_new(gensym("scope~"), (t_newmethod)scope_new,
(t_method)scope_free, sizeof(t_scope), 0, A_DEFSYM, 0);
class_addmethod(scope_class, nullfn, gensym("signal"), 0);
class_addmethod(scope_class, (t_method)scope_dsp, gensym("dsp"), 0);
class_addbang(scope_class, scope_bang);
}
/* ------------------------ bang~ -------------------------- */
static t_class *bang_tilde_class;
typedef struct _bang
{
t_object x_obj;
t_clock *x_clock;
} t_bang;
static t_int *bang_tilde_perform(t_int *w)
{
t_bang *x = (t_bang *)(w[1]);
clock_delay(x->x_clock, 0);
return (w+2);
}
static void bang_tilde_dsp(t_bang *x, t_signal **sp)
{
dsp_add(bang_tilde_perform, 1, x);
}
static void bang_tilde_tick(t_bang *x)
{
outlet_bang(x->x_obj.ob_outlet);
}
static void bang_tilde_free(t_bang *x)
{
clock_free(x->x_clock);
}
static void *bang_tilde_new(t_symbol *s)
{
t_bang *x = (t_bang *)pd_new(bang_tilde_class);
x->x_clock = clock_new(x, (t_method)bang_tilde_tick);
outlet_new(&x->x_obj, &s_bang);
return (x);
}
static void bang_tilde_setup(void)
{
bang_tilde_class = class_new(gensym("bang~"), (t_newmethod)bang_tilde_new,
(t_method)bang_tilde_free, sizeof(t_bang), 0, 0);
class_addmethod(bang_tilde_class, (t_method)bang_tilde_dsp,
gensym("dsp"), 0);
}
/* ------------------------ samplerate~~ -------------------------- */
static t_class *samplerate_tilde_class;
typedef struct _samplerate
{
t_object x_obj;
} t_samplerate;
static void samplerate_tilde_bang(t_samplerate *x)
{
outlet_float(x->x_obj.ob_outlet, sys_getsr());
}
static void *samplerate_tilde_new(t_symbol *s)
{
t_samplerate *x = (t_samplerate *)pd_new(samplerate_tilde_class);
outlet_new(&x->x_obj, &s_float);
return (x);
}
static void samplerate_tilde_setup(void)
{
samplerate_tilde_class = class_new(gensym("samplerate~"),
(t_newmethod)samplerate_tilde_new, 0, sizeof(t_samplerate), 0, 0);
class_addbang(samplerate_tilde_class, samplerate_tilde_bang);
}
/* ------------------------ global setup routine ------------------------- */
void d_misc_setup(void)
{
#ifndef FIXEDPOINT
print_setup();
#endif
scope_setup();
bang_tilde_setup();
samplerate_tilde_setup();
}
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* miscellaneous: print~; more to come.
*/
#include "m_pd.h"
#include <stdio.h>
#include <string.h>
/* ------------------------- print~ -------------------------- */
static t_class *print_class;
typedef struct _print
{
t_object x_obj;
float x_f;
t_symbol *x_sym;
int x_count;
} t_print;
static t_int *print_perform(t_int *w)
{
t_print *x = (t_print *)(w[1]);
t_float *in = (t_float *)(w[2]);
int n = (int)(w[3]);
if (x->x_count)
{
post("%s:", x->x_sym->s_name);
if (n == 1) post("%8g", in[0]);
else if (n == 2) post("%8g %8g", in[0], in[1]);
else if (n == 4) post("%8g %8g %8g %8g",
in[0], in[1], in[2], in[3]);
else while (n > 0)
{
post("%-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g %-8.5g",
in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]);
n -= 8;
in += 8;
}
x->x_count--;
}
return (w+4);
}
static void print_dsp(t_print *x, t_signal **sp)
{
dsp_add(print_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void print_float(t_print *x, t_float f)
{
if (f < 0) f = 0;
x->x_count = f;
}
static void print_bang(t_print *x)
{
x->x_count = 1;
}
static void *print_new(t_symbol *s)
{
t_print *x = (t_print *)pd_new(print_class);
x->x_sym = (s->s_name[0]? s : gensym("print~"));
x->x_count = 0;
x->x_f = 0;
return (x);
}
static void print_setup(void)
{
print_class = class_new(gensym("print~"), (t_newmethod)print_new, 0,
sizeof(t_print), 0, A_DEFSYM, 0);
CLASS_MAINSIGNALIN(print_class, t_print, x_f);
class_addmethod(print_class, (t_method)print_dsp, gensym("dsp"), 0);
class_addbang(print_class, print_bang);
class_addfloat(print_class, print_float);
}
/* ------------------------- scope~ -------------------------- */
/* this has been replaced by arrays; to be deleted later */
#include "g_canvas.h"
static t_class *scope_class;
#define SCOPESIZE 256
typedef struct _scope
{
t_object x_obj;
t_sample x_samps[SCOPESIZE];
int x_phase;
int x_drawn;
void *x_canvas;
} t_scope;
static t_int *scope_perform(t_int *w)
{
t_scope *x = (t_scope *)(w[1]);
t_float *in = (t_float *)(w[2]);
int n = (int)(w[3]), phase = x->x_phase;
while (n--)
{
x->x_samps[phase] = *in++;
phase = (phase + 1) & (SCOPESIZE-1);
}
x->x_phase = phase;
return (w+4);
}
static void scope_dsp(t_scope *x, t_signal **sp)
{
dsp_add(scope_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
}
static void scope_erase(t_scope *x)
{
if (x->x_drawn) sys_vgui(".x%x.c delete gumbo\n", x->x_canvas);
}
#define X1 10.
#define X2 20.
#define YC 5.
static void scope_bang(t_scope *x)
{
int n, phase;
char hugebuf[10000], *s = hugebuf;
scope_erase(x);
sys_vgui(".x%x.c create line 10c 5c 20c 5c -tags gumbo\n", x->x_canvas);
sprintf(s, ".x%x.c create line ", (t_int)x->x_canvas);
s += strlen(s);
for (n = 0, phase = x->x_phase;
n < SCOPESIZE; phase = ((phase+1) & (SCOPESIZE-1)), n++)
{
sprintf(s, "%fc %fc ", X1 + (X2 - X1) * (float)n * (1./SCOPESIZE),
YC - 5 * x->x_samps[phase]);
s += strlen(s);
/* post("phase %d", phase); */
}
sprintf(s, "-tags gumbo\n");
sys_gui(hugebuf);
x->x_drawn = 1;
}
static void scope_free(t_scope *x)
{
scope_erase(x);
}
static void *scope_new(t_symbol *s)
{
t_scope *x = (t_scope *)pd_new(scope_class);
error("scope: this is now obsolete; use arrays and tabwrite~ instead");
x->x_phase = 0;
x->x_drawn = 0;
x->x_canvas = canvas_getcurrent();
return (x);
}
static void scope_setup(void)
{
scope_class = class_new(gensym("scope~"), (t_newmethod)scope_new,
(t_method)scope_free, sizeof(t_scope), 0, A_DEFSYM, 0);
class_addmethod(scope_class, nullfn, gensym("signal"), 0);
class_addmethod(scope_class, (t_method)scope_dsp, gensym("dsp"), 0);
class_addbang(scope_class, scope_bang);
}
/* ------------------------ bang~ -------------------------- */
static t_class *bang_tilde_class;
typedef struct _bang
{
t_object x_obj;
t_clock *x_clock;
} t_bang;
static t_int *bang_tilde_perform(t_int *w)
{
t_bang *x = (t_bang *)(w[1]);
clock_delay(x->x_clock, 0);
return (w+2);
}
static void bang_tilde_dsp(t_bang *x, t_signal **sp)
{
dsp_add(bang_tilde_perform, 1, x);
}
static void bang_tilde_tick(t_bang *x)
{
outlet_bang(x->x_obj.ob_outlet);
}
static void bang_tilde_free(t_bang *x)
{
clock_free(x->x_clock);
}
static void *bang_tilde_new(t_symbol *s)
{
t_bang *x = (t_bang *)pd_new(bang_tilde_class);
x->x_clock = clock_new(x, (t_method)bang_tilde_tick);
outlet_new(&x->x_obj, &s_bang);
return (x);
}
static void bang_tilde_setup(void)
{
bang_tilde_class = class_new(gensym("bang~"), (t_newmethod)bang_tilde_new,
(t_method)bang_tilde_free, sizeof(t_bang), 0, 0);
class_addmethod(bang_tilde_class, (t_method)bang_tilde_dsp,
gensym("dsp"), 0);
}
/* ------------------------ samplerate~~ -------------------------- */
static t_class *samplerate_tilde_class;
typedef struct _samplerate
{
t_object x_obj;
} t_samplerate;
static void samplerate_tilde_bang(t_samplerate *x)
{
outlet_float(x->x_obj.ob_outlet, sys_getsr());
}
static void *samplerate_tilde_new(t_symbol *s)
{
t_samplerate *x = (t_samplerate *)pd_new(samplerate_tilde_class);
outlet_new(&x->x_obj, &s_float);
return (x);
}
static void samplerate_tilde_setup(void)
{
samplerate_tilde_class = class_new(gensym("samplerate~"),
(t_newmethod)samplerate_tilde_new, 0, sizeof(t_samplerate), 0, 0);
class_addbang(samplerate_tilde_class, samplerate_tilde_bang);
}
/* ------------------------ global setup routine ------------------------- */
void d_misc_setup(void)
{
#ifndef FIXEDPOINT
print_setup();
#endif
scope_setup();
bang_tilde_setup();
samplerate_tilde_setup();
}

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more