// // // chaos~ // Copyright (C) 2004 Tim Blechmann // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; see the file COPYING. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. #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(); }