| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /* | ||
| * Copyright (c) 2013 Dan Wilcox (danomatika@gmail.com) & | ||
| * Peter Brinkmann (peter.brinkmann@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| */ | ||
|
|
||
| #ifndef __Z_PRINT_UTIL_H__ | ||
| #define __Z_PRINT_UTIL_H__ | ||
|
|
||
| #include "z_libpd.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" | ||
| { | ||
| #endif | ||
|
|
||
| // Concatenate print messages into single lines before returning them to a print hook. | ||
| // ie "hello 123" is sent in 1 part -> "hello 123" | ||
| // | ||
| // For comparison, the default behavior returns individual words and spaces. | ||
| // ie "hello 123" is sent in 3 parts -> "hello", " ", "123" | ||
|
|
||
| // Assign the pointer to your print handler. | ||
| EXTERN void libpd_set_concatenated_printhook(const t_libpd_printhook hook); | ||
|
|
||
| // Assign this function pointer to libpd_printhook or libpd_queued_printhook, | ||
| // depending on whether you're using queued messages, to intercept and | ||
| // concatenate print messages: | ||
| // | ||
| // libpd_set_printhook(libpd_print_concatenator); | ||
| // libpd_set_concatenated_printhook(your_print_handler); | ||
| // | ||
| // Note: The char pointer argument is only good for the duration of the print | ||
| // callback; if you intend to use the argument after the callback has | ||
| // returned, you need to make a defensive copy. | ||
| // | ||
| void libpd_print_concatenator(const char *s); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * Copyright (c) 2012 Peter Brinkmann (peter.brinkmann@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| */ | ||
|
|
||
| #ifndef __Z_QUEUED_H__ | ||
| #define __Z_QUEUED_H__ | ||
|
|
||
| #include "z_libpd.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" | ||
| { | ||
| #endif | ||
|
|
||
| EXTERN void libpd_set_queued_printhook(const t_libpd_printhook hook); | ||
| EXTERN void libpd_set_queued_banghook(const t_libpd_banghook hook); | ||
| EXTERN void libpd_set_queued_floathook(const t_libpd_floathook hook); | ||
| EXTERN void libpd_set_queued_symbolhook(const t_libpd_symbolhook hook); | ||
| EXTERN void libpd_set_queued_listhook(const t_libpd_listhook hook); | ||
| EXTERN void libpd_set_queued_messagehook(const t_libpd_messagehook hook); | ||
|
|
||
| EXTERN void libpd_set_queued_noteonhook(const t_libpd_noteonhook hook); | ||
| EXTERN void libpd_set_queued_controlchangehook(const t_libpd_controlchangehook hook); | ||
| EXTERN void libpd_set_queued_programchangehook(const t_libpd_programchangehook hook); | ||
| EXTERN void libpd_set_queued_pitchbendhook(const t_libpd_pitchbendhook hook); | ||
| EXTERN void libpd_set_queued_aftertouchhook(const t_libpd_aftertouchhook hook); | ||
| EXTERN void libpd_set_queued_polyaftertouchhook(const t_libpd_polyaftertouchhook hook); | ||
| EXTERN void libpd_set_queued_midibytehook(const t_libpd_midibytehook hook); | ||
|
|
||
| int libpd_queued_init(); | ||
| void libpd_queued_release(); | ||
| void libpd_queued_receive_pd_messages(); | ||
| void libpd_queued_receive_midi_messages(); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| /* | ||
| * Copyright (c) 2010 Peter Brinkmann (peter.brinkmann@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| */ | ||
|
|
||
| #include <stdio.h> | ||
| #include "m_pd.h" | ||
| #include "x_libpdreceive.h" | ||
| #include "z_libpd.h" | ||
| #include "z_hooks.h" | ||
|
|
||
| static t_class *libpdrec_class; | ||
|
|
||
| typedef struct _libpdrec { | ||
| t_object x_obj; | ||
| t_symbol *x_sym; | ||
| } t_libpdrec; | ||
|
|
||
| static void libpdrecbang(t_libpdrec *x) { | ||
| if (libpd_banghook) (*libpd_banghook)(x->x_sym->s_name); | ||
| } | ||
|
|
||
| static void libpdrecfloat(t_libpdrec *x, t_float f) { | ||
| if (libpd_floathook) (*libpd_floathook)(x->x_sym->s_name, f); | ||
| } | ||
|
|
||
| static void libpdrecsymbol(t_libpdrec *x, t_symbol *s) { | ||
| if (libpd_symbolhook) (*libpd_symbolhook)(x->x_sym->s_name, s->s_name); | ||
| } | ||
|
|
||
| static void libpdrecpointer(t_libpdrec *x, t_gpointer *gp) { | ||
| // just ignore pointers for now... | ||
| } | ||
|
|
||
| static void libpdreclist(t_libpdrec *x, t_symbol *s, int argc, t_atom *argv) { | ||
| if (libpd_listhook) (*libpd_listhook)(x->x_sym->s_name, argc, argv); | ||
| } | ||
|
|
||
| static void libpdrecanything(t_libpdrec *x, t_symbol *s, | ||
| int argc, t_atom *argv) { | ||
| if (libpd_messagehook) | ||
| (*libpd_messagehook)(x->x_sym->s_name, s->s_name, argc, argv); | ||
| } | ||
|
|
||
| static void libpdreceive_free(t_libpdrec *x) { | ||
| pd_unbind(&x->x_obj.ob_pd, x->x_sym); | ||
| } | ||
|
|
||
| void *libpdreceive_new(t_symbol *s) { | ||
| t_libpdrec *x = (t_libpdrec *)pd_new(libpdrec_class); | ||
| x->x_sym = s; | ||
| pd_bind(&x->x_obj.ob_pd, s); | ||
| return x; | ||
| } | ||
|
|
||
| void libpdreceive_setup(void) { | ||
| libpdrec_class = class_new(gensym("libpd_receive"), | ||
| (t_newmethod)libpdreceive_new, (t_method)libpdreceive_free, | ||
| sizeof(t_libpdrec), CLASS_DEFAULT, A_DEFSYM, 0); | ||
| class_addbang(libpdrec_class, libpdrecbang); | ||
| class_addfloat(libpdrec_class, libpdrecfloat); | ||
| class_addsymbol(libpdrec_class, libpdrecsymbol); | ||
| class_addpointer(libpdrec_class, libpdrecpointer); | ||
| class_addlist(libpdrec_class, libpdreclist); | ||
| class_addanything(libpdrec_class, libpdrecanything); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| /* | ||
| * Copyright (c) 2010 Peter Brinkmann (peter.brinkmann@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| */ | ||
|
|
||
| #ifndef __X_LIBPDREC_H__ | ||
| #define __X_LIBPDREC_H__ | ||
|
|
||
| #include "m_pd.h" | ||
|
|
||
| void libpdreceive_setup(void); | ||
| void *libpdreceive_new(t_symbol *); | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /* | ||
| * Copyright (c) 2013 Dan Wilcox (danomatika@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| * | ||
| * See https://github.com/libpd/libpd/wiki for documentation | ||
| * | ||
| */ | ||
|
|
||
| #include "z_hooks.h" | ||
|
|
||
| t_libpd_printhook libpd_printhook = NULL; | ||
| t_libpd_banghook libpd_banghook = NULL; | ||
| t_libpd_floathook libpd_floathook = NULL; | ||
| t_libpd_symbolhook libpd_symbolhook = NULL; | ||
| t_libpd_listhook libpd_listhook = NULL; | ||
| t_libpd_messagehook libpd_messagehook = NULL; | ||
|
|
||
| t_libpd_noteonhook libpd_noteonhook = NULL; | ||
| t_libpd_controlchangehook libpd_controlchangehook = NULL; | ||
| t_libpd_programchangehook libpd_programchangehook = NULL; | ||
| t_libpd_pitchbendhook libpd_pitchbendhook = NULL; | ||
| t_libpd_aftertouchhook libpd_aftertouchhook = NULL; | ||
| t_libpd_polyaftertouchhook libpd_polyaftertouchhook = NULL; | ||
| t_libpd_midibytehook libpd_midibytehook = NULL; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /* | ||
| * Copyright (c) 2013 Dan Wilcox (danomatika@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| * | ||
| * See https://github.com/libpd/libpd/wiki for documentation | ||
| * | ||
| */ | ||
|
|
||
| #ifndef __Z_HOOKS_H__ | ||
| #define __Z_HOOKS_H__ | ||
|
|
||
| #include "z_libpd.h" | ||
|
|
||
| // the internal hooks | ||
| // in a separate file so they can be used throughout the libpd_wrapper sources, | ||
| // do *not* include this file in a user-facing header | ||
|
|
||
| extern t_libpd_printhook libpd_printhook; | ||
| extern t_libpd_banghook libpd_banghook; | ||
| extern t_libpd_floathook libpd_floathook; | ||
| extern t_libpd_symbolhook libpd_symbolhook; | ||
| extern t_libpd_listhook libpd_listhook; | ||
| extern t_libpd_messagehook libpd_messagehook; | ||
|
|
||
| extern t_libpd_noteonhook libpd_noteonhook; | ||
| extern t_libpd_controlchangehook libpd_controlchangehook; | ||
| extern t_libpd_programchangehook libpd_programchangehook; | ||
| extern t_libpd_pitchbendhook libpd_pitchbendhook; | ||
| extern t_libpd_aftertouchhook libpd_aftertouchhook; | ||
| extern t_libpd_polyaftertouchhook libpd_polyaftertouchhook; | ||
| extern t_libpd_midibytehook libpd_midibytehook; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| /* | ||
| * Copyright (c) 2010 Peter Brinkmann (peter.brinkmann@gmail.com) | ||
| * | ||
| * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
| * WARRANTIES, see the file, "LICENSE.txt," in this distribution. | ||
| * | ||
| * See http://gitorious.org/pdlib/pages/Libpd for documentation | ||
| * | ||
| */ | ||
|
|
||
| #ifndef __Z_LIBPD_H__ | ||
| #define __Z_LIBPD_H__ | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" | ||
| { | ||
| #endif | ||
|
|
||
| #include "m_pd.h" | ||
|
|
||
| EXTERN int libpd_init(void); | ||
| EXTERN void libpd_clear_search_path(void); | ||
| EXTERN void libpd_add_to_search_path(const char *sym); | ||
|
|
||
| EXTERN void *libpd_openfile(const char *basename, const char *dirname); | ||
| EXTERN void libpd_closefile(void *p); | ||
| EXTERN int libpd_getdollarzero(void *p); | ||
|
|
||
| EXTERN int libpd_blocksize(void); | ||
| EXTERN int libpd_init_audio(int inChans, int outChans, int sampleRate); | ||
| EXTERN int libpd_process_raw(const float *inBuffer, float *outBuffer); | ||
| EXTERN int libpd_process_short(const int ticks, | ||
| const short *inBuffer, short *outBuffer); | ||
| EXTERN int libpd_process_float(int ticks, | ||
| const float *inBuffer, float *outBuffer); | ||
| EXTERN int libpd_process_double(int ticks, | ||
| const double *inBuffer, double *outBuffer); | ||
|
|
||
| EXTERN int libpd_arraysize(const char *name); | ||
| // The parameters of the next two functions are inspired by memcpy. | ||
| EXTERN int libpd_read_array(float *dest, const char *src, int offset, int n); | ||
| EXTERN int libpd_write_array(const char *dest, int offset, float *src, int n); | ||
|
|
||
| EXTERN int libpd_bang(const char *recv); | ||
| EXTERN int libpd_float(const char *recv, float x); | ||
| EXTERN int libpd_symbol(const char *recv, const char *sym); | ||
|
|
||
| EXTERN void libpd_set_float(t_atom *v, float x); | ||
| EXTERN void libpd_set_symbol(t_atom *v, const char *sym); | ||
| EXTERN int libpd_list(const char *recv, int argc, t_atom *argv); | ||
| EXTERN int libpd_message(const char *recv, const char *msg, int argc, t_atom *argv); | ||
|
|
||
| EXTERN int libpd_start_message(int max_length); | ||
| EXTERN void libpd_add_float(float x); | ||
| EXTERN void libpd_add_symbol(const char *sym); | ||
| EXTERN int libpd_finish_list(const char *recv); | ||
| EXTERN int libpd_finish_message(const char *recv, const char *msg); | ||
|
|
||
| EXTERN int libpd_exists(const char *sym); | ||
| EXTERN void *libpd_bind(const char *sym); | ||
| EXTERN void libpd_unbind(void *p); | ||
|
|
||
| EXTERN int libpd_is_float(t_atom *a); | ||
| EXTERN int libpd_is_symbol(t_atom *a); | ||
| EXTERN float libpd_get_float(t_atom *a); | ||
| EXTERN char *libpd_get_symbol(t_atom *a); | ||
| EXTERN t_atom *libpd_next_atom(t_atom *a); | ||
|
|
||
| typedef void (*t_libpd_printhook)(const char *recv); | ||
| typedef void (*t_libpd_banghook)(const char *recv); | ||
| typedef void (*t_libpd_floathook)(const char *recv, float x); | ||
| typedef void (*t_libpd_symbolhook)(const char *recv, const char *sym); | ||
| typedef void (*t_libpd_listhook)(const char *recv, int argc, t_atom *argv); | ||
| typedef void (*t_libpd_messagehook)(const char *recv, const char *msg, | ||
| int argc, t_atom *argv); | ||
|
|
||
| EXTERN void libpd_set_printhook(const t_libpd_printhook hook); | ||
| EXTERN void libpd_set_banghook(const t_libpd_banghook hook); | ||
| EXTERN void libpd_set_floathook(const t_libpd_floathook hook); | ||
| EXTERN void libpd_set_symbolhook(const t_libpd_symbolhook hook); | ||
| EXTERN void libpd_set_listhook(const t_libpd_listhook hook); | ||
| EXTERN void libpd_set_messagehook(const t_libpd_messagehook hook); | ||
|
|
||
| EXTERN int libpd_noteon(int channel, int pitch, int velocity); | ||
| EXTERN int libpd_controlchange(int channel, int controller, int value); | ||
| EXTERN int libpd_programchange(int channel, int value); | ||
| EXTERN int libpd_pitchbend(int channel, int value); | ||
| EXTERN int libpd_aftertouch(int channel, int value); | ||
| EXTERN int libpd_polyaftertouch(int channel, int pitch, int value); | ||
| EXTERN int libpd_midibyte(int port, int byte); | ||
| EXTERN int libpd_sysex(int port, int byte); | ||
| EXTERN int libpd_sysrealtime(int port, int byte); | ||
|
|
||
| typedef void (*t_libpd_noteonhook)(int channel, int pitch, int velocity); | ||
| typedef void (*t_libpd_controlchangehook)(int channel, | ||
| int controller, int value); | ||
| typedef void (*t_libpd_programchangehook)(int channel, int value); | ||
| typedef void (*t_libpd_pitchbendhook)(int channel, int value); | ||
| typedef void (*t_libpd_aftertouchhook)(int channel, int value); | ||
| typedef void (*t_libpd_polyaftertouchhook)(int channel, int pitch, int value); | ||
| typedef void (*t_libpd_midibytehook)(int port, int byte); | ||
|
|
||
| EXTERN void libpd_set_noteonhook(const t_libpd_noteonhook hook); | ||
| EXTERN void libpd_set_controlchangehook(const t_libpd_controlchangehook hook); | ||
| EXTERN void libpd_set_programchangehook(const t_libpd_programchangehook hook); | ||
| EXTERN void libpd_set_pitchbendhook(const t_libpd_pitchbendhook hook); | ||
| EXTERN void libpd_set_aftertouchhook(const t_libpd_aftertouchhook hook); | ||
| EXTERN void libpd_set_polyaftertouchhook(const t_libpd_polyaftertouchhook hook); | ||
| EXTERN void libpd_set_midibytehook(const t_libpd_midibytehook hook); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,261 @@ | ||
| This file describes implementation and API changes; stuff more visible to the | ||
| user appears in the "release notes" instead. See the bottom of this file | ||
| for original notes on source style and organization. | ||
|
|
||
| 0.42.0 | ||
|
|
||
| changed definition of t_float, t_sample, t_floatarg so that they can be | ||
| set via #defines (PD_FLOATTYPE, etc). | ||
|
|
||
| 0.41.0 | ||
|
|
||
| add support for callback-based audio I/O | ||
| headers & code changed to use t_float or t_sample instead of float (patches | ||
| by zmoelnig). | ||
|
|
||
|
|
||
| 0.40.0 | ||
|
|
||
| 0.39.0 | ||
|
|
||
| canvas_dspstate and signalinlet_new() exported to m_pd.h | ||
|
|
||
| new function verbose() added to m_pd.h | ||
|
|
||
| 0.38.0 | ||
|
|
||
| finally figured out how to do "-enable-", etc., flags in the configure | ||
| script correctly. | ||
|
|
||
| The scheduler now has a hook (set_so you can add polling routines) : | ||
| sys_idlehook(). | ||
|
|
||
| I'm now uploading directly to CVS repository ("main" and "stable_0_38" | ||
| branches.) There are still problems keeping CVS's and my versions of | ||
| portaudio the same (CVS bashes the "ident" lines). | ||
|
|
||
| t_int to int in binbuf_addv prototype | ||
|
|
||
| 64-bit fix to externs makefiles | ||
|
|
||
| Pd now uses portaudio out-of-the-box; customized files are moved to | ||
| "src" directory. | ||
|
|
||
| All "tags" are printf'd as %lx to make 64-bit safe. | ||
|
|
||
| GUI queueing mechanism added: sys_queuegui() etc. | ||
|
|
||
| massive rewrite of array code to unify arrays and scalars. | ||
|
|
||
| fixed empty lists automatically to call "bang" method if one is supplied. | ||
|
|
||
| rewrote the "namelist" stuff to facilitate preference saving (s_stuff.h, | ||
| s_path.c, s_file.c, s_main.c) | ||
|
|
||
| 0.37.2 | ||
|
|
||
| expr() "exp" temporary variables renamed to avoid compilation problems | ||
|
|
||
| 0.37.1 | ||
|
|
||
| makefile.in: MANINSTDIR = $(DESTDIR)/$(MANDIR) changed to | ||
| $(DESTDIR)/$(INSTALL_PREFIX)/$(MANDIR) (thx. Mathieu Bouchard) | ||
|
|
||
| applied 2 jack patches from Luke Yelavich | ||
|
|
||
| add -fno-strict-aliasing to config script (linux&mac) to improve underflow, | ||
| etc., protection | ||
|
|
||
| add underflow protection to vcf~ object; rewrote underflow protection to be | ||
| faster in throw~/catch~ and send~/receive~ | ||
|
|
||
| fixed bug in -inchannels/-outchannels arg parsing | ||
|
|
||
| fixed u_main.tk to make "apple" key work to accelerate menus on MACOS | ||
|
|
||
| fooled with MIDI to try to get sysex and other system messages to work. | ||
| Needs lots of testing now... | ||
|
|
||
| finally fixed OSS to open audio with NODELAY... also cleared dup-on-exec flag. | ||
|
|
||
| bug fix in scalar_properties | ||
|
|
||
| major editions to the IEM GUIs to fix bugs in how "$" variables are handled. | ||
| The code still isn't pretty but hopefully at least works now. | ||
|
|
||
| tried to get alsa noninterleaved access to work (needed for RME). Failed | ||
| to get my RME card to load under ALSA and gave up for now. | ||
|
|
||
| fixed scalar drawing to fail gracefully when the template canvas disappears | ||
|
|
||
| bug fix in vd~ for very small delays (d_delay.c) | ||
|
|
||
| set up sys_oldtclversion flag to correct for changed text selection | ||
| (u_main.tk, s_main.c, g_rtext.c) | ||
|
|
||
| tried again to add "readn" support to s_audio_alsa.c: coded, but failing so far. | ||
|
|
||
| fixed broken octave divider example | ||
|
|
||
| removed "-Werror" from default makefile; fixed configure script to respect | ||
| "CFLAGS" environment variable instead. Suggest developers should use | ||
| "setenv CFLAGS -Werror". | ||
|
|
||
| added "-alsaadd" flag so people can specify alsa devnames to add to list. | ||
| fixed some problems with Pd crashing when ALSA failed to open. | ||
|
|
||
| took out the 2-pixel padding for MSW in g_canvas.g (HORIZBORDER/VERTBORDER) | ||
|
|
||
| went back to s_midi_mmio (portaudio version got assertion errors and anyway | ||
| I could never get sysex working in it as I had wanted.) | ||
|
|
||
| Took bug fixes from s_midi_pm.c, s_audio_jack.c, s_inter.c from "devel" branch; | ||
| also added "static" flag to configure.in (but the devel configure.in as a whole | ||
| doesn't seem to work for OSX, for me at least.) | ||
|
|
||
| Might have fixed a bug where labels disappear in buttons, etc, when saved | ||
| and reloaded. | ||
|
|
||
| brought s_audio_alsa.c up to alsa 1.0.0 compatibility | ||
|
|
||
| fixed "-alsaadd" (never worked before) | ||
|
|
||
| fooled with macintosh audio. Fixed some (not all) of the audio I/O APIs | ||
| to deal with open failures better (reducing sys_{in,out}channels accordingly) | ||
|
|
||
| In the Alsa API, the synchronization test was too stringent and was loosened | ||
| to 3*DACBLKSIZE/2. | ||
|
|
||
| 'make install' fixed to deal with 'extra' correctly. | ||
|
|
||
| one more improvement in jack support (guenter) | ||
|
|
||
| make an "nrt" flag so mac can disable pthread_setschedparam call if yu want. | ||
|
|
||
| ------------------- original source notes ------------- | ||
|
|
||
| 0. structure definition roadmap. First, the containment tree of things | ||
| that can be sent messages ("pure data"). (note that t_object and t_text, | ||
| and t_graph and t_canvas, should be unified...) | ||
|
|
||
| ------------ BFFORE 0.35: --------- | ||
| m_pd.h t_pd anything with a class | ||
| t_gobj "graphic object" | ||
| t_text text object | ||
| g_canvas.h | ||
| t_glist list of graphic objects | ||
| g_canvas.c t_canvas Pd "document" | ||
|
|
||
| ------------ AFTER 0.35: --------- | ||
| m_pd.h t_pd anything with a class | ||
| t_gobj "graphic object" | ||
| t_text patchable object, AKA t_object | ||
| g_canvas.h t_glist list of graphic objects, AKA t_canvas | ||
|
|
||
| ... and other structures: | ||
| g_canvas.h t_selection -- linked list of gobjs | ||
| t_editor -- editor state, allocated for visible glists | ||
| m_imp.h t_methodentry -- method handler | ||
| t_widgetbehavior -- class-dependent editing behavior for gobjs | ||
| t_parentwidgetbehavior -- objects' behavior on parent window | ||
| t_class -- method definitions, instance size, flags, etc. | ||
|
|
||
|
|
||
| 1. C coding style. The source should pass most "warnings" of C compilers | ||
| (-Wall on linux, for instance; see the makefile.) Some informalities | ||
| are intentional, for instance the loose use of function prototypes (see | ||
| below) and uncast conversions from longer to shorter numerical formats. | ||
| The code doesn't respect "const" yet. | ||
|
|
||
| 1.1. Prefixes in structure elements. The names of structure elements always | ||
| have a K&R-style prefix, as in ((t_atom)x)->a_type, where the "a_" prefix | ||
| indicates "atom." This is intended to enhance readability (although the | ||
| convention arose from a limitation of early C compilers.) Common prefixes are | ||
| "w_" (word), "a_" (atom), "s_" (symbol), "ob_" (object), "te_" (text object), | ||
| "g_" (graphical object), and "gl_" (glist, a list of graphical objects). Also, | ||
| global symbols sometimes get prefixes, as in "s_float" (the symbol whose string | ||
| is "float). Typedefs are prefixed by "t_". Most _private_ structures, i.e., | ||
| structures whose definitions appear in a ".c" file, are prefixed by "x_". | ||
|
|
||
| 1.2. Function arguments. Many functions take as their first | ||
| argument a pointer named "x", which is a pointer to a structure suggested | ||
| by the function prefix; e.g., canvas_dirty(x, n) where "x" points to a canvas | ||
| (t_canvas *x). | ||
|
|
||
| 1.3. Function Prototypes. Functions which are used in at least two different | ||
| files (besides where they originate) are prototyped in the appropriate include | ||
| file. Functions which are provided in one file and used in one other are | ||
| prototyped right where they are used. This is just to keep the size of the | ||
| ".h" files down for readability's sake. | ||
|
|
||
| 1.4. Whacko private terminology. Some terms are lifted from other historically | ||
| relevant programs, notably "ugen" (which is just a tilde object; see d_ugen.c.) | ||
|
|
||
| 1.5. Spacing. Tabs are 8 spaces; indentation is 4 spaces. Indenting | ||
| curly brackets are by themselves on their own lines, as in: | ||
|
|
||
| if (x) | ||
| { | ||
| x = 0; | ||
| } | ||
|
|
||
| Lines should fit within 80 spaces. | ||
|
|
||
| 2. Max patch-level compatibility. "Import" and "Export" functions are | ||
| provided which aspire to strict compatibility with 0.26 patches (ISPW version), | ||
| but which don't get anywhere close to that yet. Where possible, features | ||
| appearing on the Mac will comeday also be provided; for instance, the connect | ||
| message on the Mac offers segmented patch cords; these will devolve into | ||
| straight lines in Pd. Many, many UI objects in Opcode Max will not appear in | ||
| Pd, at least at first. | ||
|
|
||
| 3. Compatibility with Max 0.26 "externs", i.e., source-level compatibility. Pd | ||
| objects follow the style of 0.26 objects as closely as possible, making | ||
| exceptions in cases where the 0.26 model is clearly deficient. These are: | ||
|
|
||
| 3.1. Anything involving the MacIntosh "Handle" data type is changed to use | ||
| char * or void * instead. | ||
|
|
||
| 3.2. Pd passes true single-precision floating-point arguments to methods; | ||
| Max uses double. | ||
| Typedefs are provided: | ||
| t_floatarg, t_intarg for arguments passed by the message system | ||
| t_float, t_int for the "word" union (in atoms, for example.) | ||
|
|
||
| 3.3. Badly-named entities got name changes: | ||
|
|
||
| w_long --> w_int (in the "union word" structure) | ||
|
|
||
| 3.4. Many library functions are renamed and have different arguments; | ||
| I hope to provide an include file to alias them when compiling Max externs. | ||
|
|
||
| 4. Function name prefixes. | ||
| Many function names have prefixes which indicate what "package" they belong | ||
| to. The exceptions are: | ||
| typedmess, vmess, getfn, gensym (m_class.c) | ||
| getbytes, freebytes, resizebytes (m_memory.c) | ||
| post, error, bug (s_print.c) | ||
| which are all frequently called and which don't fit into simple categories. | ||
| Important packages are: | ||
| (pd-gui:) pdgui -- everything | ||
| (pd:) pd -- functions common to all "pd" objects | ||
| obj -- fuctions common to all "patchable" objects ala Max | ||
| sys -- "system" level functions | ||
| binbuf -- functions manipulating binbufs | ||
| class -- functions manipulating classes | ||
| (other) -- functions common to the named Pd class | ||
|
|
||
| 5. Source file prefixes. | ||
| PD: | ||
| s system interface | ||
| m message system | ||
| g graphics stuff | ||
| d DSP objects | ||
| x control objects | ||
| z other | ||
|
|
||
| PD-GUI: | ||
| t TK front end | ||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| AUTOMAKE_OPTIONS = foreign | ||
|
|
||
| pd_CFLAGS = -DPD -DINSTALL_PREFIX=\"$(prefix)\" | ||
| pd_LDFLAGS = | ||
|
|
||
| pdsend_CFLAGS = | ||
| pdreceive_CFLAGS = | ||
| pd_watchdog_CFLAGS = | ||
| LIBS = @LIBS@ | ||
| INCLUDES = @INCLUDES@ | ||
|
|
||
| SUFFIXES = .@EXTENSION@ .@SHARED_LIB@ | ||
|
|
||
| bin_PROGRAMS = pd pdsend pdreceive | ||
| pdsend_SOURCES = u_pdsend.c | ||
| pdreceive_SOURCES = u_pdreceive.c | ||
| pd_watchdog_SOURCES = s_watchdog.c | ||
| pd_LDADD = | ||
| pd_SOURCES = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c \ | ||
| g_io.c g_scalar.c g_traversal.c g_guiconnect.c g_readwrite.c g_editor.c \ | ||
| g_all_guis.c g_bang.c g_hdial.c g_hslider.c g_mycanvas.c g_numbox.c \ | ||
| g_toggle.c g_vdial.c g_vslider.c g_vumeter.c \ | ||
| m_pd.c m_class.c m_obj.c m_atom.c m_memory.c m_binbuf.c \ | ||
| m_conf.c m_glob.c m_sched.c \ | ||
| s_main.c s_inter.c s_file.c s_print.c \ | ||
| s_loader.c s_path.c s_entry.c s_audio.c s_midi.c \ | ||
| s_utf8.c \ | ||
| d_ugen.c d_ctl.c d_arithmetic.c d_osc.c d_filter.c d_dac.c d_misc.c \ | ||
| d_math.c d_fft.c d_array.c d_global.c \ | ||
| d_delay.c d_resample.c d_soundfile.c \ | ||
| x_arithmetic.c x_connective.c x_interface.c x_midi.c x_misc.c \ | ||
| x_time.c x_acoustics.c x_net.c x_text.c x_gui.c x_list.c x_array.c \ | ||
| x_scalar.c | ||
|
|
||
| pd_includedir = ${includedir}/pd | ||
| pd_include_HEADERS = m_pd.h m_imp.h g_canvas.h s_stuff.h g_all_guis.h | ||
| # compatibility: m_pd.h also goes into ${includedir}/ | ||
| include_HEADERS = m_pd.h | ||
| noinst_HEADERS = g_all_guis.h s_audio_alsa.h s_audio_paring.h s_utf8.h | ||
|
|
||
| # we want these in the dist tarball | ||
| EXTRA_DIST = CHANGELOG.txt notes.txt \ | ||
| pd.ico pd.rc \ | ||
| makefile.gnu makefile.mac makefile.mingw makefile.msvc \ | ||
| s_audio_dummy.c s_audio_audiounit.c s_audio_esd.c | ||
|
|
||
|
|
||
| # configurations per library | ||
| if ALSA | ||
| pd_CFLAGS += -DUSEAPI_ALSA | ||
| pd_LDADD += @ALSA_LIBS@ | ||
| pd_SOURCES += s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c | ||
| endif | ||
|
|
||
| if COREAUDIO | ||
| LIBS += -framework CoreAudio -framework CoreMIDI \ | ||
| -framework AudioUnit -framework AudioToolbox | ||
| endif | ||
|
|
||
| if FFTW | ||
| pd_SOURCES += d_fft_fftw.c | ||
| else | ||
| pd_SOURCES += d_fft_fftsg.c | ||
| endif | ||
|
|
||
| # TODO support Jack xrun | ||
| if JACK | ||
| pd_CFLAGS += -DUSEAPI_JACK -DJACK_XRUN | ||
| pd_SOURCES += s_audio_jack.c | ||
| if MACOSX | ||
| pd_LDFLAGS += -weak_framework Jackmp | ||
| else | ||
| pd_LDADD += @JACK_LIBS@ | ||
| endif | ||
| endif | ||
|
|
||
| # Cygwin has a function OSS /dev/dsp, but not MIDI, and Pd is only set up to | ||
| # handle a single MIDI API | ||
| if OSS | ||
| if !WINDOWS | ||
| pd_CFLAGS += -DUSEAPI_OSS | ||
| pd_SOURCES += s_audio_oss.c s_midi_oss.c | ||
| endif | ||
| endif | ||
|
|
||
| if PORTAUDIO | ||
| pd_CFLAGS += -DUSEAPI_PORTAUDIO -I$(top_srcdir)/portaudio/include | ||
| pd_LDADD += $(top_builddir)/portaudio/lib/libportaudio.la | ||
| pd_SOURCES += s_audio_pa.c s_audio_paring.c | ||
| endif | ||
|
|
||
| # ASIO needs to go after PORTAUDIO in order for it to link properly | ||
| if ASIO | ||
| pd_LDADD += $(top_builddir)/asio/libasio.la | ||
| endif | ||
|
|
||
| if PORTMIDI | ||
| INCLUDES += -I$(top_srcdir)/portmidi/pm_common -I$(top_srcdir)/portmidi/porttime | ||
| pd_LDADD += $(top_builddir)/portmidi/libportmidi.la | ||
| pd_SOURCES += s_midi_pm.c | ||
| endif | ||
|
|
||
|
|
||
| # FIXXXME | ||
| # GNU/HURD, IPHONEOS, ... have no MIDI (not even OSS) | ||
| # i think it would be better to add s_midi_dummy.c only if no other midi API can be found | ||
| # (without OS-specific checks) | ||
| # even better would be, to allow Pd to have simply have no MIDI (nor AUDIO) | ||
| if IPHONEOS | ||
| pd_SOURCES += s_midi_dummy.c | ||
| endif | ||
|
|
||
| if HURD | ||
| libpdbindir = $(pkglibdir)/bin | ||
| libpdbin_DATA = | ||
| libpdbin_PROGRAMS = pd-watchdog pd | ||
| # this flag has to have a single leading "-" for libtool, even though ld uses | ||
| # --export-dynamic, and libtool sends -Wl,--export-dynamic to ld... | ||
| pd_LDFLAGS += -export-dynamic | ||
| # on Ubuntu/Karmic 9.10, it doesn't seem to find libm, so force it | ||
| pd_LDFLAGS += $(LIBM) | ||
| # force linking to pthread, which should really be done with some autotools way | ||
| pd_LDFLAGS += -lpthread | ||
| # force linking to dl, which should really be done with some autotools way | ||
| pd_LDFLAGS += -ldl | ||
| endif | ||
|
|
||
| if LINUX | ||
| libpdbindir = $(pkglibdir)/bin | ||
| libpdbin_DATA = | ||
| libpdbin_PROGRAMS = pd-watchdog pd | ||
| # this flag has to have a single leading "-" for libtool, even though ld uses | ||
| # --export-dynamic, and libtool sends -Wl,--export-dynamic to ld... | ||
| pd_LDFLAGS += -export-dynamic | ||
| # on Ubuntu/Karmic 9.10, it doesn't seem to find libm, so force it | ||
| pd_LDFLAGS += $(LIBM) | ||
| endif | ||
|
|
||
| if MACOSX | ||
| LIBS += -framework Carbon | ||
| pd_CFLAGS += -DMACOSX #kludge, should use auto macro __APPLE__ | ||
| bin_SCRIPTS = | ||
| bin_PROGRAMS += pd-watchdog | ||
| endif | ||
|
|
||
| if WINDOWS | ||
| LIBS += -lwsock32 -lwinmm -lole32 | ||
| pd_CFLAGS += -DUSEAPI_MMIO -DPD_INTERNAL | ||
| pd_SOURCES += s_audio_mmio.c s_midi_mmio.c | ||
| bin_SCRIPTS = | ||
| endif | ||
|
|
||
| if MINGW | ||
| # To use SetDllDirectory() in s_loader.c, we need a minium of Windows | ||
| # XP SP1. WINVER isnt' fine-grained enough for that, so we use the | ||
| # next minor version of Windows, 5.2. That gives us -DWINVER=0x0502 | ||
| pd_CFLAGS += -DWISHAPP='"wish85.exe"' -DWINVER=0x0502 | ||
| bin_PROGRAMS += pd-watchdog | ||
| endif | ||
|
|
||
| etags: TAGS | ||
| etags --append --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| /* 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; | ||
| t_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_sample *in1 = (t_sample *)(w[1]); | ||
| t_sample *out = (t_sample *)(w[2]); | ||
| int n = (int)(w[3]); | ||
| while (n--) *out++ = *in1++; | ||
| return (w+4); | ||
| } | ||
|
|
||
| t_int *copy_perf8(t_int *w) | ||
| { | ||
| t_sample *in1 = (t_sample *)(w[1]); | ||
| t_sample *out = (t_sample *)(w[2]); | ||
| int n = (int)(w[3]); | ||
|
|
||
| for (; n; n -= 8, in1 += 8, out += 8) | ||
| { | ||
| t_sample f0 = in1[0]; | ||
| t_sample f1 = in1[1]; | ||
| t_sample f2 = in1[2]; | ||
| t_sample f3 = in1[3]; | ||
| t_sample f4 = in1[4]; | ||
| t_sample f5 = in1[5]; | ||
| t_sample f6 = in1[6]; | ||
| t_sample 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(); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,334 @@ | ||
| /* 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; | ||
| t_sample *c_vec; | ||
| int c_phase; | ||
| } t_delwritectl; | ||
|
|
||
| typedef struct _sigdelwrite | ||
| { | ||
| t_object x_obj; | ||
| t_symbol *x_sym; | ||
| t_float x_deltime; /* delay in msec (added by Mathieu Bouchard) */ | ||
| 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 */ | ||
| t_float x_f; | ||
| } t_sigdelwrite; | ||
|
|
||
| #define XTRASAMPS 4 | ||
| #define SAMPBLK 4 | ||
|
|
||
| static void sigdelwrite_updatesr (t_sigdelwrite *x, t_float sr) /* added by Mathieu Bouchard */ | ||
| { | ||
| int nsamps = x->x_deltime * sr * (t_float)(0.001f); | ||
| if (nsamps < 1) nsamps = 1; | ||
| nsamps += ((- nsamps) & (SAMPBLK - 1)); | ||
| nsamps += DEFDELVS; | ||
| if (x->x_cspace.c_n != nsamps) { | ||
| x->x_cspace.c_vec = (t_sample *)resizebytes(x->x_cspace.c_vec, | ||
| (x->x_cspace.c_n + XTRASAMPS) * sizeof(t_sample), | ||
| ( nsamps + XTRASAMPS) * sizeof(t_sample)); | ||
| x->x_cspace.c_n = nsamps; | ||
| x->x_cspace.c_phase = XTRASAMPS; | ||
| } | ||
| } | ||
|
|
||
| /* 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(); | ||
| } | ||
| /* | ||
| 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 | ||
| 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) | ||
| { | ||
| 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; | ||
| x->x_deltime = msec; | ||
| x->x_cspace.c_n = 0; | ||
| x->x_cspace.c_vec = getbytes(XTRASAMPS * sizeof(t_sample)); | ||
| 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_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); | ||
| sigdelwrite_updatesr(x, sp[0]->s_sr); | ||
| } | ||
|
|
||
| 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(t_sample)); | ||
| } | ||
|
|
||
| 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"), A_CANT, 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_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_updatesr(delwriter, sp[0]->s_sr); | ||
| 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"), A_CANT, 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 */ | ||
| t_float x_f; | ||
| } t_sigvd; | ||
|
|
||
| static void *sigvd_new(t_symbol *s) | ||
| { | ||
| t_sigvd *x = (t_sigvd *)pd_new(sigvd_class); | ||
| 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; | ||
| t_sample limit = nsamps - n - 1; | ||
| t_sample fn = n-1; | ||
| t_sample *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase; | ||
| t_sample zerodel = x->x_zerodel; | ||
| while (n--) | ||
| { | ||
| t_sample delsamps = x->x_sr * *in++ - zerodel, frac; | ||
| int idelsamps; | ||
| t_sample a, b, c, d, cminusb; | ||
| if (!(delsamps >= 1.00001f)) /* too small or NAN */ | ||
| delsamps = 1.00001f; | ||
| if (delsamps > limit) /* too big */ | ||
| delsamps = limit; | ||
| delsamps += fn; | ||
| fn = fn - 1.0f; | ||
| idelsamps = delsamps; | ||
| frac = delsamps - (t_sample)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 if (*x->x_sym->s_name) | ||
| 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"), A_CANT, 0); | ||
| CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f); | ||
| } | ||
|
|
||
| /* ----------------------- global setup routine ---------------- */ | ||
|
|
||
| void d_delay_setup(void) | ||
| { | ||
| sigdelwrite_setup(); | ||
| sigdelread_setup(); | ||
| sigvd_setup(); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,355 @@ | ||
| /* Copyright (c) 1997- 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" | ||
|
|
||
| /* This file interfaces to one of the Mayer, Ooura, or fftw FFT packages | ||
| to implement the "fft~", etc, Pd objects. If using Mayer, also compile | ||
| d_fft_mayer.c; if ooura, use d_fft_fftsg.c instead; if fftw, use d_fft_fftw.c | ||
| and also link in the fftw library. You can only have one of these three | ||
| linked in. The configure script can be used to select which one. | ||
| */ | ||
|
|
||
| /* ---------------- utility functions for DSP chains ---------------------- */ | ||
|
|
||
| /* swap two arrays */ | ||
| 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++) | ||
| { | ||
| t_sample f = *in1; | ||
| *in1 = *in2; | ||
| *in2 = f; | ||
| } | ||
| return (w+4); | ||
| } | ||
|
|
||
| /* take array1 (supply a pointer to beginning) and copy it, | ||
| into decreasing addresses, into array 2 (supply a pointer one past the | ||
| end), and negate the sign. */ | ||
|
|
||
| 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++; | ||
| return (w+4); | ||
| } | ||
|
|
||
| /* ------------------------ fft~ and ifft~ -------------------------------- */ | ||
| static t_class *sigfft_class, *sigifft_class; | ||
|
|
||
| typedef struct fft | ||
| { | ||
| t_object x_obj; | ||
| t_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_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"), A_CANT, 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"), A_CANT, 0); | ||
| class_sethelpsymbol(sigifft_class, gensym("fft~")); | ||
| } | ||
|
|
||
| /* ----------------------- rfft~ -------------------------------- */ | ||
|
|
||
| static t_class *sigrfft_class; | ||
|
|
||
| typedef struct rfft | ||
| { | ||
| t_object x_obj; | ||
| t_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_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 != 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+1), ((n2-1)&(~7))); | ||
| dsp_add_zero(out1 + (n2+1) + ((n2-1)&(~7)), ((n2-1)&7)); | ||
| dsp_add_zero(out2 + n2, n2); | ||
| dsp_add_zero(out2, 1); | ||
| } | ||
|
|
||
| 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"), A_CANT, 0); | ||
| class_sethelpsymbol(sigrfft_class, gensym("fft~")); | ||
| } | ||
|
|
||
| /* ----------------------- rifft~ -------------------------------- */ | ||
|
|
||
| static t_class *sigrifft_class; | ||
|
|
||
| typedef struct rifft | ||
| { | ||
| t_object x_obj; | ||
| t_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+1); | ||
| } | ||
| else | ||
| { | ||
| if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n2+1); | ||
| 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"), A_CANT, 0); | ||
| class_sethelpsymbol(sigrifft_class, gensym("fft~")); | ||
| } | ||
|
|
||
| /* ----------------------- framp~ -------------------------------- */ | ||
|
|
||
| static t_class *sigframp_class; | ||
|
|
||
| typedef struct framp | ||
| { | ||
| t_object x_obj; | ||
| t_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) | ||
| { | ||
| t_sample *inreal = (t_sample *)(w[1]); | ||
| t_sample *inimag = (t_sample *)(w[2]); | ||
| t_sample *outfreq = (t_sample *)(w[3]); | ||
| t_sample *outamp = (t_sample *)(w[4]); | ||
| t_sample lastreal = 0, currentreal = inreal[0], nextreal = inreal[1]; | ||
| t_sample lastimag = 0, currentimag = inimag[0], nextimag = inimag[1]; | ||
| int n = w[5]; | ||
| int m = n + 1; | ||
| t_sample fbin = 1, oneovern2 = 1.f/((t_sample)n * (t_sample)n); | ||
|
|
||
| inreal += 2; | ||
| inimag += 2; | ||
| *outamp++ = *outfreq++ = 0; | ||
| n -= 2; | ||
| while (n--) | ||
| { | ||
| t_sample 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) | ||
| { | ||
| t_sample 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"), A_CANT, 0); | ||
| } | ||
|
|
||
| /* ------------------------ global setup routine ------------------------- */ | ||
|
|
||
| void d_fft_setup(void) | ||
| { | ||
| sigfft_setup(); | ||
| sigrfft_setup(); | ||
| sigrifft_setup(); | ||
| sigframp_setup(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| /* Copyright (c) 1997- 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. */ | ||
|
|
||
| /* --------- Pd interface to FFTW library; imitate Mayer API ---------- */ | ||
|
|
||
| /* changes and additions for FFTW3 by Thomas Grill */ | ||
|
|
||
| #include "m_pd.h" | ||
| #include <fftw3.h> | ||
|
|
||
| int ilog2(int n); | ||
|
|
||
| #define MINFFT 0 | ||
| #define MAXFFT 30 | ||
|
|
||
| /* from the FFTW website: | ||
| #include <fftw3.h> | ||
| ... | ||
| { | ||
| fftw_complex *in, *out; | ||
| fftw_plan p; | ||
| ... | ||
| in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); | ||
| out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); | ||
| p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); | ||
| ... | ||
| fftw_execute(p); | ||
| ... | ||
| fftw_destroy_plan(p); | ||
| fftw_free(in); fftw_free(out); | ||
| } | ||
| FFTW_FORWARD or FFTW_BACKWARD, and indicates the direction of the transform you | ||
| are interested in. Alternatively, you can use the sign of the exponent in the | ||
| transform, -1 or +1, which corresponds to FFTW_FORWARD or FFTW_BACKWARD | ||
| respectively. The flags argument is either FFTW_MEASURE | ||
| */ | ||
|
|
||
| /* complex stuff */ | ||
|
|
||
| typedef struct { | ||
| fftwf_plan plan; | ||
| fftwf_complex *in,*out; | ||
| } cfftw_info; | ||
|
|
||
| static cfftw_info cfftw_fwd[MAXFFT+1 - MINFFT],cfftw_bwd[MAXFFT+1 - MINFFT]; | ||
|
|
||
| static cfftw_info *cfftw_getplan(int n,int fwd) | ||
| { | ||
| cfftw_info *info; | ||
| int logn = ilog2(n); | ||
| if (logn < MINFFT || logn > MAXFFT) | ||
| return (0); | ||
| info = (fwd?cfftw_fwd:cfftw_bwd)+(logn-MINFFT); | ||
| if (!info->plan) | ||
| { | ||
| info->in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * n); | ||
| info->out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * n); | ||
| info->plan = fftwf_plan_dft_1d(n, info->in, info->out, fwd?FFTW_FORWARD:FFTW_BACKWARD, FFTW_MEASURE); | ||
| } | ||
| return info; | ||
| } | ||
|
|
||
|
|
||
| /* real stuff */ | ||
|
|
||
| typedef struct { | ||
| fftwf_plan plan; | ||
| float *in,*out; | ||
| } rfftw_info; | ||
|
|
||
| static rfftw_info rfftw_fwd[MAXFFT+1 - MINFFT],rfftw_bwd[MAXFFT+1 - MINFFT]; | ||
|
|
||
| static rfftw_info *rfftw_getplan(int n,int fwd) | ||
| { | ||
| rfftw_info *info; | ||
| int logn = ilog2(n); | ||
| if (logn < MINFFT || logn > MAXFFT) | ||
| return (0); | ||
| info = (fwd?rfftw_fwd:rfftw_bwd)+(logn-MINFFT); | ||
| if (!info->plan) | ||
| { | ||
| info->in = (float*) fftwf_malloc(sizeof(float) * n); | ||
| info->out = (float*) fftwf_malloc(sizeof(float) * n); | ||
| info->plan = fftwf_plan_r2r_1d(n, info->in, info->out, fwd?FFTW_R2HC:FFTW_HC2R, FFTW_MEASURE); | ||
| } | ||
| return info; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| EXTERN void mayer_fht(float *fz, int n) | ||
| { | ||
| post("FHT: not yet implemented"); | ||
| } | ||
|
|
||
| static void mayer_do_cfft(int n, float *fz1, float *fz2, int fwd) | ||
| { | ||
| int i; | ||
| float *fz; | ||
| cfftw_info *p = cfftw_getplan(n, fwd); | ||
| if (!p) | ||
| return; | ||
|
|
||
| for (i = 0, fz = (float *)p->in; i < n; i++) | ||
| fz[i*2] = fz1[i], fz[i*2+1] = fz2[i]; | ||
|
|
||
| fftwf_execute(p->plan); | ||
|
|
||
| for (i = 0, fz = (float *)p->out; i < n; i++) | ||
| fz1[i] = fz[i*2], fz2[i] = fz[i*2+1]; | ||
| } | ||
|
|
||
| EXTERN void mayer_fft(int n, float *fz1, float *fz2) | ||
| { | ||
| mayer_do_cfft(n, fz1, fz2, 1); | ||
| } | ||
|
|
||
| EXTERN void mayer_ifft(int n, float *fz1, float *fz2) | ||
| { | ||
| mayer_do_cfft(n, fz1, fz2, 0); | ||
| } | ||
|
|
||
| /* | ||
| in the following the sign flips are done to | ||
| be compatible with the mayer_fft implementation, | ||
| but it's probably the mayer_fft that should be corrected... | ||
| */ | ||
|
|
||
| EXTERN void mayer_realfft(int n, float *fz) | ||
| { | ||
| int i; | ||
| rfftw_info *p = rfftw_getplan(n, 1); | ||
| if (!p) | ||
| return; | ||
|
|
||
| for (i = 0; i < n; i++) | ||
| p->in[i] = fz[i]; | ||
| fftwf_execute(p->plan); | ||
| for (i = 0; i < n/2+1; i++) | ||
| fz[i] = p->out[i]; | ||
| for (; i < n; i++) | ||
| fz[i] = -p->out[i]; | ||
| } | ||
|
|
||
| EXTERN void mayer_realifft(int n, float *fz) | ||
| { | ||
| int i; | ||
| rfftw_info *p = rfftw_getplan(n, 0); | ||
| if (!p) | ||
| return; | ||
|
|
||
| for (i = 0; i < n/2+1; i++) | ||
| p->in[i] = fz[i]; | ||
| for (; i < n; i++) | ||
| p->in[i] = -fz[i]; | ||
| fftwf_execute(p->plan); | ||
| for (i = 0; i < n; i++) | ||
| fz[i] = p->out[i]; | ||
| } | ||
|
|
||
| /* ancient ISPW-like version, used in fiddle~ and perhaps other externs | ||
| here and there. */ | ||
| void pd_fft(t_float *buf, int npoints, int inverse) | ||
| { | ||
| cfftw_info *p = cfftw_getplan(npoints, !inverse); | ||
| int i; | ||
| float *fz; | ||
| for (i = 0, fz = (float *)(p->in); i < 2 * npoints; i++) | ||
| *fz++ = buf[i]; | ||
| fftwf_execute(p->plan); | ||
| for (i = 0, fz = (float *)(p->out); i < 2 * npoints; i++) | ||
| buf[i] = *fz++; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,361 @@ | ||
| /* 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; | ||
| t_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(t_sample)); | ||
| } | ||
|
|
||
| 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"), A_CANT, 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); | ||
| } | ||
|
|
||
| /* tb: vectorized receive function */ | ||
| static t_int *sigreceive_perf8(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) | ||
| { | ||
| for (; n; n -= 8, in += 8, out += 8) | ||
| { | ||
| out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = in[3]; | ||
| out[4] = in[4]; out[5] = in[5]; out[6] = in[6]; out[7] = in[7]; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| for (; n; n -= 8, in += 8, out += 8) | ||
| { | ||
| out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; | ||
| out[4] = 0; out[5] = 0; out[6] = 0; out[7] = 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); | ||
| if (sp[0]->s_n&7) | ||
| dsp_add(sigreceive_perform, 3, | ||
| x, sp[0]->s_vec, sp[0]->s_n); | ||
| else dsp_add(sigreceive_perf8, 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"), A_CANT, 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); | ||
| } | ||
|
|
||
| /* tb: vectorized catch function */ | ||
| static t_int *sigcatch_perf8(t_int *w) | ||
| { | ||
| t_sample *in = (t_sample *)(w[1]); | ||
| t_sample *out = (t_sample *)(w[2]); | ||
| int n = (int)(w[3]); | ||
| for (; n; n -= 8, in += 8, out += 8) | ||
| { | ||
| out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = in[3]; | ||
| out[4] = in[4]; out[5] = in[5]; out[6] = in[6]; out[7] = in[7]; | ||
|
|
||
| in[0] = 0; in[1] = 0; in[2] = 0; in[3] = 0; | ||
| in[4] = 0; in[5] = 0; in[6] = 0; in[7] = 0; | ||
| } | ||
| return (w+4); | ||
| } | ||
|
|
||
| static void sigcatch_dsp(t_sigcatch *x, t_signal **sp) | ||
| { | ||
| if (x->x_n == sp[0]->s_n) | ||
| { | ||
| if(sp[0]->s_n&7) | ||
| dsp_add(sigcatch_perform, 3, x->x_vec, sp[0]->s_vec, sp[0]->s_n); | ||
| else | ||
| dsp_add(sigcatch_perf8, 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(t_sample)); | ||
| } | ||
|
|
||
| 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"), A_CANT, 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_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"), A_CANT, 0); | ||
| } | ||
|
|
||
| /* ----------------------- global setup routine ---------------- */ | ||
|
|
||
| void d_global_setup(void) | ||
| { | ||
| sigsend_setup(); | ||
| sigreceive_setup(); | ||
| sigcatch_setup(); | ||
| sigthrow_setup(); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| /* 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; | ||
| t_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) | ||
| { | ||
| int i=0; | ||
| startpost("%s:", x->x_sym->s_name); | ||
| for(i=0; i<n; i++) { | ||
| if(i%8==0)endpost(); | ||
| startpost("%.4g ", in[i]); | ||
| } | ||
| endpost(); | ||
| 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); | ||
| } | ||
|
|
||
| /* ------------------------ 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); | ||
| } | ||
|
|
||
|
|
||
| /* ------------------------ global setup routine ------------------------- */ | ||
|
|
||
| void d_misc_setup(void) | ||
| { | ||
| print_setup(); | ||
| bang_tilde_setup(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,216 @@ | ||
| /* 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. */ | ||
|
|
||
|
|
||
| #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_sample findex = (t_sample)(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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,323 @@ | ||
| /* 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. */ | ||
| /* g_7_guis.h written by Thomas Musil (c) IEM KUG Graz Austria 2000-2001 */ | ||
|
|
||
|
|
||
| #define IEM_GUI_COLNR_WHITE 0 | ||
| #define IEM_GUI_COLNR_ML_GREY 1 | ||
| #define IEM_GUI_COLNR_D_GREY 2 | ||
| #define IEM_GUI_COLNR_L_RED 3 | ||
| #define IEM_GUI_COLNR_L_ORANGE 4 | ||
| #define IEM_GUI_COLNR_L_YELLOW 5 | ||
| #define IEM_GUI_COLNR_L_GREEN 6 | ||
| #define IEM_GUI_COLNR_L_CYAN 7 | ||
| #define IEM_GUI_COLNR_L_BLUE 8 | ||
| #define IEM_GUI_COLNR_L_MAGENTA 9 | ||
|
|
||
| #define IEM_GUI_COLNR_LL_GREY 10 | ||
| #define IEM_GUI_COLNR_M_GREY 11 | ||
| #define IEM_GUI_COLNR_DD_GREY 12 | ||
| #define IEM_GUI_COLNR_RED 13 | ||
| #define IEM_GUI_COLNR_ORANGE 14 | ||
| #define IEM_GUI_COLNR_YELLOW 15 | ||
| #define IEM_GUI_COLNR_GREEN 16 | ||
| #define IEM_GUI_COLNR_CYAN 17 | ||
| #define IEM_GUI_COLNR_BLUE 18 | ||
| #define IEM_GUI_COLNR_MAGENTA 19 | ||
|
|
||
| #define IEM_GUI_COLNR_L_GREY 20 | ||
| #define IEM_GUI_COLNR_MD_GREY 21 | ||
| #define IEM_GUI_COLNR_BLACK 22 | ||
| #define IEM_GUI_COLNR_D_RED 23 | ||
| #define IEM_GUI_COLNR_D_ORANGE 24 | ||
| #define IEM_GUI_COLNR_D_YELLOW 25 | ||
| #define IEM_GUI_COLNR_D_GREEN 26 | ||
| #define IEM_GUI_COLNR_D_CYAN 27 | ||
| #define IEM_GUI_COLNR_D_BLUE 28 | ||
| #define IEM_GUI_COLNR_D_MAGENTA 29 | ||
|
|
||
| #define IEM_GUI_COLOR_SELECTED 255 | ||
| #define IEM_GUI_COLOR_NORMAL 0 | ||
|
|
||
| #define IEM_GUI_MAX_COLOR 30 | ||
|
|
||
| #define IEM_GUI_DEFAULTSIZE 15 | ||
| #define IEM_GUI_MINSIZE 8 | ||
| #define IEM_GUI_MAXSIZE 1000 | ||
| #define IEM_SL_DEFAULTSIZE 128 | ||
| #define IEM_SL_MINSIZE 2 | ||
| #define IEM_FONT_MINSIZE 4 | ||
|
|
||
| #define IEM_BNG_DEFAULTHOLDFLASHTIME 250 | ||
| #define IEM_BNG_DEFAULTBREAKFLASHTIME 50 | ||
| #define IEM_BNG_MINHOLDFLASHTIME 50 | ||
| #define IEM_BNG_MINBREAKFLASHTIME 10 | ||
|
|
||
| #define IEM_VU_DEFAULTSIZE 3 | ||
| #define IEM_VU_LARGESMALL 2 | ||
| #define IEM_VU_MINSIZE 2 | ||
| #define IEM_VU_MAXSIZE 25 | ||
| #define IEM_VU_STEPS 40 | ||
|
|
||
| #define IEM_VU_MINDB -99.9 | ||
| #define IEM_VU_MAXDB 12.0 | ||
| #define IEM_VU_OFFSET 100.0 | ||
|
|
||
| #define IEM_RADIO_MAX 128 | ||
|
|
||
| #define IEM_SYM_UNIQUE_SND 256 | ||
| #define IEM_SYM_UNIQUE_RCV 512 | ||
| #define IEM_SYM_UNIQUE_LAB 1024 | ||
| #define IEM_SYM_UNIQUE_ALL 1792 | ||
| #define IEM_FONT_STYLE_ALL 255 | ||
|
|
||
| #define IEM_MAX_SYM_LEN 127 | ||
|
|
||
| #define IEM_GUI_DRAW_MODE_UPDATE 0 | ||
| #define IEM_GUI_DRAW_MODE_MOVE 1 | ||
| #define IEM_GUI_DRAW_MODE_NEW 2 | ||
| #define IEM_GUI_DRAW_MODE_SELECT 3 | ||
| #define IEM_GUI_DRAW_MODE_ERASE 4 | ||
| #define IEM_GUI_DRAW_MODE_CONFIG 5 | ||
| #define IEM_GUI_DRAW_MODE_IO 6 | ||
|
|
||
|
|
||
| #define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER) | ||
| #define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) | ||
| #define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) | ||
| #define IS_A_DOLLAR(atom,index) ((atom+index)->a_type == A_DOLLAR) | ||
| #define IS_A_DOLLSYM(atom,index) ((atom+index)->a_type == A_DOLLSYM) | ||
|
|
||
| #define IEM_FSTYLE_FLAGS_ALL 0x007fffff | ||
| #define IEM_INIT_ARGS_ALL 0x01ffffff | ||
|
|
||
| #define IEM_GUI_OLD_SND_FLAG 1 | ||
| #define IEM_GUI_OLD_RCV_FLAG 2 | ||
|
|
||
| #define IEM_GUI_COLOR_EDITED 16711680 | ||
| #define IEMGUI_MAX_NUM_LEN 32 | ||
|
|
||
| typedef struct _iem_fstyle_flags | ||
| { | ||
| unsigned int x_font_style:6; | ||
| unsigned int x_rcv_able:1; | ||
| unsigned int x_snd_able:1; | ||
| unsigned int x_lab_is_unique:1; | ||
| unsigned int x_rcv_is_unique:1; | ||
| unsigned int x_snd_is_unique:1; | ||
| unsigned int x_lab_arg_tail_len:6; | ||
| unsigned int x_lab_is_arg_num:6; | ||
| unsigned int x_shiftdown:1; | ||
| unsigned int x_selected:1; | ||
| unsigned int x_finemoved:1; | ||
| unsigned int x_put_in2out:1; | ||
| unsigned int x_change:1; | ||
| unsigned int x_thick:1; | ||
| unsigned int x_lin0_log1:1; | ||
| unsigned int x_steady:1; | ||
| } t_iem_fstyle_flags; | ||
|
|
||
| typedef struct _iem_init_symargs | ||
| { | ||
| unsigned int x_loadinit:1; | ||
| unsigned int x_rcv_arg_tail_len:6; | ||
| unsigned int x_snd_arg_tail_len:6; | ||
| unsigned int x_rcv_is_arg_num:6; | ||
| unsigned int x_snd_is_arg_num:6; | ||
| unsigned int x_scale:1; | ||
| unsigned int x_flashed:1; | ||
| unsigned int x_locked:1; | ||
| } t_iem_init_symargs; | ||
|
|
||
| typedef void (*t_iemfunptr)(void *x, t_glist *glist, int mode); | ||
|
|
||
| typedef struct _iemgui | ||
| { | ||
| t_object x_obj; | ||
| t_glist *x_glist; | ||
| t_iemfunptr x_draw; | ||
| int x_h; | ||
| int x_w; | ||
| int x_ldx; | ||
| int x_ldy; | ||
| char x_font[MAXPDSTRING]; /* font names can be long! */ | ||
| t_iem_fstyle_flags x_fsf; | ||
| int x_fontsize; | ||
| t_iem_init_symargs x_isa; | ||
| int x_fcol; | ||
| int x_bcol; | ||
| int x_lcol; | ||
| t_symbol *x_snd; /* send symbol */ | ||
| t_symbol *x_rcv; /* receive */ | ||
| t_symbol *x_lab; /* label */ | ||
| t_symbol *x_snd_unexpanded; /* same 3, with '$' unexpanded */ | ||
| t_symbol *x_rcv_unexpanded; | ||
| t_symbol *x_lab_unexpanded; | ||
| int x_binbufindex; /* where in binbuf to find these */ | ||
| int x_labelbindex; /* where in binbuf to find label */ | ||
| } t_iemgui; | ||
|
|
||
| typedef struct _bng | ||
| { | ||
| t_iemgui x_gui; | ||
| int x_flashed; | ||
| int x_flashtime_break; | ||
| int x_flashtime_hold; | ||
| t_clock *x_clock_hld; | ||
| t_clock *x_clock_brk; | ||
| t_clock *x_clock_lck; | ||
| } t_bng; | ||
|
|
||
| typedef struct _hslider | ||
| { | ||
| t_iemgui x_gui; | ||
| int x_pos; | ||
| int x_val; | ||
| int x_lin0_log1; | ||
| int x_steady; | ||
| double x_min; | ||
| double x_max; | ||
| double x_k; | ||
| t_float x_fval; | ||
| } t_hslider; | ||
|
|
||
| typedef struct _hdial | ||
| { | ||
| t_iemgui x_gui; | ||
| int x_on; | ||
| int x_on_old; /* LATER delete this; it's used for old version */ | ||
| int x_change; | ||
| int x_number; | ||
| int x_drawn; | ||
| t_float x_fval; | ||
| t_atom x_at[2]; | ||
| } t_hdial; | ||
|
|
||
| typedef struct _toggle | ||
| { | ||
| t_iemgui x_gui; | ||
| t_float x_on; | ||
| t_float x_nonzero; | ||
| } t_toggle; | ||
|
|
||
| typedef struct _my_canvas | ||
| { | ||
| t_iemgui x_gui; | ||
| t_atom x_at[3]; | ||
| int x_vis_w; | ||
| int x_vis_h; | ||
| } t_my_canvas; | ||
|
|
||
| typedef struct _vslider | ||
| { | ||
| t_iemgui x_gui; | ||
| int x_pos; | ||
| int x_val; | ||
| int x_lin0_log1; | ||
| int x_steady; | ||
| double x_min; | ||
| double x_max; | ||
| double x_k; | ||
| t_float x_fval; | ||
| } t_vslider; | ||
|
|
||
| typedef struct _vu | ||
| { | ||
| t_iemgui x_gui; | ||
| int x_led_size; | ||
| int x_peak; | ||
| int x_rms; | ||
| t_float x_fp; | ||
| t_float x_fr; | ||
| int x_scale; | ||
| void *x_out_rms; | ||
| void *x_out_peak; | ||
| unsigned int x_updaterms:1; | ||
| unsigned int x_updatepeak:1; | ||
| } t_vu; | ||
|
|
||
| typedef struct _my_numbox | ||
| { | ||
| t_iemgui x_gui; | ||
| t_clock *x_clock_reset; | ||
| t_clock *x_clock_wait; | ||
| double x_val; | ||
| double x_min; | ||
| double x_max; | ||
| double x_k; | ||
| int x_lin0_log1; | ||
| char x_buf[IEMGUI_MAX_NUM_LEN]; | ||
| int x_numwidth; | ||
| int x_log_height; | ||
| } t_my_numbox; | ||
|
|
||
| typedef struct _vdial | ||
| { | ||
| t_iemgui x_gui; | ||
| int x_on; | ||
| int x_on_old; | ||
| int x_change; | ||
| int x_number; | ||
| int x_drawn; | ||
| t_float x_fval; | ||
| t_atom x_at[2]; | ||
| } t_vdial; | ||
|
|
||
| #define t_vradio t_vdial | ||
| #define t_hradio t_hdial | ||
|
|
||
| extern int sys_noloadbang; | ||
| extern int iemgui_color_hex[]; | ||
| extern int iemgui_vu_db2i[]; | ||
| extern int iemgui_vu_col[]; | ||
| extern char *iemgui_vu_scale_str[]; | ||
|
|
||
| EXTERN int iemgui_clip_size(int size); | ||
| EXTERN int iemgui_clip_font(int size); | ||
| EXTERN int iemgui_modulo_color(int col); | ||
| EXTERN t_symbol *iemgui_unique2dollarzero(t_symbol *s, int unique_num, int and_unique_flag); | ||
| EXTERN t_symbol *iemgui_sym2dollararg(t_symbol *s, int nth_arg, int tail_len); | ||
| EXTERN t_symbol *iemgui_dollarzero2unique(t_symbol *s, int unique_num); | ||
| EXTERN t_symbol *iemgui_dollararg2sym(t_symbol *s, int nth_arg, int tail_len, int pargc, t_atom *pargv); | ||
| EXTERN int iemgui_is_dollarzero(t_symbol *s); | ||
| EXTERN int iemgui_is_dollararg(t_symbol *s, int *tail_len); | ||
| EXTERN void iemgui_fetch_unique(t_iemgui *iemgui); | ||
| EXTERN void iemgui_fetch_parent_args(t_iemgui *iemgui, int *pargc, t_atom **pargv); | ||
| EXTERN void iemgui_verify_snd_ne_rcv(t_iemgui *iemgui); | ||
| EXTERN void iemgui_all_unique2dollarzero(t_iemgui *iemgui, t_symbol **srlsym); | ||
| EXTERN void iemgui_all_sym2dollararg(t_iemgui *iemgui, t_symbol **srlsym); | ||
| EXTERN void iemgui_all_dollarzero2unique(t_iemgui *iemgui, t_symbol **srlsym); | ||
| EXTERN t_symbol *iemgui_new_dogetname(t_iemgui *iemgui, int indx, t_atom *argv); | ||
| EXTERN void iemgui_new_getnames(t_iemgui *iemgui, int indx, t_atom *argv); | ||
| EXTERN void iemgui_all_dollararg2sym(t_iemgui *iemgui, t_symbol **srlsym); | ||
| EXTERN void iemgui_all_col2save(t_iemgui *iemgui, int *bflcol); | ||
| EXTERN void iemgui_all_colfromload(t_iemgui *iemgui, int *bflcol); | ||
| EXTERN int iemgui_compatible_col(int i); | ||
| EXTERN void iemgui_all_dollar2raute(t_symbol **srlsym); | ||
| EXTERN void iemgui_all_raute2dollar(t_symbol **srlsym); | ||
| EXTERN void iemgui_send(void *x, t_iemgui *iemgui, t_symbol *s); | ||
| EXTERN void iemgui_receive(void *x, t_iemgui *iemgui, t_symbol *s); | ||
| EXTERN void iemgui_label(void *x, t_iemgui *iemgui, t_symbol *s); | ||
| EXTERN void iemgui_label_pos(void *x, t_iemgui *iemgui, t_symbol *s, int ac, t_atom *av); | ||
| EXTERN void iemgui_label_font(void *x, t_iemgui *iemgui, t_symbol *s, int ac, t_atom *av); | ||
| EXTERN void iemgui_size(void *x, t_iemgui *iemgui); | ||
| EXTERN void iemgui_delta(void *x, t_iemgui *iemgui, t_symbol *s, int ac, t_atom *av); | ||
| EXTERN void iemgui_pos(void *x, t_iemgui *iemgui, t_symbol *s, int ac, t_atom *av); | ||
| EXTERN void iemgui_color(void *x, t_iemgui *iemgui, t_symbol *s, int ac, t_atom *av); | ||
| EXTERN int iemgui_list(void *x, t_iemgui *iemgui, t_symbol *s, int ac, t_atom *av); | ||
| EXTERN void iemgui_displace(t_gobj *z, t_glist *glist, int dx, int dy); | ||
| EXTERN void iemgui_select(t_gobj *z, t_glist *glist, int selected); | ||
| EXTERN void iemgui_delete(t_gobj *z, t_glist *glist); | ||
| EXTERN void iemgui_vis(t_gobj *z, t_glist *glist, int vis); | ||
| EXTERN void iemgui_save(t_iemgui *iemgui, t_symbol **srl, int *bflcol); | ||
| EXTERN void iemgui_properties(t_iemgui *iemgui, t_symbol **srl); | ||
| EXTERN int iemgui_dialog(t_iemgui *iemgui, t_symbol **srl, int argc, t_atom *argv); | ||
|
|
||
| EXTERN int canvas_getdollarzero(void); | ||
| EXTERN void canvas_getargs(int *argcp, t_atom **argvp); | ||
|
|
||
| EXTERN void iem_inttosymargs(t_iem_init_symargs *symargp, int n); | ||
| EXTERN int iem_symargstoint(t_iem_init_symargs *symargp); | ||
| EXTERN void iem_inttofstyle(t_iem_fstyle_flags *fstylep, int n); | ||
| EXTERN int iem_fstyletoint(t_iem_fstyle_flags *fstylep); |