forked from len0rd/rockbox
Cut the files in half and it might work better (note to self: check your tree is really clean before patching)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21070 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
4f2dfcc01b
commit
526b5580da
192 changed files with 20 additions and 69133 deletions
|
|
@ -57,62 +57,3 @@
|
|||
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 !!!
|
||||
|
||||
|
|
|
|||
|
|
@ -28,33 +28,4 @@ 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.
|
||||
|
|
|
|||
|
|
@ -50,57 +50,3 @@ 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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,47 +42,4 @@ 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.
|
||||
|
|
|
|||
|
|
@ -186,191 +186,4 @@ extern char *OSC_errorMessage;
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -11,16 +11,4 @@
|
|||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -598,607 +598,3 @@ static Boolean MatchList (const char *pattern, const char *test) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Written by Adrian Freed, The Center for New Music and Audio Technologies,
|
||||
University of California, Berkeley. Copyright (c) 1992,93,94,95,96,97,98,99,2000,01,02,03,04
|
||||
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.
|
||||
|
||||
|
||||
The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
|
||||
*/
|
||||
|
||||
/* OSC-route.c
|
||||
Max object for OSC-style dispatching
|
||||
|
||||
To-do:
|
||||
|
||||
Match a pattern against a pattern?
|
||||
Declare outlet types / distinguish leaf nodes from other children
|
||||
More sophisticated (2-pass?) allmessages scheme
|
||||
set message?
|
||||
|
||||
|
||||
pd
|
||||
-------------
|
||||
-- tweaks for Win32 www.zeggz.com/raf 13-April-2002
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#ifdef UNIX
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* structure definition of your object */
|
||||
|
||||
#define MAX_NUM 20
|
||||
#define OSC_ROUTE_VERSION "1.05"
|
||||
#define OSCWarning(x...) post(x)
|
||||
|
||||
/* the required include files */
|
||||
#include "m_pd.h"
|
||||
|
||||
|
||||
#ifndef TRUE
|
||||
typedef int Boolean;
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Fixed byte width types */
|
||||
typedef int int4; /* 4 byte int */
|
||||
|
||||
Boolean PatternMatch (const char *pattern, const char *test);
|
||||
|
||||
|
||||
|
||||
/* Version 1.04: Allows #1 thru #9 as typed-in arguments
|
||||
Version 1.05: Allows "list" messages as well as "message" messages.
|
||||
*/
|
||||
|
||||
static t_class *OSCroute_class;
|
||||
|
||||
typedef struct _OSCroute
|
||||
{
|
||||
t_object x_obj; // required header
|
||||
t_int x_num; // Number of address prefixes we store
|
||||
t_int x_complainmode; // Do we print a message if no match?
|
||||
t_int x_sendmode; // use pd internal sends instead of outlets
|
||||
char *x_prefixes[MAX_NUM];
|
||||
void *x_outlets[MAX_NUM+1];
|
||||
} t_OSCroute;
|
||||
|
||||
t_symbol *ps_list, *ps_complain, *ps_emptySymbol;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
|
||||
void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
|
||||
void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
|
||||
/* //void *OSCroute_new(t_symbol *s, int argc, atom *argv); */
|
||||
void *OSCroute_new(t_symbol *s, int argc, t_atom *argv);
|
||||
void OSCroute_version (t_OSCroute *x);
|
||||
/* void OSCroute_assist (OSCroute *x, void *box, long msg, long arg, */
|
||||
/* char *dstString); */
|
||||
void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv);
|
||||
|
||||
static char *NextSlashOrNull(char *p);
|
||||
static void StrCopyUntilSlash(char *target, const char *source);
|
||||
|
||||
|
||||
// free
|
||||
static void OSCroute_free(t_OSCroute *x)
|
||||
{
|
||||
// freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
|
||||
}
|
||||
|
||||
/* initialization routine */
|
||||
|
||||
// setup
|
||||
#ifdef WIN32
|
||||
OSC_API void OSCroute_setup(void) {
|
||||
#else
|
||||
void OSCroute_setup(void) {
|
||||
#endif
|
||||
OSCroute_class = class_new(gensym("OSCroute"), (t_newmethod)OSCroute_new,
|
||||
(t_method)OSCroute_free,sizeof(t_OSCroute), 0, A_GIMME, 0);
|
||||
class_addlist(OSCroute_class, OSCroute_list);
|
||||
class_addanything(OSCroute_class, OSCroute_anything);
|
||||
class_addmethod(OSCroute_class, (t_method)OSCroute_version, gensym("version"), A_NULL, 0, 0);
|
||||
class_sethelpsymbol(OSCroute_class, gensym("OSCroute-help.pd"));
|
||||
|
||||
/*
|
||||
class_addmethod(OSCroute_class, (t_method)OSCroute_connect,
|
||||
gensym("connect"), A_SYMBOL, A_FLOAT, 0);
|
||||
class_addmethod(OSCroute_class, (t_method)OSCroute_disconnect,
|
||||
gensym("disconnect"), 0);
|
||||
class_addmethod(OSCroute_class, (t_method)OSCroute_send, gensym("send"),
|
||||
A_GIMME, 0);
|
||||
*/
|
||||
/* ps_list = gensym("list"); */
|
||||
/* ps_complain = gensym("complain"); */
|
||||
ps_emptySymbol = gensym("");
|
||||
|
||||
post("OSCroute object version " OSC_ROUTE_VERSION " by Matt Wright. pd: jdl Win32 raf.");
|
||||
post("OSCroute Copyright © 1999 Regents of the University of California. All Rights Reserved.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* instance creation routine */
|
||||
|
||||
void *OSCroute_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
|
||||
t_OSCroute *x = (t_OSCroute *)pd_new(OSCroute_class); // get memory for a new object & initialize
|
||||
|
||||
int i; //{{raf}} n not used
|
||||
|
||||
// EnterCallback();
|
||||
|
||||
if (argc > MAX_NUM) {
|
||||
post("* OSC-route: too many arguments: %ld (max %ld)", argc, MAX_NUM);
|
||||
// ExitCallback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
x->x_complainmode = 0;
|
||||
x->x_num = 0;
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (argv[i].a_type == A_SYMBOL) {
|
||||
if (argv[i].a_w.w_symbol->s_name[0] == '/') {
|
||||
/* Now that's a nice prefix */
|
||||
x->x_prefixes[i] = argv[i].a_w.w_symbol->s_name;
|
||||
++(x->x_num);
|
||||
} else if (argv[i].a_w.w_symbol->s_name[0] == '#' &&
|
||||
argv[i].a_w.w_symbol->s_name[1] >= '1' &&
|
||||
argv[i].a_w.w_symbol->s_name[1] <= '9') {
|
||||
/* The Max programmer is trying to make a patch that will be
|
||||
a subpatch with arguments. We have to make an outlet for this
|
||||
argument. */
|
||||
x->x_prefixes[i] = "dummy";
|
||||
++(x->x_num);
|
||||
} else {
|
||||
/* Maybe this is an option we support */
|
||||
|
||||
/* if (argv[i].a_w.w_sym == ps_complain) { */
|
||||
/* x->x_complainmode = 1; */
|
||||
/* } else { */
|
||||
/* post("* OSC-route: Unrecognized argument %s", argv[i].a_w.w_sym->s_name); */
|
||||
/* } */
|
||||
|
||||
}
|
||||
|
||||
// no LONG
|
||||
|
||||
/* } else if (argv[i].a_type == A_FLOAD) { */
|
||||
/* // Convert to a numeral. Max ints are -2147483648 to 2147483647 */
|
||||
/* char *string = getbytes(12); */
|
||||
/* // I can't be bothered to plug this 12 byte memory leak */
|
||||
/* if (string == 0) { */
|
||||
/* post("* OSC-route: out of memory!"); */
|
||||
/* // ExitCallback(); */
|
||||
/* return 0; */
|
||||
/* } */
|
||||
/* sprintf(string, "%d", argv[i].a_w.w_long); */
|
||||
/* x->x_prefixes[i] = string; */
|
||||
/* ++(x->x_num); */
|
||||
|
||||
} else if (argv[i].a_type == A_FLOAT) {
|
||||
post("* OSC-route: float arguments are not OK.");
|
||||
// ExitCallback();
|
||||
return 0;
|
||||
} else {
|
||||
post("* OSC-route: unrecognized argument type!");
|
||||
// ExitCallback();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Have to create the outlets in reverse order */
|
||||
/* well, not in pd ? */
|
||||
// for (i = x->x_num-1; i >= 0; --i) {
|
||||
// for (i = 0; i <= x->x_num-1; i++) {
|
||||
for (i = 0; i <= x->x_num; i++) {
|
||||
// x->x_outlets[i] = listout(x);
|
||||
x->x_outlets[i] = outlet_new(&x->x_obj, &s_list);
|
||||
}
|
||||
|
||||
// ExitCallback();
|
||||
return (x);
|
||||
}
|
||||
|
||||
|
||||
void OSCroute_version (t_OSCroute *x) {
|
||||
// EnterCallback();
|
||||
post("OSCroute Version " OSC_ROUTE_VERSION
|
||||
", by Matt Wright. pd jdl, win32: raf.\nOSCroute Compiled " __TIME__ " " __DATE__);
|
||||
// ExitCallback();
|
||||
}
|
||||
|
||||
/* I don't know why these aren't defined in some Max #include file. */
|
||||
#define ASSIST_INLET 1
|
||||
#define ASSIST_OUTLET 2
|
||||
|
||||
void OSCroute_assist (t_OSCroute *x, void *box, long msg, long arg,
|
||||
char *dstString) {
|
||||
// EnterCallback();
|
||||
|
||||
if (msg==ASSIST_INLET) {
|
||||
sprintf(dstString, "Incoming OSC messages");
|
||||
} else if (msg==ASSIST_OUTLET) {
|
||||
if (arg < 0 || arg >= x->x_num) {
|
||||
post("* OSCroute_assist: No outlet corresponds to arg %ld!", arg);
|
||||
} else {
|
||||
sprintf(dstString, "subaddress + args for prefix %s", x->x_prefixes[arg]);
|
||||
}
|
||||
} else {
|
||||
post("* OSCroute_assist: unrecognized message %ld", msg);
|
||||
}
|
||||
|
||||
// ExitCallback();
|
||||
}
|
||||
|
||||
void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
|
||||
// EnterCallback();
|
||||
if (argc > 0 && argv[0].a_type == A_SYMBOL) {
|
||||
/* Ignore the fact that this is a "list" */
|
||||
OSCroute_doanything(x, argv[0].a_w.w_symbol, argc-1, argv+1);
|
||||
} else {
|
||||
// post("* OSC-route: invalid list beginning with a number");
|
||||
// output on unmatched outlet jdl 20020908
|
||||
if (argv[0].a_type == A_FLOAT) {
|
||||
outlet_float(x->x_outlets[x->x_num], argv[0].a_w.w_float);
|
||||
} else {
|
||||
post("* OSC-route: unrecognized atom type!");
|
||||
}
|
||||
}
|
||||
// ExitCallback();
|
||||
}
|
||||
|
||||
|
||||
void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
|
||||
// EnterCallback();
|
||||
OSCroute_doanything(x, s, argc, argv);
|
||||
// ExitCallback();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
|
||||
char *pattern, *nextSlash;
|
||||
int i;
|
||||
int matchedAnything;
|
||||
// post("*** OSCroute_anything(s %s, argc %ld)", s->s_name, (long) argc);
|
||||
|
||||
pattern = s->s_name;
|
||||
if (pattern[0] != '/') {
|
||||
post("* OSC-route: invalid message pattern %s does not begin with /", s->s_name);
|
||||
outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
|
||||
return;
|
||||
}
|
||||
|
||||
matchedAnything = 0;
|
||||
|
||||
nextSlash = NextSlashOrNull(pattern+1);
|
||||
if (*nextSlash == '\0') {
|
||||
/* last level of the address, so we'll output the argument list */
|
||||
|
||||
|
||||
#ifdef NULL_IS_DIFFERENT_FROM_BANG
|
||||
if (argc==0) {
|
||||
post("* OSC-route: why are you matching one level pattern %s with no args?",
|
||||
pattern);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < x->x_num; ++i) {
|
||||
if (PatternMatch(pattern+1, x->x_prefixes[i]+1)) {
|
||||
++matchedAnything;
|
||||
|
||||
// I hate stupid Max lists with a special first element
|
||||
if (argc == 0) {
|
||||
outlet_bang(x->x_outlets[i]);
|
||||
} else if (argv[0].a_type == A_SYMBOL) {
|
||||
// Promote the symbol that was argv[0] to the special symbol
|
||||
outlet_anything(x->x_outlets[i], argv[0].a_w.w_symbol, argc-1, argv+1);
|
||||
} else if (argc > 1) {
|
||||
// Multiple arguments starting with a number, so naturally we have
|
||||
// to use a special function to output this "list", since it's what
|
||||
// Max originally meant by "list".
|
||||
outlet_list(x->x_outlets[i], 0L, argc, argv);
|
||||
} else {
|
||||
// There was only one argument, and it was a number, so we output it
|
||||
// not as a list
|
||||
/* if (argv[0].a_type == A_LONG) { */
|
||||
|
||||
/* outlet_int(x->x_outlets[i], argv[0].a_w.w_long); */
|
||||
// } else
|
||||
if (argv[0].a_type == A_FLOAT) {
|
||||
|
||||
outlet_float(x->x_outlets[i], argv[0].a_w.w_float);
|
||||
} else {
|
||||
post("* OSC-route: unrecognized atom type!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* There's more address after this part, so our output list will begin with
|
||||
the next slash. */
|
||||
t_symbol *restOfPattern = 0; /* avoid the gensym unless we have to output */
|
||||
char patternBegin[1000];
|
||||
|
||||
|
||||
/* Get the first level of the incoming pattern to match against all our prefixes */
|
||||
StrCopyUntilSlash(patternBegin, pattern+1);
|
||||
|
||||
for (i = 0; i < x->x_num; ++i) {
|
||||
if (PatternMatch(patternBegin, x->x_prefixes[i]+1)) {
|
||||
++matchedAnything;
|
||||
if (restOfPattern == 0) {
|
||||
restOfPattern = gensym(nextSlash);
|
||||
}
|
||||
outlet_anything(x->x_outlets[i], restOfPattern, argc, argv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x->x_complainmode) {
|
||||
if (!matchedAnything) {
|
||||
post("* OSC-route: pattern %s did not match any prefixes", pattern);
|
||||
}
|
||||
}
|
||||
|
||||
// output unmatched data on rightmost outlet a la normal 'route' object, jdl 20020908
|
||||
if (!matchedAnything) {
|
||||
outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static char *NextSlashOrNull(char *p) {
|
||||
while (*p != '/' && *p != '\0') {
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void StrCopyUntilSlash(char *target, const char *source) {
|
||||
while (*source != '/' && *source != '\0') {
|
||||
*target = *source;
|
||||
++target;
|
||||
++source;
|
||||
}
|
||||
*target = 0;
|
||||
}
|
||||
|
||||
static int MyStrCopy(char *target, const char *source) {
|
||||
int i = 0;
|
||||
while (*source != '\0') {
|
||||
*target = *source;
|
||||
++target;
|
||||
++source;
|
||||
++i;
|
||||
}
|
||||
*target = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
|
||||
int i;
|
||||
t_symbol *prefixSymbol = 0;
|
||||
char prefixBuf[1000];
|
||||
char *endOfPrefix;
|
||||
t_atom a[1];
|
||||
|
||||
if (argc >= 1 && argv[0].a_type == A_SYMBOL) {
|
||||
prefixSymbol = argv[0].a_w.w_symbol;
|
||||
endOfPrefix = prefixBuf + MyStrCopy(prefixBuf,
|
||||
prefixSymbol->s_name);
|
||||
} else {
|
||||
prefixSymbol = ps_emptySymbol;
|
||||
prefixBuf[0] = '\0';
|
||||
endOfPrefix = prefixBuf;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < x->x_num; ++i) {
|
||||
post("OSC: %s%s", prefixSymbol->s_name, x->x_prefixes[i]);
|
||||
MyStrCopy(endOfPrefix, x->x_prefixes[i]);
|
||||
SETSYMBOL(a, gensym(prefixBuf));
|
||||
outlet_anything(x->x_outlets[i], s, 1, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
static const char *theWholePattern; /* Just for warning messages */
|
||||
|
||||
static Boolean MatchBrackets (const char *pattern, const char *test);
|
||||
static Boolean MatchList (const char *pattern, const char *test);
|
||||
|
||||
Boolean PatternMatch (const char * pattern, const char * test) {
|
||||
theWholePattern = pattern;
|
||||
|
||||
if (pattern == 0 || pattern[0] == 0) {
|
||||
return test[0] == 0;
|
||||
}
|
||||
|
||||
if (test[0] == 0) {
|
||||
if (pattern[0] == '*')
|
||||
return PatternMatch (pattern+1,test);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (pattern[0]) {
|
||||
case 0 : return test[0] == 0;
|
||||
case '?' : return PatternMatch (pattern + 1, test + 1);
|
||||
case '*' :
|
||||
if (PatternMatch (pattern+1, test)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return PatternMatch (pattern, test+1);
|
||||
}
|
||||
case ']' :
|
||||
case '}' :
|
||||
OSCWarning("Spurious %c in pattern \".../%s/...\"",pattern[0], theWholePattern);
|
||||
return FALSE;
|
||||
case '[' :
|
||||
return MatchBrackets (pattern,test);
|
||||
case '{' :
|
||||
return MatchList (pattern,test);
|
||||
case '\\' :
|
||||
if (pattern[1] == 0) {
|
||||
return test[0] == 0;
|
||||
} else if (pattern[1] == test[0]) {
|
||||
return PatternMatch (pattern+2,test+1);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
default :
|
||||
if (pattern[0] == test[0]) {
|
||||
return PatternMatch (pattern+1,test+1);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* we know that pattern[0] == '[' and test[0] != 0 */
|
||||
|
||||
static Boolean MatchBrackets (const char *pattern, const char *test) {
|
||||
Boolean result;
|
||||
Boolean negated = FALSE;
|
||||
const char *p = pattern;
|
||||
|
||||
if (pattern[1] == 0) {
|
||||
OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pattern[1] == '!') {
|
||||
negated = TRUE;
|
||||
p++;
|
||||
}
|
||||
|
||||
while (*p != ']') {
|
||||
if (*p == 0) {
|
||||
OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
|
||||
return FALSE;
|
||||
}
|
||||
if (p[1] == '-' && p[2] != 0) {
|
||||
if (test[0] >= p[0] && test[0] <= p[2]) {
|
||||
result = !negated;
|
||||
goto advance;
|
||||
}
|
||||
}
|
||||
if (p[0] == test[0]) {
|
||||
result = !negated;
|
||||
goto advance;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
result = negated;
|
||||
|
||||
advance:
|
||||
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
while (*p != ']') {
|
||||
if (*p == 0) {
|
||||
OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern);
|
||||
return FALSE;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return PatternMatch (p+1,test+1);
|
||||
}
|
||||
|
||||
static Boolean MatchList (const char *pattern, const char *test) {
|
||||
|
||||
const char *restOfPattern, *tp = test;
|
||||
|
||||
|
||||
for(restOfPattern = pattern; *restOfPattern != '}'; restOfPattern++) {
|
||||
if (*restOfPattern == 0) {
|
||||
OSCWarning("Unterminated { in pattern \".../%s/...\"", theWholePattern);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
restOfPattern++; /* skip close curly brace */
|
||||
|
||||
|
||||
pattern++; /* skip open curly brace */
|
||||
|
||||
while (1) {
|
||||
|
||||
if (*pattern == ',') {
|
||||
if (PatternMatch (restOfPattern, tp)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
tp = test;
|
||||
++pattern;
|
||||
}
|
||||
} else if (*pattern == '}') {
|
||||
return PatternMatch (restOfPattern, tp);
|
||||
} else if (*pattern == *tp) {
|
||||
++pattern;
|
||||
++tp;
|
||||
} else {
|
||||
tp = test;
|
||||
while (*pattern != ',' && *pattern != '}') {
|
||||
pattern++;
|
||||
}
|
||||
if (*pattern == ',') {
|
||||
pattern++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,4 @@ 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
|
||||
|
||||
|
|
|
|||
|
|
@ -15,20 +15,4 @@
|
|||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,88 +85,3 @@ void bandpass_setup(void)
|
|||
|
||||
|
||||
|
||||
/* (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
|
|
@ -84,95 +84,3 @@ void equalizer_setup(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -483,488 +483,4 @@ static void fatom_setup_common(t_class* class)
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,77 +72,4 @@ stable:
|
|||
|
||||
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -600,605 +600,4 @@ EXTERN t_symbol *iemgui_dollar2raute(t_symbol *s);
|
|||
#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
/* 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. */
|
||||
|
||||
/* this file defines the structure for "glists" and related structures and
|
||||
functions. "Glists" and "canvases" and "graphs" used to be different
|
||||
structures until being unified in version 0.35.
|
||||
|
||||
A glist occupies its own window if the "gl_havewindow" flag is set. Its
|
||||
appearance on its "parent" or "owner" (if it has one) is as a graph if
|
||||
"gl_isgraph" is set, and otherwise as a text box.
|
||||
|
||||
A glist is "root" if it has no owner, i.e., a document window. In this
|
||||
case "gl_havewindow" is always set.
|
||||
|
||||
We maintain a list of root windows, so that we can traverse the whole
|
||||
collection of everything in a Pd process.
|
||||
|
||||
If a glist has a window it may still not be "mapped." Miniaturized
|
||||
windows aren't mapped, for example, but a window is also not mapped
|
||||
immediately upon creation. In either case gl_havewindow is true but
|
||||
gl_mapped is false.
|
||||
|
||||
Closing a non-root window makes it invisible; closing a root destroys it.
|
||||
|
||||
A glist that's just a text object on its parent is always "toplevel." An
|
||||
embedded glist can switch back and forth to appear as a toplevel by double-
|
||||
clicking on it. Single-clicking a text box makes the toplevel become visible
|
||||
and raises the window it's in.
|
||||
|
||||
If a glist shows up as a graph on its parent, the graph is blanked while the
|
||||
glist has its own window, even if miniaturized.
|
||||
|
||||
*/
|
||||
|
||||
/* NOTE: this file describes Pd implementation details which may change
|
||||
in future releases. The public (stable) API is in m_pd.h. */
|
||||
|
||||
#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --------------------- geometry ---------------------------- */
|
||||
#define IOWIDTH 7 /* width of an inlet/outlet in pixels */
|
||||
#define IOMIDDLE ((IOWIDTH-1)/2)
|
||||
#define GLIST_DEFGRAPHWIDTH 200
|
||||
#define GLIST_DEFGRAPHHEIGHT 140
|
||||
/* ----------------------- data ------------------------------- */
|
||||
|
||||
typedef struct _updateheader
|
||||
{
|
||||
struct _updateheader *upd_next;
|
||||
unsigned int upd_array:1; /* true if array, false if glist */
|
||||
unsigned int upd_queued:1; /* true if we're queued */
|
||||
} t_updateheader;
|
||||
|
||||
/* types to support glists grabbing mouse motion or keys from parent */
|
||||
typedef void (*t_glistmotionfn)(void *z, t_floatarg dx, t_floatarg dy);
|
||||
typedef void (*t_glistkeyfn)(void *z, t_floatarg key);
|
||||
|
||||
EXTERN_STRUCT _rtext;
|
||||
#define t_rtext struct _rtext
|
||||
|
||||
EXTERN_STRUCT _gtemplate;
|
||||
#define t_gtemplate struct _gtemplate
|
||||
|
||||
EXTERN_STRUCT _guiconnect;
|
||||
#define t_guiconnect struct _guiconnect
|
||||
|
||||
EXTERN_STRUCT _tscalar;
|
||||
#define t_tscalar struct _tscalar
|
||||
|
||||
EXTERN_STRUCT _canvasenvironment;
|
||||
#define t_canvasenvironment struct _canvasenvironment
|
||||
|
||||
typedef struct _selection
|
||||
{
|
||||
t_gobj *sel_what;
|
||||
struct _selection *sel_next;
|
||||
} t_selection;
|
||||
|
||||
/* this structure is instantiated whenever a glist becomes visible. */
|
||||
typedef struct _editor
|
||||
{
|
||||
t_updateheader e_upd; /* update header structure */
|
||||
t_selection *e_updlist; /* list of objects to update */
|
||||
t_rtext *e_rtext; /* text responder linked list */
|
||||
t_selection *e_selection; /* head of the selection list */
|
||||
t_rtext *e_textedfor; /* the rtext if any that we are editing */
|
||||
t_gobj *e_grab; /* object being "dragged" */
|
||||
t_glistmotionfn e_motionfn; /* ... motion callback */
|
||||
t_glistkeyfn e_keyfn; /* ... keypress callback */
|
||||
t_binbuf *e_connectbuf; /* connections to deleted objects */
|
||||
t_binbuf *e_deleted; /* last stuff we deleted */
|
||||
t_guiconnect *e_guiconnect; /* GUI connection for filtering messages */
|
||||
struct _glist *e_glist; /* glist which owns this */
|
||||
int e_xwas; /* xpos on last mousedown or motion event */
|
||||
int e_ywas; /* ypos, similarly */
|
||||
int e_selectline_index1; /* indices for the selected line if any */
|
||||
int e_selectline_outno; /* (only valid if e_selectedline is set) */
|
||||
int e_selectline_index2;
|
||||
int e_selectline_inno;
|
||||
t_outconnect *e_selectline_tag;
|
||||
unsigned int e_onmotion: 3; /* action to take on motion */
|
||||
unsigned int e_lastmoved: 1; /* one if mouse has moved since click */
|
||||
unsigned int e_textdirty: 1; /* one if e_textedfor has changed */
|
||||
unsigned int e_selectedline: 1; /* one if a line is selected */
|
||||
} t_editor;
|
||||
|
||||
#define MA_NONE 0 /* e_onmotion: do nothing on mouse motion */
|
||||
#define MA_MOVE 1 /* drag the selection around */
|
||||
#define MA_CONNECT 2 /* make a connection */
|
||||
#define MA_REGION 3 /* selection region */
|
||||
#define MA_PASSOUT 4 /* send on to e_grab */
|
||||
#define MA_DRAGTEXT 5 /* drag in text editor to alter selection */
|
||||
|
||||
/* editor structure for "garrays". We don't bother to delete and regenerate
|
||||
this structure when the "garray" becomes invisible or visible, although we
|
||||
could do so if the structure gets big (like the "editor" above.) */
|
||||
|
||||
typedef struct _arrayvis
|
||||
{
|
||||
t_updateheader av_upd; /* update header structure */
|
||||
t_garray *av_garray; /* owning structure */
|
||||
} t_arrayvis;
|
||||
|
||||
/* the t_tick structure describes where to draw x and y "ticks" for a glist */
|
||||
|
||||
typedef struct _tick /* where to put ticks on x or y axes */
|
||||
{
|
||||
float k_point; /* one point to draw a big tick at */
|
||||
float k_inc; /* x or y increment per little tick */
|
||||
int k_lperb; /* little ticks per big; 0 if no ticks to draw */
|
||||
} t_tick;
|
||||
|
||||
/* the t_glist structure, which describes a list of elements that live on an
|
||||
area of a window.
|
||||
|
||||
*/
|
||||
|
||||
struct _glist
|
||||
{
|
||||
t_object gl_obj; /* header in case we're a glist */
|
||||
t_gobj *gl_list; /* the actual data */
|
||||
struct _gstub *gl_stub; /* safe pointer handler */
|
||||
int gl_valid; /* incremented when pointers might be stale */
|
||||
struct _glist *gl_owner; /* parent glist, supercanvas, or 0 if none */
|
||||
int gl_pixwidth; /* width in pixels (on parent, if a graph) */
|
||||
int gl_pixheight;
|
||||
float gl_x1; /* bounding rectangle in our own coordinates */
|
||||
float gl_y1;
|
||||
float gl_x2;
|
||||
float gl_y2;
|
||||
int gl_screenx1; /* screen coordinates when toplevel */
|
||||
int gl_screeny1;
|
||||
int gl_screenx2;
|
||||
int gl_screeny2;
|
||||
t_tick gl_xtick; /* ticks marking X values */
|
||||
int gl_nxlabels; /* number of X coordinate labels */
|
||||
t_symbol **gl_xlabel; /* ... an array to hold them */
|
||||
float gl_xlabely; /* ... and their Y coordinates */
|
||||
t_tick gl_ytick; /* same as above for Y ticks and labels */
|
||||
int gl_nylabels;
|
||||
t_symbol **gl_ylabel;
|
||||
float gl_ylabelx;
|
||||
t_editor *gl_editor; /* editor structure when visible */
|
||||
t_symbol *gl_name; /* symbol bound here */
|
||||
int gl_font; /* nominal font size in points, e.g., 10 */
|
||||
struct _glist *gl_next; /* link in list of toplevels */
|
||||
t_canvasenvironment *gl_env; /* root canvases and abstractions only */
|
||||
unsigned int gl_havewindow:1; /* true if we own a window */
|
||||
unsigned int gl_mapped:1; /* true if, moreover, it's "mapped" */
|
||||
unsigned int gl_dirty:1; /* (root canvas only:) patch has changed */
|
||||
unsigned int gl_loading:1; /* am now loading from file */
|
||||
unsigned int gl_willvis:1; /* make me visible after loading */
|
||||
unsigned int gl_edit:1; /* edit mode */
|
||||
unsigned int gl_isdeleting:1; /* we're inside glist_delete -- hack! */
|
||||
unsigned int gl_stretch:1; /* stretch contents on resize */
|
||||
unsigned int gl_isgraph:1; /* show as graph on parent */
|
||||
};
|
||||
|
||||
#define gl_gobj gl_obj.te_g
|
||||
#define gl_pd gl_gobj.g_pd
|
||||
|
||||
/* a data structure to describe a field in a pure datum */
|
||||
|
||||
#define DT_FLOAT 0
|
||||
#define DT_SYMBOL 1
|
||||
#define DT_LIST 2
|
||||
#define DT_ARRAY 3
|
||||
|
||||
typedef struct _dataslot
|
||||
{
|
||||
int ds_type;
|
||||
t_symbol *ds_name;
|
||||
t_symbol *ds_arraytemplate; /* filled in for arrays only */
|
||||
} t_dataslot;
|
||||
|
||||
|
||||
/* T.Grill - changed t_pd member to t_pdobj to avoid name clashed */
|
||||
typedef struct _template
|
||||
{
|
||||
t_pd t_pdobj; /* header */
|
||||
struct _gtemplate *t_list; /* list of "struct"/gtemplate objects */
|
||||
t_symbol *t_sym; /* name */
|
||||
int t_n; /* number of dataslots (fields) */
|
||||
t_dataslot *t_vec; /* array of dataslots */
|
||||
} t_template;
|
||||
|
||||
struct _array
|
||||
{
|
||||
int a_n; /* number of elements */
|
||||
int a_elemsize; /* size in bytes; LATER get this from template */
|
||||
char *a_vec; /* array of elements */
|
||||
t_symbol *a_templatesym; /* template for elements */
|
||||
int a_valid; /* protection against stale pointers into array */
|
||||
t_gpointer a_gp; /* pointer to scalar or array element we're in */
|
||||
t_gstub *a_stub;
|
||||
};
|
||||
|
||||
/* structure for traversing all the connections in a glist */
|
||||
typedef struct _linetraverser
|
||||
{
|
||||
t_canvas *tr_x;
|
||||
t_object *tr_ob;
|
||||
int tr_nout;
|
||||
int tr_outno;
|
||||
t_object *tr_ob2;
|
||||
t_outlet *tr_outlet;
|
||||
t_inlet *tr_inlet;
|
||||
int tr_nin;
|
||||
int tr_inno;
|
||||
int tr_x11, tr_y11, tr_x12, tr_y12;
|
||||
int tr_x21, tr_y21, tr_x22, tr_y22;
|
||||
int tr_lx1, tr_ly1, tr_lx2, tr_ly2;
|
||||
t_outconnect *tr_nextoc;
|
||||
int tr_nextoutno;
|
||||
} t_linetraverser;
|
||||
|
||||
/* function types used to define graphical behavior for gobjs, a bit like X
|
||||
widgets. We don't use Pd methods because Pd's typechecking can't specify the
|
||||
types of pointer arguments. Also it's more convenient this way, since
|
||||
every "patchable" object can just get the "text" behaviors. */
|
||||
|
||||
/* Call this to get a gobj's bounding rectangle in pixels */
|
||||
typedef void (*t_getrectfn)(t_gobj *x, struct _glist *glist,
|
||||
int *x1, int *y1, int *x2, int *y2);
|
||||
/* and this to displace a gobj: */
|
||||
typedef void (*t_displacefn)(t_gobj *x, struct _glist *glist, int dx, int dy);
|
||||
/* change color to show selection: */
|
||||
typedef void (*t_selectfn)(t_gobj *x, struct _glist *glist, int state);
|
||||
/* change appearance to show activation/deactivation: */
|
||||
typedef void (*t_activatefn)(t_gobj *x, struct _glist *glist, int state);
|
||||
/* warn a gobj it's about to be deleted */
|
||||
typedef void (*t_deletefn)(t_gobj *x, struct _glist *glist);
|
||||
/* making visible or invisible */
|
||||
typedef void (*t_visfn)(t_gobj *x, struct _glist *glist, int flag);
|
||||
/* field a mouse click (when not in "edit" mode) */
|
||||
typedef int (*t_clickfn)(t_gobj *x, struct _glist *glist,
|
||||
int xpix, int ypix, int shift, int alt, int dbl, int doit);
|
||||
/* ... and later, resizing; getting/setting font or color... */
|
||||
|
||||
struct _widgetbehavior
|
||||
{
|
||||
t_getrectfn w_getrectfn;
|
||||
t_displacefn w_displacefn;
|
||||
t_selectfn w_selectfn;
|
||||
t_activatefn w_activatefn;
|
||||
t_deletefn w_deletefn;
|
||||
t_visfn w_visfn;
|
||||
t_clickfn w_clickfn;
|
||||
};
|
||||
|
||||
/* -------- behaviors for scalars defined by objects in template --------- */
|
||||
/* these are set by "drawing commands" in g_template.c which add appearance to
|
||||
scalars, which live in some other window. If the scalar is just included
|
||||
in a canvas the "parent" is a misnomer. There is also a text scalar object
|
||||
which really does draw the scalar on the parent window; see g_scalar.c. */
|
||||
|
||||
/* note how the click function wants the whole scalar, not the "data", so
|
||||
doesn't work on array elements... LATER reconsider this */
|
||||
|
||||
/* bounding rectangle: */
|
||||
typedef void (*t_parentgetrectfn)(t_gobj *x, struct _glist *glist,
|
||||
t_word *data, t_template *tmpl, float basex, float basey,
|
||||
int *x1, int *y1, int *x2, int *y2);
|
||||
/* displace it */
|
||||
typedef void (*t_parentdisplacefn)(t_gobj *x, struct _glist *glist,
|
||||
t_word *data, t_template *tmpl, float basex, float basey,
|
||||
int dx, int dy);
|
||||
/* change color to show selection */
|
||||
typedef void (*t_parentselectfn)(t_gobj *x, struct _glist *glist,
|
||||
t_word *data, t_template *tmpl, float basex, float basey,
|
||||
int state);
|
||||
/* change appearance to show activation/deactivation: */
|
||||
typedef void (*t_parentactivatefn)(t_gobj *x, struct _glist *glist,
|
||||
t_word *data, t_template *tmpl, float basex, float basey,
|
||||
int state);
|
||||
/* making visible or invisible */
|
||||
typedef void (*t_parentvisfn)(t_gobj *x, struct _glist *glist,
|
||||
t_word *data, t_template *tmpl, float basex, float basey,
|
||||
int flag);
|
||||
/* field a mouse click */
|
||||
typedef int (*t_parentclickfn)(t_gobj *x, struct _glist *glist,
|
||||
t_scalar *sc, t_template *tmpl, float basex, float basey,
|
||||
int xpix, int ypix, int shift, int alt, int dbl, int doit);
|
||||
|
||||
struct _parentwidgetbehavior
|
||||
{
|
||||
t_parentgetrectfn w_parentgetrectfn;
|
||||
t_parentdisplacefn w_parentdisplacefn;
|
||||
t_parentselectfn w_parentselectfn;
|
||||
t_parentactivatefn w_parentactivatefn;
|
||||
t_parentvisfn w_parentvisfn;
|
||||
t_parentclickfn w_parentclickfn;
|
||||
};
|
||||
|
||||
/* cursor definitions; used as return value for t_parentclickfn */
|
||||
#define CURSOR_RUNMODE_NOTHING 0
|
||||
#define CURSOR_RUNMODE_CLICKME 1
|
||||
#define CURSOR_RUNMODE_THICKEN 2
|
||||
#define CURSOR_RUNMODE_ADDPOINT 3
|
||||
#define CURSOR_EDITMODE_NOTHING 4
|
||||
#define CURSOR_EDITMODE_CONNECT 5
|
||||
#define CURSOR_EDITMODE_DISCONNECT 6
|
||||
EXTERN void canvas_setcursor(t_glist *x, unsigned int cursornum);
|
||||
|
||||
extern t_canvas *canvas_editing; /* last canvas to start text edting */
|
||||
extern t_canvas *canvas_whichfind; /* last canvas we did a find in */
|
||||
extern t_canvas *canvas_list; /* list of all root canvases */
|
||||
extern t_class *vinlet_class, *voutlet_class;
|
||||
extern int glist_valid; /* incremented when pointers might be stale */
|
||||
|
||||
/* ------------------- functions on any gobj ----------------------------- */
|
||||
EXTERN void gobj_getrect(t_gobj *x, t_glist *owner, int *x1, int *y1,
|
||||
int *x2, int *y2);
|
||||
EXTERN void gobj_displace(t_gobj *x, t_glist *owner, int dx, int dy);
|
||||
EXTERN void gobj_select(t_gobj *x, t_glist *owner, int state);
|
||||
EXTERN void gobj_activate(t_gobj *x, t_glist *owner, int state);
|
||||
EXTERN void gobj_delete(t_gobj *x, t_glist *owner);
|
||||
EXTERN void gobj_vis(t_gobj *x, t_glist *glist, int flag);
|
||||
EXTERN int gobj_click(t_gobj *x, struct _glist *glist,
|
||||
int xpix, int ypix, int shift, int alt, int dbl, int doit);
|
||||
EXTERN void gobj_save(t_gobj *x, t_binbuf *b);
|
||||
EXTERN void gobj_properties(t_gobj *x, struct _glist *glist);
|
||||
EXTERN void gobj_save(t_gobj *x, t_binbuf *b);
|
||||
|
||||
/* -------------------- functions on glists --------------------- */
|
||||
EXTERN t_glist *glist_new( void);
|
||||
EXTERN void glist_init(t_glist *x);
|
||||
EXTERN void glist_add(t_glist *x, t_gobj *g);
|
||||
EXTERN void glist_cleanup(t_glist *x);
|
||||
EXTERN void glist_free(t_glist *x);
|
||||
|
||||
EXTERN void glist_clear(t_glist *x);
|
||||
EXTERN t_canvas *glist_getcanvas(t_glist *x);
|
||||
EXTERN int glist_isselected(t_glist *x, t_gobj *y);
|
||||
EXTERN void glist_select(t_glist *x, t_gobj *y);
|
||||
EXTERN void glist_deselect(t_glist *x, t_gobj *y);
|
||||
EXTERN void glist_noselect(t_glist *x);
|
||||
EXTERN void glist_selectall(t_glist *x);
|
||||
EXTERN void glist_delete(t_glist *x, t_gobj *y);
|
||||
EXTERN void glist_retext(t_glist *x, t_text *y);
|
||||
EXTERN void glist_grab(t_glist *x, t_gobj *y, t_glistmotionfn motionfn,
|
||||
t_glistkeyfn keyfn, int xpos, int ypos);
|
||||
EXTERN int glist_isvisible(t_glist *x);
|
||||
EXTERN int glist_istoplevel(t_glist *x);
|
||||
EXTERN t_glist *glist_findgraph(t_glist *x);
|
||||
EXTERN int glist_getfont(t_glist *x);
|
||||
EXTERN void glist_sort(t_glist *canvas);
|
||||
EXTERN void glist_read(t_glist *x, t_symbol *filename, t_symbol *format);
|
||||
EXTERN void glist_mergefile(t_glist *x, t_symbol *filename, t_symbol *format);
|
||||
|
||||
EXTERN float glist_pixelstox(t_glist *x, float xpix);
|
||||
EXTERN float glist_pixelstoy(t_glist *x, float ypix);
|
||||
EXTERN float glist_xtopixels(t_glist *x, float xval);
|
||||
EXTERN float glist_ytopixels(t_glist *x, float yval);
|
||||
EXTERN float glist_dpixtodx(t_glist *x, float dxpix);
|
||||
EXTERN float glist_dpixtody(t_glist *x, float dypix);
|
||||
|
||||
EXTERN void glist_redrawitem(t_glist *owner, t_gobj *gobj);
|
||||
EXTERN void glist_getnextxy(t_glist *gl, int *xval, int *yval);
|
||||
EXTERN void glist_glist(t_glist *g, t_symbol *s, int argc, t_atom *argv);
|
||||
EXTERN t_glist *glist_addglist(t_glist *g, t_symbol *sym,
|
||||
float x1, float y1, float x2, float y2,
|
||||
float px1, float py1, float px2, float py2);
|
||||
EXTERN void glist_arraydialog(t_glist *parent, t_symbol *name,
|
||||
t_floatarg size, t_floatarg saveit, t_floatarg newgraph);
|
||||
EXTERN t_binbuf *glist_writetobinbuf(t_glist *x, int wholething);
|
||||
EXTERN int glist_isgraph(t_glist *x);
|
||||
EXTERN void glist_redraw(t_glist *x);
|
||||
EXTERN void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime,
|
||||
char *tag, int x1, int y1, int x2, int y2);
|
||||
EXTERN void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag);
|
||||
EXTERN void canvas_create_editor(t_glist *x, int createit);
|
||||
void canvas_deletelinesforio(t_canvas *x, t_text *text,
|
||||
t_inlet *inp, t_outlet *outp);
|
||||
|
||||
|
||||
/* -------------------- functions on texts ------------------------- */
|
||||
EXTERN void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize);
|
||||
EXTERN void text_drawborder(t_text *x, t_glist *glist, char *tag,
|
||||
int width, int height, int firsttime);
|
||||
EXTERN void text_eraseborder(t_text *x, t_glist *glist, char *tag);
|
||||
EXTERN int text_xcoord(t_text *x, t_glist *glist);
|
||||
EXTERN int text_ycoord(t_text *x, t_glist *glist);
|
||||
EXTERN int text_xpix(t_text *x, t_glist *glist);
|
||||
EXTERN int text_ypix(t_text *x, t_glist *glist);
|
||||
EXTERN int text_shouldvis(t_text *x, t_glist *glist);
|
||||
|
||||
/* -------------------- functions on rtexts ------------------------- */
|
||||
#define RTEXT_DOWN 1
|
||||
#define RTEXT_DRAG 2
|
||||
#define RTEXT_DBL 3
|
||||
#define RTEXT_SHIFT 4
|
||||
|
||||
EXTERN t_rtext *rtext_new(t_glist *glist, t_text *who);
|
||||
EXTERN t_rtext *glist_findrtext(t_glist *gl, t_text *who);
|
||||
EXTERN void rtext_draw(t_rtext *x);
|
||||
EXTERN void rtext_erase(t_rtext *x);
|
||||
EXTERN t_rtext *rtext_remove(t_rtext *first, t_rtext *x);
|
||||
EXTERN int rtext_height(t_rtext *x);
|
||||
EXTERN void rtext_displace(t_rtext *x, int dx, int dy);
|
||||
EXTERN void rtext_select(t_rtext *x, int state);
|
||||
EXTERN void rtext_activate(t_rtext *x, int state);
|
||||
EXTERN void rtext_free(t_rtext *x);
|
||||
EXTERN void rtext_key(t_rtext *x, int n, t_symbol *s);
|
||||
EXTERN void rtext_mouse(t_rtext *x, int xval, int yval, int flag);
|
||||
EXTERN void rtext_retext(t_rtext *x);
|
||||
EXTERN int rtext_width(t_rtext *x);
|
||||
EXTERN int rtext_height(t_rtext *x);
|
||||
EXTERN char *rtext_gettag(t_rtext *x);
|
||||
EXTERN void rtext_gettext(t_rtext *x, char **buf, int *bufsize);
|
||||
|
||||
/* -------------------- functions on canvases ------------------------ */
|
||||
EXTERN t_class *canvas_class;
|
||||
|
||||
EXTERN t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv);
|
||||
EXTERN t_symbol *canvas_makebindsym(t_symbol *s);
|
||||
EXTERN void canvas_vistext(t_canvas *x, t_text *y);
|
||||
EXTERN void canvas_fixlinesfor(t_canvas *x, t_text *text);
|
||||
EXTERN void canvas_deletelinesfor(t_canvas *x, t_text *text);
|
||||
EXTERN void canvas_stowconnections(t_canvas *x);
|
||||
EXTERN void canvas_restoreconnections(t_canvas *x);
|
||||
EXTERN void canvas_redraw(t_canvas *x);
|
||||
|
||||
EXTERN t_inlet *canvas_addinlet(t_canvas *x, t_pd *who, t_symbol *sym);
|
||||
EXTERN void canvas_rminlet(t_canvas *x, t_inlet *ip);
|
||||
EXTERN t_outlet *canvas_addoutlet(t_canvas *x, t_pd *who, t_symbol *sym);
|
||||
EXTERN void canvas_rmoutlet(t_canvas *x, t_outlet *op);
|
||||
EXTERN void canvas_redrawallfortemplate(t_canvas *tmpl);
|
||||
EXTERN void canvas_zapallfortemplate(t_canvas *tmpl);
|
||||
EXTERN void canvas_setusedastemplate(t_canvas *x);
|
||||
EXTERN t_canvas *canvas_getcurrent(void);
|
||||
EXTERN void canvas_setcurrent(t_canvas *x);
|
||||
EXTERN void canvas_unsetcurrent(t_canvas *x);
|
||||
EXTERN t_symbol *canvas_realizedollar(t_canvas *x, t_symbol *s);
|
||||
EXTERN t_canvas *canvas_getrootfor(t_canvas *x);
|
||||
EXTERN void canvas_dirty(t_canvas *x, t_int n);
|
||||
EXTERN int canvas_getfont(t_canvas *x);
|
||||
typedef int (*t_canvasapply)(t_canvas *x, t_int x1, t_int x2, t_int x3);
|
||||
|
||||
EXTERN t_int *canvas_recurapply(t_canvas *x, t_canvasapply *fn,
|
||||
t_int x1, t_int x2, t_int x3);
|
||||
|
||||
EXTERN void canvas_resortinlets(t_canvas *x);
|
||||
EXTERN void canvas_resortoutlets(t_canvas *x);
|
||||
EXTERN void canvas_free(t_canvas *x);
|
||||
EXTERN void canvas_updatewindowlist( void);
|
||||
EXTERN void canvas_editmode(t_canvas *x, t_floatarg yesplease);
|
||||
EXTERN int canvas_isabstraction(t_canvas *x);
|
||||
EXTERN int canvas_istable(t_canvas *x);
|
||||
EXTERN int canvas_showtext(t_canvas *x);
|
||||
EXTERN void canvas_vis(t_canvas *x, t_floatarg f);
|
||||
EXTERN t_canvasenvironment *canvas_getenv(t_canvas *x);
|
||||
EXTERN void canvas_rename(t_canvas *x, t_symbol *s, t_symbol *dir);
|
||||
EXTERN void canvas_loadbang(t_canvas *x);
|
||||
EXTERN int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos,
|
||||
int *x1p, int *y1p, int *x2p, int *y2p);
|
||||
EXTERN int canvas_setdeleting(t_canvas *x, int flag);
|
||||
|
||||
typedef void (*t_undofn)(t_canvas *canvas, void *buf,
|
||||
int action); /* a function that does UNDO/REDO */
|
||||
#define UNDO_FREE 0 /* free current undo/redo buffer */
|
||||
#define UNDO_UNDO 1 /* undo */
|
||||
#define UNDO_REDO 2 /* redo */
|
||||
EXTERN void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf,
|
||||
const char *name);
|
||||
EXTERN void canvas_noundo(t_canvas *x);
|
||||
EXTERN int canvas_getindex(t_canvas *x, t_gobj *y);
|
||||
|
||||
/* T.Grill - made public for dynamic object creation */
|
||||
/* in g_editor.c */
|
||||
EXTERN void canvas_connect(t_canvas *x,
|
||||
t_floatarg fwhoout, t_floatarg foutno,t_floatarg fwhoin, t_floatarg finno);
|
||||
EXTERN void canvas_disconnect(t_canvas *x,
|
||||
float index1, float outno, float index2, float inno);
|
||||
EXTERN int canvas_isconnected (t_canvas *x,
|
||||
t_text *ob1, int n1, t_text *ob2, int n2);
|
||||
EXTERN void canvas_selectinrect(t_canvas *x, int lox, int loy, int hix, int hiy);
|
||||
|
||||
|
||||
/* ---- functions on canvasses as objects --------------------- */
|
||||
|
||||
EXTERN void canvas_fattenforscalars(t_canvas *x,
|
||||
int *x1, int *y1, int *x2, int *y2);
|
||||
EXTERN void canvas_visforscalars(t_canvas *x, t_glist *glist, int vis);
|
||||
EXTERN int canvas_clicksub(t_canvas *x, int xpix, int ypix, int shift,
|
||||
int alt, int dbl, int doit);
|
||||
EXTERN t_glist *canvas_getglistonsuper(void);
|
||||
|
||||
EXTERN void linetraverser_start(t_linetraverser *t, t_canvas *x);
|
||||
EXTERN t_outconnect *linetraverser_next(t_linetraverser *t);
|
||||
EXTERN void linetraverser_skipobject(t_linetraverser *t);
|
||||
|
||||
/* --------------------- functions on tscalars --------------------- */
|
||||
|
||||
EXTERN void tscalar_getrect(t_tscalar *x, t_glist *owner,
|
||||
int *xp1, int *yp1, int *xp2, int *yp2);
|
||||
EXTERN void tscalar_vis(t_tscalar *x, t_glist *owner, int flag);
|
||||
EXTERN int tscalar_click(t_tscalar *x, int xpix, int ypix, int shift,
|
||||
int alt, int dbl, int doit);
|
||||
|
||||
/* --------- functions on garrays (graphical arrays) -------------------- */
|
||||
|
||||
EXTERN t_template *garray_template(t_garray *x);
|
||||
|
||||
/* -------------------- arrays --------------------- */
|
||||
EXTERN t_garray *graph_array(t_glist *gl, t_symbol *s, t_symbol *tmpl,
|
||||
t_floatarg f, t_floatarg saveit);
|
||||
EXTERN t_array *array_new(t_symbol *templatesym, t_gpointer *parent);
|
||||
EXTERN void array_resize(t_array *x, t_template *tmpl, int n);
|
||||
EXTERN void array_free(t_array *x);
|
||||
|
||||
/* --------------------- gpointers and stubs ---------------- */
|
||||
EXTERN t_gstub *gstub_new(t_glist *gl, t_array *a);
|
||||
EXTERN void gstub_cutoff(t_gstub *gs);
|
||||
EXTERN void gpointer_setglist(t_gpointer *gp, t_glist *glist, t_scalar *x);
|
||||
|
||||
/* --------------------- scalars ------------------------- */
|
||||
EXTERN void word_init(t_word *wp, t_template *tmpl, t_gpointer *gp);
|
||||
EXTERN void word_restore(t_word *wp, t_template *tmpl,
|
||||
int argc, t_atom *argv);
|
||||
EXTERN t_scalar *scalar_new(t_glist *owner,
|
||||
t_symbol *templatesym);
|
||||
EXTERN void scalar_getbasexy(t_scalar *x, float *basex, float *basey);
|
||||
|
||||
/* ------helper routines for "garrays" and "plots" -------------- */
|
||||
EXTERN int array_doclick(t_array *array, t_glist *glist, t_gobj *gobj,
|
||||
t_symbol *elemtemplatesym,
|
||||
float linewidth, float xloc, float xinc, float yloc,
|
||||
int xpix, int ypix, int shift, int alt, int dbl, int doit);
|
||||
|
||||
EXTERN void array_getcoordinate(t_glist *glist,
|
||||
char *elem, int xonset, int yonset, int wonset, int indx,
|
||||
float basex, float basey, float xinc,
|
||||
float *xp, float *yp, float *wp);
|
||||
|
||||
EXTERN int array_getfields(t_symbol *elemtemplatesym,
|
||||
t_canvas **elemtemplatecanvasp,
|
||||
t_template **elemtemplatep, int *elemsizep,
|
||||
int *xonsetp, int *yonsetp, int *wonsetp);
|
||||
|
||||
/* --------------------- templates ------------------------- */
|
||||
EXTERN t_template *template_new(t_symbol *sym, int argc, t_atom *argv);
|
||||
EXTERN void template_free(t_template *x);
|
||||
EXTERN int template_match(t_template *x1, t_template *x2);
|
||||
EXTERN int template_find_field(t_template *x, t_symbol *name, int *p_onset,
|
||||
int *p_type, t_symbol **p_arraytype);
|
||||
EXTERN t_float template_getfloat(t_template *x, t_symbol *fieldname, t_word *wp,
|
||||
int loud);
|
||||
EXTERN void template_setfloat(t_template *x, t_symbol *fieldname, t_word *wp,
|
||||
t_float f, int loud);
|
||||
EXTERN t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname,
|
||||
t_word *wp, int loud);
|
||||
EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname,
|
||||
t_word *wp, t_symbol *s, int loud);
|
||||
|
||||
EXTERN t_template *gtemplate_get(t_gtemplate *x);
|
||||
EXTERN t_template *template_findbyname(t_symbol *s);
|
||||
EXTERN t_canvas *template_findcanvas(t_template *tmpl);
|
||||
|
||||
EXTERN t_float template_getfloat(t_template *x, t_symbol *fieldname,
|
||||
t_word *wp, int loud);
|
||||
EXTERN void template_setfloat(t_template *x, t_symbol *fieldname,
|
||||
t_word *wp, t_float f, int loud);
|
||||
EXTERN t_symbol *template_getsymbol(t_template *x, t_symbol *fieldname,
|
||||
t_word *wp, int loud);
|
||||
EXTERN void template_setsymbol(t_template *x, t_symbol *fieldname,
|
||||
t_word *wp, t_symbol *s, int loud);
|
||||
|
||||
/* ----------------------- guiconnects, g_guiconnect.c --------- */
|
||||
EXTERN t_guiconnect *guiconnect_new(t_pd *who, t_symbol *sym);
|
||||
EXTERN void guiconnect_notarget(t_guiconnect *x, double timedelay);
|
||||
|
||||
/* ------------- IEMGUI routines used in other g_ files ---------------- */
|
||||
EXTERN t_symbol *iemgui_raute2dollar(t_symbol *s);
|
||||
EXTERN t_symbol *iemgui_dollar2raute(t_symbol *s);
|
||||
|
||||
#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,11 +6,4 @@
|
|||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -377,382 +377,3 @@ void gcanvas_setup(void)
|
|||
}
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -83,92 +83,3 @@ void highpass_setup(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -88,93 +88,3 @@ void highshelf_setup(void)
|
|||
}
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -224,229 +224,3 @@ void hlshelf_setup(void)
|
|||
}
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -215,220 +215,3 @@ void image_setup(void)
|
|||
}
|
||||
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -85,94 +85,3 @@ void lowpass_setup(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -89,94 +89,3 @@ void lowshelf_setup(void)
|
|||
}
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -648,653 +648,4 @@ defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
|
|||
|
||||
#define __m_pd_h_
|
||||
#endif /* __m_pd_h_ */
|
||||
/* 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. */
|
||||
|
||||
#ifndef __m_pd_h_
|
||||
|
||||
#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PD_VERSION 0.37 /* oops, don't use this... */ */
|
||||
#define PD_MAJOR_VERSION 0 /* ... use these two instead. */
|
||||
#define PD_MINOR_VERSION 37
|
||||
|
||||
/* old name for "MSW" flag -- we have to take it for the sake of many old
|
||||
"nmakefiles" for externs, which will define NT and not MSW */
|
||||
#if defined(NT) && !defined(MSW)
|
||||
#define MSW
|
||||
#endif
|
||||
|
||||
#ifdef MSW
|
||||
// #pragma warning( disable : 4091 )
|
||||
#pragma warning( disable : 4305 ) /* uncast const double to float */
|
||||
#pragma warning( disable : 4244 ) /* uncast float/int conversion etc. */
|
||||
#pragma warning( disable : 4101 ) /* unused automatic variables */
|
||||
#endif /* MSW */
|
||||
|
||||
/* the external storage class is "extern" in UNIX; in MSW it's ugly. */
|
||||
#ifdef MSW
|
||||
#ifdef PD_INTERNAL
|
||||
#define EXTERN __declspec(dllexport) extern
|
||||
#else
|
||||
#define EXTERN __declspec(dllimport) extern
|
||||
#endif /* PD_INTERNAL */
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif /* MSW */
|
||||
|
||||
/* and depending on the compiler, hidden data structures are
|
||||
declared differently: */
|
||||
#if defined( __GNUC__) || defined( __BORLANDC__ ) || defined( __MWERKS__ )
|
||||
#define EXTERN_STRUCT struct
|
||||
#else
|
||||
#define EXTERN_STRUCT extern struct
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(_SIZE_T) && !defined(_SIZE_T_)
|
||||
#include <stddef.h> /* just for size_t -- how lame! */
|
||||
#endif
|
||||
|
||||
#define MAXPDSTRING 1000 /* use this for anything you want */
|
||||
#define MAXPDARG 5 /* max number of args we can typecheck today */
|
||||
|
||||
/* signed and unsigned integer types the size of a pointer: */
|
||||
#ifdef __alpha__
|
||||
typedef long t_int;
|
||||
#else
|
||||
typedef int t_int;
|
||||
#endif
|
||||
|
||||
typedef float t_float; /* a floating-point number at most the same size */
|
||||
typedef float t_floatarg; /* floating-point type for function calls */
|
||||
|
||||
typedef struct _symbol
|
||||
{
|
||||
char *s_name;
|
||||
struct _class **s_thing;
|
||||
struct _symbol *s_next;
|
||||
} t_symbol;
|
||||
|
||||
EXTERN_STRUCT _array;
|
||||
#define t_array struct _array /* g_canvas.h */
|
||||
|
||||
/* pointers to glist and array elements go through a "stub" which sticks
|
||||
around after the glist or array is freed. The stub itself is deleted when
|
||||
both the glist/array is gone and the refcount is zero, ensuring that no
|
||||
gpointers are pointing here. */
|
||||
|
||||
#define GP_NONE 0 /* the stub points nowhere (has been cut off) */
|
||||
#define GP_GLIST 1 /* the stub points to a glist element */
|
||||
#define GP_ARRAY 2 /* ... or array */
|
||||
|
||||
typedef struct _gstub
|
||||
{
|
||||
union
|
||||
{
|
||||
struct _glist *gs_glist; /* glist we're in */
|
||||
struct _array *gs_array; /* array we're in */
|
||||
} gs_un;
|
||||
int gs_which; /* GP_GLIST/GP_ARRAY */
|
||||
int gs_refcount; /* number of gpointers pointing here */
|
||||
} t_gstub;
|
||||
|
||||
typedef struct _gpointer /* pointer to a gobj in a glist */
|
||||
{
|
||||
union
|
||||
{
|
||||
struct _scalar *gp_scalar; /* scalar we're in (if glist) */
|
||||
union word *gp_w; /* raw data (if array) */
|
||||
} gp_un;
|
||||
int gp_valid; /* number which must match gpointee */
|
||||
t_gstub *gp_stub; /* stub which points to glist/array */
|
||||
} t_gpointer;
|
||||
|
||||
typedef union word
|
||||
{
|
||||
t_float w_float;
|
||||
t_symbol *w_symbol;
|
||||
t_gpointer *w_gpointer;
|
||||
t_array *w_array;
|
||||
struct _glist *w_list;
|
||||
int w_index;
|
||||
} t_word;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
A_NULL,
|
||||
A_FLOAT,
|
||||
A_SYMBOL,
|
||||
A_POINTER,
|
||||
A_SEMI,
|
||||
A_COMMA,
|
||||
A_DEFFLOAT,
|
||||
A_DEFSYM,
|
||||
A_DOLLAR,
|
||||
A_DOLLSYM,
|
||||
A_GIMME,
|
||||
A_CANT
|
||||
} t_atomtype;
|
||||
|
||||
#define A_DEFSYMBOL A_DEFSYM /* better name for this */
|
||||
|
||||
typedef struct _atom
|
||||
{
|
||||
t_atomtype a_type;
|
||||
union word a_w;
|
||||
} t_atom;
|
||||
|
||||
EXTERN_STRUCT _class;
|
||||
#define t_class struct _class
|
||||
|
||||
EXTERN_STRUCT _outlet;
|
||||
#define t_outlet struct _outlet
|
||||
|
||||
EXTERN_STRUCT _inlet;
|
||||
#define t_inlet struct _inlet
|
||||
|
||||
EXTERN_STRUCT _binbuf;
|
||||
#define t_binbuf struct _binbuf
|
||||
|
||||
EXTERN_STRUCT _clock;
|
||||
#define t_clock struct _clock
|
||||
|
||||
EXTERN_STRUCT _outconnect;
|
||||
#define t_outconnect struct _outconnect
|
||||
|
||||
EXTERN_STRUCT _glist;
|
||||
#define t_glist struct _glist
|
||||
#define t_canvas struct _glist /* LATER lose this */
|
||||
|
||||
typedef t_class *t_pd; /* pure datum: nothing but a class pointer */
|
||||
|
||||
typedef struct _gobj /* a graphical object */
|
||||
{
|
||||
t_pd g_pd; /* pure datum header (class) */
|
||||
struct _gobj *g_next; /* next in list */
|
||||
} t_gobj;
|
||||
|
||||
typedef struct _scalar /* a graphical object holding data */
|
||||
{
|
||||
t_gobj sc_gobj; /* header for graphical object */
|
||||
t_symbol *sc_template; /* template name (LATER replace with pointer) */
|
||||
t_word sc_vec[1]; /* indeterminate-length array of words */
|
||||
} t_scalar;
|
||||
|
||||
typedef struct _text /* patchable object - graphical, with text */
|
||||
{
|
||||
t_gobj te_g; /* header for graphical object */
|
||||
t_binbuf *te_binbuf; /* holder for the text */
|
||||
t_outlet *te_outlet; /* linked list of outlets */
|
||||
t_inlet *te_inlet; /* linked list of inlets */
|
||||
short te_xpix; /* x&y location (within the toplevel) */
|
||||
short te_ypix;
|
||||
short te_width; /* requested width in chars, 0 if auto */
|
||||
unsigned int te_type:2; /* from defs below */
|
||||
} t_text;
|
||||
|
||||
#define T_TEXT 0 /* just a textual comment */
|
||||
#define T_OBJECT 1 /* a MAX style patchable object */
|
||||
#define T_MESSAGE 2 /* a MAX stype message */
|
||||
#define T_ATOM 3 /* a cell to display a number or symbol */
|
||||
|
||||
#define te_pd te_g.g_pd
|
||||
|
||||
/* t_object is synonym for t_text (LATER unify them) */
|
||||
|
||||
typedef struct _text t_object;
|
||||
|
||||
#define ob_outlet te_outlet
|
||||
#define ob_inlet te_inlet
|
||||
#define ob_binbuf te_binbuf
|
||||
#define ob_pd te_g.g_pd
|
||||
#define ob_g te_g
|
||||
|
||||
typedef void (*t_method)(void);
|
||||
typedef void *(*t_newmethod)( void);
|
||||
typedef void (*t_gotfn)(void *x, ...);
|
||||
|
||||
/* ---------------- pre-defined objects and symbols --------------*/
|
||||
EXTERN t_pd pd_objectmaker; /* factory for creating "object" boxes */
|
||||
EXTERN t_pd pd_canvasmaker; /* factory for creating canvases */
|
||||
EXTERN t_symbol s_pointer;
|
||||
EXTERN t_symbol s_float;
|
||||
EXTERN t_symbol s_symbol;
|
||||
EXTERN t_symbol s_bang;
|
||||
EXTERN t_symbol s_list;
|
||||
EXTERN t_symbol s_anything;
|
||||
EXTERN t_symbol s_signal;
|
||||
EXTERN t_symbol s__N;
|
||||
EXTERN t_symbol s__X;
|
||||
EXTERN t_symbol s_x;
|
||||
EXTERN t_symbol s_y;
|
||||
EXTERN t_symbol s_;
|
||||
|
||||
/* --------- prototypes from the central message system ----------- */
|
||||
EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
|
||||
EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
|
||||
EXTERN t_symbol *gensym(char *s);
|
||||
EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
|
||||
EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
|
||||
EXTERN void nullfn(void);
|
||||
EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...);
|
||||
#define mess0(x, s) ((*getfn((x), (s)))((x)))
|
||||
#define mess1(x, s, a) ((*getfn((x), (s)))((x), (a)))
|
||||
#define mess2(x, s, a,b) ((*getfn((x), (s)))((x), (a),(b)))
|
||||
#define mess3(x, s, a,b,c) ((*getfn((x), (s)))((x), (a),(b),(c)))
|
||||
#define mess4(x, s, a,b,c,d) ((*getfn((x), (s)))((x), (a),(b),(c),(d)))
|
||||
#define mess5(x, s, a,b,c,d,e) ((*getfn((x), (s)))((x), (a),(b),(c),(d),(e)))
|
||||
EXTERN void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv);
|
||||
EXTERN t_pd *pd_newest(void);
|
||||
|
||||
/* --------------- memory management -------------------- */
|
||||
EXTERN void *getbytes(size_t nbytes);
|
||||
EXTERN void *getzbytes(size_t nbytes);
|
||||
EXTERN void *copybytes(void *src, size_t nbytes);
|
||||
EXTERN void freebytes(void *x, size_t nbytes);
|
||||
EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize);
|
||||
|
||||
/* -------------------- atoms ----------------------------- */
|
||||
|
||||
#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0)
|
||||
#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0)
|
||||
#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \
|
||||
(atom)->a_w.w_gpointer = (gp))
|
||||
#define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f))
|
||||
#define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \
|
||||
(atom)->a_w.w_symbol = (s))
|
||||
#define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \
|
||||
(atom)->a_w.w_index = (n))
|
||||
#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \
|
||||
(atom)->a_w.w_symbol= (s))
|
||||
|
||||
EXTERN t_float atom_getfloat(t_atom *a);
|
||||
EXTERN t_int atom_getint(t_atom *a);
|
||||
EXTERN t_symbol *atom_getsymbol(t_atom *a);
|
||||
EXTERN t_symbol *atom_gensym(t_atom *a);
|
||||
EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv);
|
||||
EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv);
|
||||
EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv);
|
||||
|
||||
EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize);
|
||||
|
||||
/* ------------------ binbufs --------------- */
|
||||
|
||||
EXTERN t_binbuf *binbuf_new(void);
|
||||
EXTERN void binbuf_free(t_binbuf *x);
|
||||
EXTERN t_binbuf *binbuf_duplicate(t_binbuf *y);
|
||||
|
||||
EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size);
|
||||
EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp);
|
||||
EXTERN void binbuf_clear(t_binbuf *x);
|
||||
EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv);
|
||||
EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...);
|
||||
EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y);
|
||||
EXTERN void binbuf_addsemi(t_binbuf *x);
|
||||
EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv);
|
||||
EXTERN void binbuf_print(t_binbuf *x);
|
||||
EXTERN int binbuf_getnatom(t_binbuf *x);
|
||||
EXTERN t_atom *binbuf_getvec(t_binbuf *x);
|
||||
EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv);
|
||||
EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname,
|
||||
int crflag);
|
||||
EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname,
|
||||
int crflag);
|
||||
EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir,
|
||||
int crflag);
|
||||
EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir);
|
||||
EXTERN t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av,
|
||||
int tonew);
|
||||
|
||||
/* ------------------ clocks --------------- */
|
||||
|
||||
typedef long long t_time;
|
||||
EXTERN t_clock *clock_new(void *owner, t_method fn);
|
||||
EXTERN void clock_set(t_clock *x, t_time systime);
|
||||
EXTERN void clock_delay(t_clock *x, t_time delaytime);
|
||||
EXTERN void clock_unset(t_clock *x);
|
||||
EXTERN t_time clock_getlogicaltime(void);
|
||||
EXTERN t_time clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */
|
||||
EXTERN t_time clock_gettimesince(t_time prevsystime);
|
||||
EXTERN t_time clock_getsystimeafter(t_time delaytime);
|
||||
EXTERN void clock_free(t_clock *x);
|
||||
|
||||
/* ----------------- pure data ---------------- */
|
||||
EXTERN t_pd *pd_new(t_class *cls);
|
||||
EXTERN void pd_free(t_pd *x);
|
||||
EXTERN void pd_bind(t_pd *x, t_symbol *s);
|
||||
EXTERN void pd_unbind(t_pd *x, t_symbol *s);
|
||||
EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c);
|
||||
EXTERN void pd_pushsym(t_pd *x);
|
||||
EXTERN void pd_popsym(t_pd *x);
|
||||
EXTERN t_symbol *pd_getfilename(void);
|
||||
EXTERN t_symbol *pd_getdirname(void);
|
||||
EXTERN void pd_bang(t_pd *x);
|
||||
EXTERN void pd_pointer(t_pd *x, t_gpointer *gp);
|
||||
EXTERN void pd_float(t_pd *x, t_float f);
|
||||
EXTERN void pd_symbol(t_pd *x, t_symbol *s);
|
||||
EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv);
|
||||
EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv);
|
||||
#define pd_class(x) (*(x))
|
||||
|
||||
/* ----------------- pointers ---------------- */
|
||||
EXTERN void gpointer_init(t_gpointer *gp);
|
||||
EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto);
|
||||
EXTERN void gpointer_unset(t_gpointer *gp);
|
||||
EXTERN int gpointer_check(const t_gpointer *gp, int headok);
|
||||
|
||||
/* ----------------- patchable "objects" -------------- */
|
||||
EXTERN_STRUCT _inlet;
|
||||
#define t_inlet struct _inlet
|
||||
EXTERN_STRUCT _outlet;
|
||||
#define t_outlet struct _outlet
|
||||
|
||||
EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
|
||||
t_symbol *s2);
|
||||
EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp);
|
||||
EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp);
|
||||
EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp);
|
||||
EXTERN void inlet_free(t_inlet *x);
|
||||
|
||||
EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s);
|
||||
EXTERN void outlet_bang(t_outlet *x);
|
||||
EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp);
|
||||
EXTERN void outlet_float(t_outlet *x, t_float f);
|
||||
EXTERN void outlet_symbol(t_outlet *x, t_symbol *s);
|
||||
EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
|
||||
EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv);
|
||||
EXTERN t_symbol *outlet_getsymbol(t_outlet *x);
|
||||
EXTERN void outlet_free(t_outlet *x);
|
||||
EXTERN t_object *pd_checkobject(t_pd *x);
|
||||
|
||||
|
||||
/* -------------------- canvases -------------- */
|
||||
|
||||
EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir);
|
||||
|
||||
EXTERN void canvas_setargs(int argc, t_atom *argv);
|
||||
EXTERN void canvas_getargs(int *argcp, t_atom **argvp);
|
||||
EXTERN t_symbol *canvas_getcurrentdir(void);
|
||||
EXTERN t_glist *canvas_getcurrent(void);
|
||||
EXTERN void canvas_makefilename(t_glist *c, char *file,
|
||||
char *result,int resultsize);
|
||||
EXTERN t_symbol *canvas_getdir(t_glist *x);
|
||||
EXTERN int sys_fontwidth(int fontsize);
|
||||
EXTERN int sys_fontheight(int fontsize);
|
||||
EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b);
|
||||
|
||||
/* ---------------- widget behaviors ---------------------- */
|
||||
|
||||
EXTERN_STRUCT _widgetbehavior;
|
||||
#define t_widgetbehavior struct _widgetbehavior
|
||||
|
||||
EXTERN_STRUCT _parentwidgetbehavior;
|
||||
#define t_parentwidgetbehavior struct _parentwidgetbehavior
|
||||
EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x);
|
||||
|
||||
/* -------------------- classes -------------- */
|
||||
|
||||
#define CLASS_DEFAULT 0 /* flags for new classes below */
|
||||
#define CLASS_PD 1
|
||||
#define CLASS_GOBJ 2
|
||||
#define CLASS_PATCHABLE 3
|
||||
#define CLASS_NOINLET 8
|
||||
|
||||
#define CLASS_TYPEMASK 3
|
||||
|
||||
|
||||
EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod,
|
||||
t_method freemethod, size_t size, int flags, t_atomtype arg1, ...);
|
||||
EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s,
|
||||
t_atomtype type1, ...);
|
||||
EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
|
||||
t_atomtype arg1, ...);
|
||||
EXTERN void class_addbang(t_class *c, t_method fn);
|
||||
EXTERN void class_addpointer(t_class *c, t_method fn);
|
||||
EXTERN void class_doaddfloat(t_class *c, t_method fn);
|
||||
EXTERN void class_addsymbol(t_class *c, t_method fn);
|
||||
EXTERN void class_addlist(t_class *c, t_method fn);
|
||||
EXTERN void class_addanything(t_class *c, t_method fn);
|
||||
EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s);
|
||||
EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w);
|
||||
EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w);
|
||||
EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c);
|
||||
EXTERN char *class_getname(t_class *c);
|
||||
EXTERN char *class_gethelpname(t_class *c);
|
||||
EXTERN void class_setdrawcommand(t_class *c);
|
||||
EXTERN int class_isdrawcommand(t_class *c);
|
||||
EXTERN void class_domainsignalin(t_class *c, int onset);
|
||||
#define CLASS_MAINSIGNALIN(c, type, field) \
|
||||
class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
|
||||
|
||||
/* prototype for functions to save Pd's to a binbuf */
|
||||
typedef void (*t_savefn)(t_gobj *x, t_binbuf *b);
|
||||
EXTERN void class_setsavefn(t_class *c, t_savefn f);
|
||||
EXTERN t_savefn class_getsavefn(t_class *c);
|
||||
/* prototype for functions to open properties dialogs */
|
||||
typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist);
|
||||
EXTERN void class_setpropertiesfn(t_class *c, t_propertiesfn f);
|
||||
EXTERN t_propertiesfn class_getpropertiesfn(t_class *c);
|
||||
|
||||
#ifndef PD_CLASS_DEF
|
||||
#define class_addbang(x, y) class_addbang((x), (t_method)(y))
|
||||
#define class_addpointer(x, y) class_addpointer((x), (t_method)(y))
|
||||
#define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y))
|
||||
#define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y))
|
||||
#define class_addlist(x, y) class_addlist((x), (t_method)(y))
|
||||
#define class_addanything(x, y) class_addanything((x), (t_method)(y))
|
||||
#endif
|
||||
|
||||
/* ------------ printing --------------------------------- */
|
||||
EXTERN void post(char *fmt, ...);
|
||||
EXTERN void startpost(char *fmt, ...);
|
||||
EXTERN void poststring(char *s);
|
||||
EXTERN void postfloat(float f);
|
||||
EXTERN void postatom(int argc, t_atom *argv);
|
||||
EXTERN void endpost(void);
|
||||
EXTERN void error(char *fmt, ...);
|
||||
EXTERN void bug(char *fmt, ...);
|
||||
EXTERN void pd_error(void *object, char *fmt, ...);
|
||||
EXTERN void sys_logerror(char *object, char *s);
|
||||
EXTERN void sys_unixerror(char *object);
|
||||
EXTERN void sys_ouch(void);
|
||||
|
||||
#ifdef __linux__
|
||||
EXTERN char* sys_get_path( void);
|
||||
#endif
|
||||
EXTERN void sys_addpath(const char* p);
|
||||
|
||||
|
||||
/* ------------ system interface routines ------------------- */
|
||||
EXTERN int sys_isreadablefile(const char *name);
|
||||
EXTERN void sys_bashfilename(const char *from, char *to);
|
||||
EXTERN void sys_unbashfilename(const char *from, char *to);
|
||||
EXTERN int open_via_path(const char *name, const char *ext, const char *dir,
|
||||
char *dirresult, char **nameresult, unsigned int size, int bin);
|
||||
EXTERN int sched_geteventno(void);
|
||||
EXTERN double sys_getrealtime(void);
|
||||
|
||||
|
||||
/* ------------ threading ------------------- */
|
||||
/* T.Grill - see m_sched.c */
|
||||
|
||||
EXTERN void sys_lock(void);
|
||||
EXTERN void sys_unlock(void);
|
||||
EXTERN int sys_trylock(void);
|
||||
|
||||
|
||||
/* --------------- signals ----------------------------------- */
|
||||
|
||||
#define MAXLOGSIG 32
|
||||
#define MAXSIGSIZE (1 << MAXLOGSIG)
|
||||
#ifndef FIXEDPOINT
|
||||
typedef float t_sample;
|
||||
#else
|
||||
#include "m_fixed.h"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _signal
|
||||
{
|
||||
int s_n; /* number of points in the array */
|
||||
t_sample *s_vec; /* the array */
|
||||
float s_sr; /* sample rate */
|
||||
int s_refcount; /* number of times used */
|
||||
int s_isborrowed; /* whether we're going to borrow our array */
|
||||
struct _signal *s_borrowedfrom; /* signal to borrow it from */
|
||||
struct _signal *s_nextfree; /* next in freelist */
|
||||
struct _signal *s_nextused; /* next in used list */
|
||||
} t_signal;
|
||||
|
||||
|
||||
typedef t_int *(*t_perfroutine)(t_int *args);
|
||||
|
||||
EXTERN t_int *plus_perform(t_int *args);
|
||||
EXTERN t_int *zero_perform(t_int *args);
|
||||
EXTERN t_int *copy_perform(t_int *args);
|
||||
|
||||
EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n);
|
||||
EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n);
|
||||
EXTERN void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n);
|
||||
EXTERN void dsp_add_zero(t_sample *out, int n);
|
||||
|
||||
EXTERN int sys_getblksize(void);
|
||||
EXTERN float sys_getsr(void);
|
||||
EXTERN int sys_get_inchannels(void);
|
||||
EXTERN int sys_get_outchannels(void);
|
||||
|
||||
EXTERN void dsp_add(t_perfroutine f, int n, ...);
|
||||
EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec);
|
||||
EXTERN void pd_fft(float *buf, int npoints, int inverse);
|
||||
EXTERN int ilog2(int n);
|
||||
|
||||
EXTERN void mayer_fht(t_sample *fz, int n);
|
||||
EXTERN void mayer_fft(int n, t_sample *real, t_sample *imag);
|
||||
EXTERN void mayer_ifft(int n, t_sample *real, t_sample *imag);
|
||||
EXTERN void mayer_realfft(int n, t_sample *real);
|
||||
EXTERN void mayer_realifft(int n, t_sample *real);
|
||||
|
||||
EXTERN t_sample *cos_table;
|
||||
|
||||
#define LOGCOSTABSIZE 9
|
||||
#define COSTABSIZE (1<<LOGCOSTABSIZE)
|
||||
|
||||
EXTERN int canvas_suspend_dsp(void);
|
||||
EXTERN void canvas_resume_dsp(int oldstate);
|
||||
EXTERN void canvas_update_dsp(void);
|
||||
|
||||
/* IOhannes { (up/downsampling) */
|
||||
typedef struct _resample
|
||||
{
|
||||
int method; /* up/downsampling method ID */
|
||||
|
||||
t_int downsample; /* downsampling factor */
|
||||
t_int upsample; /* upsampling factor */
|
||||
|
||||
t_sample *s_vec; /* here we hold the resampled data */
|
||||
int s_n;
|
||||
|
||||
t_sample *coeffs; /* coefficients for filtering... */
|
||||
int coefsize;
|
||||
|
||||
t_sample *buffer; /* buffer for filtering */
|
||||
int bufsize;
|
||||
} t_resample;
|
||||
|
||||
EXTERN void resample_init(t_resample *x);
|
||||
EXTERN void resample_free(t_resample *x);
|
||||
|
||||
EXTERN void resample_dsp(t_resample *x, t_sample *in, int insize, t_sample *out, int outsize, int method);
|
||||
EXTERN void resamplefrom_dsp(t_resample *x, t_sample *in, int insize, int outsize, int method);
|
||||
EXTERN void resampleto_dsp(t_resample *x, t_sample *out, int insize, int outsize, int method);
|
||||
/* } IOhannes */
|
||||
|
||||
/* ----------------------- utility functions for signals -------------- */
|
||||
EXTERN float mtof(float);
|
||||
EXTERN float ftom(float);
|
||||
EXTERN float rmstodb(float);
|
||||
EXTERN float powtodb(float);
|
||||
EXTERN float dbtorms(float);
|
||||
EXTERN float dbtopow(float);
|
||||
|
||||
EXTERN float q8_sqrt(float);
|
||||
EXTERN float q8_rsqrt(float);
|
||||
#ifndef N32
|
||||
EXTERN float qsqrt(float); /* old names kept for extern compatibility */
|
||||
EXTERN float qrsqrt(float);
|
||||
#endif
|
||||
/* --------------------- data --------------------------------- */
|
||||
|
||||
/* graphical arrays */
|
||||
EXTERN_STRUCT _garray;
|
||||
#define t_garray struct _garray
|
||||
|
||||
EXTERN t_class *garray_class;
|
||||
EXTERN int garray_getfloatarray(t_garray *x, int *size, t_sample **vec);
|
||||
EXTERN float garray_get(t_garray *x, t_symbol *s, t_int indx);
|
||||
EXTERN void garray_redraw(t_garray *x);
|
||||
EXTERN int garray_npoints(t_garray *x);
|
||||
EXTERN char *garray_vec(t_garray *x);
|
||||
EXTERN void garray_resize(t_garray *x, t_floatarg f);
|
||||
EXTERN void garray_usedindsp(t_garray *x);
|
||||
EXTERN void garray_setsaveit(t_garray *x, int saveit);
|
||||
EXTERN t_class *scalar_class;
|
||||
|
||||
EXTERN t_float *value_get(t_symbol *s);
|
||||
EXTERN void value_release(t_symbol *s);
|
||||
EXTERN int value_getfloat(t_symbol *s, t_float *f);
|
||||
EXTERN int value_setfloat(t_symbol *s, t_float f);
|
||||
|
||||
/* ------- GUI interface - functions to send strings to TK --------- */
|
||||
EXTERN void sys_vgui(char *fmt, ...);
|
||||
EXTERN void sys_gui(char *s);
|
||||
|
||||
/* dialog window creation and destruction */
|
||||
EXTERN void gfxstub_new(t_pd *owner, void *key, const char *cmd);
|
||||
EXTERN void gfxstub_deleteforkey(void *key);
|
||||
|
||||
extern t_class *glob_pdobject; /* object to send "pd" messages */
|
||||
|
||||
/*------------- Max 0.26 compatibility --------------------*/
|
||||
|
||||
/* the following reflects the new way classes are laid out, with the class
|
||||
pointing to the messlist and not vice versa. Externs shouldn't feel it. */
|
||||
typedef t_class *t_externclass;
|
||||
|
||||
EXTERN void c_extern(t_externclass *cls, t_newmethod newroutine,
|
||||
t_method freeroutine, t_symbol *name, size_t size, int tiny, \
|
||||
t_atomtype arg1, ...);
|
||||
EXTERN void c_addmess(t_method fn, t_symbol *sel, t_atomtype arg1, ...);
|
||||
|
||||
#define t_getbytes getbytes
|
||||
#define t_freebytes freebytes
|
||||
#define t_resizebytes resizebytes
|
||||
#define typedmess pd_typedmess
|
||||
#define vmess pd_vmess
|
||||
|
||||
/* A definition to help gui objects straddle 0.34-0.35 changes. If this is
|
||||
defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
|
||||
|
||||
#define PD_USE_TE_XPIX
|
||||
|
||||
#if 0
|
||||
/* a test for NANs and denormals. Should only be necessary on i386. */
|
||||
#define PD_BADFLOAT(f) ((((*(unsigned int*)&(f))&0x7f800000)==0) || \
|
||||
(((*(unsigned int*)&(f))&0x7f800000)==0x7f800000))
|
||||
/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
|
||||
#define PD_BIGORSMALL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
|
||||
(((*(unsigned int*)&(f))&0x60000000)==0x60000000))
|
||||
#else
|
||||
#define PD_BADFLOAT(f) 0
|
||||
#define PD_BIGORSMALL(f) 0
|
||||
#endif
|
||||
|
||||
#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __m_pd_h_
|
||||
#endif /* __m_pd_h_ */
|
||||
|
|
|
|||
|
|
@ -32,35 +32,3 @@ install:
|
|||
%.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) $+
|
||||
|
|
@ -181,186 +181,4 @@ void moog_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,96 +83,3 @@ void notch_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -213,218 +213,4 @@ 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
|
|
@ -54,57 +54,3 @@ typedef struct _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
|
||||
|
|
|
|||
|
|
@ -310,315 +310,3 @@ void shell_setup(void)
|
|||
}
|
||||
|
||||
|
||||
/* (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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -51,56 +51,4 @@ void slider_setup(void) {
|
|||
#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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,66 +61,4 @@ void sliderh_setup(void) {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,16 +11,4 @@
|
|||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,21 +16,4 @@
|
|||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,60 +55,4 @@ void zerox_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,129 +124,4 @@ void biquad_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,141 +136,3 @@ void bp_tilde_setup(void)
|
|||
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"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,61 +56,4 @@ void clip_tilde_setup(void)
|
|||
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
|
|
@ -60,63 +60,3 @@ void cos_tilde_setup(void)
|
|||
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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,55 +50,4 @@ void dbtopow_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,56 +51,4 @@ void dbtorms_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,44 +41,3 @@ static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
|
|||
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -98,103 +98,4 @@ void delread_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,87 +82,4 @@ void delwrite_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,131 +124,3 @@ void env_tilde_setup(void )
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,47 +42,4 @@ void ftom_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,95 +90,4 @@ void hip_tilde_setup(void)
|
|||
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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,50 +45,4 @@ void d_intern_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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,105 +98,3 @@ void line_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -88,93 +88,4 @@ void lop_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,26 +23,3 @@ install:
|
|||
%.$(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) $+
|
||||
|
|
|
|||
|
|
@ -47,52 +47,4 @@ void mtof_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,59 +52,3 @@ void noise_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -84,91 +84,3 @@ void osc_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,72 +67,3 @@ void phasor_tilde_setup(void)
|
|||
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"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,56 +51,3 @@ void powtodb_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,81 +76,4 @@ void print_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,55 +50,4 @@ void rmstodb_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,111 +52,6 @@ float qrsqrt(float f) {return (q8_rsqrt(f)); }
|
|||
|
||||
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -73,78 +73,4 @@ void samphold_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,57 +54,3 @@ typedef struct _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
|
||||
|
|
|
|||
|
|
@ -195,294 +195,6 @@ static void sfread_state(t_sfread* x)
|
|||
|
||||
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -239,242 +239,3 @@ void sfwrite_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,70 +65,4 @@ void sig_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,60 +55,4 @@ void snapshot_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,80 +75,3 @@ void sqrt_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,134 +131,3 @@ void tabosc4_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,134 +131,3 @@ void tabplay_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,55 +50,4 @@ void tabread_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,107 +104,3 @@ void tabread4_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,100 +95,4 @@ void tabread_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,64 +59,3 @@ void tabreceive_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,100 +97,3 @@ void tabsend_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,87 +82,4 @@ void tabwrite_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,134 +131,3 @@ void tabwrite_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,138 +133,4 @@ void threshold_tilde_setup( void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,122 +117,3 @@ void vcf_tilde_setup(void)
|
|||
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"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,95 +90,4 @@ void vd_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,187 +182,4 @@ void vline_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,91 +86,3 @@ void vsnapshot_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,54 +51,3 @@ void wrap_tilde_setup(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,3 @@
|
|||
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
|
||||
|
|
|
|||
|
|
@ -840,845 +840,3 @@ void d_arithmetic_setup(void)
|
|||
min_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. */
|
||||
|
||||
/* arithmetic binops (+, -, *, /).
|
||||
If no creation argument is given, there are two signal inlets for vector/vector
|
||||
operation; otherwise it's vector/scalar and the second inlet takes a float
|
||||
to reset the value.
|
||||
*/
|
||||
|
||||
#include "m_pd.h"
|
||||
|
||||
/* ----------------------------- plus ----------------------------- */
|
||||
static t_class *plus_class, *scalarplus_class;
|
||||
|
||||
typedef struct _plus
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_plus;
|
||||
|
||||
typedef struct _scalarplus
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
t_float x_g; /* inlet value */
|
||||
} t_scalarplus;
|
||||
|
||||
static void *plus_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
if (argc > 1) post("+~: extra arguments ignored");
|
||||
if (argc)
|
||||
{
|
||||
t_scalarplus *x = (t_scalarplus *)pd_new(scalarplus_class);
|
||||
floatinlet_new(&x->x_obj, &x->x_g);
|
||||
x->x_g = atom_getfloatarg(0, argc, argv);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_plus *x = (t_plus *)pd_new(plus_class);
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
t_int *plus_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]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = *in1++ + *in2++;
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *plus_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in1 = (t_sample *)(w[1]);
|
||||
t_sample *in2 = (t_sample *)(w[2]);
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
|
||||
t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
|
||||
|
||||
t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
|
||||
t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
|
||||
|
||||
out[0] = f0 + g0; out[1] = f1 + g1; out[2] = f2 + g2; out[3] = f3 + g3;
|
||||
out[4] = f4 + g4; out[5] = f5 + g5; out[6] = f6 + g6; out[7] = f7 + g7;
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarplus_perform(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample f = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = *in++ + f;
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarplus_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample g = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
|
||||
t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
|
||||
|
||||
out[0] = f0 + g; out[1] = f1 + g; out[2] = f2 + g; out[3] = f3 + g;
|
||||
out[4] = f4 + g; out[5] = f5 + g; out[6] = f6 + g; out[7] = f7 + g;
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n)
|
||||
{
|
||||
if (n&7)
|
||||
dsp_add(plus_perform, 4, in1, in2, out, n);
|
||||
else
|
||||
dsp_add(plus_perf8, 4, in1, in2, out, n);
|
||||
}
|
||||
|
||||
static void plus_dsp(t_plus *x, t_signal **sp)
|
||||
{
|
||||
dsp_add_plus(sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void scalarplus_dsp(t_scalarplus *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(scalarplus_perform, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(scalarplus_perf8, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void plus_setup(void)
|
||||
{
|
||||
plus_class = class_new(gensym("+~"), (t_newmethod)plus_new, 0,
|
||||
sizeof(t_plus), 0, A_GIMME, 0);
|
||||
class_addmethod(plus_class, (t_method)plus_dsp, gensym("dsp"), 0);
|
||||
CLASS_MAINSIGNALIN(plus_class, t_plus, x_f);
|
||||
class_sethelpsymbol(plus_class, gensym("sigbinops"));
|
||||
scalarplus_class = class_new(gensym("+~"), 0, 0,
|
||||
sizeof(t_scalarplus), 0, 0);
|
||||
CLASS_MAINSIGNALIN(scalarplus_class, t_scalarplus, x_f);
|
||||
class_addmethod(scalarplus_class, (t_method)scalarplus_dsp, gensym("dsp"),
|
||||
0);
|
||||
class_sethelpsymbol(scalarplus_class, gensym("sigbinops"));
|
||||
}
|
||||
|
||||
/* ----------------------------- minus ----------------------------- */
|
||||
static t_class *minus_class, *scalarminus_class;
|
||||
|
||||
typedef struct _minus
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_minus;
|
||||
|
||||
typedef struct _scalarminus
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
t_float x_g;
|
||||
} t_scalarminus;
|
||||
|
||||
static void *minus_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
if (argc > 1) post("-~: extra arguments ignored");
|
||||
if (argc)
|
||||
{
|
||||
t_scalarminus *x = (t_scalarminus *)pd_new(scalarminus_class);
|
||||
floatinlet_new(&x->x_obj, &x->x_g);
|
||||
x->x_g = atom_getfloatarg(0, argc, argv);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_minus *x = (t_minus *)pd_new(minus_class);
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
t_int *minus_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]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = *in1++ - *in2++;
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *minus_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in1 = (t_sample *)(w[1]);
|
||||
t_sample *in2 = (t_sample *)(w[2]);
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
|
||||
t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
|
||||
|
||||
t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
|
||||
t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
|
||||
|
||||
out[0] = f0 - g0; out[1] = f1 - g1; out[2] = f2 - g2; out[3] = f3 - g3;
|
||||
out[4] = f4 - g4; out[5] = f5 - g5; out[6] = f6 - g6; out[7] = f7 - g7;
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarminus_perform(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample f = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = *in++ - f;
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarminus_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample g = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
|
||||
t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
|
||||
|
||||
out[0] = f0 - g; out[1] = f1 - g; out[2] = f2 - g; out[3] = f3 - g;
|
||||
out[4] = f4 - g; out[5] = f5 - g; out[6] = f6 - g; out[7] = f7 - g;
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void minus_dsp(t_minus *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(minus_perform, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(minus_perf8, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void scalarminus_dsp(t_scalarminus *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(scalarminus_perform, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(scalarminus_perf8, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void minus_setup(void)
|
||||
{
|
||||
minus_class = class_new(gensym("-~"), (t_newmethod)minus_new, 0,
|
||||
sizeof(t_minus), 0, A_GIMME, 0);
|
||||
CLASS_MAINSIGNALIN(minus_class, t_minus, x_f);
|
||||
class_addmethod(minus_class, (t_method)minus_dsp, gensym("dsp"), 0);
|
||||
class_sethelpsymbol(minus_class, gensym("sigbinops"));
|
||||
scalarminus_class = class_new(gensym("-~"), 0, 0,
|
||||
sizeof(t_scalarminus), 0, 0);
|
||||
CLASS_MAINSIGNALIN(scalarminus_class, t_scalarminus, x_f);
|
||||
class_addmethod(scalarminus_class, (t_method)scalarminus_dsp, gensym("dsp"),
|
||||
0);
|
||||
class_sethelpsymbol(scalarminus_class, gensym("sigbinops"));
|
||||
}
|
||||
|
||||
/* ----------------------------- times ----------------------------- */
|
||||
|
||||
static t_class *times_class, *scalartimes_class;
|
||||
|
||||
typedef struct _times
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_times;
|
||||
|
||||
typedef struct _scalartimes
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
t_float x_g;
|
||||
} t_scalartimes;
|
||||
|
||||
static void *times_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
if (argc > 1) post("*~: extra arguments ignored");
|
||||
if (argc)
|
||||
{
|
||||
t_scalartimes *x = (t_scalartimes *)pd_new(scalartimes_class);
|
||||
floatinlet_new(&x->x_obj, &x->x_g);
|
||||
x->x_g = atom_getfloatarg(0, argc, argv);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_times *x = (t_times *)pd_new(times_class);
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
t_int *times_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]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = mult(*in1++,*in2++);
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *times_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in1 = (t_sample *)(w[1]);
|
||||
t_sample *in2 = (t_sample *)(w[2]);
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
|
||||
t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
|
||||
|
||||
t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
|
||||
t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
|
||||
|
||||
out[0] = mult(f0,g0); out[1] = mult(f1,g1); out[2] = mult(f2,g2); out[3] = mult(f3,g3);
|
||||
out[4] = mult(f4,g4); out[5] = mult(f5,g5); out[6] = mult(f6,g6); out[7] = mult(f7,g7);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalartimes_perform(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample f = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = mult(*in++,f);
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalartimes_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample g = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
|
||||
t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
|
||||
|
||||
out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
|
||||
out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void times_dsp(t_times *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(times_perform, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(times_perf8, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void scalartimes_dsp(t_scalartimes *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(scalartimes_perform, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(scalartimes_perf8, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void times_setup(void)
|
||||
{
|
||||
times_class = class_new(gensym("*~"), (t_newmethod)times_new, 0,
|
||||
sizeof(t_times), 0, A_GIMME, 0);
|
||||
CLASS_MAINSIGNALIN(times_class, t_times, x_f);
|
||||
class_addmethod(times_class, (t_method)times_dsp, gensym("dsp"), 0);
|
||||
class_sethelpsymbol(times_class, gensym("sigbinops"));
|
||||
scalartimes_class = class_new(gensym("*~"), 0, 0,
|
||||
sizeof(t_scalartimes), 0, 0);
|
||||
CLASS_MAINSIGNALIN(scalartimes_class, t_scalartimes, x_f);
|
||||
class_addmethod(scalartimes_class, (t_method)scalartimes_dsp, gensym("dsp"),
|
||||
0);
|
||||
class_sethelpsymbol(scalartimes_class, gensym("sigbinops"));
|
||||
}
|
||||
|
||||
/* ----------------------------- over ----------------------------- */
|
||||
static t_class *over_class, *scalarover_class;
|
||||
|
||||
typedef struct _over
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_over;
|
||||
|
||||
typedef struct _scalarover
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
t_float x_g;
|
||||
} t_scalarover;
|
||||
|
||||
static void *over_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
if (argc > 1) post("/~: extra arguments ignored");
|
||||
if (argc)
|
||||
{
|
||||
t_scalarover *x = (t_scalarover *)pd_new(scalarover_class);
|
||||
floatinlet_new(&x->x_obj, &x->x_g);
|
||||
x->x_g = atom_getfloatarg(0, argc, argv);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_over *x = (t_over *)pd_new(over_class);
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
t_int *over_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]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--)
|
||||
{
|
||||
float g = *in2++;
|
||||
*out++ = (g ? *in1++ / g : 0);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *over_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in1 = (t_sample *)(w[1]);
|
||||
t_sample *in2 = (t_sample *)(w[2]);
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
|
||||
t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
|
||||
|
||||
t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
|
||||
t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
|
||||
|
||||
out[0] = (g0? idiv(f0,g0) : 0);
|
||||
out[1] = (g1? idiv(f1,g1) : 0);
|
||||
out[2] = (g2? idiv(f2,g2) : 0);
|
||||
out[3] = (g3? idiv(f3,g3) : 0);
|
||||
out[4] = (g4? idiv(f4,g4) : 0);
|
||||
out[5] = (g5? idiv(f5,g5) : 0);
|
||||
out[6] = (g6? idiv(f6,g6) : 0);
|
||||
out[7] = (g7? idiv(f7,g7) : 0);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarover_perform(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample f = idiv(ftofix(1.),ftofix(*(t_float *)(w[2])));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--) *out++ = mult(*in++,f);
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarover_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample g = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
if (g) g = idiv(ftofix(1.f),g);
|
||||
for (; n; n -= 8, in += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
|
||||
t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
|
||||
|
||||
out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
|
||||
out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void over_dsp(t_over *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(over_perform, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(over_perf8, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void scalarover_dsp(t_scalarover *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(scalarover_perform, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(scalarover_perf8, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void over_setup(void)
|
||||
{
|
||||
over_class = class_new(gensym("/~"), (t_newmethod)over_new, 0,
|
||||
sizeof(t_over), 0, A_GIMME, 0);
|
||||
CLASS_MAINSIGNALIN(over_class, t_over, x_f);
|
||||
class_addmethod(over_class, (t_method)over_dsp, gensym("dsp"), 0);
|
||||
class_sethelpsymbol(over_class, gensym("sigbinops"));
|
||||
scalarover_class = class_new(gensym("/~"), 0, 0,
|
||||
sizeof(t_scalarover), 0, 0);
|
||||
CLASS_MAINSIGNALIN(scalarover_class, t_scalarover, x_f);
|
||||
class_addmethod(scalarover_class, (t_method)scalarover_dsp, gensym("dsp"),
|
||||
0);
|
||||
class_sethelpsymbol(scalarover_class, gensym("sigbinops"));
|
||||
}
|
||||
|
||||
/* ----------------------------- max ----------------------------- */
|
||||
static t_class *max_class, *scalarmax_class;
|
||||
|
||||
typedef struct _max
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_max;
|
||||
|
||||
typedef struct _scalarmax
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
t_float x_g;
|
||||
} t_scalarmax;
|
||||
|
||||
static void *max_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
if (argc > 1) post("max~: extra arguments ignored");
|
||||
if (argc)
|
||||
{
|
||||
t_scalarmax *x = (t_scalarmax *)pd_new(scalarmax_class);
|
||||
floatinlet_new(&x->x_obj, &x->x_g);
|
||||
x->x_g = atom_getfloatarg(0, argc, argv);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_max *x = (t_max *)pd_new(max_class);
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
t_int *max_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]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--)
|
||||
{
|
||||
t_sample f = *in1++, g = *in2++;
|
||||
*out++ = (f > g ? f : g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *max_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in1 = (t_sample *)(w[1]);
|
||||
t_sample *in2 = (t_sample *)(w[2]);
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
|
||||
t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
|
||||
|
||||
t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
|
||||
t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
|
||||
|
||||
out[0] = (f0 > g0 ? f0 : g0); out[1] = (f1 > g1 ? f1 : g1);
|
||||
out[2] = (f2 > g2 ? f2 : g2); out[3] = (f3 > g3 ? f3 : g3);
|
||||
out[4] = (f4 > g4 ? f4 : g4); out[5] = (f5 > g5 ? f5 : g5);
|
||||
out[6] = (f6 > g6 ? f6 : g6); out[7] = (f7 > g7 ? f7 : g7);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarmax_perform(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample f = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--)
|
||||
{
|
||||
t_sample g = *in++;
|
||||
*out++ = (f > g ? f : g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarmax_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample g = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
|
||||
t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
|
||||
|
||||
out[0] = (f0 > g ? f0 : g); out[1] = (f1 > g ? f1 : g);
|
||||
out[2] = (f2 > g ? f2 : g); out[3] = (f3 > g ? f3 : g);
|
||||
out[4] = (f4 > g ? f4 : g); out[5] = (f5 > g ? f5 : g);
|
||||
out[6] = (f6 > g ? f6 : g); out[7] = (f7 > g ? f7 : g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void max_dsp(t_max *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(max_perform, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(max_perf8, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void scalarmax_dsp(t_scalarmax *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(scalarmax_perform, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(scalarmax_perf8, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void max_setup(void)
|
||||
{
|
||||
max_class = class_new(gensym("max~"), (t_newmethod)max_new, 0,
|
||||
sizeof(t_max), 0, A_GIMME, 0);
|
||||
CLASS_MAINSIGNALIN(max_class, t_max, x_f);
|
||||
class_addmethod(max_class, (t_method)max_dsp, gensym("dsp"), 0);
|
||||
class_sethelpsymbol(max_class, gensym("sigbinops"));
|
||||
scalarmax_class = class_new(gensym("max~"), 0, 0,
|
||||
sizeof(t_scalarmax), 0, 0);
|
||||
CLASS_MAINSIGNALIN(scalarmax_class, t_scalarmax, x_f);
|
||||
class_addmethod(scalarmax_class, (t_method)scalarmax_dsp, gensym("dsp"),
|
||||
0);
|
||||
class_sethelpsymbol(scalarmax_class, gensym("sigbinops"));
|
||||
}
|
||||
|
||||
/* ----------------------------- min ----------------------------- */
|
||||
static t_class *min_class, *scalarmin_class;
|
||||
|
||||
typedef struct _min
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_min;
|
||||
|
||||
typedef struct _scalarmin
|
||||
{
|
||||
t_object x_obj;
|
||||
t_float x_g;
|
||||
float x_f;
|
||||
} t_scalarmin;
|
||||
|
||||
static void *min_new(t_symbol *s, int argc, t_atom *argv)
|
||||
{
|
||||
if (argc > 1) post("min~: extra arguments ignored");
|
||||
if (argc)
|
||||
{
|
||||
t_scalarmin *x = (t_scalarmin *)pd_new(scalarmin_class);
|
||||
floatinlet_new(&x->x_obj, &x->x_g);
|
||||
x->x_g = atom_getfloatarg(0, argc, argv);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_min *x = (t_min *)pd_new(min_class);
|
||||
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
|
||||
outlet_new(&x->x_obj, &s_signal);
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
t_int *min_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]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--)
|
||||
{
|
||||
t_sample f = *in1++, g = *in2++;
|
||||
*out++ = (f < g ? f : g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *min_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in1 = (t_sample *)(w[1]);
|
||||
t_sample *in2 = (t_sample *)(w[2]);
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
|
||||
t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
|
||||
|
||||
t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
|
||||
t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
|
||||
|
||||
out[0] = (f0 < g0 ? f0 : g0); out[1] = (f1 < g1 ? f1 : g1);
|
||||
out[2] = (f2 < g2 ? f2 : g2); out[3] = (f3 < g3 ? f3 : g3);
|
||||
out[4] = (f4 < g4 ? f4 : g4); out[5] = (f5 < g5 ? f5 : g5);
|
||||
out[6] = (f6 < g6 ? f6 : g6); out[7] = (f7 < g7 ? f7 : g7);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarmin_perform(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample f = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--)
|
||||
{
|
||||
t_sample g = *in++;
|
||||
*out++ = (f < g ? f : g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *scalarmin_perf8(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]);
|
||||
t_sample g = ftofix(*(t_float *)(w[2]));
|
||||
t_sample *out = (t_sample *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
for (; n; n -= 8, in += 8, out += 8)
|
||||
{
|
||||
t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
|
||||
t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
|
||||
|
||||
out[0] = (f0 < g ? f0 : g); out[1] = (f1 < g ? f1 : g);
|
||||
out[2] = (f2 < g ? f2 : g); out[3] = (f3 < g ? f3 : g);
|
||||
out[4] = (f4 < g ? f4 : g); out[5] = (f5 < g ? f5 : g);
|
||||
out[6] = (f6 < g ? f6 : g); out[7] = (f7 < g ? f7 : g);
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void min_dsp(t_min *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(min_perform, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(min_perf8, 4,
|
||||
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void scalarmin_dsp(t_scalarmin *x, t_signal **sp)
|
||||
{
|
||||
if (sp[0]->s_n&7)
|
||||
dsp_add(scalarmin_perform, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
else
|
||||
dsp_add(scalarmin_perf8, 4, sp[0]->s_vec, &x->x_g,
|
||||
sp[1]->s_vec, sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void min_setup(void)
|
||||
{
|
||||
min_class = class_new(gensym("min~"), (t_newmethod)min_new, 0,
|
||||
sizeof(t_min), 0, A_GIMME, 0);
|
||||
CLASS_MAINSIGNALIN(min_class, t_min, x_f);
|
||||
class_addmethod(min_class, (t_method)min_dsp, gensym("dsp"), 0);
|
||||
class_sethelpsymbol(min_class, gensym("sigbinops"));
|
||||
scalarmin_class = class_new(gensym("min~"), 0, 0,
|
||||
sizeof(t_scalarmin), 0, 0);
|
||||
CLASS_MAINSIGNALIN(scalarmin_class, t_scalarmin, x_f);
|
||||
class_addmethod(scalarmin_class, (t_method)scalarmin_dsp, gensym("dsp"),
|
||||
0);
|
||||
class_sethelpsymbol(scalarmin_class, gensym("sigbinops"));
|
||||
}
|
||||
|
||||
/* ----------------------- global setup routine ---------------- */
|
||||
void d_arithmetic_setup(void)
|
||||
{
|
||||
plus_setup();
|
||||
minus_setup();
|
||||
times_setup();
|
||||
over_setup();
|
||||
max_setup();
|
||||
min_setup();
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -782,787 +782,4 @@ void d_ctl_setup(void)
|
|||
}
|
||||
|
||||
#endif
|
||||
/* 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. */
|
||||
|
||||
/* sig~ and line~ control-to-signal converters;
|
||||
snapshot~ signal-to-control converter.
|
||||
*/
|
||||
|
||||
#include "m_pd.h"
|
||||
#include "math.h"
|
||||
|
||||
/* -------------------------- sig~ ------------------------------ */
|
||||
static t_class *sig_tilde_class;
|
||||
|
||||
typedef struct _sig
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
} t_sig;
|
||||
|
||||
static t_int *sig_tilde_perform(t_int *w)
|
||||
{
|
||||
t_float f = *(t_float *)(w[1]);
|
||||
t_float *out = (t_float *)(w[2]);
|
||||
int n = (int)(w[3]);
|
||||
while (n--)
|
||||
*out++ = f;
|
||||
return (w+4);
|
||||
}
|
||||
|
||||
static t_int *sig_tilde_perf8(t_int *w)
|
||||
{
|
||||
t_float f = *(t_float *)(w[1]);
|
||||
t_float *out = (t_float *)(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);
|
||||
}
|
||||
|
||||
void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n)
|
||||
{
|
||||
if (n&7)
|
||||
dsp_add(sig_tilde_perform, 3, in, out, n);
|
||||
else
|
||||
dsp_add(sig_tilde_perf8, 3, in, out, n);
|
||||
}
|
||||
|
||||
static void sig_tilde_float(t_sig *x, t_float f)
|
||||
{
|
||||
x->x_f = 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 = f;
|
||||
outlet_new(&x->x_obj, gensym("signal"));
|
||||
return (x);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
#ifndef FIXEDPOINT
|
||||
|
||||
/* -------------------------- line~ ------------------------------ */
|
||||
static t_class *line_tilde_class;
|
||||
|
||||
typedef struct _line
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_target;
|
||||
float x_value;
|
||||
float x_biginc;
|
||||
float x_inc;
|
||||
float x_1overn;
|
||||
float x_dspticktomsec;
|
||||
float x_inletvalue;
|
||||
float x_inletwas;
|
||||
int x_ticksleft;
|
||||
int x_retarget;
|
||||
} t_line;
|
||||
|
||||
static t_int *line_tilde_perform(t_int *w)
|
||||
{
|
||||
t_line *x = (t_line *)(w[1]);
|
||||
t_float *out = (t_float *)(w[2]);
|
||||
int n = (int)(w[3]);
|
||||
float f = x->x_value;
|
||||
|
||||
if (PD_BIGORSMALL(f))
|
||||
x->x_value = f = 0;
|
||||
if (x->x_retarget)
|
||||
{
|
||||
int nticks = x->x_inletwas * x->x_dspticktomsec;
|
||||
if (!nticks) nticks = 1;
|
||||
x->x_ticksleft = nticks;
|
||||
x->x_biginc = (x->x_target - x->x_value)/(float)nticks;
|
||||
x->x_inc = x->x_1overn * x->x_biginc;
|
||||
x->x_retarget = 0;
|
||||
}
|
||||
if (x->x_ticksleft)
|
||||
{
|
||||
float 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_tilde_float(t_line *x, t_float f)
|
||||
{
|
||||
if (x->x_inletvalue <= 0)
|
||||
{
|
||||
x->x_target = x->x_value = f;
|
||||
x->x_ticksleft = x->x_retarget = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
x->x_target = f;
|
||||
x->x_retarget = 1;
|
||||
x->x_inletwas = x->x_inletvalue;
|
||||
x->x_inletvalue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void line_tilde_stop(t_line *x)
|
||||
{
|
||||
x->x_target = x->x_value;
|
||||
x->x_ticksleft = x->x_retarget = 0;
|
||||
}
|
||||
|
||||
static void line_tilde_dsp(t_line *x, t_signal **sp)
|
||||
{
|
||||
dsp_add(line_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
|
||||
x->x_1overn = 1./sp[0]->s_n;
|
||||
x->x_dspticktomsec = sp[0]->s_sr / (1000 * sp[0]->s_n);
|
||||
}
|
||||
|
||||
static void *line_tilde_new(void)
|
||||
{
|
||||
t_line *x = (t_line *)pd_new(line_tilde_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);
|
||||
}
|
||||
|
||||
static void line_tilde_setup(void)
|
||||
{
|
||||
line_tilde_class = class_new(gensym("line~"), line_tilde_new, 0,
|
||||
sizeof(t_line), 0, 0);
|
||||
class_addfloat(line_tilde_class, (t_method)line_tilde_float);
|
||||
class_addmethod(line_tilde_class, (t_method)line_tilde_dsp,
|
||||
gensym("dsp"), 0);
|
||||
class_addmethod(line_tilde_class, (t_method)line_tilde_stop,
|
||||
gensym("stop"), 0);
|
||||
}
|
||||
|
||||
/* -------------------------- vline~ ------------------------------ */
|
||||
static t_class *vline_tilde_class;
|
||||
|
||||
typedef struct _vseg
|
||||
{
|
||||
double s_targettime;
|
||||
double s_starttime;
|
||||
float s_target;
|
||||
struct _vseg *s_next;
|
||||
} t_vseg;
|
||||
|
||||
typedef struct _vline
|
||||
{
|
||||
t_object x_obj;
|
||||
double x_value;
|
||||
double x_inc;
|
||||
double x_referencetime;
|
||||
double x_samppermsec;
|
||||
double x_msecpersamp;
|
||||
double x_targettime;
|
||||
float 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_float *out = (t_float *)(w[2]);
|
||||
int n = (int)(w[3]), i;
|
||||
double f = x->x_value;
|
||||
double inc = x->x_inc;
|
||||
double msecpersamp = x->x_msecpersamp;
|
||||
double samppermsec = x->x_samppermsec;
|
||||
double timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp;
|
||||
t_vseg *s = x->x_list;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
double 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
|
||||
{
|
||||
double incpermsec = (s->s_target - f)/
|
||||
(s->s_targettime - s->s_starttime);
|
||||
f = f + incpermsec * (timenext - s->s_starttime);
|
||||
inc = 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 = x->x_inc = 0, x->x_targettime = 1e20;
|
||||
*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;
|
||||
x->x_target = x->x_value;
|
||||
x->x_targettime = 1e20;
|
||||
}
|
||||
|
||||
static void vline_tilde_float(t_vline *x, t_float f)
|
||||
{
|
||||
double timenow = clock_gettimesince(x->x_referencetime);
|
||||
float inlet1 = (x->x_inlet1 < 0 ? 0 : x->x_inlet1);
|
||||
float inlet2 = x->x_inlet2;
|
||||
double starttime = timenow + inlet2;
|
||||
t_vseg *s1, *s2, *deletefrom = 0, *snew;
|
||||
if (PD_BIGORSMALL(f))
|
||||
f = 0;
|
||||
|
||||
/* negative delay input means stop and jump immediately to new value */
|
||||
if (inlet2 < 0)
|
||||
{
|
||||
x->x_value = f;
|
||||
vline_tilde_stop(x);
|
||||
return;
|
||||
}
|
||||
snew = (t_vseg *)t_getbytes(sizeof(*snew));
|
||||
/* 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 = ((double)(sp[0]->s_sr)) / 1000;
|
||||
x->x_msecpersamp = ((double)1000) / 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;
|
||||
x->x_targettime = 1e20;
|
||||
return (x);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
/* -------------------------- snapshot~ ------------------------------ */
|
||||
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_float *in = (t_float *)(w[1]);
|
||||
t_float *out = (t_float *)(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, x->x_value);
|
||||
}
|
||||
|
||||
static void snapshot_tilde_set(t_snapshot *x, t_floatarg f)
|
||||
{
|
||||
x->x_value = f;
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
/* -------------------------- vsnapshot~ ------------------------------ */
|
||||
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_float *in = (t_float *)(w[1]);
|
||||
t_vsnapshot *x = (t_vsnapshot *)(w[2]);
|
||||
t_float *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));
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- env~ - simple envelope follower. ----------------- */
|
||||
|
||||
#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 */
|
||||
float *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 */
|
||||
float x_result; /* result to output */
|
||||
float x_sumbuf[MAXOVERLAP]; /* summing buffer */
|
||||
float x_f;
|
||||
} t_sigenv;
|
||||
|
||||
t_class *env_tilde_class;
|
||||
static void env_tilde_tick(t_sigenv *x);
|
||||
|
||||
static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod)
|
||||
{
|
||||
int npoints = fnpoints;
|
||||
int period = fperiod;
|
||||
t_sigenv *x;
|
||||
float *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(float) * (npoints + MAXVSTAKEN))))
|
||||
{
|
||||
error("env: couldn't allocate buffer");
|
||||
return (0);
|
||||
}
|
||||
x = (t_sigenv *)pd_new(env_tilde_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] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints;
|
||||
for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
|
||||
x->x_clock = clock_new(x, (t_method)env_tilde_tick);
|
||||
x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
|
||||
x->x_f = 0;
|
||||
return (x);
|
||||
}
|
||||
|
||||
static t_int *env_tilde_perform(t_int *w)
|
||||
{
|
||||
t_sigenv *x = (t_sigenv *)(w[1]);
|
||||
t_float *in = (t_float *)(w[2]);
|
||||
int n = (int)(w[3]);
|
||||
int count;
|
||||
float *sump;
|
||||
in += n;
|
||||
for (count = x->x_phase, sump = x->x_sumbuf;
|
||||
count < x->x_npoints; count += x->x_realperiod, sump++)
|
||||
{
|
||||
float *hp = x->x_buf + count;
|
||||
float *fp = in;
|
||||
float sum = *sump;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
fp--;
|
||||
sum += *hp++ * (*fp * *fp);
|
||||
}
|
||||
*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 env_tilde_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(env_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
|
||||
if (sp[0]->s_n > MAXVSTAKEN) bug("env_tilde_dsp");
|
||||
}
|
||||
|
||||
static void env_tilde_tick(t_sigenv *x) /* callback function for the clock */
|
||||
{
|
||||
outlet_float(x->x_outlet, powtodb(x->x_result));
|
||||
}
|
||||
|
||||
static void env_tilde_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 )
|
||||
{
|
||||
env_tilde_class = class_new(gensym("env~"), (t_newmethod)env_tilde_new,
|
||||
(t_method)env_tilde_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
|
||||
CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, x_f);
|
||||
class_addmethod(env_tilde_class, (t_method)env_tilde_dsp, gensym("dsp"), 0);
|
||||
}
|
||||
|
||||
/* --------------------- threshold~ ----------------------------- */
|
||||
|
||||
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 */
|
||||
float x_hithresh; /* value of high threshold */
|
||||
float 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 = hithresh;
|
||||
x->x_hideadtime = hideadtime;
|
||||
x->x_lothresh = 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)
|
||||
{
|
||||
float *in1 = (float *)(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);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
/* ------------------------ global setup routine ------------------------- */
|
||||
|
||||
void d_ctl_setup(void)
|
||||
{
|
||||
sig_tilde_setup();
|
||||
line_tilde_setup();
|
||||
vline_tilde_setup();
|
||||
snapshot_tilde_setup();
|
||||
vsnapshot_tilde_setup();
|
||||
env_tilde_setup();
|
||||
threshold_tilde_setup();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -182,187 +182,3 @@ void d_dac_setup(void)
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -317,322 +317,3 @@ void d_delay_setup(void)
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -342,347 +342,4 @@ void d_fft_setup(void)
|
|||
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
|
|
@ -545,550 +545,4 @@ void d_filter_setup(void)
|
|||
sigbiquad_setup();
|
||||
sigsamphold_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. */
|
||||
|
||||
/* "filters", both linear and nonlinear.
|
||||
*/
|
||||
#include "m_pd.h"
|
||||
#include <math.h>
|
||||
|
||||
/* ---------------- hip~ - 1-pole 1-zero hipass filter. ----------------- */
|
||||
|
||||
typedef struct hipctl
|
||||
{
|
||||
float c_x;
|
||||
float 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)
|
||||
{
|
||||
if (f < 0) f = 0;
|
||||
x->x_hz = f;
|
||||
x->x_ctl->c_coef = 1 - f * (2 * 3.14159) / x->x_sr;
|
||||
if (x->x_ctl->c_coef < 0)
|
||||
x->x_ctl->c_coef = 0;
|
||||
else if (x->x_ctl->c_coef > 1)
|
||||
x->x_ctl->c_coef = 1;
|
||||
}
|
||||
|
||||
static t_int *sighip_perform(t_int *w)
|
||||
{
|
||||
float *in = (float *)(w[1]);
|
||||
float *out = (float *)(w[2]);
|
||||
t_hipctl *c = (t_hipctl *)(w[3]);
|
||||
int n = (t_int)(w[4]);
|
||||
int i;
|
||||
float last = c->c_x;
|
||||
float coef = c->c_coef;
|
||||
if (coef < 1)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
float new = *in++ + coef * last;
|
||||
*out++ = new - last;
|
||||
last = new;
|
||||
}
|
||||
if (PD_BIGORSMALL(last))
|
||||
last = 0;
|
||||
c->c_x = last;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
*out++ = *in++;
|
||||
c->c_x = 0;
|
||||
}
|
||||
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 sighip_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);
|
||||
}
|
||||
|
||||
/* ---------------- lop~ - 1-pole lopass filter. ----------------- */
|
||||
|
||||
typedef struct lopctl
|
||||
{
|
||||
float c_x;
|
||||
float 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)
|
||||
{
|
||||
if (f < 0) f = 0;
|
||||
x->x_hz = f;
|
||||
x->x_ctl->c_coef = f * (2 * 3.14159) / x->x_sr;
|
||||
if (x->x_ctl->c_coef > 1)
|
||||
x->x_ctl->c_coef = 1;
|
||||
else if (x->x_ctl->c_coef < 0)
|
||||
x->x_ctl->c_coef = 0;
|
||||
}
|
||||
|
||||
static void siglop_clear(t_siglop *x, t_floatarg q)
|
||||
{
|
||||
x->x_cspace.c_x = 0;
|
||||
}
|
||||
|
||||
static t_int *siglop_perform(t_int *w)
|
||||
{
|
||||
float *in = (float *)(w[1]);
|
||||
float *out = (float *)(w[2]);
|
||||
t_lopctl *c = (t_lopctl *)(w[3]);
|
||||
int n = (t_int)(w[4]);
|
||||
int i;
|
||||
float last = c->c_x;
|
||||
float coef = c->c_coef;
|
||||
float feedback = 1 - coef;
|
||||
for (i = 0; i < n; i++)
|
||||
last = *out++ = coef * *in++ + feedback * last;
|
||||
if (PD_BIGORSMALL(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 siglop_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);
|
||||
}
|
||||
|
||||
/* ---------------- bp~ - 2-pole bandpass filter. ----------------- */
|
||||
|
||||
typedef struct bpctl
|
||||
{
|
||||
float c_x1;
|
||||
float c_x2;
|
||||
float c_coef1;
|
||||
float c_coef2;
|
||||
float 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 = 2.0f * sigbp_qcos(omega) * r;
|
||||
x->x_ctl->c_coef2 = - r * r;
|
||||
x->x_ctl->c_gain = 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)
|
||||
{
|
||||
float *in = (float *)(w[1]);
|
||||
float *out = (float *)(w[2]);
|
||||
t_bpctl *c = (t_bpctl *)(w[3]);
|
||||
int n = (t_int)(w[4]);
|
||||
int i;
|
||||
float last = c->c_x1;
|
||||
float prev = c->c_x2;
|
||||
float coef1 = c->c_coef1;
|
||||
float coef2 = c->c_coef2;
|
||||
float gain = c->c_gain;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
float output = *in++ + coef1 * last + coef2 * prev;
|
||||
*out++ = gain * output;
|
||||
prev = last;
|
||||
last = output;
|
||||
}
|
||||
if (PD_BIGORSMALL(last))
|
||||
last = 0;
|
||||
if (PD_BIGORSMALL(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 sigbp_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);
|
||||
}
|
||||
|
||||
/* ---------------- biquad~ - raw biquad filter ----------------- */
|
||||
|
||||
typedef struct biquadctl
|
||||
{
|
||||
float c_x1;
|
||||
float c_x2;
|
||||
float c_fb1;
|
||||
float c_fb2;
|
||||
float c_ff1;
|
||||
float c_ff2;
|
||||
float 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)
|
||||
{
|
||||
float *in = (float *)(w[1]);
|
||||
float *out = (float *)(w[2]);
|
||||
t_biquadctl *c = (t_biquadctl *)(w[3]);
|
||||
int n = (t_int)(w[4]);
|
||||
int i;
|
||||
float last = c->c_x1;
|
||||
float prev = c->c_x2;
|
||||
float fb1 = c->c_fb1;
|
||||
float fb2 = c->c_fb2;
|
||||
float ff1 = c->c_ff1;
|
||||
float ff2 = c->c_ff2;
|
||||
float ff3 = c->c_ff3;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
float output = *in++ + fb1 * last + fb2 * prev;
|
||||
if (PD_BIGORSMALL(output))
|
||||
output = 0;
|
||||
*out++ = ff1 * output + ff2 * last + 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 = fb1;
|
||||
c->c_fb2 = fb2;
|
||||
c->c_ff1 = ff1;
|
||||
c->c_ff2 = ff2;
|
||||
c->c_ff3 = 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 sigbiquad_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);
|
||||
}
|
||||
|
||||
/* ---------------- samphold~ - sample and hold ----------------- */
|
||||
|
||||
typedef struct sigsamphold
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
float x_lastin;
|
||||
float 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)
|
||||
{
|
||||
float *in1 = (float *)(w[1]);
|
||||
float *in2 = (float *)(w[2]);
|
||||
float *out = (float *)(w[3]);
|
||||
t_sigsamphold *x = (t_sigsamphold *)(w[4]);
|
||||
int n = (t_int)(w[5]);
|
||||
int i;
|
||||
float lastin = x->x_lastin;
|
||||
float lastout = x->x_lastout;
|
||||
for (i = 0; i < n; i++, *in1++)
|
||||
{
|
||||
float 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 = 1e20;
|
||||
}
|
||||
|
||||
static void sigsamphold_set(t_sigsamphold *x, t_float f)
|
||||
{
|
||||
x->x_lastout = f;
|
||||
}
|
||||
|
||||
void sigsamphold_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);
|
||||
}
|
||||
|
||||
/* ------------------------ setup routine ------------------------- */
|
||||
|
||||
void d_filter_setup(void)
|
||||
{
|
||||
sighip_setup();
|
||||
siglop_setup();
|
||||
sigbp_setup();
|
||||
sigbiquad_setup();
|
||||
sigsamphold_setup();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,311 +306,3 @@ void d_global_setup(void)
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,519 +514,4 @@ int main()
|
|||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
** Algorithm: complex multiplication
|
||||
**
|
||||
** Performance: Bad accuracy, great speed.
|
||||
**
|
||||
** The simplest, way of generating trig values. Note, this method is
|
||||
** not stable, and errors accumulate rapidly.
|
||||
**
|
||||
** Computation: 2 *, 1 + per value.
|
||||
*/
|
||||
|
||||
|
||||
#include "m_fixed.h"
|
||||
|
||||
|
||||
#define TRIG_FAST
|
||||
|
||||
#ifdef TRIG_FAST
|
||||
char mtrig_algorithm[] = "Simple";
|
||||
#define TRIG_VARS \
|
||||
t_fixed t_c,t_s;
|
||||
#define TRIG_INIT(k,c,s) \
|
||||
{ \
|
||||
t_c = fcostab[k]; \
|
||||
t_s = fsintab[k]; \
|
||||
c = itofix(1); \
|
||||
s = 0; \
|
||||
}
|
||||
#define TRIG_NEXT(k,c,s) \
|
||||
{ \
|
||||
t_fixed t = c; \
|
||||
c = mult(t,t_c) - mult(s,t_s); \
|
||||
s = mult(t,t_s) + mult(s,t_c); \
|
||||
}
|
||||
#define TRIG_23(k,c1,s1,c2,s2,c3,s3) \
|
||||
{ \
|
||||
c2 = mult(c1,c1) - mult(s1,s1); \
|
||||
s2 = (mult(c1,s1)<<2); \
|
||||
c3 = mult(c2,c1) - mult(s2,s1); \
|
||||
s3 = mult(c2,s1) + mult(s2,c1); \
|
||||
}
|
||||
#endif
|
||||
#define TRIG_RESET(k,c,s)
|
||||
|
||||
/*
|
||||
** Algorithm: O. Buneman's trig generator.
|
||||
**
|
||||
** Performance: Good accuracy, mediocre speed.
|
||||
**
|
||||
** Manipulates a log(n) table to stably create n evenly spaced trig
|
||||
** values. The newly generated values lay halfway between two
|
||||
** known values, and are calculated by appropriatelly scaling the
|
||||
** average of the known trig values appropriatelly according to the
|
||||
** angle between them. This process is inherently stable; and is
|
||||
** about as accurate as most trig library functions. The errors
|
||||
** caused by this code segment are primarily due to the less stable
|
||||
** method to calculate values for 2t and s 3t. Note: I believe this
|
||||
** algorithm is patented(!), see readme file for more details.
|
||||
**
|
||||
** Computation: 1 +, 1 *, much integer math, per trig value
|
||||
**
|
||||
*/
|
||||
|
||||
#ifdef TRIG_GOOD
|
||||
#define TRIG_VARS \
|
||||
int t_lam=0; \
|
||||
double coswrk[TRIG_TABLE_SIZE],sinwrk[TRIG_TABLE_SIZE];
|
||||
#define TRIG_INIT(k,c,s) \
|
||||
{ \
|
||||
int i; \
|
||||
for (i=0 ; i<=k ; i++) \
|
||||
{coswrk[i]=fcostab[i];sinwrk[i]=fsintab[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]); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define TRIG_TAB_SIZE 22
|
||||
|
||||
static long long halsec[TRIG_TAB_SIZE]= {1,2,3};
|
||||
|
||||
#define FFTmult(x,y) mult(x,y)
|
||||
|
||||
|
||||
|
||||
|
||||
#include "d_imayer_tables.h"
|
||||
|
||||
#define SQRT2 ftofix(1.414213562373095048801688724209698)
|
||||
|
||||
|
||||
void imayer_fht(t_fixed *fz, int n)
|
||||
{
|
||||
int k,k1,k2,k3,k4,kx;
|
||||
t_fixed *fi,*fn,*gi;
|
||||
TRIG_VARS;
|
||||
|
||||
for (k1=1,k2=0;k1<n;k1++)
|
||||
{
|
||||
t_fixed 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)
|
||||
{
|
||||
t_fixed 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)
|
||||
{
|
||||
t_fixed 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 = FFTmult(SQRT2,bc4);
|
||||
bg2 = FFTmult(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
|
||||
{
|
||||
t_fixed 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
|
||||
{
|
||||
t_fixed 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 = FFTmult(SQRT2, gi[k3]);
|
||||
g2 = FFTmult(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++)
|
||||
{
|
||||
t_fixed c2,s2;
|
||||
TRIG_NEXT(k,c1,s1);
|
||||
c2 = FFTmult(c1,c1) - FFTmult(s1,s1);
|
||||
s2 = 2*FFTmult(c1,s1);
|
||||
fn = fz + n;
|
||||
fi = fz +ii;
|
||||
gi = fz +k1-ii;
|
||||
do
|
||||
{
|
||||
t_fixed a,b,g0,f0,f1,g1,f2,g2,f3,g3;
|
||||
b = FFTmult(s2,fi[k1]) - FFTmult(c2,gi[k1]);
|
||||
a = FFTmult(c2,fi[k1]) + FFTmult(s2,gi[k1]);
|
||||
f1 = fi[0 ] - a;
|
||||
f0 = fi[0 ] + a;
|
||||
g1 = gi[0 ] - b;
|
||||
g0 = gi[0 ] + b;
|
||||
b = FFTmult(s2,fi[k3]) - FFTmult(c2,gi[k3]);
|
||||
a = FFTmult(c2,fi[k3]) + FFTmult(s2,gi[k3]);
|
||||
f3 = fi[k2] - a;
|
||||
f2 = fi[k2] + a;
|
||||
g3 = gi[k2] - b;
|
||||
g2 = gi[k2] + b;
|
||||
b = FFTmult(s1,f2) - FFTmult(c1,g3);
|
||||
a = FFTmult(c1,f2) + FFTmult(s1,g3);
|
||||
fi[k2] = f0 - a;
|
||||
fi[0 ] = f0 + a;
|
||||
gi[k3] = g1 - b;
|
||||
gi[k1] = g1 + b;
|
||||
b = FFTmult(c1,g2) - FFTmult(s1,f3);
|
||||
a = FFTmult(s1,g2) + FFTmult(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 imayer_fft(int n, t_fixed *real, t_fixed *imag)
|
||||
{
|
||||
t_fixed a,b,c,d;
|
||||
t_fixed 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)>>1; real[j] = (q-t)>>1;
|
||||
imag[i] = (s-r)>>1; imag[j] = (s+r)>>1;
|
||||
}
|
||||
imayer_fht(real,n);
|
||||
imayer_fht(imag,n);
|
||||
}
|
||||
|
||||
void imayer_ifft(int n, t_fixed *real, t_fixed *imag)
|
||||
{
|
||||
t_fixed a,b,c,d;
|
||||
t_fixed q,r,s,t;
|
||||
int i,j,k;
|
||||
imayer_fht(real,n);
|
||||
imayer_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)>>1; imag[j] = (s-r)>>1;
|
||||
real[i] = (q-t)>>1; real[j] = (q+t)>>1;
|
||||
}
|
||||
}
|
||||
|
||||
void imayer_realfft(int n, t_fixed *real)
|
||||
{
|
||||
t_fixed a,b,c,d;
|
||||
int i,j,k;
|
||||
imayer_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)>>1;
|
||||
real[i] = (a+b)>>1;
|
||||
}
|
||||
}
|
||||
|
||||
void imayer_realifft(int n, t_fixed *real)
|
||||
{
|
||||
t_fixed 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);
|
||||
}
|
||||
imayer_fht(real,n);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
static double dfcostab[TRIG_TAB_SIZE]=
|
||||
{
|
||||
.00000000000000000000000000000000000000000000000000,
|
||||
.70710678118654752440084436210484903928483593768847,
|
||||
.92387953251128675612818318939678828682241662586364,
|
||||
.98078528040323044912618223613423903697393373089333,
|
||||
.99518472667219688624483695310947992157547486872985,
|
||||
.99879545620517239271477160475910069444320361470461,
|
||||
.99969881869620422011576564966617219685006108125772,
|
||||
.99992470183914454092164649119638322435060646880221,
|
||||
.99998117528260114265699043772856771617391725094433,
|
||||
.99999529380957617151158012570011989955298763362218,
|
||||
.99999882345170190992902571017152601904826792288976,
|
||||
.99999970586288221916022821773876567711626389934930,
|
||||
.99999992646571785114473148070738785694820115568892,
|
||||
.99999998161642929380834691540290971450507605124278,
|
||||
.99999999540410731289097193313960614895889430318945,
|
||||
.99999999885102682756267330779455410840053741619428,
|
||||
.99999999971275670684941397221864177608908945791828,
|
||||
.99999999992818917670977509588385049026048033310951
|
||||
};
|
||||
static double dfsintab[TRIG_TAB_SIZE]=
|
||||
{
|
||||
1.0000000000000000000000000000000000000000000000000,
|
||||
.70710678118654752440084436210484903928483593768846,
|
||||
.38268343236508977172845998403039886676134456248561,
|
||||
.19509032201612826784828486847702224092769161775195,
|
||||
.09801714032956060199419556388864184586113667316749,
|
||||
.04906767432741801425495497694268265831474536302574,
|
||||
.02454122852291228803173452945928292506546611923944,
|
||||
.01227153828571992607940826195100321214037231959176,
|
||||
.00613588464915447535964023459037258091705788631738,
|
||||
.00306795676296597627014536549091984251894461021344,
|
||||
.00153398018628476561230369715026407907995486457522,
|
||||
.00076699031874270452693856835794857664314091945205,
|
||||
.00038349518757139558907246168118138126339502603495,
|
||||
.00019174759731070330743990956198900093346887403385,
|
||||
.00009587379909597734587051721097647635118706561284,
|
||||
.00004793689960306688454900399049465887274686668768,
|
||||
.00002396844980841821872918657716502182009476147489,
|
||||
.00001198422490506970642152156159698898480473197753
|
||||
};
|
||||
|
||||
static double dhalsec[TRIG_TAB_SIZE]=
|
||||
{
|
||||
0,
|
||||
0,
|
||||
.54119610014619698439972320536638942006107206337801,
|
||||
.50979557910415916894193980398784391368261849190893,
|
||||
.50241928618815570551167011928012092247859337193963,
|
||||
.50060299823519630134550410676638239611758632599591,
|
||||
.50015063602065098821477101271097658495974913010340,
|
||||
.50003765191554772296778139077905492847503165398345,
|
||||
.50000941253588775676512870469186533538523133757983,
|
||||
.50000235310628608051401267171204408939326297376426,
|
||||
.50000058827484117879868526730916804925780637276181,
|
||||
.50000014706860214875463798283871198206179118093251,
|
||||
.50000003676714377807315864400643020315103490883972,
|
||||
.50000000919178552207366560348853455333939112569380,
|
||||
.50000000229794635411562887767906868558991922348920,
|
||||
.50000000057448658687873302235147272458812263401372,
|
||||
.50000000014362164661654736863252589967935073278768,
|
||||
.50000000003590541164769084922906986545517021050714
|
||||
};
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int writetables()
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("/* Tables for fixed point lookup with %d bit precision*/\n\n",fix1);
|
||||
|
||||
printf("static int fsintab[TRIG_TAB_SIZE]= {\n");
|
||||
|
||||
for (i=0;i<TRIG_TAB_SIZE-1;i++)
|
||||
printf("%ld, \n",ftofix(dfsintab[i]));
|
||||
printf("%ld }; \n",ftofix(dfsintab[i]));
|
||||
|
||||
|
||||
printf("\n\nstatic int fcostab[TRIG_TAB_SIZE]= {\n");
|
||||
|
||||
for (i=0;i<TRIG_TAB_SIZE-1;i++)
|
||||
printf("%ld, \n",ftofix(dfcostab[i]));
|
||||
printf("%ld }; \n",ftofix(dfcostab[i]));
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define OUTPUT \
|
||||
fprintf(stderr,"Integer - Float\n");\
|
||||
for (i=0;i<NP;i++)\
|
||||
fprintf(stderr,"%f %f --> %f %f\n",fixtof(r[i]),fixtof(im[i]),\
|
||||
fr[i],fim[i]);\
|
||||
fprintf(stderr,"\n\n");
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
t_fixed r[256];
|
||||
t_fixed im[256];
|
||||
float fr[256];
|
||||
float fim[256];
|
||||
|
||||
|
||||
#if 1
|
||||
writetables();
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
t_fixed c1,s1,c2,s2,c3,s3;
|
||||
int k;
|
||||
int i;
|
||||
|
||||
TRIG_VARS;
|
||||
|
||||
for (k=2;k<10;k+=2) {
|
||||
TRIG_INIT(k,c1,s1);
|
||||
for (i=0;i<8;i++) {
|
||||
TRIG_NEXT(k,c1,s1);
|
||||
TRIG_23(k,c1,s1,c2,s2,c3,s3);
|
||||
printf("TRIG value k=%d,%d val1 = %f %f\n",k,i,fixtof(c1),fixtof(s1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
#define NP 16
|
||||
|
||||
for (i=0;i<NP;i++) {
|
||||
fr[i] = 0.;
|
||||
r[i] = 0.;
|
||||
fim[i] = 0.;
|
||||
im[i] = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i=0;i<NP;i++) {
|
||||
if (i&1) {
|
||||
fr[i] = 0.1*i;
|
||||
r[i] = ftofix(0.1*i);
|
||||
}
|
||||
else {
|
||||
fr[i] = 0.;
|
||||
r[i] = 0.;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
for (i=0;i<NP;i++) {
|
||||
fr[i] = 0.1;
|
||||
r[i] = ftofix(0.1);
|
||||
}
|
||||
#endif
|
||||
|
||||
r[1] = ftofix(0.1);
|
||||
fr[1] = 0.1;
|
||||
|
||||
|
||||
|
||||
/* TEST RUN */
|
||||
|
||||
OUTPUT
|
||||
|
||||
imayer_fft(NP,r,im);
|
||||
mayer_fft(NP,fr,fim);
|
||||
// imayer_fht(r,NP);
|
||||
// mayer_fht(fr,NP);
|
||||
|
||||
#if 1
|
||||
for (i=0;i<NP;i++) {
|
||||
r[i] = mult(ftofix(0.01),r[i]);
|
||||
fr[i] = 0.01*fr[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
OUTPUT
|
||||
|
||||
|
||||
imayer_fft(NP,r,im);
|
||||
mayer_fft(NP,fr,fim);
|
||||
|
||||
OUTPUT
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,53 +48,4 @@ static int fcostab[TRIG_TAB_SIZE]= {
|
|||
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 };
|
||||
|
|
|
|||
|
|
@ -571,576 +571,3 @@ void d_math_setup(void)
|
|||
class_sethelpsymbol(powtodb_tilde_class, s);
|
||||
}
|
||||
|
||||
/* 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," in this distribution. */
|
||||
|
||||
/* mathematical functions and other transfer functions, including tilde
|
||||
versions of stuff from x_acoustics.c.
|
||||
*/
|
||||
|
||||
#include "m_pd.h"
|
||||
#include <math.h>
|
||||
#define LOGTEN 2.302585092994
|
||||
|
||||
/* ------------------------- clip~ -------------------------- */
|
||||
static t_class *clip_class;
|
||||
|
||||
typedef struct _clip
|
||||
{
|
||||
t_object x_obj;
|
||||
float x_f;
|
||||
t_sample x_lo;
|
||||
t_sample 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_float *in = (t_float *)(w[2]);
|
||||
t_float *out = (t_float *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
while (n--)
|
||||
{
|
||||
float f = *in++;
|
||||
if (f < x->x_lo) f = x->x_lo;
|
||||
if (f > x->x_hi) f = x->x_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);
|
||||
}
|
||||
|
||||
static void clip_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);
|
||||
}
|
||||
|
||||
/* 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 sigrsqrt_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);
|
||||
}
|
||||
|
||||
|
||||
/* sigsqrt - square root good to 8 mantissa bits */
|
||||
|
||||
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 sigsqrt_setup(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------ wrap~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2);
|
||||
t_int n = *(t_int *)(w+3);
|
||||
while (n--)
|
||||
{
|
||||
float f = *in++;
|
||||
int k = f;
|
||||
if (f > 0) *out++ = f-k;
|
||||
else *out++ = f - (k-1);
|
||||
}
|
||||
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 sigwrap_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);
|
||||
}
|
||||
|
||||
/* ------------------------------ mtof_tilde~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
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 <= -1500) *out = 0;
|
||||
else
|
||||
{
|
||||
if (f > 1499) f = 1499;
|
||||
*out = 8.17579891564 * exp(.0577622650 * f);
|
||||
}
|
||||
}
|
||||
return (w + 4);
|
||||
}
|
||||
|
||||
static void mtof_tilde_dsp(t_mtof_tilde *x, t_signal **sp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------ ftom_tilde~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
*out = (f > 0 ? 17.3123405046 * log(.12231220585 * f) : -1500);
|
||||
}
|
||||
return (w + 4);
|
||||
}
|
||||
|
||||
static void ftom_tilde_dsp(t_ftom_tilde *x, t_signal **sp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------ dbtorms~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------ rmstodb~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------ dbtopow~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------ powtodb~ -------------------------- */
|
||||
|
||||
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)
|
||||
{
|
||||
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 + 10./LOGTEN * log(f);
|
||||
*out = (g < 0 ? 0 : g);
|
||||
}
|
||||
}
|
||||
return (w + 4);
|
||||
}
|
||||
|
||||
static void powtodb_tilde_dsp(t_powtodb_tilde *x, t_signal **sp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------ global setup routine ------------------------- */
|
||||
|
||||
void d_math_setup(void)
|
||||
{
|
||||
t_symbol *s = gensym("acoustics~.pd");
|
||||
clip_setup();
|
||||
sigrsqrt_setup();
|
||||
sigsqrt_setup();
|
||||
sigwrap_setup();
|
||||
mtof_tilde_setup();
|
||||
ftom_tilde_setup();
|
||||
dbtorms_tilde_setup();
|
||||
rmstodb_tilde_setup();
|
||||
dbtopow_tilde_setup();
|
||||
powtodb_tilde_setup();
|
||||
|
||||
class_sethelpsymbol(mtof_tilde_class, s);
|
||||
class_sethelpsymbol(ftom_tilde_class, s);
|
||||
class_sethelpsymbol(dbtorms_tilde_class, s);
|
||||
class_sethelpsymbol(rmstodb_tilde_class, s);
|
||||
class_sethelpsymbol(dbtopow_tilde_class, s);
|
||||
class_sethelpsymbol(powtodb_tilde_class, s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -417,422 +417,4 @@ void mayer_realifft(int n, REAL *real)
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,268 +257,3 @@ void d_misc_setup(void)
|
|||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -533,538 +533,3 @@ void d_osc_setup(void)
|
|||
noise_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. */
|
||||
|
||||
/* sinusoidal oscillator and table lookup; see also tabosc4~ in d_array.c.
|
||||
*/
|
||||
|
||||
#include "m_pd.h"
|
||||
#include "math.h"
|
||||
|
||||
#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
|
||||
|
||||
/* machine-dependent definitions. These ifdefs really
|
||||
should have been by CPU type and not by operating system! */
|
||||
#ifdef IRIX
|
||||
/* big-endian. Most significant byte is at low address in memory */
|
||||
#define HIOFFSET 0 /* word offset to find MSB */
|
||||
#define LOWOFFSET 1 /* word offset to find LSB */
|
||||
#define int32 long /* a data type that has 32 bits */
|
||||
#else
|
||||
#ifdef MSW
|
||||
/* little-endian; most significant byte is at highest address */
|
||||
#define HIOFFSET 1
|
||||
#define LOWOFFSET 0
|
||||
#define int32 long
|
||||
#else
|
||||
#ifdef __FreeBSD__
|
||||
#include <machine/endian.h>
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define HIOFFSET 1
|
||||
#define LOWOFFSET 0
|
||||
#else
|
||||
#define HIOFFSET 0 /* word offset to find MSB */
|
||||
#define LOWOFFSET 1 /* word offset to find LSB */
|
||||
#endif /* BYTE_ORDER */
|
||||
#include <sys/types.h>
|
||||
#define int32 int32_t
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
|
||||
#error No byte order defined
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define HIOFFSET 1
|
||||
#define LOWOFFSET 0
|
||||
#else
|
||||
#define HIOFFSET 0 /* word offset to find MSB */
|
||||
#define LOWOFFSET 1 /* word offset to find LSB */
|
||||
#endif /* __BYTE_ORDER */
|
||||
|
||||
#include <sys/types.h>
|
||||
#define int32 int32_t
|
||||
|
||||
#else
|
||||
#ifdef MACOSX
|
||||
#define HIOFFSET 0 /* word offset to find MSB */
|
||||
#define LOWOFFSET 1 /* word offset to find LSB */
|
||||
#define int32 int /* a data type that has 32 bits */
|
||||
|
||||
#endif /* MACOSX */
|
||||
#endif /* __linux__ */
|
||||
#endif /* MSW */
|
||||
#endif /* SGI */
|
||||
|
||||
union tabfudge
|
||||
{
|
||||
double tf_d;
|
||||
int32 tf_i[2];
|
||||
};
|
||||
|
||||
|
||||
/* -------------------------- phasor~ ------------------------------ */
|
||||
static t_class *phasor_class, *scalarphasor_class;
|
||||
|
||||
#if 1 /* in the style of R. Hoeldrich (ICMC 1995 Banff) */
|
||||
|
||||
typedef struct _phasor
|
||||
{
|
||||
t_object x_obj;
|
||||
double x_phase;
|
||||
float x_conv;
|
||||
float 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 = 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_float *in = (t_float *)(w[2]);
|
||||
t_float *out = (t_float *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
double dphase = x->x_phase + UNITBIT32;
|
||||
union tabfudge tf;
|
||||
int normhipart;
|
||||
float conv = x->x_conv;
|
||||
|
||||
tf.tf_d = UNITBIT32;
|
||||
normhipart = tf.tf_i[HIOFFSET];
|
||||
tf.tf_d = dphase;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
dphase += *in++ * conv;
|
||||
*out++ = tf.tf_d - UNITBIT32;
|
||||
tf.tf_d = dphase;
|
||||
}
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
x->x_phase = tf.tf_d - UNITBIT32;
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void phasor_dsp(t_phasor *x, t_signal **sp)
|
||||
{
|
||||
x->x_conv = 1./sp[0]->s_sr;
|
||||
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 = f;
|
||||
}
|
||||
|
||||
static void phasor_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);
|
||||
}
|
||||
|
||||
#endif /* Hoeldrich version */
|
||||
|
||||
/* ------------------------ cos~ ----------------------------- */
|
||||
|
||||
float *cos_table;
|
||||
|
||||
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_float *in = (t_float *)(w[1]);
|
||||
t_float *out = (t_float *)(w[2]);
|
||||
int n = (int)(w[3]);
|
||||
float *tab = cos_table, *addr, f1, f2, frac;
|
||||
double dphase;
|
||||
int normhipart;
|
||||
union tabfudge tf;
|
||||
|
||||
tf.tf_d = UNITBIT32;
|
||||
normhipart = tf.tf_i[HIOFFSET];
|
||||
|
||||
#if 0 /* this is the readable version of the code. */
|
||||
while (n--)
|
||||
{
|
||||
dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
|
||||
tf.tf_d = dphase;
|
||||
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
*out++ = f1 + frac * (f2 - f1);
|
||||
}
|
||||
#endif
|
||||
#if 1 /* this is the same, unwrapped by hand. */
|
||||
dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
|
||||
tf.tf_d = dphase;
|
||||
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
while (--n)
|
||||
{
|
||||
dphase = (double)(*in++ * (float)(COSTABSIZE)) + UNITBIT32;
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
tf.tf_d = dphase;
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
|
||||
*out++ = f1 + frac * (f2 - f1);
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
}
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
*out++ = f1 + frac * (f2 - f1);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
static void cos_maketable(void)
|
||||
{
|
||||
int i;
|
||||
float *fp, phase, phsinc = (2. * 3.14159) / COSTABSIZE;
|
||||
union tabfudge tf;
|
||||
|
||||
if (cos_table) return;
|
||||
cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
|
||||
for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
|
||||
fp++, phase += phsinc)
|
||||
*fp = cos(phase);
|
||||
|
||||
/* here we check at startup whether the byte alignment
|
||||
is as we declared it. If not, the code has to be
|
||||
recompiled the other way. */
|
||||
tf.tf_d = UNITBIT32 + 0.5;
|
||||
if ((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000)
|
||||
bug("cos~: unexpected machine alignment");
|
||||
}
|
||||
|
||||
static void cos_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);
|
||||
cos_maketable();
|
||||
}
|
||||
|
||||
/* ------------------------ osc~ ----------------------------- */
|
||||
|
||||
static t_class *osc_class, *scalarosc_class;
|
||||
|
||||
typedef struct _osc
|
||||
{
|
||||
t_object x_obj;
|
||||
double x_phase;
|
||||
float x_conv;
|
||||
float 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 = 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_float *in = (t_float *)(w[2]);
|
||||
t_float *out = (t_float *)(w[3]);
|
||||
int n = (int)(w[4]);
|
||||
float *tab = cos_table, *addr, f1, f2, frac;
|
||||
double dphase = x->x_phase + UNITBIT32;
|
||||
int normhipart;
|
||||
union tabfudge tf;
|
||||
float conv = x->x_conv;
|
||||
|
||||
tf.tf_d = UNITBIT32;
|
||||
normhipart = tf.tf_i[HIOFFSET];
|
||||
#if 0
|
||||
while (n--)
|
||||
{
|
||||
tf.tf_d = dphase;
|
||||
dphase += *in++ * conv;
|
||||
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
*out++ = f1 + frac * (f2 - f1);
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
tf.tf_d = dphase;
|
||||
dphase += *in++ * conv;
|
||||
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
while (--n)
|
||||
{
|
||||
tf.tf_d = dphase;
|
||||
f1 = addr[0];
|
||||
dphase += *in++ * conv;
|
||||
f2 = addr[1];
|
||||
addr = tab + (tf.tf_i[HIOFFSET] & (COSTABSIZE-1));
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
*out++ = f1 + frac * (f2 - f1);
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
}
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
*out++ = f1 + frac * (f2 - f1);
|
||||
#endif
|
||||
|
||||
tf.tf_d = UNITBIT32 * COSTABSIZE;
|
||||
normhipart = tf.tf_i[HIOFFSET];
|
||||
tf.tf_d = dphase + (UNITBIT32 * COSTABSIZE - UNITBIT32);
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
x->x_phase = tf.tf_d - UNITBIT32 * COSTABSIZE;
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
static void osc_dsp(t_osc *x, t_signal **sp)
|
||||
{
|
||||
x->x_conv = COSTABSIZE/sp[0]->s_sr;
|
||||
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 = COSTABSIZE * f;
|
||||
}
|
||||
|
||||
static void osc_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);
|
||||
|
||||
cos_maketable();
|
||||
}
|
||||
|
||||
/* ---------------- vcf~ - 2-pole bandpass filter. ----------------- */
|
||||
|
||||
typedef struct vcfctl
|
||||
{
|
||||
float c_re;
|
||||
float c_im;
|
||||
float c_q;
|
||||
float 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 = 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 ? f : 0.f);
|
||||
}
|
||||
|
||||
static t_int *sigvcf_perform(t_int *w)
|
||||
{
|
||||
float *in1 = (float *)(w[1]);
|
||||
float *in2 = (float *)(w[2]);
|
||||
float *out1 = (float *)(w[3]);
|
||||
float *out2 = (float *)(w[4]);
|
||||
t_vcfctl *c = (t_vcfctl *)(w[5]);
|
||||
int n = (t_int)(w[6]);
|
||||
int i;
|
||||
float re = c->c_re, re2;
|
||||
float im = c->c_im;
|
||||
float q = c->c_q;
|
||||
float qinv = (q > 0? 1.0f/q : 0);
|
||||
float ampcorrect = 2.0f - 2.0f / (q + 2.0f);
|
||||
float isr = c->c_isr;
|
||||
float coefr, coefi;
|
||||
float *tab = cos_table, *addr, f1, f2, frac;
|
||||
double dphase;
|
||||
int normhipart, tabindex;
|
||||
union tabfudge tf;
|
||||
|
||||
tf.tf_d = UNITBIT32;
|
||||
normhipart = tf.tf_i[HIOFFSET];
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
float cf, cfindx, r, oneminusr;
|
||||
cf = *in2++ * isr;
|
||||
if (cf < 0) cf = 0;
|
||||
cfindx = cf * (float)(COSTABSIZE/6.28318f);
|
||||
r = (qinv > 0 ? 1 - cf * qinv : 0);
|
||||
if (r < 0) r = 0;
|
||||
oneminusr = 1.0f - r;
|
||||
dphase = ((double)(cfindx)) + UNITBIT32;
|
||||
tf.tf_d = dphase;
|
||||
tabindex = tf.tf_i[HIOFFSET] & (COSTABSIZE-1);
|
||||
addr = tab + tabindex;
|
||||
tf.tf_i[HIOFFSET] = normhipart;
|
||||
frac = tf.tf_d - UNITBIT32;
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
coefr = r * (f1 + frac * (f2 - f1));
|
||||
|
||||
addr = tab + ((tabindex - (COSTABSIZE/4)) & (COSTABSIZE-1));
|
||||
f1 = addr[0];
|
||||
f2 = addr[1];
|
||||
coefi = r * (f1 + frac * (f2 - f1));
|
||||
|
||||
f1 = *in1++;
|
||||
re2 = re;
|
||||
*out1++ = re = ampcorrect * oneminusr * f1
|
||||
+ coefr * re2 - coefi * im;
|
||||
*out2++ = im = coefi * re2 + coefr * im;
|
||||
}
|
||||
if (PD_BIGORSMALL(re))
|
||||
re = 0;
|
||||
if (PD_BIGORSMALL(im))
|
||||
im = 0;
|
||||
c->c_re = re;
|
||||
c->c_im = im;
|
||||
return (w+7);
|
||||
}
|
||||
|
||||
static void sigvcf_dsp(t_sigvcf *x, t_signal **sp)
|
||||
{
|
||||
x->x_ctl->c_isr = 6.28318f/sp[0]->s_sr;
|
||||
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 sigvcf_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);
|
||||
}
|
||||
|
||||
/* -------------------------- noise~ ------------------------------ */
|
||||
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_float *out = (t_float *)(w[1]);
|
||||
int *vp = (int *)(w[2]);
|
||||
int n = (int)(w[3]);
|
||||
int val = *vp;
|
||||
while (n--)
|
||||
{
|
||||
*out++ = ((float)((val & 0x7fffffff) - 0x40000000)) *
|
||||
(float)(1.0 / 0x40000000);
|
||||
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);
|
||||
}
|
||||
|
||||
static void noise_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);
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------- global setup routine ---------------- */
|
||||
void d_osc_setup(void)
|
||||
{
|
||||
phasor_setup();
|
||||
cos_setup();
|
||||
osc_setup();
|
||||
sigvcf_setup();
|
||||
noise_setup();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,228 +223,4 @@ void resampleto_dsp(t_resample *x,
|
|||
|
||||
return;
|
||||
}
|
||||
/* 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. */
|
||||
|
||||
/* upsampling/downsampling methods for inlet~/outlet~
|
||||
*
|
||||
* mfg.gfd.uil
|
||||
* IOhannes
|
||||
*
|
||||
* 2509:forum::für::umläute:2001
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "m_pd.h"
|
||||
|
||||
/* --------------------- up/down-sampling --------------------- */
|
||||
t_int *downsampling_perform_0(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]); /* original signal */
|
||||
t_sample *out = (t_sample *)(w[2]); /* downsampled signal */
|
||||
int down = (int)(w[3]); /* downsampling factor */
|
||||
int parent = (int)(w[4]); /* original vectorsize */
|
||||
|
||||
int n=parent/down;
|
||||
|
||||
while(n--){
|
||||
*out++=*in;
|
||||
in+=down;
|
||||
}
|
||||
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *upsampling_perform_0(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]); /* original signal */
|
||||
t_sample *out = (t_sample *)(w[2]); /* upsampled signal */
|
||||
int up = (int)(w[3]); /* upsampling factor */
|
||||
int parent = (int)(w[4]); /* original vectorsize */
|
||||
|
||||
int n=parent*up;
|
||||
t_sample *dummy = out;
|
||||
|
||||
while(n--)*out++=0;
|
||||
|
||||
n = parent;
|
||||
out = dummy;
|
||||
while(n--){
|
||||
*out=*in++;
|
||||
out+=up;
|
||||
}
|
||||
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *upsampling_perform_hold(t_int *w)
|
||||
{
|
||||
t_sample *in = (t_sample *)(w[1]); /* original signal */
|
||||
t_sample *out = (t_sample *)(w[2]); /* upsampled signal */
|
||||
int up = (int)(w[3]); /* upsampling factor */
|
||||
int parent = (int)(w[4]); /* original vectorsize */
|
||||
int i=up;
|
||||
|
||||
int n=parent;
|
||||
t_sample *dum_out = out;
|
||||
t_sample *dum_in = in;
|
||||
|
||||
while (i--) {
|
||||
n = parent;
|
||||
out = dum_out+i;
|
||||
in = dum_in;
|
||||
while(n--){
|
||||
*out=*in++;
|
||||
out+=up;
|
||||
}
|
||||
}
|
||||
return (w+5);
|
||||
}
|
||||
|
||||
t_int *upsampling_perform_linear(t_int *w)
|
||||
{
|
||||
t_resample *x= (t_resample *)(w[1]);
|
||||
t_sample *in = (t_sample *)(w[2]); /* original signal */
|
||||
t_sample *out = (t_sample *)(w[3]); /* upsampled signal */
|
||||
int up = (int)(w[4]); /* upsampling factor */
|
||||
int parent = (int)(w[5]); /* original vectorsize */
|
||||
int length = parent*up;
|
||||
int n;
|
||||
t_sample *fp;
|
||||
t_sample a=*x->buffer, b=*in;
|
||||
|
||||
|
||||
for (n=0; n<length; n++) {
|
||||
t_float findex = (t_float)(n+1)/up;
|
||||
int index = findex;
|
||||
t_sample frac=findex - index;
|
||||
if (frac==0.)frac=1.;
|
||||
*out++ = frac * b + (1.-frac) * a;
|
||||
fp = in+index;
|
||||
b=*fp;
|
||||
a=(index)?*(fp-1):a;
|
||||
}
|
||||
|
||||
*x->buffer = a;
|
||||
return (w+6);
|
||||
}
|
||||
|
||||
/* ----------------------- public -------------------------------- */
|
||||
|
||||
/* utils */
|
||||
|
||||
void resample_init(t_resample *x)
|
||||
{
|
||||
x->method=0;
|
||||
|
||||
x->downsample=x->upsample=1;
|
||||
|
||||
x->s_n = x->coefsize = x->bufsize = 0;
|
||||
x->s_vec = x->coeffs = x->buffer = 0;
|
||||
}
|
||||
|
||||
void resample_free(t_resample *x)
|
||||
{
|
||||
if (x->s_n) t_freebytes(x->s_vec, x->s_n*sizeof(*x->s_vec));
|
||||
if (x->coefsize) t_freebytes(x->coeffs, x->coefsize*sizeof(*x->coeffs));
|
||||
if (x->bufsize) t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer));
|
||||
|
||||
x->s_n = x->coefsize = x->bufsize = 0;
|
||||
x->s_vec = x->coeffs = x->buffer = 0;
|
||||
}
|
||||
|
||||
|
||||
/* dsp-adding */
|
||||
|
||||
void resample_dsp(t_resample *x,
|
||||
t_sample* in, int insize,
|
||||
t_sample* out, int outsize,
|
||||
int method)
|
||||
{
|
||||
if (insize == outsize){
|
||||
bug("nothing to be done");
|
||||
return;
|
||||
}
|
||||
|
||||
if (insize > outsize) { /* downsampling */
|
||||
if (insize % outsize) {
|
||||
error("bad downsampling factor");
|
||||
return;
|
||||
}
|
||||
switch (method) {
|
||||
default:
|
||||
dsp_add(downsampling_perform_0, 4, in, out, insize/outsize, insize);
|
||||
}
|
||||
|
||||
|
||||
} else { /* upsampling */
|
||||
if (outsize % insize) {
|
||||
error("bad upsampling factor");
|
||||
return;
|
||||
}
|
||||
switch (method) {
|
||||
case 1:
|
||||
dsp_add(upsampling_perform_hold, 4, in, out, outsize/insize, insize);
|
||||
break;
|
||||
case 2:
|
||||
if (x->bufsize != 1) {
|
||||
t_freebytes(x->buffer, x->bufsize*sizeof(*x->buffer));
|
||||
x->bufsize = 1;
|
||||
x->buffer = t_getbytes(x->bufsize*sizeof(*x->buffer));
|
||||
}
|
||||
dsp_add(upsampling_perform_linear, 5, x, in, out, outsize/insize, insize);
|
||||
break;
|
||||
default:
|
||||
dsp_add(upsampling_perform_0, 4, in, out, outsize/insize, insize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resamplefrom_dsp(t_resample *x,
|
||||
t_sample *in,
|
||||
int insize, int outsize, int method)
|
||||
{
|
||||
if (insize==outsize) {
|
||||
t_freebytes(x->s_vec, x->s_n * sizeof(*x->s_vec));
|
||||
x->s_n = 0;
|
||||
x->s_vec = in;
|
||||
return;
|
||||
}
|
||||
|
||||
if (x->s_n != outsize) {
|
||||
t_sample *buf=x->s_vec;
|
||||
t_freebytes(buf, x->s_n * sizeof(*buf));
|
||||
buf = (t_sample *)t_getbytes(outsize * sizeof(*buf));
|
||||
x->s_vec = buf;
|
||||
x->s_n = outsize;
|
||||
}
|
||||
|
||||
resample_dsp(x, in, insize, x->s_vec, x->s_n, method);
|
||||
return;
|
||||
}
|
||||
|
||||
void resampleto_dsp(t_resample *x,
|
||||
t_sample *out,
|
||||
int insize, int outsize, int method)
|
||||
{
|
||||
if (insize==outsize) {
|
||||
if (x->s_n)t_freebytes(x->s_vec, x->s_n * sizeof(*x->s_vec));
|
||||
x->s_n = 0;
|
||||
x->s_vec = out;
|
||||
return;
|
||||
}
|
||||
|
||||
if (x->s_n != insize) {
|
||||
t_sample *buf=x->s_vec;
|
||||
t_freebytes(buf, x->s_n * sizeof(*buf));
|
||||
buf = (t_sample *)t_getbytes(insize * sizeof(*buf));
|
||||
x->s_vec = buf;
|
||||
x->s_n = insize;
|
||||
}
|
||||
|
||||
resample_dsp(x, x->s_vec, x->s_n, out, outsize, method);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue