From 45932d6b4b33ecd4f4dc2e7eab9f210dfa46cc34 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Fri, 24 Dec 2004 15:31:14 +0000 Subject: xmas's changes svn path=/trunk/externals/tb/; revision=2427 --- chaos/src/Makefile.am | 13 +-- chaos/src/chaos.hpp | 3 +- chaos/src/chaos_base.hpp | 103 +++------------------ chaos/src/chaos_dsp.cpp | 171 ---------------------------------- chaos/src/chaos_dsp.hpp | 223 ++++++++++++++++++++++++++++++++++++++++++++- chaos/src/logistic_map.hpp | 2 +- chaos/src/lorenz.hpp | 8 +- chaos/src/main.cpp | 6 +- chaos/src/ode_base.cpp | 2 +- chaos/src/ode_base.hpp | 42 ++++----- 10 files changed, 269 insertions(+), 304 deletions(-) diff --git a/chaos/src/Makefile.am b/chaos/src/Makefile.am index 9f99c3f..43ad73b 100644 --- a/chaos/src/Makefile.am +++ b/chaos/src/Makefile.am @@ -1,6 +1,7 @@ -NAME = chaos~ +NAME = chaos -BUILT_SOURCES = main.cpp ode_base.cpp chaos_base.cpp chaos_dsp.cpp +BUILT_SOURCES = main.cpp ode_base.cpp chaos_base.cpp chaos_dsp.cpp \ + lorenz_dsp.cpp CXXFLAGS = @CXXFLAGS@ \ @@ -17,7 +18,7 @@ FRAMEWORKS = @FRAMEWORKS@ TARGET =$(NAME).@EXTENSION@ -OBJECTS = $(patsubst %.cpp,./%.@OBJEXT@,$(BUILT_SOURCES)) +OBJECTS = $(patsubst %.cpp,%.@OBJEXT@,$(BUILT_SOURCES)) SYSDIR = @SYSDIR@ @@ -26,10 +27,10 @@ SYSDIR = @SYSDIR@ all-local: $(OBJECTS) - $(CXX) $(LDFLAGS) -shared ./*.@OBJEXT@ $(LIBS) -o ../$(TARGET) + $(CXX) $(LDFLAGS) -shared $^ $(LIBS) -o ../$(TARGET) strip --strip-unneeded ../$(TARGET) -./%.@OBJEXT@ : %.cpp +%.@OBJEXT@ : %.cpp $(CXX) -c $(CXXFLAGS) $< -o $@ dist-hook: @@ -38,7 +39,7 @@ dist-hook: clean-local: rm -f ../$(TARGET) - rm -f ../obj/* + rm -f ./*.@OBJEXT@ install-exec-local: install ../$(TARGET) $(SYSDIR)extra \ No newline at end of file diff --git a/chaos/src/chaos.hpp b/chaos/src/chaos.hpp index 4f51902..65a9c46 100644 --- a/chaos/src/chaos.hpp +++ b/chaos/src/chaos.hpp @@ -22,7 +22,7 @@ #define FLEXT_ATTRIBUTES 1 -//#include "flext.h" +#include "flext.h" /* internal we can work with a higher precision than pd */ #ifdef DOUBLE_PRECISION @@ -31,5 +31,6 @@ typedef double data_t; typedef t_float data_t; #endif + #define __chaos_hpp #endif /* __chaos_hpp */ diff --git a/chaos/src/chaos_base.hpp b/chaos/src/chaos_base.hpp index a42e275..795383e 100644 --- a/chaos/src/chaos_base.hpp +++ b/chaos/src/chaos_base.hpp @@ -1,4 +1,4 @@ -a// +// // // chaos~ // Copyright (C) 2004 Tim Blechmann @@ -21,6 +21,7 @@ a// #ifndef __chaos_base_hpp #include "chaos.hpp" +#include "chaos_defs.hpp" class chaos_base { @@ -36,7 +37,9 @@ public: return m_num_eq; } - virtual void m_step(); + virtual void m_step() + { + } data_t * m_data; // state of the system @@ -45,98 +48,16 @@ protected: }; #define CHAOS_CALLBACKS \ -FLEXT_CALLGET_F(m_system->get_num_eq); - -#define CHAOS_ATTRIBUTES \ -FLEXT_ADDATTR_GET("dimension",m_system->get_num_eq); - - - -// macros for simplified system state functions -#define CHAOS_SYS_SETFUNC(NAME, NR) \ - void set_##NAME(t_float f) \ - { \ - m_data[NR] = (data_t) f; \ - } - -#define CHAOS_SYS_SETFUNC_PRED(NAME, NR, PRED) \ - void set_##NAME(t_float f) \ - { \ - if ( PRED(f) ) \ - m_data[NR] = (data_t) f; \ - else \ - post("value for dimension " #NAME " %f out of range", f); \ - } - -#define CHAOS_SYS_GETFUNC(NAME, NR) \ - t_float get_##NAME() \ - { \ - return (t_float)m_data[NR]; \ - } - -/* to be called in the public part */ -#define CHAOS_SYSVAR_FUNCS_PRED(NAME, NR, PRED) \ -public: \ -CHAOS_SYS_SETFUNC_PRED(NAME, NR, PRED) \ -CHAOS_SYS_GETFUNC(NAME, NR) - -#define CHAOS_SYSVAR_FUNCS(NAME, NR) \ -public: \ -CHAOS_SYS_SETFUNC(NAME, NR) \ -CHAOS_SYS_GETFUNC(NAME, NR) - - - -// macros for simplified system parameter functions -#define CHAOS_PAR_SETFUNC(NAME) \ - void set_##NAME(t_float f) \ - { \ - m_##NAME = (data_t) f; \ - } - -#define CHAOS_PAR_SETFUNC_PRED(NAME, PRED) \ - void set_##NAME(t_float f) \ - { \ - if ( PRED(f) ) \ - m_##NAME = (data_t) f; \ - else \ - post("value for parameter " #NAME " %f out of range", f); \ - } - -#define CHAOS_PAR_GETFUNC(NAME) \ - t_float get_##NAME() \ - { \ - return (t_float)m_##NAME; \ - } - - -#define CHAOS_SYSPAR_FUNCS_PRED(NAME, PRED) \ -public: \ -CHAOS_PAR_SETFUNC_PRED(NAME, PRED) \ -CHAOS_PAR_GETFUNC(NAME) \ -private: \ -data_t m_##NAME; \ -public: - -#define CHAOS_SYSPAR_FUNCS(NAME) \ public: \ -CHAOS_PAR_SETFUNC(NAME) \ -CHAOS_PAR_GETFUNC(NAME) \ -private: \ -data_t m_##NAME; \ -public: - - -#define CHAOS_SYS_CALLBACKS(NAME) \ -FLEXT_CALLVAR_F(m_system->get_##NAME, m_system->set_##NAME); - -#define CHAOS_SYS_ATTRIBUTE(NAME) \ -FLEXT_ADDATTR_VAR(#NAME,m_system->get_##NAME, m_system->set_##NAME); +void get_dimension(int &i) \ +{ \ + i = m_system->get_num_eq(); \ +} \ +FLEXT_CALLGET_I(get_dimension); -#define CHAOS_SYS_INIT(NAME, VALUE) \ -set_##NAME(VALUE); +#define CHAOS_ATTRIBUTES \ +FLEXT_ADDATTR_GET("dimension",get_dimension); -#define CHAOS_PARAMETER(NAME) m_##NAME #define __chaos_base_hpp diff --git a/chaos/src/chaos_dsp.cpp b/chaos/src/chaos_dsp.cpp index 790be06..2040312 100644 --- a/chaos/src/chaos_dsp.cpp +++ b/chaos/src/chaos_dsp.cpp @@ -20,174 +20,3 @@ #include "chaos_dsp.hpp" - -void chaos_dsp::m_signal(int n, t_sample *const *insigs, - t_sample *const *outsigs) -{ - if (m_freq >= m_sr * 0.5) - { - m_signal_(n, insigs, outsigs); - return; - } - - switch (m_method) - { - case 0: - m_signal_n(n, insigs, outsigs); - return; - case 1: - m_signal_l(n, insigs, outsigs); - return; - case 2: - m_signal_c(n, insigs, outsigs); - return; - } -} - -void chaos_dsp::m_signal_(int n, t_sample *const *insigs, - t_sample *const *outsigs) -{ - int outlets = m_system->get_num_eq(); - - for (int i = 0; i!=n; ++i) - { - m_system->m_step(); - for (int j = 0; j != outlets; ++j) - { - outsigs[j][i] = m_system->get_data(j); - } - } - -} - -void chaos_dsp::m_signal_n(int n, t_sample *const *insigs, - t_sample *const *outsigs) -{ - int outlets = m_system->get_num_eq(); - - int phase = m_phase; - - int i = 0; - - while (n) - { - if (m_phase == 0) - { - m_system->m_step(); - phase = int (m_sr / m_freq); - } - - int next = (phase < n) ? phase : n; - n -= next; - phase -=next; - - while (next--) - { - for (int j = 0; j != outlets; ++j) - { - outsigs[j][i] = m_system->get_data(j); - } - ++i; - } - } - m_phase = phase; -} - - -/* linear and cubic interpolation adapted from supercollider by James McCartney */ - -void chaos_dsp::m_signal_l(int n, t_sample *const *insigs, - t_sample *const *outsigs) -{ - int outlets = m_system->get_num_eq(); - - int phase = m_phase; - - int i = 0; - - while (n) - { - if (m_phase == 0) - { - m_system->m_step(); - phase = int (m_sr / m_freq); - - for (int j = 0; j != outlets; ++j) - m_slopes[j] = (m_system->get_data(j) - m_values[j]) / phase; - } - - int next = (phase < n) ? phase : n; - n -= next; - phase -=next; - - while (next--) - { - for (int j = 0; j != outlets; ++j) - { - outsigs[j][i] = m_values[j]; - m_values[j]+=m_slopes[j]; - } - ++i; - } - } - m_phase = phase; -} - - -void chaos_dsp::m_signal_c(int n, t_sample *const *insigs, - t_sample *const *outsigs) -{ - int outlets = m_system->get_num_eq(); - - int phase = m_phase; - - int i = 0; - - while (n) - { - if (m_phase == 0) - { - m_system->m_step(); - phase = int (m_sr / m_freq); - phase = (phase > 2) ? phase : 2; - - for (int j = 0; j != outlets; ++j) - { - t_sample value = m_nextvalues[j]; - m_nextvalues[j]= m_system->get_data(j); - - m_values[j] = m_nextmidpts[j]; - m_nextmidpts[j] = (m_values[j] + value) * 0.5f; - - float fseglen = (float)phase; - m_curves[j] = 2.f * (m_nextmidpts[j] - m_values[j] - fseglen * m_slopes[j]) - / (fseglen * fseglen + fseglen); - - m_values[j] = value; - } - } - - int next = (phase < n) ? phase : n; - n -= next; - phase -=next; - - while (next--) - { - for (int j = 0; j != outlets; ++j) - { - outsigs[j][i] = m_values[j]; - m_slopes[j]+=m_curves[j]; - m_values[j]+=m_slopes[j]; - } - ++i; - } - } - m_phase = phase; -} - - -void chaos_dsp::m_dsp(int n, t_sample *const *insigs, - t_sample *const *outsigs) -{ - m_sr = Samplerate(); -} diff --git a/chaos/src/chaos_dsp.hpp b/chaos/src/chaos_dsp.hpp index 12efaa8..65e6203 100644 --- a/chaos/src/chaos_dsp.hpp +++ b/chaos/src/chaos_dsp.hpp @@ -20,12 +20,12 @@ #include "chaos_base.hpp" -class chaos_dsp +template class chaos_dsp : public flext_dsp { FLEXT_HEADER(chaos_dsp, flext_dsp); -protected: +public: /* signal functions: */ /* for frequency = sr/2 */ @@ -38,11 +38,15 @@ protected: void m_signal_c(int n, t_sample *const *insigs,t_sample *const *outsigs); virtual void m_signal(int n, t_sample *const *insigs,t_sample *const *outsigs); - virtual void m_dsp(int n, t_sample *const *insigs,t_sample *const *outsigs); - + virtual void m_dsp(int n, t_sample *const *insigs,t_sample *const *outsigs) + { + m_sr = Samplerate(); + } + + /* local data for system, output and interpolation */ - chaos_base * m_system; /* the system */ + system * m_system; /* the system */ t_sample * m_values; /* actual value */ t_sample * m_slopes; /* actual slope for cubic interpolation */ @@ -59,3 +63,212 @@ protected: char m_method; /* interpolation method */ }; + + +/* create constructor / destructor */ \ +#define CHAOS_DSP_INIT(SYSTEM, ATTRIBUTES) \ +FLEXT_HEADER(SYSTEM##_dsp, chaos_dsp) \ + \ +SYSTEM##_dsp(int argc, t_atom* argv ) \ +{ \ + m_system = new SYSTEM; \ + \ + int size = m_system->get_num_eq(); \ + \ + for (int i = 0; i != size; ++i) \ + AddOutSignal(); \ + \ + m_values = new t_float[size]; \ + m_slopes = new t_float[size]; \ + m_nextvalues = new t_float[size]; \ + m_nextmidpts = new t_float[size]; \ + m_curves = new t_float[size]; \ + \ + m_freq = GetAFloat(argv[0]); \ + m_method = (char)GetAFloat(argv[1]); \ + m_phase = 0; \ + \ + ATTRIBUTES; \ +} \ + \ +~SYSTEM##_dsp() \ +{ \ + delete m_system; \ + delete m_values; \ + delete m_slopes; \ + delete m_nextvalues; \ + delete m_nextmidpts; \ + delete m_curves; \ +} + + + + +template +void chaos_dsp::m_signal(int n, t_sample *const *insigs, + t_sample *const *outsigs) +{ + if (m_freq >= m_sr * 0.5) + { + m_signal_(n, insigs, outsigs); + return; + } + + switch (m_method) + { + case 0: + m_signal_n(n, insigs, outsigs); + return; + case 1: + m_signal_l(n, insigs, outsigs); + return; + case 2: + m_signal_c(n, insigs, outsigs); + return; + } +} + +template +void chaos_dsp::m_signal_(int n, t_sample *const *insigs, + t_sample *const *outsigs) +{ + int outlets = m_system->get_num_eq(); + + for (int i = 0; i!=n; ++i) + { + m_system->m_step(); + for (int j = 0; j != outlets; ++j) + { + outsigs[j][i] = m_system->get_data(j); + } + } + +} + +template +void chaos_dsp::m_signal_n(int n, t_sample *const *insigs, + t_sample *const *outsigs) +{ + int outlets = m_system->get_num_eq(); + + int phase = m_phase; + + int i = 0; + + while (n) + { + if (m_phase == 0) + { + m_system->m_step(); + phase = int (m_sr / m_freq); + } + + int next = (phase < n) ? phase : n; + n -= next; + phase -=next; + + while (next--) + { + for (int j = 0; j != outlets; ++j) + { + outsigs[j][i] = m_system->get_data(j); + } + ++i; + } + } + m_phase = phase; +} + + +/* linear and cubic interpolation adapted from supercollider by James McCartney */ + +template +void chaos_dsp::m_signal_l(int n, t_sample *const *insigs, + t_sample *const *outsigs) +{ + int outlets = m_system->get_num_eq(); + + int phase = m_phase; + + int i = 0; + + while (n) + { + if (m_phase == 0) + { + m_system->m_step(); + phase = int (m_sr / m_freq); + + for (int j = 0; j != outlets; ++j) + m_slopes[j] = (m_system->get_data(j) - m_values[j]) / phase; + } + + int next = (phase < n) ? phase : n; + n -= next; + phase -=next; + + while (next--) + { + for (int j = 0; j != outlets; ++j) + { + outsigs[j][i] = m_values[j]; + m_values[j]+=m_slopes[j]; + } + ++i; + } + } + m_phase = phase; +} + + +template +void chaos_dsp::m_signal_c(int n, t_sample *const *insigs, + t_sample *const *outsigs) +{ + int outlets = m_system->get_num_eq(); + + int phase = m_phase; + + int i = 0; + + while (n) + { + if (m_phase == 0) + { + m_system->m_step(); + phase = int (m_sr / m_freq); + phase = (phase > 2) ? phase : 2; + + for (int j = 0; j != outlets; ++j) + { + t_sample value = m_nextvalues[j]; + m_nextvalues[j]= m_system->get_data(j); + + m_values[j] = m_nextmidpts[j]; + m_nextmidpts[j] = (m_values[j] + value) * 0.5f; + + float fseglen = (float)phase; + m_curves[j] = 2.f * (m_nextmidpts[j] - m_values[j] - fseglen * m_slopes[j]) + / (fseglen * fseglen + fseglen); + + m_values[j] = value; + } + } + + int next = (phase < n) ? phase : n; + n -= next; + phase -=next; + + while (next--) + { + for (int j = 0; j != outlets; ++j) + { + outsigs[j][i] = m_values[j]; + m_slopes[j]+=m_curves[j]; + m_values[j]+=m_slopes[j]; + } + ++i; + } + } + m_phase = phase; +} diff --git a/chaos/src/logistic_map.hpp b/chaos/src/logistic_map.hpp index e0111f7..94b38d0 100644 --- a/chaos/src/logistic_map.hpp +++ b/chaos/src/logistic_map.hpp @@ -54,7 +54,7 @@ public: return (f > 0) && (f < 4); } - CHAOS_SYSVAR_FUNCS_PRED(x, m_pred_x); + CHAOS_SYSVAR_FUNCS_PRED(x, 0, m_pred_x); bool m_pred_x(t_float f) { diff --git a/chaos/src/lorenz.hpp b/chaos/src/lorenz.hpp index e3e5ccd..700e4a1 100644 --- a/chaos/src/lorenz.hpp +++ b/chaos/src/lorenz.hpp @@ -26,14 +26,16 @@ // taken from Willi-Hans Steeb: Chaos and Fractals class lorenz - : protected ode_base + : public ode_base { public: - logistic() + lorenz() { m_num_eq = 3; m_data = new data_t[3]; + CHAOS_SYS_INIT(method,0); + CHAOS_SYS_INIT(dt,1); CHAOS_SYS_INIT(x1,0.8); CHAOS_SYS_INIT(x2,0.8); CHAOS_SYS_INIT(x3,0.8); @@ -44,7 +46,7 @@ public: set_method(0); } - ~logistic() + ~lorenz() { delete m_data; } diff --git a/chaos/src/main.cpp b/chaos/src/main.cpp index df25010..b0f2ad0 100644 --- a/chaos/src/main.cpp +++ b/chaos/src/main.cpp @@ -23,7 +23,9 @@ void chaos_library_setup() { - post("chaos~ version"PACKAGE_VERSION"\n"); + post("chaos~ version "PACKAGE_VERSION"\n"); + + FLEXT_DSP_SETUP(lorenz_dsp); } - + FLEXT_LIB_SETUP(chaos, chaos_library_setup); diff --git a/chaos/src/ode_base.cpp b/chaos/src/ode_base.cpp index cfedeee..9665d83 100644 --- a/chaos/src/ode_base.cpp +++ b/chaos/src/ode_base.cpp @@ -83,7 +83,7 @@ void ode_base::m_step() rk2(); break; case 2: - rk3(); + rk4(); break; } diff --git a/chaos/src/ode_base.hpp b/chaos/src/ode_base.hpp index 5fdd6d1..6fa7e27 100644 --- a/chaos/src/ode_base.hpp +++ b/chaos/src/ode_base.hpp @@ -24,14 +24,15 @@ #include "chaos_base.hpp" class ode_base - : protected chaos_base + : public chaos_base { public: void set_method(int i) { if (i >=0 && i <4) m_method = (unsigned char) i; - post("no such method"); + else + post("no such method"); } t_int get_method() @@ -39,44 +40,39 @@ public: return (int) m_method; } - void set_dt(t_float f) - { - if (f >= 0) - m_dt = (data_t)f; - else - post("invalid value for dt: %f", f); - } - - t_float get_dt() + CHAOS_SYSPAR_FUNCS_PRED(dt, m_pred_dt); + + bool m_pred_dt(t_float f) { - return (t_float) m_dt; + return (f >= 0); } - void m_step(); + virtual void m_step(); protected: unsigned char m_method; /* 0: rk1, 1: rk2, 3: rk4 */ - data_t m_dt; /* step width */ data_t* m_k[3]; /* temporary arrays for runge kutta */ data_t* m_tmp; - virtual void m_system (data_t* deriv, data_t* data); + virtual void m_system (data_t* deriv, data_t* data) + { + } void rk1 (); void rk2 (); void rk4 (); }; -#define ODE_CALLBACKS \ -CHAOS_CALLBACKS; \ -FLEXT_CALLVAR_I(m_system->get_method, m_system->set_method); \ -FLEXT_CALLVAR_F(m_system->get_dt, m_system->set_dt); +#define ODE_CALLBACKS \ +CHAOS_CALLBACKS; \ +CHAOS_SYS_CALLBACKS_I(method); \ +CHAOS_SYS_CALLBACKS(dt); -#define ODE_ATTRIBUTES \ -CHAOS_ATTRIBUTES; \ -FLEXT_ADDATTR_VAR("method", m_system->get_method, m_system->set_method); \ -FLEXT_ADDATTR_VAR("dt",m_system->get_dt, m_system->set_dt); +#define ODE_ATTRIBUTES \ +CHAOS_ATTRIBUTES; \ +CHAOS_SYS_ATTRIBUTE(method); \ +CHAOS_SYS_ATTRIBUTE(dt); #define __ode_base_hpp -- cgit v1.2.1