Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jwilkes/purr-data
  • aggraef/purr-data
  • samthursfield/purr-data
  • prakhar/purr-data
  • yadu05/purr-data
  • NegiAkash890/purr-data
  • prateekpardeshi/purr-data
  • Shruti3004/purr-data
  • hidimpu/purr-data
  • Atseosi/purr-data
  • piyushjasaiwal/purr-data
  • deveshprasad/purr-data
  • skm_7/purr-data
  • sankt/purr-data
  • ashim_tom/purr-data
  • dineshsoni02/purr-data
  • chaitanya1-coder/purr-data
  • Nitish0007/purr-data
  • nitin/purr-data
  • shuvam09/purr-data
  • gabrielabittencourt/purr-data
  • sivasai/purr-data
  • flachyjoe/purr-data
  • ishankaler/purr-data
  • prateek/purr-data
  • RukshanJS/purr-data
  • rajatshrm648/purr-data
  • Srashti/purr-data
  • Paarth/purr-data
  • AniruddhaGawali/purr-data
  • brittneyjuliet/purr-data
  • prakharagarwal1/purr-data
  • Shreyanshpaliwalcmsmn/purr-data
  • k_amrut/purr-data
  • AyushAnand/purr-data
  • Va16hav07/purr-data
36 results
Show changes
Showing
with 5045 additions and 0 deletions
float rrand(int *seed);
float prand(int *seed);
Welcome to LyonPotpourri, version 3.0 (64-bit version).
http://disis.music.vt.edu/eric/LyonSoftware/Pd/LyonPotpourri/
LyonPotpourri is a collection of externals developed for the creation and performance of computer music. The externals were originally developed for Max/MSP, and then extended into hybrid code that could compile for both Max/MSP and Pd. As of version 3.0, the code bases of Max/MSP and Pd have diverged to such an extent that I decided to split the LyonPotpourri code into separate Pd and Max/MSP versions.
The Pd platform tends toward minimalism. Therefore, it is particularly advantageous for Pd users to become adept at designing their own externals. It is hoped that in addition to the utility of specific externals in this collection, the source code will be helpful for computer musicians who wish to learn how to write their own externals. For further guidance on that subject, please see my book “Designing Audio Objects for Max/MSP and Pd.”
LyonPotpourri 3.0 is Copyright Eric Lyon, 2007-2013, and is covered under the MIT license. Please see the accompanying License file for details.
Object Listing:
- adsr~ a simple ADSR envelope that can be click triggered
- arrayfilt~ fft-based filtering by drawing into an array
- bashfest~ a click driven buffer player with randomized DSP
- buffet~ provides operations on a stored buffer
- bvplay~ selective playback from a stored buffer with enveloping and increment control
- cartopol~ convert a spectral frame from cartesian to polar form
- channel~ access to a precise address in the signal vector
- chopper~ munging loop playback from a buffer
- clean_selector~ like selector~ but crossfades when switching channels
- click~ converts a bang to a click
- click2float~ translates a signal click to a float message
- clickhold~ sample and hold a click
- convolver~ non-real-time convolution with impulses of arbitrary size
- distortion~ lookup function distortion
- dmach~ pattern based sample accurate drum machine prototype
- expflam~ converts a click to an exponential flam click pattern
- flanjah~ simple flanger
- function~ write various functions into an array
- granola~ granular pitch scaling
- granulesf~ granular synthesis module reading from a soundfile in a buffer
- granule~ granular synthesis module reading from a stored waveform in a buffer
- kbuffer~ low sampling rate buffer to capture gestures
- killdc~ DC block filter
- latch~ sustain an incoming click with sample-accurate timing
- magfreq_analysis~ transforms a time domain signal to a magnitude/frequency spectrum
- markov~ implements a first order Markov chain
- mask~ a click driven pattern sequencer
- npan~ power-panning to an arbitrary number of output channels
- oscil~ oscillator with flexible waveform specification
- phasemod~ phase modulated waveform
- player~ click driven buffer player that can sustain multiple iterations
- poltocar~ convert spectral frame from polar to complex representation
- pulser~ pulse wave generated by additive synthesis
- quadpan~ pan an incoming sound within a quadraphonic plane
- rotapan~ rotate an array of input channels to the same number of output channels
- rtrig~ generates random click triggers
- samm~ sample accurate multiple metronomes, with click signal articulation
- sarec~ sample accurate recording
- sel~ sample-accurate implementation of the sel algorithm
- shoehorn~ collapse from a larger number to a smaller number of audio channels
- sigseq~ signal level numerical sequencer
- splitbank~ - split an incoming sound into complementary, independently tunable spectra
- splitspec~ split an incoming sound into complementary spectra
- squash~ implementation of a compression algorithm by Chris Penrose
- stutter~ stuttering playback from an array
- vdb~ a delay line using an array for storage (no vector limit on feedback delaytime)
- vdp~ a simple, self-contained delay unit
- vecdex~ outputs the sample index within the current signal vector
- waveshape~ a Chebychev function lookup waveshaper
- windowvec~ apply a Hann window to the input signal vector
Best wishes for the success of your creative projects and explorations!
Eric Lyon
ericlyon@vt.edu
Department of Music
Institute for Creativity, Arts, and Technology
Virginia Tech
# lyonpotpourri3.0
Welcome to LyonPotpourri, version 3.0 (64-bit version).
http://disis.music.vt.edu/eric/LyonSoftware/Pd/LyonPotpourri/
LyonPotpourri is a collection of externals developed for the creation and performance of computer music. The externals were originally developed for Max/MSP, and then extended into hybrid code that could compile for both Max/MSP and Pd. As of version 3.0, the code bases of Max/MSP and Pd have diverged to such an extent that I decided to split the LyonPotpourri code into separate Pd and Max/MSP versions.
The Pd platform tends toward minimalism. Therefore, it is particularly advantageous for Pd users to become adept at designing their own externals. It is hoped that in addition to the utility of specific externals in this collection, the source code will be helpful for computer musicians who wish to learn how to write their own externals. For further guidance on that subject, please see my book “Designing Audio Objects for Max/MSP and Pd.”
LyonPotpourri 3.0 is Copyright Eric Lyon, 2007-2013, and is covered under the MIT license. Please see the accompanying License file for details.
Object Listing:
- adsr~ a simple ADSR envelope that can be click triggered
- arrayfilt~ fft-based filtering by drawing into an array
- bashfest~ a click driven buffer player with randomized DSP
- buffet~ provides operations on a stored buffer
- bvplay~ selective playback from a stored buffer with enveloping and increment control
- cartopol~ convert a spectral frame from cartesian to polar form
- channel~ access to a precise address in the signal vector
- chopper~ munging loop playback from a buffer
- clean_selector~ like selector~ but crossfades when switching channels
- click~ converts a bang to a click
- click2float~ translates a signal click to a float message
- clickhold~ sample and hold a click
- convolver~ non-real-time convolution with impulses of arbitrary size
- distortion~ lookup function distortion
- dmach~ pattern based sample accurate drum machine prototype
- expflam~ converts a click to an exponential flam click pattern
- flanjah~ simple flanger
- function~ write various functions into an array
- granola~ granular pitch scaling
- granulesf~ granular synthesis module reading from a soundfile in a buffer
- granule~ granular synthesis module reading from a stored waveform in a buffer
- kbuffer~ low sampling rate buffer to capture gestures
- killdc~ DC block filter
- latch~ sustain an incoming click with sample-accurate timing
- magfreq_analysis~ transforms a time domain signal to a magnitude/frequency spectrum
- markov~ implements a first order Markov chain
- mask~ a click driven pattern sequencer
- npan~ power-panning to an arbitrary number of output channels
- oscil~ oscillator with flexible waveform specification
- phasemod~ phase modulated waveform
- player~ click driven buffer player that can sustain multiple iterations
- poltocar~ convert spectral frame from polar to complex representation
- pulser~ pulse wave generated by additive synthesis
- quadpan~ pan an incoming sound within a quadraphonic plane
- rotapan~ rotate an array of input channels to the same number of output channels
- rtrig~ generates random click triggers
- samm~ sample accurate multiple metronomes, with click signal articulation
- sarec~ sample accurate recording
- sel~ sample-accurate implementation of the sel algorithm
- shoehorn~ collapse from a larger number to a smaller number of audio channels
- sigseq~ signal level numerical sequencer
- splitbank~ - split an incoming sound into complementary, independently tunable spectra
- splitspec~ split an incoming sound into complementary spectra
- squash~ implementation of a compression algorithm by Chris Penrose
- stutter~ stuttering playback from an array
- vdb~ a delay line using an array for storage (no vector limit on feedback delaytime)
- vdp~ a simple, self-contained delay unit
- vecdex~ outputs the sample index within the current signal vector
- waveshape~ a Chebychev function lookup waveshaper
- windowvec~ apply a Hann window to the input signal vector
Best wishes for the success of your creative projects and explorations!
Eric Lyon
ericlyon@vt.edu
Department of Music
Institute for Creativity, Arts, and Technology
Virginia Tech
Updates to LyonPotpourri 3.0
12.22.2013
Nothing yet!
\ No newline at end of file
#N canvas 487 392 455 385 10;
#X obj 115 233 adsr~;
#X msg 115 94 bang;
#X obj 35 187 osc~ 400;
#X obj 97 274 *~;
#X obj 97 304 *~ 0.1;
#X obj 97 335 dac~;
#X msg 175 112 10 50 50 50;
#X text 254 115 adsr data as list;
#X msg 182 137 100 50 100 500;
#X obj 175 90 loadbang;
#N canvas 0 22 673 325 individual-adsr-elements 0;
#X obj 62 244 outlet;
#X msg 62 158 set_a \$1;
#X msg 135 159 set_d \$1;
#X msg 210 158 set_s \$1;
#X msg 283 159 set_r \$1;
#X msg 353 159 set_gain1 \$1;
#X msg 451 160 set_gain2 \$1;
#X obj 353 110 vsl 15 30 0 1 0 0 empty empty empty 0 -8 0 8 -242048
-1 -1 2900 1;
#X obj 451 109 vsl 15 30 0 1 0 0 empty empty empty 0 -8 0 8 -242048
-1 -1 2030 1;
#X obj 62 106 vsl 15 30 1 100 0 0 empty empty empty 0 -8 0 8 -242048
-1 -1 1435 1;
#X obj 135 110 vsl 15 30 10 100 0 0 empty empty empty 0 -8 0 8 -242048
-1 -1 1289 1;
#X obj 210 107 vsl 15 30 50 500 0 0 empty empty empty 0 -8 0 8 -242048
-1 -1 967 1;
#X obj 283 109 vsl 15 30 50 1000 0 0 empty empty empty 0 -8 0 8 -242048
-1 -1 458 1;
#X msg 62 40 50 50 200 200 1 0.7;
#X obj 62 64 unpack f f f f f f;
#X obj 62 16 loadbang;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 0 0;
#X connect 7 0 5 0;
#X connect 8 0 6 0;
#X connect 9 0 1 0;
#X connect 10 0 2 0;
#X connect 11 0 3 0;
#X connect 12 0 4 0;
#X connect 13 0 14 0;
#X connect 14 0 9 0;
#X connect 14 1 10 0;
#X connect 14 2 11 0;
#X connect 14 3 12 0;
#X connect 14 4 7 0;
#X connect 14 5 8 0;
#X connect 15 0 13 0;
#X restore 194 163 pd individual-adsr-elements;
#X obj 205 200 samm~ 40 1;
#X text 30 39 adsr~ - An ADSR envelope triggered by signal clicks or
bangs;
#X obj 26 4 cnv 15 155 25 empty empty LyonPotpourri 20 12 1 18 -260097
-204786 0;
#X text 111 74 trigger ADSR;
#X text 273 197 slow click metronome;
#X connect 0 0 3 1;
#X connect 1 0 0 0;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 4 0 5 0;
#X connect 4 0 5 1;
#X connect 6 0 0 0;
#X connect 8 0 0 0;
#X connect 9 0 6 0;
#X connect 10 0 0 0;
#X connect 11 0 0 0;
#include "MSPd.h"
/* internal metronome now redundant so disabled */
// LyonPotpourri 3.0 - Max references removed
static t_class *adsr_class;
#define OBJECT_NAME "adsr~"
typedef struct _adsr
{
t_object x_obj;
float x_f;
// Variables Here
float a;
float d;
float s;
float r;
int ebreak1;
int ebreak2;
int ebreak3;
int asamps;
int dsamps;
int ssamps;
int rsamps;
int asamps_last;
int dsamps_last;
int ssamps_last;
int rsamps_last;
float tempo;
float egain1;
float egain2;
int tempomode;
int beat_subdiv;
int tsamps;
int counter;
float srate;
short manual_override;
float click_gain; // input click sets volume too
short mute;
} t_adsr;
static void *adsr_new(t_symbol *s, int argc, t_atom *argv);
t_int *adsr_perform(t_int *w);
void adsr_dsp(t_adsr *x, t_signal **sp);
void adsr_assist(t_adsr *x, void *b, long m, long a, char *s);
void adsr_bang(t_adsr *x);
void adsr_manual_override(t_adsr *x, t_floatarg toggle);
void adsr_list (t_adsr *x, t_atom *msg, short argc, t_atom *argv);
void adsr_tempomode(t_adsr *x, t_atom *msg, short argc, t_atom *argv);
void adsr_set_a(t_adsr *x, t_floatarg f);
void adsr_set_d(t_adsr *x, t_floatarg f);
void adsr_set_s(t_adsr *x, t_floatarg f);
void adsr_set_r(t_adsr *x, t_floatarg f);
void adsr_set_gain1(t_adsr *x, t_floatarg f);
void adsr_set_gain2(t_adsr *x, t_floatarg f);
void set_tempo(t_adsr *x, t_floatarg f);
void adsr_mute(t_adsr *x, t_floatarg f);
void atom_arg_getfloat(float *c, long idx, long ac, t_atom *av);
void atom_arg_getsym(t_symbol **c, long idx, long ac, t_atom *av);
void adsr_tilde_setup(void){
adsr_class = class_new(gensym("adsr~"), (t_newmethod)adsr_new,
0,sizeof(t_adsr), 0,A_GIMME,0);
CLASS_MAINSIGNALIN(adsr_class, t_adsr, x_f);
class_addmethod(adsr_class,(t_method)adsr_dsp,gensym("dsp"),0);
class_addmethod(adsr_class,(t_method)adsr_mute,gensym("mute"),A_FLOAT,0);
class_addmethod(adsr_class,(t_method)adsr_list,gensym("list"),A_GIMME,0);
class_addmethod(adsr_class,(t_method)adsr_set_a,gensym("set_a"),A_FLOAT,0);
class_addmethod(adsr_class,(t_method)adsr_set_d,gensym("set_d"),A_FLOAT,0);
class_addmethod(adsr_class,(t_method)adsr_set_s,gensym("set_s"),A_FLOAT,0);
class_addmethod(adsr_class,(t_method)adsr_set_r,gensym("set_r"),A_FLOAT,0);
class_addmethod(adsr_class,(t_method)adsr_set_gain1,gensym("set_gain1"),A_FLOAT,0);
class_addmethod(adsr_class,(t_method)adsr_set_gain2,gensym("set_gain2"),A_FLOAT,0);
class_addbang(adsr_class,(t_method)adsr_bang);
potpourri_announce(OBJECT_NAME);
}
void adsr_mute(t_adsr *x, t_floatarg f)
{
x->mute = (short)f;
}
void adsr_set_gain1(t_adsr *x, t_floatarg f)
{
x->egain1 = f;
return;
}
void adsr_set_gain2(t_adsr *x, t_floatarg f)
{
x->egain2 = f;
return;
}
void adsr_bang(t_adsr *x) {
x->counter = 0;
return;
}
void adsr_set_a(t_adsr *x, t_floatarg f)
{
f /= 1000.0;
x->a = f;
x->asamps = x->a * x->srate;
if( x->tempomode) {
x->rsamps = x->tsamps - (x->asamps+x->dsamps+x->ssamps);
if( x->rsamps < 0 ) {
x->rsamps = 0;
}
} else {
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
}
x->ebreak1 = x->asamps;
x->ebreak2 = x->asamps+x->dsamps;
x->ebreak3 = x->asamps+x->dsamps+x->ssamps;
return ;
}
void adsr_set_d(t_adsr *x, t_floatarg f)
{
f /= 1000.0 ;
x->d = f;
x->dsamps = x->d * x->srate;
if( x->tempomode) {
x->rsamps = x->tsamps - (x->asamps+x->dsamps+x->ssamps);
if( x->rsamps < 0 ) {
x->rsamps = 0;
}
} else {
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
}
x->ebreak2 = x->asamps+x->dsamps;
x->ebreak3 = x->asamps+x->dsamps+x->ssamps;
return ;
}
void adsr_set_s(t_adsr *x, t_floatarg f)
{
f /= 1000.0;
x->s = f;
x->ssamps = x->s * x->srate;
if( x->tempomode) {
x->rsamps = x->tsamps - (x->asamps+x->dsamps+x->ssamps);
if( x->rsamps < 0 ) {
x->rsamps = 0;
}
} else {
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
}
x->ebreak3 = x->asamps+x->dsamps+x->ssamps;
return ;
}
void adsr_set_r(t_adsr *x, t_floatarg f)
{
f /= 1000.0;
if( x->tempomode) {
return;
} else {
x->r = f;
x->rsamps = x->r * x->srate;
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
}
return ;
}
void adsr_list (t_adsr *x, t_atom *msg, short argc, t_atom *argv)
{
t_atom *fraud; // make compiler happy
fraud = msg;
x->rsamps = x->tsamps - (x->asamps+x->dsamps+x->ssamps);
if( x->rsamps < 0 )
x->rsamps = 0;
x->a = (atom_getfloatarg(0,argc,argv)) * .001;
x->d = (atom_getfloatarg(1,argc,argv)) * .001;
x->s = (atom_getfloatarg(2,argc,argv)) * .001;
x->r = (atom_getfloatarg(3,argc,argv)) * .001;
x->asamps = x->a * x->srate;
x->dsamps = x->d * x->srate;
x->ssamps = x->s * x->srate;
x->rsamps = x->r * x->srate;
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
x->ebreak1 = x->asamps;
x->ebreak2 = x->asamps+x->dsamps;
x->ebreak3 = x->asamps+x->dsamps+x->ssamps;
}
static void *adsr_new(t_symbol *s, int argc, t_atom *argv)
{
t_adsr *x = (t_adsr *)pd_new(adsr_class);
t_symbol *fraud; // make compiler happy
fraud = s;
outlet_new(&x->x_obj, gensym("signal"));
x->srate = sys_getsr();
if(!x->srate){
error("zero sampling rate, setting to 44100");
x->srate = 44100;
}
x->a = 10;
x->d = 50;
x->s = 100;
x->r = 100;
x->egain1 = .7;
x->egain2 = .1;
atom_arg_getfloat(&x->a,0,argc,argv);
atom_arg_getfloat(&x->d,1,argc,argv);
atom_arg_getfloat(&x->s,2,argc,argv);
atom_arg_getfloat(&x->r,3,argc,argv);
atom_arg_getfloat(&x->egain1,4,argc,argv);
atom_arg_getfloat(&x->egain2,5,argc,argv);
x->a *= .001;
x->d *= .001;
x->s *= .001;
x->r *= .001;
x->asamps = x->a * x->srate;
x->dsamps = x->d * x->srate;
x->ssamps = x->s * x->srate;
x->rsamps = x->r * x->srate;
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
x->ebreak1 = x->asamps;
x->ebreak2 = x->asamps+x->dsamps;
x->ebreak3 = x->asamps+x->dsamps+x->ssamps;
x->counter = 0;
x->click_gain = 0.0;
x->mute = 0;
return x;
}
t_int *adsr_perform(t_int *w)
{
t_adsr *x = (t_adsr *) (w[1]);
t_float *in = (t_float *)(w[2]);
t_float *out = (t_float *)(w[3]);
int n = (int) w[4];
int tsamps = x->tsamps;
int counter = x->counter;
int ebreak1 = x->ebreak1;
int ebreak2 = x->ebreak2;
int ebreak3 = x->ebreak3;
float egain1 = x->egain1;
float egain2 = x->egain2;
int asamps = x->asamps;
int dsamps = x->dsamps;
int ssamps = x->ssamps;
int rsamps = x->rsamps;
// short manual_override = x->manual_override;
float click_gain = x->click_gain;
float etmp;
float env_val;
float input_val;
/*********************************************/
if(x->mute){
while(n--) *out++ = 0.0;
return w+5;
}
while(n--) {
input_val = *in++;
if(input_val){
click_gain = input_val;
counter = 0;
}
if( counter < ebreak1 ){
env_val = (float) counter / (float) asamps;
} else if (counter < ebreak2) {
etmp = (float) (counter - ebreak1) / (float) dsamps;
env_val = (1.0 - etmp) + (egain1 * etmp);
} else if (counter < ebreak3) {
etmp = (float) (counter - ebreak2) / (float) ssamps;
env_val = (egain1 * (1.0 - etmp)) + (egain2 * etmp);
} else if( counter < tsamps ){
env_val = ((float)(tsamps-counter)/(float)rsamps) * egain2 ;
} else {
env_val = 0.0;
}
if(click_gain && env_val && (click_gain != 1.0) ){
env_val *= click_gain;
}
*out++ = env_val;
if(counter < tsamps)
counter++;
}
x->counter = counter;
x->click_gain = click_gain;
return (w+5);
}
void adsr_dsp(t_adsr *x, t_signal **sp)
{
if(x->srate != sp[0]->s_sr ){
x->srate = sp[0]->s_sr;
x->asamps = x->a * x->srate;
x->dsamps = x->d * x->srate;
x->ssamps = x->s * x->srate;
x->rsamps = x->r * x->srate;
x->tsamps = x->asamps+x->dsamps+x->ssamps+x->rsamps;
x->ebreak1 = x->asamps;
x->ebreak2 = x->asamps+x->dsamps;
x->ebreak3 = x->asamps+x->dsamps+x->ssamps;
x->counter = 0;
}
dsp_add(adsr_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, (t_int)sp[0]->s_n);
}
#N canvas 814 114 449 293 10;
#X obj 31 238 dac~;
#X obj 31 81 noise~;
#X text 32 36 arrayfilt~ filters a sound with the contents of an array
\, so that filters can be drawn by hand;
#X floatatom 70 144 5 0 0 0 gain - -, f 5;
#X obj 31 178 *~ 0.05;
#N canvas 172 134 1229 589 array-fft-block 0;
#X obj 121 66 inlet~;
#X obj 122 415 outlet~;
#X obj 121 98 windowvec~;
#X obj 121 136 rfft~, f 6;
#X obj 187 464 block~ 1024 8;
#X obj 121 171 cartopol~;
#X obj 122 289 poltocar~;
#X obj 122 319 rifft~;
#X obj 122 382 windowvec~;
#X obj 122 349 *~ 0;
#X obj 290 185 *;
#X msg 242 107 1 1024 8;
#X obj 242 138 unpack f f f;
#X obj 242 217 /;
#X floatatom 242 249 12 0 0 0 - - -, f 12;
#X text 323 250 rescale factor;
#X obj 242 76 loadbang;
#N canvas 0 22 450 278 (subpatch) 0;
#X array arrayfilt1 513 float 3;
#A 0 0.95 0.935714 0.914285 0.909523 0.921429 0.921429 0.921429 0.921429
0.921429 0.921429 0.914286 0.907143 0.889286 0.885714 0.871429 0.850001
0.842858 0.840477 0.838096 0.835715 0.832143 0.835714 0.835714 0.835714
0.835714 0.835714 0.835714 0.835714 0.835714 0.835714 0.835714 0.835714
0.835714 0.835714 0.842857 0.842857 0.753574 0.757146 0.760717 0.764289
0.764289 0.764289 0.764289 0.764289 0.764289 0.764289 0.764289 0.757146
0.757146 0.752384 0.747622 0.74286 0.74286 0.74286 0.74286 0.74286
0.74286 0.737503 0.732146 0.726788 0.721431 0.714288 0.700002 0.69524
0.690479 0.685717 0.664288 0.642859 0.624492 0.606124 0.587757 0.569389
0.551022 0.532654 0.514287 0.428572 0.271429 0.271429 0.271429 0.271429
0.271429 0.271429 0.271429 0.271429 0.271429 0.265714 0.26 0.254286
0.248571 0.242857 0.235714 0.228571 0.214285 0.2 0.178571 0.171428
0.160714 0.114285 0.107142 0.0571415 0.021427 0.0178556 0.0142841 0.00714123
0.00714123 0.00714123 0.00714123 0.00714123 0.00714123 0.00714123 0.00624837
0.00535551 0.00446264 0.00356978 0.00267692 0.00178406 0.000891194
-1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06
-1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06
-1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06
-1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06
-1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06 -1.66893e-06
-1.66893e-06 0.00714123 0.00714123 0.00714123 0.00714123 0.00714123
0.00714123 0.00714123 0.00714123 0.00714123 0.0142841 0.0142841 0.0142841
0.0178556 0.021427 0.021427 0.0285699 0.0285699 0.0321414 0.0357128
0.0357128 0.0428557 0.0428557 0.0428557 0.0428557 0.0428557 0.0428557
0.0428557 0.0428557 0.0428557 0.0428557 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0290476 0.0295238
0.03 0.0304762 0.0309524 0.0314286 0.0319048 0.032381 0.0328572 0.0333334
0.0338096 0.0342858 0.0347619 0.0352381 0.0357143 0.0357143 0.0357143
0.0357143 0.0357143 0.0357143 0.0357143 0.0357143 0.0357143 0.0363637
0.037013 0.0376624 0.0383117 0.0389611 0.0396105 0.0402598 0.0409092
0.0415585 0.0422079 0.0428572 0.0464287 0.0500001 0.0500001 0.0500001
0.0500001 0.0500001 0.0500001 0.0500001 0.0500001 0.0517859 0.0535716
0.0553573 0.057143 0.0607145 0.0642859 0.0642859 0.0642859 0.0642859
0.0642859 0.0642859 0.0642859 0.0642859 0.0642859 0.0642859 0.0642859
0.0642859 0.0642859 0.0660717 0.0678574 0.0696431 0.0714288 0.0726193
0.0738098 0.0750003 0.0761908 0.0773813 0.0785717 0.0785717 0.0785717
0.0785717 0.0785717 0.0785717 0.0785717 0.0785717 0.0785717 0.0797622
0.0809527 0.0821432 0.0833337 0.0845242 0.0857146 0.086364 0.0870133
0.0876627 0.088312 0.0889614 0.0896108 0.0902601 0.0909095 0.0915588
0.0922082 0.0928575 0.0935069 0.0941562 0.0948056 0.095455 0.0961043
0.0967537 0.097403 0.0980524 0.0987017 0.0993511 0.1 0.1 0.1 0.1 0.1
0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.0928575 0.0928575
0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575
0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575
0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575
0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575
0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575
0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575 0.0928575
0.0928575 1 1;
#X coords 0 1 513 0 400 140 1 0 0;
#X restore 525 133 graph;
#X msg 428 432 \; arrayfilt1 const 0;
#X obj 678 443 tabwrite arrayfilt1;
#X msg 678 363 1 \$1;
#X obj 678 400 unpack f f;
#X floatatom 678 324 5 0 0 0 - - -, f 5;
#X text 715 323 set a range of bin gains to 1;
#X text 549 437 zero out array;
#X obj 77 227 arrayfilt~ arrayfilt1;
#X text 644 102 Size the filter to (FFT size / 2) + 1;
#X text 879 103 in this case \, 513;
#X text 934 214 draw into array to change filter properties;
#X text 542 475 flat response;
#X msg 427 469 \; arrayfilt1 const 1;
#X text 120 444 set FFT size to 1024 \, with an overlap of 8;
#X connect 0 0 2 0;
#X connect 2 0 3 0;
#X connect 3 0 5 0;
#X connect 3 1 5 1;
#X connect 5 0 25 0;
#X connect 5 1 25 1;
#X connect 6 0 7 0;
#X connect 6 1 7 1;
#X connect 7 0 9 0;
#X connect 8 0 1 0;
#X connect 9 0 8 0;
#X connect 10 0 13 1;
#X connect 11 0 12 0;
#X connect 12 0 13 0;
#X connect 12 1 10 0;
#X connect 12 2 10 1;
#X connect 13 0 14 0;
#X connect 14 0 9 1;
#X connect 16 0 11 0;
#X connect 20 0 21 0;
#X connect 21 0 19 0;
#X connect 21 1 19 1;
#X connect 22 0 20 0;
#X connect 25 0 6 0;
#X connect 25 1 6 1;
#X restore 31 113 pd array-fft-block;
#X obj 26 4 cnv 15 155 25 empty empty LyonPotpourri 20 12 1 18 -260097
-204786 0;
#X text 79 224 A demonstration of using fft primitives with a simple
external that operates on bin magnitudes;
#X connect 1 0 5 0;
#X connect 3 0 4 1;
#X connect 4 0 0 0;
#X connect 4 0 0 1;
#X connect 5 0 4 0;
#include "MSPd.h"
static t_class *arrayfilt_class;
/* Pd version of arrayfilt~ */
#define OBJECT_NAME "arrayfilt~"
typedef struct _arrayfilt
{
t_object x_obj;
t_float x_f;
t_word *a_samples;
int a_frames;
t_symbol *arrayname;
} t_arrayfilt;
void *arrayfilt_new(t_symbol *msg, short argc, t_atom *argv);
void arrayfilt_dsp(t_arrayfilt *x, t_signal **sp);
void arrayfilt_setarray(t_arrayfilt *x);
void arrayfilt_tilde_setup(void){
arrayfilt_class = class_new(gensym("arrayfilt~"), (t_newmethod)arrayfilt_new,
0, sizeof(t_arrayfilt),0,A_GIMME,0);
CLASS_MAINSIGNALIN(arrayfilt_class, t_arrayfilt, x_f);
class_addmethod(arrayfilt_class, (t_method)arrayfilt_dsp, gensym("dsp"),0);
potpourri_announce(OBJECT_NAME);
}
void *arrayfilt_new(t_symbol *msg, short argc, t_atom *argv)
{
t_arrayfilt *x = (t_arrayfilt *)pd_new(arrayfilt_class);
// t_symbol *arrayname;
inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("signal"), gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->arrayname = atom_getsymbolarg(0, argc, argv);
arrayfilt_setarray(x);
return x;
}
void arrayfilt_setarray(t_arrayfilt *x)
{
t_garray *a;
t_symbol *arrayname = x->arrayname;
if (!(a = (t_garray *)pd_findbyclass(arrayname, garray_class))) {
if (*arrayname->s_name) pd_error(x, "arrayflt~: %s: no such array", arrayname->s_name);
}
else {
garray_usedindsp(a);
if (!garray_getfloatwords(a, &x->a_frames, &x->a_samples))
{
pd_error(x, "%s: bad template for player~", arrayname->s_name);
}
}
}
t_int *arrayfilt_perform(t_int *w)
{
int i;
t_arrayfilt *x = (t_arrayfilt *) w[1];
t_float *mag_in = (t_float *) w[2];
t_float *phase_in = (t_float *) w[3];
t_float *mag_out = (t_float *) w[4];
t_float *phase_out = (t_float *) w[5];
t_float mag, phase;
t_word *a_samples = x->a_samples;
int a_frames = x->a_frames;
int n = (int) w[6];
int N2 = n / 2;
arrayfilt_setarray(x);
if(a_frames < N2+1) {
goto exit;
}
for(i = 0; i < N2 + 1; i++){
mag = mag_in[i];
phase = phase_in[i];
mag_out[i] = mag * a_samples[i].w_float;
phase_out[i] = phase;
}
exit:
return (w + 7);
}
void arrayfilt_dsp(t_arrayfilt *x, t_signal **sp)
{
dsp_add(arrayfilt_perform,6, x,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, (t_int)sp[0]->s_n);
}
#include "MSPd.h"
#include "ugens.h"
#include <string.h>
/* calling codes for DSP modules */
#define TRANSPOSE 0
#define RINGMOD 1
#define FLANGE 2
#define BUTTER 3
#define TRUNCATE 4
#define SWEEPRESON 5
#define COMB 6
#define SLIDECOMB 7
#define REVERB1 8
#define ELLIPSE 9
#define COMPDIST 10
#define FEED1 11
#define RETRO 12
#define FLAM1 13
#define FLAM2 14
#define EXPFLAM 15
#define COMB4 16
#define RINGFEED 17
#define RESONADSR 18
#define STV 19
//////
#define ROOT2 (1.4142135623730950488)
#define PI2 (6.2831853071795862319959)
// #define BUFFER_SIZE (1<<15)
#define LOPASS 0
#define HIPASS 1
#define BANDPASS 2
#define COMBFADE (.04 )
#define MAXFILTER 12 /*must be at least as big as see below */
#define ELLIPSE_FILTER_COUNT 11 /*actual number of filters*/
#define MAX_COEF 48
#define MY_MAX 2147483647.0 /* for rand() */
/*data types */
typedef struct
{
float *data;//contains cycle data
int len;//length of array
int p;//position pointer
} t_cycle;
typedef struct
{
long phase; // current phase in frames
double phasef; // current phase in frames
float gain; // gain for this note
float gainL;// left gain
float gainR;// right gain
short status;// status of this event slot
float *workbuffer;//sample processing space (both input and output)
float *inbuf;//pointer to input part of workbuffer
float *outbuf;//pointer to output part of workbuffer
int in_start;// location in workbuffer to read from input
int out_start;// location in workbuffer to write output
int sample_frames;//actual size in frames of sample, which changes if it gets bigger
int countdown;//latency counter before we actually start sending out samples
int out_channels; //number of channels per frame of output
short completed;//did the defer call do its thing?
} t_event;
typedef struct _bashfest
{
t_object x_obj;
float x_f;
float sr; // sampling rate
t_symbol *wavename; // name of waveform buffer
short hosed; // buffers are bad
float fadeout; // fadeout time in sample frames (if truncation)
float sync; // input from groove sync signal
float increment; // read increment
int most_recent_event; // position in array where last note was initiated
long b_nchans; // channels of buffer
long b_valid; // state of buffer
long b_frames; // number of frames in sample buffer
t_word *b_samples; // pointer samples in buffer
int overlap_max; // max number of simultaneous plays
t_event *events; //note attacks
int active_events; // how many currently activated notes?
int buf_samps;//total samples in workbuffer
int halfbuffer;//buf_samps / 2
int buf_frames;// number of sample frames in workbuffer
int latency_samples;// amount of samples to count down before playing sample
float *params; // parameter list
float *odds;// odds for each process happening
int max_process_per_note;//what it says
int min_process_per_note;//ditto
int new_slot;//position for newest note
float new_gain;//recently assigned gain
short verbose;//toggle Max window error reporting
float work_buffer_size;// size in ms of work buffers
t_cycle tcycle;//contains an optional transposition cycle
short block_dsp;//flag to turn off all dsp and play straight from MSP buffer
short sound_lock;//keep current processed sound in buffer
short grab;//flag to copy immediate processed buffer into MSP buffer
char sound_name[256];
float *trigger_vec;//stores incoming trigger vectors
int vs;//Max/MSP vector size
/* stuff for bashfest DSP */
float *sinewave;
int sinelen;
short mute;
float maxdelay;
float *delayline1;
float *delayline2;
LSTRUCT *eel; // for ellipse processor
float *mini_delay[4]; // small delay lines for allpass filter
float max_mini_delay ;
float *transfer_function;
int tf_len; // length of transfer function
float *feedfunc1;
float *feedfunc2;
float *feedfunc3;
float *feedfunc4;
int feedfunclen;
int flamfunc1len;
float *flamfunc1;
CMIXCOMB *combies;
CMIXADSR *adsr;
float max_comb_lpt;
float *reverb_ellipse_data;
float **ellipse_data;
float *dcflt;
CMIXOSC oscar;
CMIXRESON resies[2];
} t_bashfest;
/*function prototypes*/
void putsine (float *arr, int len);
float boundrand(float min, float max);
void mycombset(float loopt,float rvt,int init,float *a,float srate);
float mycomb(float samp,float *a);
void setweights(float *a, int len);
void delset2(float *a,int *l,float xmax, float srate);
void delput2(float x,float *a,int *l);
float dliget2(float *a,float dwait,int *l,float srate);
void butterLopass( float *in, float *out, float cutoff, int frames, int channels, float srate);
void butterBandpass(float *in, float *out, float center, float bandwidth, int frames,int channels, float srate);
void butterHipass(float *in, float *out, float cutoff, int frames,int channels, float srate);
void butset(float *a);
void lobut(float *a, float cutoff,float SR);
void hibut(float *a, float cutoff, float SR);
void bpbut(float *a, float formant, float bandwidth, float SR);
void butter_filter(float *in,float *out,float *a, int frames, int channels, int channel);
void rsnset2(float cf,float bw,float scl,float xinit,float *a,float srate);
float reson(float x,float *a);
void ellipset(float *list, LSTRUCT *eel, int *nsects, float *xnorm);
float ellipse(float x, LSTRUCT *eel, int nsects, float xnorm);
float allpass(float samp,float *a);
void init_reverb_data(float *a);
void init_ellipse_data(float **a);
void setExpFlamFunc(float *arr, int flen, float v1,float v2,float alpha);
void setflamfunc1(float *arr, int flen);
void funcgen1(float *outArray, int outlen, float duration, float outMin, float outMax,
float speed1, float speed2, float gain1, float gain2, float *phs1, float *phs2,
float *sine, int sinelen);
void normtab(float *inarr,float *outarr, float min, float max, int len);
float mapp(float in,float imin,float imax,float omin,float omax);
float oscil(float amp,float si,float *farray,int len,float *phs);
void set_dcflt(float *a);
void set_distortion_table(float *arr, float cut, float max, int len);
float dlookup(float samp,float *arr,int len);
void do_compdist(float *in,float *out,int sampFrames,int nchans,int channel,
float cutoff,float maxmult,int lookupflag,float *table,int range,float bufMaxamp);
float getmaxamp(float *arr, int len);
void buildadsr(CMIXADSR *a);
/*bashfest dsp functions */
void feed1(float *inbuf, float *outbuf, int in_frames, int out_frames,int channels, float *functab1,
float *functab2,float *functab3,float *functab4,int funclen,
float duration, float maxDelay, t_bashfest *x);
void reverb1me(float *in, float *out, int inFrames, int out_frames, int nchans,
int channel, float revtime, float dry, t_bashfest *x);
void killdc( float *inbuf, int in_frames, int channels, t_bashfest *x);
#include "bashfest.h"
void transpose(t_bashfest *x, int slot, int *pcount)
{
float *inbuf;
float *outbuf;
int i;
int iphs = 0;
int ip2;
float m1, m2;
float phs = 0;
int out_frames;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
float *params = x->params;
// float srate = x->sr;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
int buf_frames = x->buf_frames;
float tfac;
++(*pcount);
tfac = params[ (*pcount)++ ];
// out_start MUST BE SET WITH RESPECT TO in_start
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
// fprintf(stderr,"TRANSPOSE: in %d out %d\n", w->in_start, w->out_start);
out_frames = (float) in_frames / tfac ;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
for( i = 0; i < out_frames * channels; i += channels ){
iphs = phs;
m2 = phs - iphs;
m1 = 1. - m2;
if( channels == 1 ){
*outbuf++ = inbuf[iphs] * m1 + inbuf[ iphs + 1] * m2 ;
} else if( channels == 2 ){
ip2 = iphs * 2;
*outbuf++ = inbuf[ip2] * m1 + inbuf[ ip2 + 2] * m2 ;
*outbuf++ = inbuf[ip2 + 1] * m1 + inbuf[ ip2 + 3] * m2 ;
}
phs += tfac ;
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void ringmod(t_bashfest *x, int slot, int *pcount)
{
float *sinewave = x->sinewave;
float *inbuf, *outbuf;
int sinelen = x->sinelen;
int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
float *params = x->params;
float srate = x->sr;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
// int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
int i;
float phase = 0.0;
float si;
float rmodFreq;
++(*pcount);
rmodFreq = params[(*pcount)++];
// fprintf(stderr,"-*-*- EXECUTING RINGMOD -*-*-\n");
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
si = ((float) sinelen / srate) * rmodFreq ;
// inbuf = inbuf + in_start ;
for(i = 0; i < frames*channels; i += channels ){
*outbuf++ = *inbuf++ * sinewave[(int)phase];
if( channels == 2 ){
*outbuf++ = *inbuf++ * sinewave[(int)phase];
}
phase += si;
while( phase > sinelen )
phase -= sinelen;
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void retrograde(t_bashfest *x, int slot, int *pcount)
{
int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
// float *params = x->params;
// float srate = x->sr;
int i ;
int swap1, swap2;
float tmpsamp;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
memcpy(outbuf, inbuf, in_frames * channels * sizeof(float) );
if( channels == 1 ){
for(i = 0; i < (frames/2) ; i++ ){
swap2 = (frames - 1 - i);
tmpsamp = outbuf[i];
outbuf[i] = outbuf[swap2];
outbuf[swap2] = tmpsamp;
}
}
/* this would also work for mono, but we'll save a few multiplies */
else {
for(i = 0; i < (frames/2) ; i++ ){
swap1 = i * channels ;
swap2 = (frames - 1 - i) * channels;
tmpsamp = outbuf[swap1];
outbuf[swap1] = outbuf[swap2];
outbuf[swap2] = tmpsamp;
++swap1;
++swap2;
tmpsamp = outbuf[swap1];
outbuf[swap1] = outbuf[swap2];
outbuf[swap2] = tmpsamp;
}
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void comber(t_bashfest *x, int slot, int *pcount)
{
int channels = x->events[slot].out_channels;
float *params = x->params;
float srate = x->sr;
float *delayline1 = x->delayline1;
float *delayline2 = x->delayline2;
float max_delay = x->maxdelay ;
int buf_frames = x->buf_frames;
int out_frames ;
float overhang, revtime, delay ;
// float *comb1, *comb2;
int combsamps;
int i;
int fade_frames;
float fadegain;
int fadestart;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
/******************************/
++(*pcount);
delay = params[(*pcount)++];
revtime = params[(*pcount)++];
overhang = params[(*pcount)++];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
if( delay <= 0.0 ){
error("comber got bad delay value\n");
return;
}
if( delay > max_delay ){
delay = max_delay ;
}
if( overhang < COMBFADE )
overhang = COMBFADE;
out_frames = in_frames + overhang * srate ;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
combsamps = delay * srate + 20 ;
mycombset(delay,revtime,0,delayline1,srate);
if( channels == 2 )
mycombset(delay,revtime,0,delayline2,srate);
// ADD IN ORIGINAL SIGNAL
for( i = 0; i < in_frames*channels; i += channels){
*outbuf++ += mycomb(*inbuf++, delayline1);
if( channels == 2 ){
*outbuf++ += mycomb(*inbuf++,delayline2);
}
}
for( i = in_frames * channels; i < out_frames*channels; i += channels){
*outbuf++ = mycomb( 0.0 , delayline1);
if( channels == 2 ){
*outbuf++ = mycomb( 0.0 , delayline2);
}
}
fade_frames = COMBFADE * srate;
fadestart = (out_frames - fade_frames) * channels ;
for( i = 0; i < fade_frames * channels; i += channels ){
fadegain = 1.0 - (float) i / (float) (fade_frames * channels) ;
*(inbuf + fadestart + i) *= fadegain;
if(channels == 2){
*(inbuf + fadestart + i + 1) *= fadegain;
}
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void flange(t_bashfest *x, int slot, int *pcount)
{
int i;
float si;
float mindel, maxdel;
float fac1, fac2;
int dv1[2], dv2[2]; /* cmix bookkeeping */
float delsamp1, delsamp2 ;
float delay_time;
// float dliget2();
float speed, feedback, phase, minres, maxres;
float hangover ;
int hangframes ;
// float *inbuf = x->events[slot].workbuffer;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
// int buflen = x->buf_samps;
float *params = x->params;
float srate = x->sr;
// int in_start = x->events[slot].in_start;
float *delayline1 = x->delayline1;
float *delayline2 = x->delayline2;
float max_delay = x->maxdelay ;
float *sinewave = x->sinewave;
int sinelen = x->sinelen ;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
minres = params[(*pcount)++];
maxres = params[(*pcount)++];
speed = params[(*pcount)++];
feedback = params[(*pcount)++];
phase = params[(*pcount)++];
hangover = feedback * 0.25 ; // maybe log relation
hangframes = srate * hangover ;
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
if( minres <= 0. || maxres <= 0. ){
error("flange: got zero frequency resonances as input");
return;
}
mindel = 1.0/maxres;
maxdel = 1.0/minres;
if( maxdel > max_delay ){
maxdel = max_delay;
error("flange: too large delay time shortened");
}
delset2(delayline1, dv1, maxdel,srate);
if( channels == 2 ){
delset2(delayline2, dv2, maxdel,srate);
}
si = ((float) sinelen/srate) * speed ;
if( phase > 1.0 ){
phase = 0;
error("flange: given > 1 initial phase");
}
delsamp1 = delsamp2 = 0;
phase *= sinelen;
fac2 = .5 * (maxdel - mindel) ;
fac1 = mindel + fac2;
for(i = 0; i < in_frames*channels; i += channels ){
/* homemade oscillator */
delay_time = fac1 + fac2 * sinewave[(int) phase];
if( delay_time < .00001 ){
delay_time = .00001;
}
phase += si;
while( phase > sinelen )
phase -= sinelen;
delput2( *inbuf + delsamp1*feedback, delayline1, dv1);
delsamp1 = dliget2(delayline1, delay_time, dv1,srate);
*outbuf++ = (*inbuf++ + delsamp1) ;
if( channels == 2 ){
delput2( *inbuf+delsamp2*feedback, delayline2, dv2);
delsamp2 = dliget2(delayline2, delay_time, dv2,srate);
*outbuf++ = (*inbuf++ + delsamp2) ;
}
}
/* NOW DO HANGOVER */
for(i = 0; i < hangframes*channels; i += channels ){
delay_time = fac1 + fac2 * sinewave[ (int) phase ];
if( delay_time < .00001 ){
delay_time = .00001;
}
phase += si;
while( phase > sinelen )
phase -= sinelen;
delput2( delsamp1*feedback, delayline1, dv1);
delsamp1 = dliget2(delayline1, delay_time, dv1,srate);
*outbuf++ = delsamp1 ;
if( channels == 2 ){
delput2( delsamp2*feedback, delayline2, dv2);
delsamp2 = dliget2(delayline2, delay_time, dv2,srate);
*outbuf++ = delsamp2 ;
}
}
x->events[slot].sample_frames += hangframes;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void butterme(t_bashfest *x, int slot, int *pcount)
{
int ftype;
float cutoff, cf, bw;
int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
float *params = x->params;
float srate = x->sr;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
// int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
ftype = params[(*pcount)++];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
if(ftype == HIPASS){
cutoff = params[(*pcount)++];
butterHipass(inbuf, outbuf, cutoff, frames, channels, srate);
}
else if(ftype == LOPASS){
cutoff = params[(*pcount)++];
butterLopass(inbuf, outbuf, cutoff, frames, channels, srate);
}
else if(ftype == BANDPASS){
cf = params[(*pcount)++];
bw = params[(*pcount)++];
butterBandpass(inbuf, outbuf, cf, bw, frames, channels, srate);
} else {
error("%d not a valid Butterworth filter",ftype);
return;
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void truncateme(t_bashfest *x, int slot, int *pcount)
{
float shortdur ;
int out_frames;
int i;
float fadegain ;
int fade_frames;
int fadestart;
float fadeout;
int channels = x->events[slot].out_channels;
float *params = x->params;
float srate = x->sr;
float *inbuf, *outbuf;
int in_start;
int out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
shortdur = params[ (*pcount)++ ];
fadeout = params[ (*pcount)++ ];
fade_frames = fadeout * srate ;
out_frames = shortdur * srate ;
if( out_frames >= in_frames ){
// error("truncation requesting >= original duration, no truncation");
return;
}
in_start = x->events[slot].in_start;
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
if( fade_frames <= 0 ){
error("truncation with 0 length fade!");
return;
}
if( fade_frames > out_frames ){
error("truncation requested fadeout > new duration, adjusting...");
fade_frames = out_frames;
}
memcpy(outbuf, inbuf, in_frames * sizeof(float) );
fadestart = (out_frames - fade_frames) * channels ;
for( i = 0; i < fade_frames * channels; i += channels ){
fadegain = 1.0 - (float) i / (float) (fade_frames * channels) ;
outbuf[fadestart + i] *= fadegain;
if( channels == 2 ){
outbuf[ fadestart + i + 1] *= fadegain;
}
}
x->events[slot].sample_frames = out_frames ;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
// Pd only - not reentrant - appears that sine wave gets screwed up ???
void sweepreson(t_bashfest *x, int slot, int *pcount)
{
int i;
float bwfac;
float minfreq, maxfreq, speed, phase;
float q1[5], q2[5];
float cf, bw;
float si;
float fac1, fac2;
// float inmax, outmax, rescale ;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
float *params = x->params;
float srate = x->sr;
float *sinewave = x->sinewave;
int sinelen = x->sinelen ;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
minfreq = params[(*pcount)++];
maxfreq = params[(*pcount)++];
bwfac = params[(*pcount)++];
speed = params[(*pcount)++];
phase = params[(*pcount)++];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
si = ((float) sinelen / srate) * speed ;
if( phase > 1.0 ){
phase = 0;
error("sweepreson: given > 1 initial phase");
}
phase *= sinelen;
fac2 = .5 * (maxfreq - minfreq) ;
fac1 = minfreq + fac2;
cf = fac1 + fac2 * sinewave[(int) phase];
bw = bwfac * cf;
rsnset2( cf, bw, 2.0, 0.0, q1, srate );
if( channels == 2 ){
rsnset2( cf, bw, 2.0, 0.0, q2, srate );
}
for(i = 0; i < in_frames; i++ ){
// homemade oscillator
phase += si;
while( phase >= sinelen )
phase -= sinelen;
fac2 = .5 * (maxfreq - minfreq) ;
fac1 = minfreq + fac2;
cf = fac1 + fac2 * sinewave[(int) phase];
bw = bwfac * cf;
if(cf < 10 || cf > 8000 || bw < 1 || srate < 100){
post("danger values, cf %f bw %f sr %f",cf, bw, srate);
}
rsnset2( cf, bw, 2.0, 1.0, q1, srate );
// clicks stop if we don't apply filter above, and if attacks come too fast
*outbuf++ = reson(*inbuf++, q1);
if( channels == 2 ){
// rsnset2( cf, bw, 2.0, 1.0, q2, srate );
*outbuf++ = reson(*inbuf++, q2);
}
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void slidecomb(t_bashfest *x, int slot, int *pcount)
{
float overhang, feedback, delay1, delay2;
// int combsamps;
int i;
int fade_frames;
float fadegain;
int fadestart;
int dv1[2], dv2[2]; /* cmix bookkeeping */
float delsamp1 = 0, delsamp2 = 0;
float m1, m2;
float delay_time;
int out_frames ;
int channels = x->events[slot].out_channels;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
// float *sinewave = x->sinewave;
// int sinelen = x->sinelen ;
float max_delay = x->maxdelay;
float *delayline1 = x->delayline1;
float *delayline2 = x->delayline2;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
delay1 = params[(*pcount)++];
delay2 = params[(*pcount)++];
feedback = params[(*pcount)++];
overhang = params[(*pcount)++];
// post("del1 %f del2 %f srate %f",delay1,delay2, srate);
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
if( overhang < COMBFADE )
overhang = COMBFADE;
out_frames = in_frames + overhang * srate ;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
delset2(delayline1, dv1, max_delay, srate);
if( channels == 2 ){
delset2(delayline2, dv2, max_delay, srate);
}
for( i = 0; i < in_frames*channels; i += channels){
m2 = (float) i / (float) (out_frames * channels) ;
m1 = 1. - m2;
delay_time = delay1 * m1 + delay2 * m2 ;
delput2(*inbuf +delsamp1*feedback, delayline1, dv1);
delsamp1 = dliget2(delayline1, delay_time, dv1, srate);
*outbuf++ = *inbuf++ + delsamp1;
if( channels == 2 ){
delput2( *inbuf + delsamp2*feedback, delayline2, dv2);
delsamp2 = dliget2(delayline2, delay_time, dv2, srate);
*outbuf++ = *inbuf++ + delsamp2 ;
}
}
for( i = in_frames * channels; i < out_frames*channels; i += channels){
m2 = (float) i / (float) (out_frames * channels) ;
m1 = 1. - m2;
delay_time = delay1 * m1 + delay2 * m2 ;
delput2( delsamp1*feedback, delayline1, dv1);
*outbuf++ = delsamp1 = dliget2( delayline1, delay_time, dv1, srate );
if( channels == 2 ){
delput2( delsamp2*feedback, delayline2, dv2);
*outbuf++ = delsamp2 = dliget2( delayline2, delay_time, dv2, srate );
}
}
fade_frames = COMBFADE * srate;
fadestart = (out_frames - fade_frames) * channels ;
for( i = 0; i < fade_frames * channels; i += channels ){
fadegain = 1.0 - (float) i / (float) (fade_frames * channels) ;
*(outbuf + fadestart + i) *= fadegain;
if( channels == 2 ){
*(outbuf + fadestart + i + 1) *= fadegain;
}
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
// still a crash whore in Pd:
void reverb1(t_bashfest *x, int slot, int *pcount)
{
float revtime, overhang;
int channel_to_compute;
float drygain;
int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
revtime = params[(*pcount)++];
if( revtime >= 1. ){
error("reverb1 does not like feedback values over 1.");
revtime = .99 ;
}
overhang = params[(*pcount)++];
drygain = params[(*pcount)++];
out_frames = in_frames + srate * overhang;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
for( channel_to_compute = 0; channel_to_compute < channels; channel_to_compute++) {
reverb1me( inbuf, outbuf, in_frames, out_frames, channels, channel_to_compute, revtime, drygain, x);
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void ellipseme(t_bashfest *x, int slot, int *pcount)
{
int i,j;
int nsects;
float xnorm;
int filtercode ;
float *fltdata;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
// int buf_frames = x->buf_frames;
float *params = x->params;
// float srate = x->sr;
float **flts = x->ellipse_data;
LSTRUCT *eel = x->eel;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
filtercode = params[(*pcount)++];
if( filtercode >= ELLIPSE_FILTER_COUNT ){
error("there is no %d ellipse data",filtercode);
return;
};
fltdata = flts[ filtercode ];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
for( j = 0; j < channels; j++) {
ellipset(fltdata,eel,&nsects,&xnorm);
for( i = j; i < in_frames * channels ; i += channels ){
outbuf[i] = ellipse(inbuf[i], eel, nsects,xnorm);
}
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void feed1me(t_bashfest *x, int slot, int *pcount)
{
// int i;
float mindelay, maxdelay, speed1, speed2;
float phz1 = .13, phz2 = .251;
float dur;
float minfeedback = .1, maxfeedback = .7;
float desired_dur;
float overhang;
/* main variables */
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
int out_frames;
/* process specfic*/
int flen = x->feedfunclen ;
float *func1 = x->feedfunc1;
float *func2 = x->feedfunc2;
float *func3 = x->feedfunc3;
float *func4 = x->feedfunc4;
float my_max_delay = x->max_mini_delay;
float *sinewave = x->sinewave;
int sinelen = x->sinelen ;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
mindelay = params[ (*pcount)++ ];
maxdelay = params[ (*pcount)++ ];
speed1 = params[ (*pcount)++ ];
speed2 = params[ (*pcount)++ ];
overhang = params[ (*pcount)++ ];
if( maxdelay > my_max_delay ){
error("feed1: too high max delay, adjusted");
maxdelay = my_max_delay ;
}
dur = in_frames / srate ;
desired_dur = dur + overhang;
out_frames = srate * desired_dur ;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
funcgen1( func1, flen, desired_dur, mindelay, maxdelay,
speed1, speed2, 1.0, 1.0, &phz1, &phz2, sinewave, sinelen);
phz1 /= (float) flen; phz2 /= (float) flen;
funcgen1( func2, flen, desired_dur, mindelay*.5, maxdelay*2.0,
speed1*1.25, speed2*.75, 1.0, 1.0, &phz1, &phz2, sinewave, sinelen);
phz1 /= (float) flen; phz2 /= (float) flen;
funcgen1( func3, flen, desired_dur, minfeedback, maxfeedback,
speed1*.35, speed2*1.25, 1.0, 1.0, &phz1, &phz2, sinewave, sinelen);
phz1 /= (float) flen; phz2 /= (float) flen;
funcgen1( func4,flen, desired_dur, minfeedback, maxfeedback,
speed1*.55, speed2*2.25, 1.0, 1.0, &phz1, &phz2, sinewave, sinelen);
feed1( inbuf, outbuf, in_frames, out_frames, channels, func1, func2, func3, func4, flen, dur, my_max_delay, x);
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void flam1(t_bashfest *x, int slot, int *pcount)
{
// int channel_to_compute;
int attacks;
float gain2;
float gainatten;
float delay;
float gain = 1.0;
int i, j, k, delaysamps, delayoffset = 0;
// float inputmax;
int delay_frames;
/* main variables */
float *inbuf;
float *outbuf;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buflen = x->buf_samps;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int out_frames;
int halfbuffer = x->halfbuffer;
/* process specfic*/
++(*pcount);
attacks = params[(*pcount)++];
gain2 = params[(*pcount)++];
gainatten = params[(*pcount)++];
delay = params[(*pcount)++];
if( attacks <= 1 ){
error("flam1: too few attacks: %d",attacks);
return;
}
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
delay_frames = srate * delay + 0.5;
delaysamps = channels * delay_frames;
out_frames = in_frames + (srate * delay * (float) (attacks - 1));
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
for( i = 0; i < out_frames * channels; i++ ){
outbuf[i] = 0.0 ;
}
for(i = 0; i < attacks; i++ ){
if(in_frames + delay_frames * i >= out_frames){
// error("breaking at attack %d",i);
break;
}
for(j = 0; j < in_frames * channels; j += channels ){
for( k = 0; k < channels; k++ ){
outbuf[j + k + delayoffset] += *(inbuf +j + k) * gain;
}
}
delayoffset += delaysamps;
if( i == 0 ){
gain = gain2;
} else {
gain *= gainatten;
}
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void flam2(t_bashfest *x, int slot, int *pcount)
{
// int channel_to_compute;
int attacks;
float gain2;
float gainatten;
float delay1,delay2;
float gain = 1.0;
int i, j, k, delaysamps, delayoffset = 0;
int f_endpoint;
// float inputmax, outputmax, rescale;
int delay_frames;
float now = 0.0;
int findex;
float inval;
float curdelay;
/* main variables */
float *inbuf;
float *outbuf;
int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buflen = x->buf_samps;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int halfbuffer = x->halfbuffer;
float *flamfunc1 = x->flamfunc1;
int flamfunclen = x->flamfunc1len;
/* process specfic*/
++(*pcount);
attacks = params[(*pcount)++];
gain2 = params[(*pcount)++];
gainatten = params[(*pcount)++];
delay1 = params[(*pcount)++];
delay2 = params[(*pcount)++];
if( attacks <= 1 ){
error("flam2: recieved too few attacks: %d",attacks);
return;
}
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
for( i = 0; i < attacks - 1; i++ ){
findex = ((float)i/(float)attacks) * (float)flamfunclen ;
inval = flamfunc1[findex];
curdelay = mapp(inval, 0., 1., delay2, delay1);
now += curdelay;
}
out_frames = in_frames + (srate * now);
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
for( i = 0; i < out_frames * channels; i++ ){
outbuf[i] = 0.0 ;
}
f_endpoint = in_frames;
// first time delay_offset is zero
for( i = 0; i < attacks; i++ ){
findex = ((float)i/(float)attacks) * (float)flamfunclen ;
inval = flamfunc1[findex];
curdelay = mapp(inval, 0., 1., delay2, delay1);
delay_frames = srate * curdelay + 0.5;
delaysamps = delay_frames * channels;
if(f_endpoint >= out_frames){
// error("flam2: breaking at attack %d",i);
break;
}
for(j = 0; j < in_frames * channels; j += channels ){
for( k = 0; k < channels; k++ ){
outbuf[j + k + delayoffset] += *(inbuf + j + k) * gain;
}
}
delayoffset += delaysamps;
f_endpoint = in_frames + delayoffset/channels;
if( i == 0 ){
gain = gain2;
} else {
gain *= gainatten;
}
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void expflam(t_bashfest *x, int slot, int *pcount)
{
int attacks;
float gain2;
float gainatten;
float delay1,delay2;
float gain = 1.0;
int i, j, k, delaysamps, delayoffset = 0, f_endpoint;
// float inputmax, outputmax, rescale;
int delay_frames;
float now = 0.0;
// int findex;
// float inval;
float curdelay;
float slope;
/* main variables */
float *inbuf;
float *outbuf;
int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buflen = x->buf_samps;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int halfbuffer = x->halfbuffer;
float *expfunc = x->feedfunc1;
// int funclen = x->feedfunclen;
/* process specfic*/
++(*pcount);
attacks = params[(*pcount)++];
gain2 = params[(*pcount)++];
gainatten = params[(*pcount)++];
delay1 = params[(*pcount)++];
delay2 = params[(*pcount)++];
slope = params[(*pcount)++];
if( attacks <= 1 ){
error("expflam: recieved too few attacks: %d",attacks);
return;
}
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
setExpFlamFunc(expfunc, attacks, delay1, delay2, slope);
for( i = 0; i < attacks - 1; i++ ){
now += expfunc[i];
}
out_frames = in_frames + (srate * now);
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
for( i = 0; i < out_frames * channels; i++ ){
outbuf[i] = 0.0 ;
}
f_endpoint = in_frames;
for( i = 0; i < attacks; i++ ){
curdelay = expfunc[i];
delay_frames = srate * curdelay + 0.5;
delaysamps = delay_frames * channels;
if(f_endpoint >= out_frames){
// error("expflam: breaking at attack %d",i);
break;
}
for(j = 0; j < in_frames * channels; j += channels ){
for( k = 0; k < channels; k++ ){
outbuf[j + k + delayoffset] += *(inbuf + j + k) * gain;
}
}
delayoffset += delaysamps;
f_endpoint = in_frames + delayoffset/channels;
if( i == 0 ){
gain = gain2;
} else {
gain *= gainatten;
}
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void comb4(t_bashfest *x, int slot, int *pcount)
{
float overhang, revtime ;
int i, j, k;
int fadeFrames;
float fadegain;
int fadestart;
float input_sample;
float rez;
/* main variables */
int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
/* process specific */
CMIXCOMB *combies = x->combies;
float maxloop = x->max_comb_lpt;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
for( j = 0; j < 4; j++ ){
rez = params[(*pcount)++] ;
if( rez == 0.0){
error("comb4: 0 resonance frequency not allowed");
return;
}
if( 1./rez > maxloop ){
error("comb4: %f is too long loop",1./rez);
return;
}
combies[j].lpt = 1. / rez ;
}
revtime = params[(*pcount)++];
overhang = params[(*pcount)++];
if( overhang < COMBFADE )
overhang = COMBFADE;
out_frames = in_frames + overhang * srate;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
for( j = 0; j < 4; j++ ){
mycombset( combies[j].lpt, revtime, 0, combies[j].arr, srate);
}
inbuf = x->events[slot].workbuffer + in_start;
for( j = 0; j < channels; j++ ){
for( i = 0; i < in_frames * channels; i += channels ){
input_sample = *(inbuf + i + j) ; // we can move inside loop
*(outbuf + i + j ) = 0.0; // comment out to leave original sound into it
for( k = 0; k < 4; k++ ){
*(outbuf + i + j) += mycomb(input_sample, combies[k].arr);
}
}
}
for( i = in_frames * channels; i < out_frames * channels; i += channels ){
for( j = 0; j < channels; j++ ){
*(outbuf + i + j) = 0.0;
for( k = 0; k < 4; k++ ){
*(outbuf +i+j) += mycomb(0.0,combies[k].arr);
}
}
}
fadeFrames = COMBFADE * srate; // ok - this is just the fadeout
fadestart = (out_frames - fadeFrames) * channels ;
for( i = 0; i < fadeFrames * channels; i += channels ){
fadegain = 1.0 - (float) i / (float) (fadeFrames * channels) ;
*(outbuf + fadestart + i) *= fadegain;
if( channels == 2 ){
*(outbuf + fadestart + i + 1) *= fadegain;
}
}
killdc(outbuf, out_frames, channels, x);
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void compdist(t_bashfest *x, int slot, int *pcount)
{
float cutoff, maxmult;
int lookupflag;
int channel_to_compute;
float maxamp;
/* main variables */
// int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
// int buf_frames = x->buf_frames;
float *params = x->params;
// float srate = x->sr;
/* function specific*/
int range = x->tf_len;
float *table = x->transfer_function;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
cutoff = params[(*pcount)++];
maxmult = params[(*pcount)++];
lookupflag = params[(*pcount)++];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
maxamp = getmaxamp(inbuf, in_frames*channels) ;
if(lookupflag){
set_distortion_table(table, cutoff, maxmult, range);
}
for( channel_to_compute = 0; channel_to_compute < channels; channel_to_compute++) {
do_compdist(inbuf, outbuf, in_frames, channels, channel_to_compute,
cutoff, maxmult, lookupflag, table, range, maxamp);
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void ringfeed(t_bashfest *x, int slot, int *pcount)
{
float overhang;
int i, j;
int fade_frames;
float fadegain;
int fadestart;
float input_sample;
float rez ;
/* main variables */
int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
/*function specific*/
float *sinewave = x->sinewave;
int sinelen = x->sinelen ;
CMIXCOMB *combies = x->combies;
CMIXRESON *resies = x->resies;
CMIXOSC oscar = x->oscar;
float maxloop = x->max_comb_lpt;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
oscar.func = sinewave;
oscar.len = sinelen;
oscar.si = params[(*pcount)++] * ((float)oscar.len / srate);
oscar.phs = 0;
rez = params[(*pcount)++] ;
if( rez > 0 )
combies[0].lpt = 1. / rez ;
else error("zero comb resonance is bad luck");
if(combies[0].lpt > maxloop)
error("ringfeed does not appreciate looptimes as large as %f",combies[0].lpt);
combies[0].rvbt = params[(*pcount)++] ;
if(combies[0].rvbt >= 1.0) {
error("ringfeed dislikes feedback values >= 1");
combies[0].rvbt = .99 ;
}
resies[0].cf = params[(*pcount)++];
resies[0].bw = resies[0].cf * params[(*pcount)++];
overhang = params[(*pcount)++] ;
inbuf = x->events[slot].workbuffer + in_start;
for( i = 0; i < channels ; i++ ){
mycombset( combies[0].lpt, combies[0].rvbt, 0, combies[i].arr,srate);
rsnset2(resies[0].cf, resies[0].bw, RESON_NO_SCL, 0., resies[i].q, srate);
}
/* MINIMUM OVERHANG */
if( overhang < COMBFADE )
overhang = COMBFADE;
out_frames = in_frames + overhang * srate ;
if( out_frames > buf_frames / 2 ){
out_frames = buf_frames / 2 ;
}
/* INPUT LOOP */
for( i = 0; i < in_frames * channels; i += channels ){
for( j = 0; j < channels; j++ ){
input_sample = *(inbuf + i + j ) ;
input_sample *= oscil(1.0, oscar.si, oscar.func, oscar.len, &oscar.phs);
input_sample += mycomb(input_sample, combies[j].arr);
*(outbuf +i+j) = reson(input_sample, resies[j].q);
}
}
/* COMB TAILS */
for( i = in_frames * channels; i < out_frames * channels; i += channels ){
for( j = 0; j < channels; j++ ){
*(outbuf +i+j) = reson(mycomb( 0.0, combies[j].arr), resies[j].q );
}
}
/* FADE OUT ON MIX */
fade_frames = COMBFADE * srate;
fadestart = (out_frames - fade_frames) * channels ;
for( i = 0; i < fade_frames * channels; i += channels ){
fadegain = 1.0 - (float) i / (float) (fade_frames * channels) ;
*(outbuf + fadestart + i) *= fadegain;
if( channels == 2 ){
*(outbuf + fadestart + i + 1) *= fadegain;
}
}
x->events[slot].sample_frames = out_frames;
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void resonadsr(t_bashfest *x, int slot, int *pcount)
{
int i;
float bwfac;
float q1[5], q2[5];
float cf, bw;
float si;
float notedur;
float phase = 0.;
// int j = 0;
/* main variables */
// int out_frames;
// int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
// int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
/*function specific*/
CMIXADSR *a = x->adsr;
int funclen = a->len;
float *adsrfunc = a->func;
++(*pcount);
a->a = params[(*pcount)++];
a->d = params[(*pcount)++];
a->r = params[(*pcount)++];
a->v1 = params[(*pcount)++];
a->v2 = params[(*pcount)++];
a->v3 = params[(*pcount)++];
a->v4 = params[(*pcount)++];
bwfac = params[(*pcount)++];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
notedur = (float) in_frames / srate ;
a->s = notedur - (a->a+a->d+a->r);
if( a->s <= 0.0 ){
a->a=a->d=a->s=a->r= notedur/ 4. ;
}
buildadsr(a);
si = ((float) funclen / srate) / notedur ;
phase = 0;
rsnset2(adsrfunc[(int)phase], adsrfunc[(int) phase]*bwfac, 2.0, 0.0, q1, srate);
if( channels == 2 ){
rsnset2( adsrfunc[(int)phase], adsrfunc[(int) phase]*bwfac, 2.0, 0.0, q2, srate );
}
for(i = 0; i < in_frames*channels; i += channels ){
phase += si;
if( phase > funclen - 1)
phase = funclen - 1; /* stop at end of function */
cf = adsrfunc[ (int) phase ];
bw = bwfac * cf ;
rsnset2( cf, bw, 2.0, 1.0, q1, srate );
outbuf[i] = reson(inbuf[i], q1);
if( channels == 2 ){
rsnset2( cf, bw, 2.0, 1.0, q2, srate );
outbuf[i+1] = reson(inbuf[i+1], q2);
}
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
}
void stv(t_bashfest *x, int slot, int *pcount)
{
int i,j;
/* main variables */
// int out_frames;
int frames = x->events[slot].sample_frames;
int channels = x->events[slot].out_channels;
// int buf_frames = x->buf_frames;
float *params = x->params;
float srate = x->sr;
/*function specific*/
float *sinewave = x->sinewave;
int sinelen = x->sinelen ;
float *delayline1 = x->delayline1;
float *delayline2 = x->delayline2;
float max_delay = x->maxdelay ;
CMIXOSC osc1, osc2; // put into main object structure
float mindel, maxdel;
float fac1, fac2;
int dv1[2], dv2[2]; /* cmix bookkeeping */
float delay_time;
float speed1, speed2, depth ;
// float max;
float *inbuf, *outbuf;
int in_start = x->events[slot].in_start;
int out_start = x->events[slot].out_start;
// int in_frames = x->events[slot].sample_frames;
int buflen = x->buf_samps;
int halfbuffer = x->halfbuffer;
++(*pcount);
speed1 = params[(*pcount)++];
speed2 = params[(*pcount)++];
depth = params[(*pcount)++];
out_start = (in_start + halfbuffer) % buflen ;
inbuf = x->events[slot].workbuffer + in_start;
outbuf = x->events[slot].workbuffer + out_start;
mindel = .001;
maxdel = depth;
if( maxdel > max_delay ){
maxdel = max_delay;
}
delset2(delayline1, dv1, max_delay,srate);
delset2(delayline2, dv2, max_delay,srate);
fac2 = .5 * (maxdel - mindel) ;
fac1 = mindel + fac2;
osc1.func = sinewave;
osc1.len = sinelen;
osc1.si = ((float) sinelen / srate ) * speed1 ;
osc1.phs = 0;
osc1.amp = fac2;
osc2.func = sinewave;
osc2.len = sinelen;
osc2.si = ((float) sinelen / srate ) * speed2 ;
osc2.phs = 0;
osc2.amp = fac2;
if( channels == 1 ){
for(i = 0, j = 0; i < frames; i++, j+=2 ){
delay_time = fac1 +
oscil(osc1.amp, osc1.si, osc1.func, osc1.len, &osc1.phs);
delput2( inbuf[i], delayline1, dv1);
outbuf[j] = dliget2(delayline1, delay_time, dv1,srate);
delay_time = fac1 +
oscil(osc2.amp, osc2.si, osc2.func, osc2.len, &osc2.phs);
delput2( inbuf[i], delayline2, dv2);
outbuf[j + 1] = dliget2(delayline2, delay_time, dv2,srate);
}
}
else if( channels == 2 ){
for(i = 0; i < frames*2; i += 2 ){
delay_time = fac1 +
oscil(osc1.amp, osc1.si, osc1.func, osc1.len, &osc1.phs);
delput2( inbuf[i], delayline1, dv1);
outbuf[i] = dliget2(delayline1, delay_time, dv1,srate);
delay_time = fac1 +
oscil(osc2.amp, osc2.si, osc2.func, osc2.len, &osc2.phs);
delput2( inbuf[i + 1], delayline2, dv2);
outbuf[i + 1] = dliget2(delayline2, delay_time, dv2,srate);
}
}
x->events[slot].out_start = in_start;
x->events[slot].in_start = (x->events[slot].out_start + halfbuffer) % buflen ;
x->events[slot].out_channels = 2; // we are now stereo, regardless of what we were before
}
#include "bashfest.h"
#include "stdlib.h"
void putsine (float *arr, int len);
float boundrand(float min, float max);
void putsine (float *arr, int len)
{
int i;
double twopi;
twopi = 8.0 * atan2(1.,1.);
for ( i = 0; i < len ; i++) {
*(arr + i) = sin( twopi * i / len);
}
}
float boundrand(float min, float max)
{
return min + (max-min) * ((float)rand()/MY_MAX);
}
void mycombset(float loopt,float rvt,int init,float *a,float srate)
{
int j;
a[0] = (3.0 + (loopt * srate + .5));
a[1] = rvt;
if(!init) {
for(j=3; j<(int)*a; j++)
a[j] = 0;
a[2] = 3;
}
}
float mycomb(float samp,float *a)
{
float temp,*aptr;
if ( a[2] >= (int) a[0])
a[2] = 3;
aptr = a + (int)a[2];
a[2]++;
temp = *aptr;
*aptr = *aptr * a[1] + samp;
return(temp);
}
void setweights(float *a, int len)
{
float sum = 0.0;
int i;
for(i=0;i<len;i++)
sum += a[i];
if(sum == 0.0){
error("zero odds sum");
}
for(i=0;i<len;i++)
a[i] /= sum;
for(i=1;i<len;i++)
a[i] += a[i-1];
}
void delset2(float *a,int *l,float xmax, float srate)
{
/* delay initialization. a is address of float array, l is size-2 int
* array for bookkeeping variables, xmax, is maximum expected delay */
int i;
*l = 0;
*(l+1) = (int)(xmax * srate + .5);
for(i = 0; i < *(l+1); i++) *(a+i) = 0;
}
void delput2(float x,float *a,int *l)
{
/* put value in delay line. See delset. x is float */
*(a + (*l)++) = x;
if(*(l) >= *(l+1)) *l -= *(l+1);
}
float dliget2(float *a,float wait,int *l,float srate)
{
/* get interpolated value from delay line, wait seconds old */
register int im1;
float x = wait * srate;
register int i = x;
float frac = x - i;
i = *l - i;
im1 = i - 1;
if(i <= 0) {
if(i < 0) i += *(l+1);
if(i < 0) return(0.);
if(im1 < 0) im1 += *(l+1);
}
return(*(a+i) + frac * (*(a+im1) - *(a+i)));
}
void butterLopass( float *in, float *out, float cutoff, int frames, int channels, float srate)
{
int channel_to_compute;
float data[8];
for( channel_to_compute = 0; channel_to_compute < channels; channel_to_compute++) {
butset( data );
lobut(data, cutoff, srate);
butter_filter( in, out, data, frames, channels, channel_to_compute);
}
}
void butterBandpass(float *in, float *out, float center, float bandwidth, int frames,int channels, float srate)
{
int channel_to_compute;
float data[8];
for( channel_to_compute = 0; channel_to_compute < channels; channel_to_compute++) {
butset( data );
bpbut(data, center, bandwidth, srate);
butter_filter( in, out, data, frames, channels, channel_to_compute);
}
}
void butterHipass(float *in, float *out, float cutoff, int frames,int channels, float srate)
{
int channel_to_compute;
float data[8];
for( channel_to_compute = 0; channel_to_compute < channels; channel_to_compute++) {
butset( data );
hibut(data, cutoff, srate);
butter_filter( in, out, data, frames, channels, channel_to_compute);
}
}
void butset(float *a)
{
a[6] = a[7] = 0.0;
}
void lobut(float *a, float cutoff,float SR)
{
register float c;
c = 1.0 / tan( PI * cutoff / SR);
a[1] = 1.0 / ( 1.0 + ROOT2 * c + c * c);
a[2] = a[1] + a[1];
a[3] = a[1];
a[4] = 2.0 * ( 1.0 - c*c) * a[1];
a[5] = ( 1.0 - ROOT2 * c + c * c) * a[1];
}
void hibut(float *a, float cutoff, float SR)
{
register float c;
c = tan( PI * cutoff / SR);
a[1] = 1.0 / ( 1.0 + ROOT2 * c + c * c);
a[2] = -2.0 * a[1];
a[3] = a[1];
a[4] = 2.0 * ( c*c - 1.0) * a[1];
a[5] = ( 1.0 - ROOT2 * c + c * c) * a[1];
}
void bpbut(float *a, float formant, float bandwidth,float SR)
{
register float c, d;
c = 1.0 / tan( PI * bandwidth / SR);
d = 2.0 * cos( 2.0 * PI * formant / SR);
a[1] = 1.0 / ( 1.0 + c);
a[2] = 0.0;
a[3] = -a[1];
a[4] = - c * d * a[1];
a[5] = ( c - 1.0) * a[1];
}
/* in array can == out array */
void butter_filter(float *in,float *out,float *a, int frames, int channels, int channel)
{
int i;
float t ,y ;
for( i = channel ; i < frames * channels; i+= channels )
{
t = *(in + i) - a[4] * a[6] - a[5] * a[7];
y = t * a[1] + a[2] * a[6] + a[3] * a[7];
a[7] = a[6];
a[6] = t;
*(out + i) = y;
}
}
void rsnset2(float cf,float bw,float scl,float xinit,float *a,float srate)
{
// double exp(),cos(),sqrt();
float c,temp;
if(!xinit) {
a[4] = 0;
a[3] = 0;
}
a[2] = exp(-PI2 * bw/srate);
temp = 1. - a[2];
c = a[2] + 1;
a[1] = 4. * a[2]/c * cos(PI2 * cf/srate);
if(scl < 0) a[0] = 1;
if(scl) a[0] = sqrt(temp/c*(c*c-a[1]*a[1]));
if(!scl) a[0] = temp*sqrt(1.-a[1]*a[1]/(4.*a[2]));
}
float reson(float x,float *a)
{
float temp;
temp = *a * x + *(a+1) * *(a+3) - *(a+2) * *(a+4);
*(a+4) = *(a+3);
*(a+3) = temp;
return(temp);
}
float allpass(float samp,float *a)
{
float temp,*aptr;
if ( a[STARTM1] >= (int) a[0]) a[STARTM1] = START;
aptr = a + (int)a[STARTM1];
a[STARTM1] ++;
temp = *aptr;
*aptr = *aptr * a[1] + samp;
return(temp - a[1] * *aptr);
}
void init_reverb_data(float *a)
{
a[0] = 2;
a[1] = -0.61043329;
a[2] = -1.4582246;
a[3] = 1;
a[4] = 0.75887003;
a[5] = 1;
a[6] = -0.6922953;
a[7] = 0;
a[8] = 0;
a[9] = 0.035888535;
}
void reverb1me(float *in, float *out, int inFrames, int out_frames, int nchans,
int channel, float revtime, float dry, t_bashfest *x)
{
float dels[4];// stick into main structure
float **alpo = x->mini_delay ;
float a1,a2,a3,a4;
int i;
// int alsmp ;
float *fltdata = x->reverb_ellipse_data;
int nsects;
float xnorm;
LSTRUCT *eel = x->eel;
float wet;
// float max;
float srate = x->sr;
// float max_del = x->max_mini_delay ;
wet = cos(1.570796 * dry);
dry = sin(1.570796 * dry);
/* combset uses reverb time , mycombset uses feedback */
for( i = 0; i < 4; i++ ){
dels[i] = boundrand(.005, .1 );
if(dels[i] < .005 || dels[i] > 0.1) {
post("reverb1: bad random delay time: %f",dels[i]);
dels[i] = .05;
}
mycombset(dels[i], revtime, 0, alpo[i], srate);
}
ellipset(fltdata,eel,&nsects,&xnorm);
for( i = channel ; i < inFrames * nchans; i += nchans ){
a1 = allpass(in[i], alpo[0]);
a2 = allpass(in[i], alpo[1]);
a3 = allpass(in[i], alpo[2]);
a4 = allpass(in[i], alpo[3]);
out[i] = in[i] * dry + ellipse((a1+a2+a3+a4), eel, nsects,xnorm) * wet;
}
for( i = channel + inFrames * nchans; i < out_frames * nchans; i += nchans ){
a1 = allpass(0.0, alpo[0]);
a2 = allpass(0.0, alpo[1]);
a3 = allpass(0.0, alpo[2]);
a4 = allpass(0.0, alpo[3]);
out[i] = ellipse((a1+a2+a3+a4), eel, nsects,xnorm) * wet;
}
}
void feed1(float *inbuf, float *outbuf, int in_frames, int out_frames,int channels, float *functab1,
float *functab2,float *functab3,float *functab4,int funclen,
float duration, float maxDelay, t_bashfest *x)
{
int i;
float srate = x->sr;
float *delayLine1a = x->mini_delay[0];
float *delayLine2a = x->mini_delay[1];
float *delayLine1b = x->mini_delay[2];
float *delayLine2b = x->mini_delay[3];
int dv1a[2], dv2a[2]; /* cmix bookkeeping */
int dv1b[2], dv2b[2]; /* cmix bookkeeping */
float delsamp1a=0, delsamp2a=0 ;
float delsamp1b=0, delsamp2b=0 ;
float delay1, delay2, feedback1, feedback2;
float funcSi, funcPhs;
float putsamp;
/***************************/
funcPhs = 0.;
// read once during note
funcSi = ((float) funclen / srate) / duration ;
delset2(delayLine1a, dv1a, maxDelay,srate);
delset2(delayLine2a, dv2a, maxDelay,srate);
if( channels == 2 ){
delset2(delayLine1b, dv1b, maxDelay,srate);
delset2(delayLine2b, dv2b, maxDelay,srate);
}
for(i = 0; i < out_frames*channels; i += channels ){
// buffer loop
delay1 = functab1[ (int) funcPhs ];
delay2 = functab2[ (int) funcPhs ];
feedback1 = functab3[ (int) funcPhs ];
feedback2 = functab4[ (int) funcPhs ];
funcPhs += funcSi;
if( funcPhs >= (float) funclen )
funcPhs = 0;
putsamp = i < in_frames * channels ? inbuf[i] + delsamp1a*feedback1 : 0.0;
outbuf[i] = putsamp; // zero instead ??
delput2( putsamp, delayLine1a, dv1a);
delsamp1a = dliget2(delayLine1a, delay1, dv1a,srate);
putsamp = delsamp1a+delsamp2a*feedback2 ;
delput2( putsamp, delayLine2a, dv2a);
delsamp2a = dliget2(delayLine2a, delay2, dv2a, srate);
outbuf[i] += delsamp2a;
if( channels == 2 ){
putsamp = i < in_frames * channels ? inbuf[i+1] + delsamp1a*feedback1 : 0.0;
outbuf[i+1] = putsamp;
delput2( putsamp, delayLine1b, dv1b);
delsamp1b = dliget2(delayLine1b, delay1, dv1b, srate);
putsamp = delsamp1b+delsamp2b*feedback2;
delput2( putsamp, delayLine2b, dv2b);
delsamp2b = dliget2(delayLine2b, delay2, dv2b, srate);
outbuf[i+1] += delsamp2b;
}
}
}
void setflamfunc1(float *arr, int flen)
{
int i;
float x;
for ( i = 0; i < flen; i++){
x = (float)i / (float) flen ;
*(arr + i) = ((x - 1) / (x + 1)) * -1. ;
}
}
void setExpFlamFunc(float *arr, int flen, float v1,float v2,float alpha)
{
int i;
if( alpha == 0 )
alpha = .00000001 ;
for ( i = 0; i < flen; i++){
*(arr + i) = v1 + (v2-v1) * ((1-exp((float)i*alpha/((float)flen-1.)))/(1-exp(alpha)));
}
}
void funcgen1(float *outArray, int outlen, float duration, float outMin, float outMax,
float speed1, float speed2, float gain1, float gain2, float *phs1, float *phs2,
float *sine, int sinelen)
{
float si1, si2;
float localSR;
int i;
localSR = duration * (float) outlen ;
*phs1 *= (float) sinelen;
*phs2 *= (float) sinelen;
si1 = ((float)sinelen/localSR) * speed1;
si2 = ((float)sinelen/localSR) * speed2;
for( i = 0; i < outlen; i++ ){
*(outArray + i) = oscil(gain1, si1, sine, sinelen, phs1) ;
*(outArray + i) += oscil(gain2, si2, sine, sinelen, phs2) ;
}
normtab( outArray, outArray, outMin, outMax, outlen);
}
void normtab(float *inarr,float *outarr, float min, float max, int len)
{
int i;
float imin=9999999999., imax=-9999999999.;
for(i = 0; i < len ; i++){
if( imin > inarr[i] )
imin = inarr[i];
if( imax < inarr[i] )
imax = inarr[i];
}
for(i = 0; i < len; i++ )
outarr[i] = mapp(inarr[i], imin, imax, min, max);
}
float mapp(float in,float imin,float imax,float omin,float omax)
{
if( imax == 0.0 )
{
return 0.0 ;
}
return( omin+((omax-omin)*((in-imin)/(imax-imin))) );
}
float oscil(float amp,float si,float *farray,int len,float *phs)
{
register int i = *phs;
*phs += si;
while(*phs >= len)
*phs -= len;
return(*(farray+i) * amp);
}
void killdc( float *inbuf, int in_frames, int channels, t_bashfest *x)
{
int i,j=1;
LSTRUCT *eel = x->eel;
int nsects;
float xnorm;
float *dcflt = x->dcflt;
/* float dcflt[64] =
{3, -1.9999924 , -1.9992482 , 1.0000000
, .99928019 ,
-1.9999956 , -1.9964080 , 1.0000000 , .99645999 ,
-1.9999994 , -1.9805074 , 1.0000000 , .98069401 ,
.98817413E+00};*/
for( j = 0; j < channels; j++) {
ellipset(dcflt,eel,&nsects,&xnorm);
for( i = j; i < in_frames * channels ; i += channels ){
inbuf[i] = ellipse(inbuf[i], eel, nsects,xnorm);
}
}
}
void set_dcflt(float *a)
{
a[0] = 3;
a[1] = -1.9999924;
a[2] = -1.9992482;
a[3] = 1;
a[4] = 0.99928019;
a[5] = -1.9999956;
a[6] = -1.996408;
a[7] = 1;
a[8] = 0.99645999;
a[9] = -1.9999994;
a[10] = -1.9805074;
a[11] = 1;
a[12] = 0.98069401;
a[13] = 0.98817413;
}
void set_distortion_table(float *arr, float cut, float max, int len)
{
int i, len2;
float samp;
len2 = len>>1 ;
for( i = len2; i < len; i++ ){
samp = (float)(i - len2) / (float) len2 ;
if( samp > cut )
samp = mapp( samp, cut, 1.0, cut, max );
*(arr + i) = samp;
}
for( i = 0; i < len2; i++ )
*(arr + i) = - *(arr + len - (i+1));
}
float dlookup(float samp,float *arr,int len)
{
return arr[(int) (((samp+1.0)/2.0) * (float) len)];
}
void do_compdist(float *in,float *out,int sampFrames,int nchans,int channel,
float cutoff,float maxmult,int lookupflag,float *table,int range,float bufMaxamp)
{
int i;
float rectsamp;
for( i = channel ; i < sampFrames * nchans; i+= nchans )
{
if( lookupflag){
*(out + i) = dlookup( *(in + i)/bufMaxamp, table, range );
} else {
rectsamp = fabs( *(in + i) ) / bufMaxamp;
if( rectsamp > cutoff ){
*(in + i) = *(out + i) *
mapp( rectsamp, cutoff, 1.0, cutoff, maxmult);
}
}
}
}
float getmaxamp(float *arr, int len)
{
int i;
float max = 0;
for(i = 0; i < len; i++ ){
if( fabs(arr[i]) > max )
max = fabs(arr[i]);
}
return max;
}
void buildadsr(CMIXADSR *a)
{
float A = a->a;
float D = a->d;
float S = a->s;
float R = a->r;
float f1 = a->v1;
float f2 = a->v2;
float f3 = a->v3;
float f4 = a->v4;
int funclen = a->len;
float *func = a->func;
float total;
int ipoint = 0;
int i;
int segs[4];
float m1,m2;
total = A + D + S + R ;
segs[0] = (A/total) * funclen;
segs[1] = (D/total) * funclen;
segs[2] = (S/total) * funclen;
segs[3] = funclen - (segs[0]+segs[1]+segs[2]);
if( f1 > 20000. || f1 < -20000. ){
f1 = 250.0;
}
if( f2 > 20000. || f2 < -20000. ){
f2 = 1250.0;
}
if( f3 > 20000. || f3 < -20000. ){
f3 = 950.0;
}
if( f4 > 20000. || f4 < -20000. ){
f4 = f1;
}
if( segs[0] <= 0 || segs[1] <= 0 || segs[2] <= 0 || segs[3] <= 0 ){
for( i = 0; i < 4; i++ ){
segs[i] = funclen / 4;
}
}
for( i = 0 ; i < segs[0]; i++ ){
m1 = 1.-(float)i/(float)(segs[0]);
m2 = 1. - m1;
*(func +i ) = f1 * m1 + f2 * m2;
}
ipoint = i;
for( i = 0 ; i < segs[1]; i++ ){
m1 = 1.-(float)i/(float)(segs[1]);
m2 = 1. - m1;
*(func + i + ipoint) = f2 * m1 + f3 * m2;
}
ipoint += i;
for( i = 0 ; i < segs[2]; i++ ){
m1 = 1.-(float)i/(float)(segs[2]);
m2 = 1. - m1;
*(func + i + ipoint) = f3;
}
ipoint += i;
for( i = 0 ; i < segs[3]; i++ ){
m1 = 1.-(float)i/(float)(segs[3]);
m2 = 1. - m1;
*(func + ipoint + i) = f3 * m1 + f4 * m2;
}
ipoint += i;
}
#N canvas 405 213 512 342 10;
#N canvas 0 22 450 300 (subpatch) 0;
#X array bashdrum 16884 float 2;
#X coords 0 1 16884 -1 60 20 1;
#X restore 291 75 graph;
#X obj 146 297 dac~;
#N canvas 696 403 518 368 load-samples 0;
#X obj 41 107 soundfiler;
#X msg 41 39 bang;
#X obj 41 65 openpanel;
#X obj 158 26 loadbang;
#X msg 41 87 read -resize \$1 bashdrum;
#X obj 156 132 loadbang;
#X msg 157 52 read -resize sound/kick_11d.aiff bashdrum;
#X msg 111 161 read -resize sound/hi_c_12b.aiff hihat;
#X msg 148 203 read -resize sound/KR55SNAR.aiff snare;
#X connect 1 0 2 0;
#X connect 2 0 4 0;
#X connect 3 0 6 0;
#X connect 4 0 0 0;
#X connect 5 0 7 0;
#X connect 5 0 8 0;
#X connect 6 0 0 0;
#X connect 7 0 0 0;
#X connect 8 0 0 0;
#X restore 291 110 pd load-samples;
#X floatatom 429 211 5 0 0 0 - - -, f 5;
#X msg 429 183 0.5;
#X obj 429 156 loadbang;
#X obj 146 113 samm~ 120 4;
#N canvas 525 461 474 324 hatter 0;
#X obj 74 99 player~ hihat 1;
#X obj 174 70 sig~ 1;
#X obj 74 47 mask~ 1 0.7 0.7 0.7 1 0 0.5 0.6 1 0.7 1 0 1 0.7 0 0;
#X obj 74 19 inlet~;
#X obj 74 222 vdp~ 500;
#X msg 311 123 44100;
#X msg 266 122 16384;
#X obj 278 148 /;
#X obj 266 97 t b b;
#X floatatom 99 196 10 0 0 0 - - -, f 10;
#X obj 293 73 loadbang;
#X obj 266 75 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X obj 74 275 outlet~;
#X text 137 223 compensate for bashfest latency;
#X obj 279 179 * 1000;
#X floatatom 135 253 5 0 0 0 - - -, f 5;
#X obj 74 248 *~ 0.15;
#X connect 0 0 4 0;
#X connect 1 0 0 1;
#X connect 2 0 0 0;
#X connect 3 0 2 0;
#X connect 4 0 16 0;
#X connect 5 0 7 1;
#X connect 6 0 7 0;
#X connect 7 0 14 0;
#X connect 8 0 6 0;
#X connect 8 1 5 0;
#X connect 9 0 4 1;
#X connect 10 0 8 0;
#X connect 11 0 8 0;
#X connect 14 0 9 0;
#X connect 15 0 16 1;
#X connect 16 0 12 0;
#X restore 82 201 pd hatter;
#N canvas 0 22 450 300 (subpatch) 0;
#X array hihat 9097 float 2;
#X coords 0 1 9097 -1 60 20 1;
#X restore 356 75 graph;
#N canvas 0 22 462 312 metronome-control 0;
#X floatatom 52 88 5 0 0 0 - - -, f 5;
#X msg 51 112 tempo \$1;
#X msg 127 59 120;
#X msg 51 55 60;
#X msg 138 114 pause;
#X msg 190 114 resume;
#X obj 81 150 outlet;
#X msg 92 56 140;
#X connect 0 0 1 0;
#X connect 1 0 6 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 6 0;
#X connect 5 0 6 0;
#X connect 7 0 0 0;
#X restore 146 73 pd metronome-control;
#N canvas 441 424 622 472 processor-control 0;
#X obj 169 182 outlet;
#N canvas 301 93 925 625 set-processor-odds 0;
#X obj 87 552 outlet;
#X msg 392 170 setodds 0 0 0 0 0 1;
#X text 543 169 sweepreson;
#X msg 391 316 setodds 0 0 0 0 0 0 0 0 0 0 0 1;
#X msg 388 481 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X msg 391 447 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X msg 388 509 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X text 708 509 resonadsr;
#X msg 387 535 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X text 468 51 transpose;
#X msg 393 54 setodds 1;
#X text 485 75 ringmod;
#X msg 394 76 setodds 0 1;
#X text 518 145 truncate;
#X msg 393 145 setodds 0 0 0 0 1;
#X msg 393 239 setodds 0 0 0 0 0 0 0 0 1;
#X msg 86 160 flatodds;
#X text 362 8 Processors by position in list. Any list combination
will select a set of processors in specified weighting for random selection.
;
#X text 493 99 flange;
#X msg 392 100 setodds 0 0 1;
#X text 514 121 butterworth filters;
#X msg 394 120 setodds 0 0 0 1;
#X msg 394 192 setodds 0 0 0 0 0 0 1;
#X text 545 191 comb;
#X text 565 214 slidecomb;
#X msg 393 215 setodds 0 0 0 0 0 0 0 1;
#X text 586 239 reverb;
#X msg 392 265 setodds 0 0 0 0 0 0 0 0 0 1;
#X text 590 268 elliptical filters;
#X msg 392 291 setodds 0 0 0 0 0 0 0 0 0 0 1;
#X text 608 293 distortion/compression;
#X text 615 313 feedback;
#X msg 390 343 setodds 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X text 624 342 reverse;
#X msg 390 367 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X text 649 366 flam1;
#X msg 390 391 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X text 664 391 flam2;
#X msg 390 417 setodds 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1;
#X text 671 419 expflam;
#X text 688 442 comb4;
#X text 700 479 ringmod/feedback;
#X text 722 535 stereo vdelay;
#X msg -21 73 setodds 0.25 0.5 1 0 0 1 0.2 0 0 1 1 0.1 0.1 0 0 0.3
;
#X msg -12 96 setodds 1 1 1 1 1 1 1 1 0 1 1 0 1 0.2 0.2 0.2 1 1 1 1
;
#X text 2 53 a couple distributions;
#X text 85 141 equal distribution;
#X connect 1 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 0 0;
#X connect 8 0 0 0;
#X connect 10 0 0 0;
#X connect 12 0 0 0;
#X connect 14 0 0 0;
#X connect 15 0 0 0;
#X connect 16 0 0 0;
#X connect 19 0 0 0;
#X connect 21 0 0 0;
#X connect 22 0 0 0;
#X connect 25 0 0 0;
#X connect 27 0 0 0;
#X connect 29 0 0 0;
#X connect 32 0 0 0;
#X connect 34 0 0 0;
#X connect 36 0 0 0;
#X connect 38 0 0 0;
#X connect 43 0 0 0;
#X connect 44 0 0 0;
#X restore 170 80 pd set-processor-odds;
#N canvas 0 22 466 316 efficiency 0;
#X msg 53 138 mute \$1;
#X obj 53 98 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
;
#X msg 168 119 block_dsp \$1;
#X obj 169 89 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 139 182 outlet;
#X text 211 93 turn off dsp;
#X text 54 81 mute object;
#X connect 0 0 4 0;
#X connect 1 0 0 0;
#X connect 2 0 4 0;
#X connect 3 0 2 0;
#X restore 284 155 pd efficiency;
#N canvas 415 474 641 390 process-amount 0;
#X obj 78 207 outlet;
#N canvas 680 241 454 304 setodds 0;
#X msg 124 131 minimum_process \$1;
#X obj 158 91 unpack f f;
#X msg 294 131 maximum_process \$1;
#X obj 125 163 outlet;
#X obj 159 58 inlet;
#X connect 0 0 3 0;
#X connect 1 0 0 0;
#X connect 1 1 2 0;
#X connect 2 0 3 0;
#X connect 4 0 1 0;
#X restore 79 165 pd setodds;
#X msg 79 130 0 1;
#X msg 36 130 0 0;
#X msg 120 131 1 1;
#X msg 156 131 1 2;
#X text 162 164 set minimum and maximum processing iterations.;
#X text 164 185 More processing means cooler sounds \, but could;
#X msg 194 131 2 4;
#X text 163 205 also overtax your CPU.;
#X obj 120 94 loadbang;
#X msg 234 133 4 8;
#X connect 1 0 0 0;
#X connect 2 0 1 0;
#X connect 3 0 1 0;
#X connect 4 0 1 0;
#X connect 5 0 1 0;
#X connect 8 0 1 0;
#X connect 10 0 4 0;
#X connect 11 0 1 0;
#X restore 207 116 pd process-amount;
#X msg 75 135 grab;
#X text 17 103 grab new sound from current processing;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X restore 6 74 pd processor-control;
#N canvas 0 22 450 300 (subpatch) 0;
#X array snare 9284 float 2;
#X coords 0 1 9284 -1 60 20 1;
#X restore 420 75 graph;
#X obj 146 178 bashfest~ snare 2000 16384 12;
#X obj 146 139 mask~ 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1;
#N canvas 46 411 513 413 bassdrum 0;
#X obj 156 100 sig~ 1;
#X obj 35 7 inlet~;
#X obj 35 270 vdp~ 500;
#X msg 272 178 44100;
#X msg 227 177 16384;
#X obj 239 203 /;
#X obj 227 152 t b b;
#X floatatom 61 243 10 0 0 0 - - -, f 10;
#X obj 254 128 loadbang;
#X obj 227 130 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X obj 35 353 outlet~;
#X text 98 271 compensate for bashfest latency;
#X floatatom 73 308 5 0 0 0 - - -, f 5;
#X obj 239 226 * 1000;
#X obj 35 147 player~ bashdrum 1;
#X obj 35 36 mask~ 1 0 1 1 1 0 0 0 1 0 0 0 1 0 1 0;
#X obj 35 327 *~ 0.4;
#X obj 77 292 hsl 90 8 0 0.5 0 0 empty empty empty -2 -8 0 10 -261820
-1 -1 0 1;
#X connect 0 0 14 1;
#X connect 1 0 15 0;
#X connect 2 0 16 0;
#X connect 3 0 5 1;
#X connect 4 0 5 0;
#X connect 5 0 13 0;
#X connect 6 0 4 0;
#X connect 6 1 3 0;
#X connect 7 0 2 1;
#X connect 8 0 6 0;
#X connect 9 0 6 0;
#X connect 12 0 16 1;
#X connect 13 0 7 0;
#X connect 14 0 2 0;
#X connect 15 0 14 0;
#X connect 16 0 10 0;
#X connect 17 0 12 0;
#X restore 7 202 pd bassdrum;
#X obj 146 223 *~ 0.4;
#X obj 200 224 *~ 0.4;
#N canvas 0 22 458 308 stereo-mix 0;
#X obj 91 54 inlet~;
#X obj 186 60 inlet~;
#X obj 91 166 outlet~;
#X obj 186 160 outlet~;
#X obj 91 107 *~ 0.2;
#X obj 186 109 *~ 0.2;
#X obj 301 47 inlet;
#X floatatom 301 73 5 0 0 0 - - -, f 5;
#X connect 0 0 4 0;
#X connect 1 0 5 0;
#X connect 4 0 2 0;
#X connect 5 0 3 0;
#X connect 6 0 7 0;
#X connect 7 0 5 1;
#X connect 7 0 4 1;
#X restore 146 266 pd stereo-mix;
#X obj 266 247 hsl 100 12 0 1 0 0 empty empty gain -2 -8 0 10 -261820
-1 -1 0 1;
#X text 3 41 bashfest~ is a click triggered soundfile player with random
DSP., f 65;
#X text 153 159 args: array \, maxdur \, latency \, voices;
#X obj 3 5 cnv 15 155 25 empty empty LyonPotpourri 20 12 1 18 -260097
-204786 0;
#X connect 3 0 15 1;
#X connect 3 0 16 1;
#X connect 4 0 3 0;
#X connect 5 0 4 0;
#X connect 6 0 13 0;
#X connect 6 0 7 0;
#X connect 6 0 14 0;
#X connect 7 0 17 1;
#X connect 7 0 17 0;
#X connect 9 0 6 0;
#X connect 10 0 12 0;
#X connect 12 0 15 0;
#X connect 12 1 16 0;
#X connect 13 0 12 0;
#X connect 14 0 17 1;
#X connect 14 0 17 0;
#X connect 15 0 17 0;
#X connect 16 0 17 1;
#X connect 17 0 1 0;
#X connect 17 1 1 1;
#X connect 18 0 17 2;
#import "MSPd.h"
#include "bashfest.h"
#include <string.h>
/* THIS IS PROBABLY THE LIMITING FACTOR FOR LARGE BUFFER SIZES
SO, MAKE THIS A PARAMETER, -OR- BUFFER THE INPUT TRIGGER ITSELF!!!
*/
#define DEFAULT_MAX_OVERLAP (8) // number of overlapping instances allowed
#define ACTIVE 0
#define INACTIVE 1
#define MAX_VEC 2048
#define DEFAULT_BUFFER_SIZE 4000.0 // 4 second default buffer size * 2
#define DEFAULT_LATENCY 8192 //latency in samples after a trigger for note to start
#define MAX_PARAMETERS 2048
#define PROCESS_COUNT 20
#define CYCLE_MAX 1024
#define OBJECT_NAME "bashfest~"
static t_class *bashfest_class;
void *bashfest_new(t_symbol *msg, short argc, t_atom *argv);
t_int *bashfest_perform_hosed(t_int *w);
void bashfest_dsp(t_bashfest *x, t_signal **sp);
void bashfest_dsp_free(t_bashfest *x);
int bashfest_set_parameters(t_bashfest *x,float *params);
t_int *bashfest_perform(t_int *w);
void bashfest_deploy_dsp(t_bashfest *x);
void bashfest_copy_to_MSP_buffer(t_bashfest *x, int slot);
/*user messages*/
void bashfest_stop(t_bashfest *x);
void bashfest_info(t_bashfest *x);
void bashfest_mute(t_bashfest *x, t_floatarg t);
void bashfest_maximum_process(t_bashfest *x, t_floatarg n);
void bashfest_minimum_process(t_bashfest *x, t_floatarg n);
void bashfest_setbuf(t_bashfest *x, t_symbol *wavename);
void bashfest_flatodds(t_bashfest *x);
void bashfest_killproc(t_bashfest *x, long p);
void bashfest_soloproc(t_bashfest *x, long p);
void bashfest_latency(t_bashfest *x, long n);
void bashfest_verbose(t_bashfest *x, long t);
void bashfest_block_dsp(t_bashfest *x, t_floatarg t);
void bashfest_gozero(t_bashfest *x);
void bashfest_grab(t_bashfest *x);
void bashfest_setodds(t_bashfest *x,t_symbol *msg, short argc, t_atom *argv);
void bashfest_tcycle(t_bashfest *x,t_symbol *msg, short argc, t_atom *argv);
/* function code */
void killdc( float *inbuf, int in_frames, int channels, t_bashfest *x);
void ringmod(t_bashfest *x, int slot, int *pcount);
void retrograde(t_bashfest *x, int slot, int *pcount);
void comber(t_bashfest *x, int slot, int *pcount);
void transpose(t_bashfest *x, int slot, int *pcount);
void flange(t_bashfest *x, int slot, int *pcount);
void butterme(t_bashfest *x, int slot, int *pcount);
void truncateme(t_bashfest *x, int slot, int *pcount);
void sweepreson(t_bashfest *x, int slot, int *pcount);
void slidecomb(t_bashfest *x, int slot, int *pcount);
void reverb1(t_bashfest *x, int slot, int *pcount);
void ellipseme(t_bashfest *x, int slot, int *pcount);
void feed1me(t_bashfest *x, int slot, int *pcount);
void flam1(t_bashfest *x, int slot, int *pcount);
void flam2(t_bashfest *x, int slot, int *pcount);
void expflam(t_bashfest *x, int slot, int *pcount);
void comb4(t_bashfest *x, int slot, int *pcount);
void ringfeed(t_bashfest *x, int slot, int *pcount);
void resonadsr(t_bashfest *x, int slot, int *pcount);
void stv(t_bashfest *x, int slot, int *pcount);
void compdist(t_bashfest *x, int slot, int *pcount);
void atom_arg_getfloat(float *c, long idx, long ac, t_atom *av);
void atom_arg_getsym(t_symbol **c, long idx, long ac, t_atom *av);
void bashfest_tilde_setup(void)
{
bashfest_class = class_new(gensym("bashfest~"),(t_newmethod)bashfest_new,(t_method)bashfest_dsp_free, sizeof(t_bashfest), 0, A_GIMME,0);
CLASS_MAINSIGNALIN(bashfest_class,t_bashfest, x_f );
class_addmethod(bashfest_class,(t_method)bashfest_dsp,gensym("dsp"),A_CANT,0);
class_addmethod(bashfest_class,(t_method)bashfest_setbuf,gensym("setbuf"),A_SYMBOL,0);
class_addmethod(bashfest_class,(t_method)bashfest_stop,gensym("stop"),0);
class_addmethod(bashfest_class,(t_method)bashfest_flatodds,gensym("flatodds"),0);
class_addmethod(bashfest_class,(t_method)bashfest_soloproc,gensym("soloproc"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_killproc,gensym("killproc"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_latency,gensym("latency"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_mute,gensym("mute"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_verbose,gensym("verbose"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_setodds,gensym("setodds"),A_GIMME,0);
class_addmethod(bashfest_class,(t_method)bashfest_tcycle,gensym("tcycle"),A_GIMME,0);
class_addmethod(bashfest_class,(t_method)bashfest_gozero,gensym("gozero"),0);
class_addmethod(bashfest_class,(t_method)bashfest_grab,gensym("grab"),0);
class_addmethod(bashfest_class,(t_method)bashfest_maximum_process,gensym("maximum_process"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_minimum_process,gensym("minimum_process"),A_FLOAT,0);
class_addmethod(bashfest_class,(t_method)bashfest_block_dsp,gensym("block_dsp"),A_FLOAT,0);
potpourri_announce(OBJECT_NAME);
}
void bashfest_block_dsp(t_bashfest *x, t_floatarg t)
{
x->block_dsp = (short)t;
}
void bashfest_maximum_process(t_bashfest *x, t_floatarg n)
{
if(n < 0){
error("illegal val to maximum_process");
return;
}
x->max_process_per_note = (int)n;
}
void bashfest_minimum_process(t_bashfest *x, t_floatarg n)
{
if(n < 0){
error("illegal val to minimum_process");
return;
}
x->min_process_per_note = (int)n;
}
void bashfest_verbose(t_bashfest *x, long t)
{
x->verbose = t;
}
void bashfest_latency(t_bashfest *x, long n)
{
if(n < x->vs){
error("latency cannot be less than %d",x->vs);
return;
}
/* if(n > x->latency_samples){
x->trigger_buffer = (float *) realloc(x->trigger_buffer, n * sizeof(float));
}
x->tb_inpt = 0;
x->tb_outpt = x->latency_samples - x->vs;*/
x->latency_samples = n;
}
void bashfest_stop(t_bashfest *x)
{
int i;
for(i = 0; i < x->overlap_max; i++){
x->events[i].status = INACTIVE;
}
}
void bashfest_mute(t_bashfest *x, t_floatarg t)
{
x->mute = (short)t;
}
void bashfest_grab(t_bashfest *x)
{
x->grab = 1;
}
void bashfest_tcycle(t_bashfest *x,t_symbol *msg, short argc, t_atom *argv)
{
t_cycle tcycle = x->tcycle;
int i;
float data=1.0;
if(argc < 1){
error("no data for tcycle!");
return;
} else if(argc > CYCLE_MAX){
error("%d is the maximum size tcycle",CYCLE_MAX);
return;
}
x->tcycle.len = argc;
x->tcycle.p = 0;
for(i=0;i<argc;i++){
atom_arg_getfloat(&data,i,argc,argv);
if(data <= 0.0){
error("bad data for tcycle:%f",data);
} else {
tcycle.data[i] = data;
}
}
}
void bashfest_gozero(t_bashfest *x)
{
x->tcycle.p = 0;
}
void bashfest_setodds(t_bashfest *x,t_symbol *msg, short argc, t_atom *argv)
{
int i;
if(argc > PROCESS_COUNT){
error("there are only %d processes",PROCESS_COUNT);
return;
}
for(i=0;i<PROCESS_COUNT;i++){
x->odds[i] = 0.0;
}
for(i=0;i<argc;i++){
x->odds[i] = atom_getfloatarg(i,argc,argv);
}
setweights(x->odds,PROCESS_COUNT);
}
void bashfest_soloproc(t_bashfest *x, long p)
{
int i;
if(p < 0 || p >= PROCESS_COUNT){
error("bad %d",p);
}
for(i=0;i<PROCESS_COUNT;i++){
x->odds[i] = 0.0;
}
x->odds[p] = 1.0;
setweights(x->odds,PROCESS_COUNT);
}
void bashfest_killproc(t_bashfest *x, long p)
{
int i;
if(p < 0 || p >= PROCESS_COUNT){
error("bad %d",p);
}
for(i=0;i<PROCESS_COUNT;i++){
x->odds[i] = 1.0;
}
x->odds[p] = 0.0;
setweights(x->odds,PROCESS_COUNT);
}
void bashfest_flatodds(t_bashfest *x)
{
int i;
for(i=0;i<PROCESS_COUNT;i++){
x->odds[i] = 1.0;
}
setweights(x->odds,PROCESS_COUNT);
}
void *bashfest_new(t_symbol *msg, short argc, t_atom *argv)
{
t_bashfest *x = (t_bashfest *)pd_new(bashfest_class);
// outlet_new(&x->x_obj, gensym("signal"));
int i;
long membytes = 0;
float tmpfloat;
srand(time(0));
x->sr = sys_getsr();
x->vs = sys_getblksize();
if(! x->sr)
x->sr = 44100;
x->work_buffer_size = DEFAULT_BUFFER_SIZE;
// x->latency_samples = DEFAULT_LATENCY;
// x->overlap_max = DEFAULT_MAX_OVERLAP;
/* argument list: buffer name, work buffer duration, latency in samples, number of overlaps */
atom_arg_getsym(&x->wavename,0,argc,argv);
/* We probably don't want to segfault when instantiating with no args, so */
if (!x->wavename) x->wavename = &s_;
atom_arg_getfloat(&x->work_buffer_size,1,argc,argv);
tmpfloat = DEFAULT_LATENCY;
atom_arg_getfloat(&tmpfloat,2,argc,argv);
x->latency_samples = tmpfloat;
tmpfloat = DEFAULT_MAX_OVERLAP;
atom_arg_getfloat(&tmpfloat,3,argc,argv);
x->overlap_max = tmpfloat;
outlet_new(&x->x_obj, gensym("signal"));
outlet_new(&x->x_obj, gensym("signal"));
x->sinelen = 8192;
x->verbose = 0;
x->most_recent_event = 0;
x->active_events = 0;
x->increment = 1.0;
x->block_dsp = 0;
x->grab = 0;
/*
x->tb_inpt = 0;
if(x->latency_samples < x->vs){
x->latency_samples = x->vs;//might need x->vs * 2 here
error("latency forced to %d samples",x->vs);
}
x->tb_outpt = x->latency_samples - x->vs;
*/
/* buffer contains space for both input and output, thus factor of 2 */
x->buf_frames = 2 * x->work_buffer_size * .001 * x->sr;
x->buf_samps = x->buf_frames * 2;
x->halfbuffer = x->buf_samps / 2;
x->maxdelay = 1.0; // in seconds
/*memory allocation */
x->events = (t_event *) t_getbytes(x->overlap_max * sizeof(t_event));
x->trigger_vec = (float *) t_getbytes(MAX_VEC * sizeof(float));
x->sinewave = t_getbytes(x->sinelen * sizeof(float));
x->params = t_getbytes(MAX_PARAMETERS * sizeof(float));
x->odds = t_getbytes(64 * sizeof(float));
// x->trigger_buffer = calloc(x->latency_samples, sizeof(float));
for(i=0;i<64;i++)
x->odds[i] = 0;
putsine(x->sinewave, x->sinelen);
for(i=0;i<x->overlap_max;i++){
x->events[i].workbuffer = (float *) t_getbytes(x->buf_samps * sizeof(float));
}
x->delayline1 = (float *) t_getbytes(x->maxdelay * x->sr * sizeof(float));
x->delayline2 = (float *) t_getbytes(x->maxdelay * x->sr * sizeof(float));
x->max_mini_delay = .25;
x->eel = (LSTRUCT *) t_getbytes(MAXSECTS * sizeof(LSTRUCT));
for( i = 0; i < 4 ; i++ ){
x->mini_delay[i] =
(float *) t_getbytes(((int)(x->sr * x->max_mini_delay) + 1) * sizeof(float));
}
x->reverb_ellipse_data = (float *) t_getbytes(16 * sizeof(float));
x->ellipse_data = (float **) t_getbytes(MAXFILTER * sizeof(float *));
for(i=0;i<MAXFILTER;i++){
x->ellipse_data[i] = (float *) t_getbytes(MAX_COEF * sizeof(float));
}
x->tf_len = 1;
x->tf_len <<= 16;
x->transfer_function = (float *) t_getbytes(x->tf_len * sizeof(float) );
x->feedfunclen = 8192 ;
x->feedfunc1 = (float *) t_getbytes( x->feedfunclen * sizeof(float) );
x->feedfunc2 = (float *) t_getbytes( x->feedfunclen * sizeof(float) );
x->feedfunc3 = (float *) t_getbytes( x->feedfunclen * sizeof(float) );
x->feedfunc4 = (float *) t_getbytes( x->feedfunclen * sizeof(float) );
x->flamfunc1len = 8192 ;
x->flamfunc1 = (float *) t_getbytes( x->flamfunc1len * sizeof(float));
setflamfunc1(x->flamfunc1,x->flamfunc1len);
x->max_comb_lpt = 0.15 ;// watch out here
x->combies = (CMIXCOMB *) t_getbytes(4 * sizeof(CMIXCOMB));
for( i = 0; i < 4; i++ ){
x->combies[i].len = x->sr * x->max_comb_lpt + 2;
x->combies[i].arr = (float *) t_getbytes(x->combies[i].len * sizeof(float));
}
x->adsr = (CMIXADSR *) t_getbytes(1 * sizeof(CMIXADSR));
x->adsr->len = 32768 ;
x->adsr->func = (float *) t_getbytes(x->adsr->len * sizeof(float) );
x->dcflt = (float *) t_getbytes(16 * sizeof(float));
x->tcycle.data = (float *) t_getbytes(CYCLE_MAX * sizeof(float));
x->tcycle.len = 0;
for(i=0;i<x->overlap_max;i++){
x->events[i].phasef = x->events[i].phase = 0.0;
}
membytes = x->overlap_max * sizeof(t_event);
membytes += x->sinelen * sizeof(float);
membytes += MAX_PARAMETERS * sizeof(float);
membytes += 64 * sizeof(float);
membytes += x->buf_samps * sizeof(float) * x->overlap_max;
membytes += x->maxdelay * x->sr * sizeof(float) * 2;
membytes += MAXSECTS * sizeof(LSTRUCT);
membytes += ((int)(x->sr * x->max_mini_delay) + 1) * sizeof(float) * 4;
membytes += 16 * sizeof(float);
membytes += MAXFILTER * sizeof(float *);
membytes += MAX_COEF * sizeof(float) * MAXFILTER;
membytes += x->tf_len * sizeof(float);
membytes += x->feedfunclen * sizeof(float) * 4;
membytes += x->flamfunc1len * sizeof(float);
membytes += 4 * sizeof(CMIXCOMB);
membytes += x->combies[0].len * sizeof(float) * 4;
membytes += sizeof(CMIXADSR);
membytes += x->adsr->len * sizeof(float);
membytes += 16 * sizeof(float);
membytes += CYCLE_MAX * sizeof(float);
// post("total memory for this bashfest %.2f MBytes",(float)membytes/1000000.);
/* be sure to finish clearing memory */
set_dcflt(x->dcflt);
init_reverb_data(x->reverb_ellipse_data);
init_ellipse_data(x->ellipse_data);
for(i=0;i<PROCESS_COUNT;i++){
x->odds[i] = 1;
}
x->max_process_per_note = 2;
setweights(x->odds,PROCESS_COUNT);
x->mute = 0;
for(i = 0; i < x->overlap_max; i++){
x->events[i].status = INACTIVE;
}
return (x);
}
void bashfest_setbuf(t_bashfest *x, t_symbol *wavename)
{
t_garray *a;
x->hosed = 0;
x->b_frames = 0;
x->b_nchans = 1;
x->b_valid = 0;
int b_frames;
if (!(a = (t_garray *)pd_findbyclass(wavename, garray_class))) {
if (*wavename->s_name) pd_error(x, "bashfest~: %s: no such array",
wavename->s_name);
x->b_samples = 0;
x->hosed = 1;
}
else if (!garray_getfloatwords(a, &b_frames, &x->b_samples)) {
pd_error(x, "%s: bad array for bashfest~", wavename->s_name);
x->b_samples = 0;
x->hosed = 1;
}
else {
x->b_frames = (long)b_frames;
// post("%d frames in buffer %s",x->b_frames, wavename->s_name);
garray_usedindsp(a);
x->b_valid = 1;
}
}
t_int *bashfest_perform_hosed(t_int *w)
{
// t_bashfest *x = (t_bashfest *) (w[1]);
// float *trigger = (t_float *)(w[2]);
float *outchanL = (t_float *)(w[3]);
float *outchanR = (t_float *)(w[4]);
int n = (int) w[5];
// try bzero
// while(n--) *outchanL++ = *outchanR++ = 0.0;
memset((char *)outchanL, 0, sizeof(float) * n);
memset((char *)outchanR, 0, sizeof(float) * n);
return(w+6);
}
/* modified for dsp turnoff*/
t_int *bashfest_perform(t_int *w)
{
t_bashfest *x = (t_bashfest *) (w[1]);
float *t_vec = (t_float *)(w[2]);
float *outchanL = (t_float *)(w[3]);
float *outchanR = (t_float *)(w[4]);
int n = (int) w[5];
t_word *b_samples;
long b_nchans;
// long b_valid;
long b_frames;
t_event *events = x->events;
// int active_events = x->active_events;
float increment = x->increment;
int overlap_max = x->overlap_max;
int iphase;
int flimit;
short insert_success;
int new_insert;
int i,j,k;
t_cycle tcycle = x->tcycle;
float gain;
// short bail;
float frac;
float samp1, samp2;
float maxphase;
int theft_candidate;
int out_channels;
float *processed_drum;
char *sound_name = x->sound_name;
int latency_samples = x->latency_samples;
float *trigger_vec = x->trigger_vec;
for(i = 0; i < n; i++)
trigger_vec[i] = t_vec[i];
if(x->mute || x->hosed){
while(n--) {
*outchanL++ = *outchanR++ = 0.0;
}
return(w+6);
}
bashfest_setbuf(x, x->wavename);
if(! x->b_valid) {
while(n--) {
*outchanL++ = *outchanR++ = 0.0;
}
return(w+6);
}
b_samples = x->b_samples;
b_frames = x->b_frames;
b_nchans = 1; // for Pd
if(x->block_dsp){
/* computation savings if processing is blocked */
/* preliminary transposition will be set here */
if(tcycle.len > 0){
increment = tcycle.data[tcycle.p];
// post("position %d, increment %f",tcycle.p,increment );
} else {
increment = 1.0;
//error("increment default, len is zero");
}
// initial cleaning
for(i=0; i<n; i++){
outchanL[i] = outchanR[i] = 0.0;
}
flimit = (b_frames - 1) * 2;
for(i = 0; i < overlap_max; i++){
if(events[i].status == ACTIVE){
gain = events[i].gain;
if(b_nchans == 1){ /* mono */
flimit = (b_frames - 1);
for(j = 0; j < n; j++){
if(events[i].countdown > 0){
--events[i].countdown;
} else {
iphase = events[i].phasef;
frac = events[i].phasef - iphase;
if(increment > 0){
if(iphase == flimit || increment == 1.0){
outchanL[j] += b_samples[iphase].w_float * gain;
outchanR[j] += b_samples[iphase].w_float * gain;
} else {
samp1 = b_samples[iphase].w_float;
samp2 = b_samples[iphase+1].w_float;
samp1 = gain * (samp1 + frac * (samp2-samp1));
outchanL[j] += samp1;
outchanR[j] += samp1;
}
} else { /*negative increment case (currently unused but might be useful)*/
if(iphase == 0.0 || increment == -1.0 ){
outchanL[j] += b_samples[iphase].w_float * gain;
outchanR[j] += b_samples[iphase].w_float * gain;
} else {
samp2 = b_samples[iphase].w_float;
samp1 = b_samples[iphase-1].w_float;
samp1 = gain * (samp1 + frac * (samp2-samp1));
outchanL[j] += samp1;
outchanR[j] += samp1;
}
}
events[i].phasef += increment;
if( events[i].phasef < 0.0 || events[i].phasef >= b_frames){
events[i].status = INACTIVE;
events[i].phasef = 0;
// post("valid exit mono note");
break;
}
}
}
} else if(b_nchans == 2){
/*
for(j = 0; j < n; j++){
if(events[i].countdown > 0){
--events[i].countdown;
} else {
iphase = events[i].phasef;
frac = events[i].phasef - iphase;
iphase *= 2;
if(increment > 0){
if(iphase == flimit || increment == 1.0){
outchanL[j] += b_samples[iphase] * gain;
outchanR[j] += b_samples[iphase+1] * gain;
} else {
samp1 = b_samples[iphase];
samp2 = b_samples[iphase+2];
outchanL[j] += gain * (samp1 + frac * (samp2-samp1));
samp1 = b_samples[iphase+1];
samp2 = b_samples[iphase+3];
outchanR[j] += gain * (samp1 + frac * (samp2-samp1));
}
} else {
if(iphase == 0.0 || increment == -1.0 ){
outchanL[j] += b_samples[iphase] * gain;
outchanR[j] += b_samples[iphase+1] * gain;
} else {
samp2 = b_samples[iphase];
samp1 = b_samples[iphase-2];
outchanL[j] += gain * (samp1 + frac * (samp2-samp1));
samp2 = b_samples[iphase+1];
samp1 = b_samples[iphase-1];
outchanR[j] += gain * (samp1 + frac * (samp2-samp1));
}
}
events[i].phasef += increment;
if( events[i].phasef < 0.0 || events[i].phasef >= b_frames){
events[i].status = INACTIVE;
break;
}
}
}*/
}
}
}
for(i=0; i<n; i++){
if(trigger_vec[i]){
gain = trigger_vec[i];
insert_success = 0;
for(j=0; j<overlap_max; j++){
if(events[j].status == INACTIVE){
events[j].status = ACTIVE;
events[j].gain = gain;
if(increment > 0){
events[j].phasef = 0.0;
} else {
events[j].phasef = b_frames - 1;
}
insert_success = 1;
new_insert = j;
break;
}
}
if(!insert_success){ // steal a note
maxphase = 0;
theft_candidate = 0;
for(k = 0; k < overlap_max; k++){
if(events[k].phasef > maxphase){
maxphase = events[k].phasef;
theft_candidate = k;
}
}
new_insert = theft_candidate;
events[new_insert].gain = gain;
if(increment > 0){
events[new_insert].phasef = 0.0;
} else {
events[new_insert].phasef = b_frames - 1;
}
insert_success = 1;
post("stealing a note at %d for buffer %s", new_insert, sound_name);
}
events[new_insert].countdown = latency_samples;
events[new_insert].status = ACTIVE;
x->new_slot = new_insert;
x->new_gain = gain;
// post("new note at slot %d",new_insert);
if(tcycle.len > 0){
increment = tcycle.data[tcycle.p++];
if(tcycle.p >= tcycle.len){
tcycle.p = 0;
}
x->tcycle.p = tcycle.p;
} else {
increment = 1.0;
}
for(k=i; k<n; k++){
//roll out for remaining portion of vector
if(events[new_insert].countdown > 0){
--events[new_insert].countdown;
} else {
if(b_nchans == 1){
iphase = events[new_insert].phasef;
frac = events[new_insert].phasef - iphase;
if(iphase < 0 || iphase >= b_frames){
error("aborting on phase %f",events[new_insert].phasef);
break;
}
if(increment > 0){
if(iphase == flimit || increment == 1.0){
outchanL[k] += b_samples[iphase].w_float * gain;
outchanR[k] += b_samples[iphase].w_float * gain;
} else {
samp1 = b_samples[iphase].w_float;
samp2 = b_samples[iphase+1].w_float;
samp1 = gain * (samp1 + frac * (samp2-samp1));
outchanL[k] += samp1;
outchanR[k] += samp1;
}
} else { /*negative increment case (currently unused but might be useful)*/
if(iphase == 0.0 || increment == -1.0 ){
outchanL[k] += b_samples[iphase].w_float * gain;
outchanR[k] += b_samples[iphase].w_float * gain;
} else {
samp2 = b_samples[iphase].w_float;
samp1 = b_samples[iphase-2].w_float;
samp1 = gain * (samp1 + frac * (samp2-samp1));
outchanL[k] += samp1;
outchanR[k] += samp1;
}
}
events[new_insert].phasef += increment;
if( events[new_insert].phasef < 0.0 || events[new_insert].phasef >= b_frames){
events[new_insert].status = INACTIVE;
break;
}
} else if(b_nchans == 2)
{ /*
iphase = events[new_insert].phasef;
frac = events[new_insert].phasef - iphase;
iphase *= 2;
if(increment > 0){
if(iphase == flimit || increment == 1.0){
outchanL[k] += b_samples[iphase] * gain;
outchanR[k] += b_samples[iphase+1] * gain;
} else {
samp1 = b_samples[iphase];
samp2 = b_samples[iphase+2];
outchanL[k] += gain * (samp1 + frac * (samp2-samp1));
samp1 = b_samples[iphase+1];
samp2 = b_samples[iphase+3];
outchanR[k] += gain * (samp1 + frac * (samp2-samp1));
}
} else {
if(iphase == 0.0 || increment == -1.0 ){
outchanL[k] += b_samples[iphase] * gain;
outchanR[k] += b_samples[iphase+1] * gain;
} else {
samp2 = b_samples[iphase];
samp1 = b_samples[iphase-2];
outchanL[k] += gain * (samp1 + frac * (samp2-samp1));
samp2 = b_samples[iphase+1];
samp1 = b_samples[iphase-1];
outchanR[k] += gain * (samp1 + frac * (samp2-samp1));
}
}
events[new_insert].phasef += increment;
if( events[new_insert].phasef < 0.0 || events[new_insert].phasef >= b_frames){
events[new_insert].status = INACTIVE;
break;
} */
}
}
}
}
}
x->increment = increment;
/* x->tb_inpt = tb_inpt;
x->tb_outpt = tb_outpt;*/
return(w+6);
/* end of block_dsp contingecy code */
}
/* main body of bashfest processing */
for(i=0; i<n; i++){ /* pre-clean buffers*/
outchanL[i] = outchanR[i] = 0.0;
}
/* add output from all active buffers into global outlet buffers */
for(i = 0; i < overlap_max; i++){
if( events[i].status == ACTIVE){
out_channels = events[i].out_channels;
/* assign the output part of work buffer to the local float buffer */
processed_drum = events[i].workbuffer + events[i].in_start;
for(j = 0; j < n; j++){
if(x->grab){
x->grab = 0;
// if too slow, defend with defer_low()
bashfest_copy_to_MSP_buffer(x,i);
}
if(events[i].countdown > 0){
--events[i].countdown;
} else {
if(out_channels == 1){
outchanL[j] += processed_drum[events[i].phase] * events[i].gainL;
outchanR[j] += processed_drum[events[i].phase] * events[i].gainR;
} else if(out_channels == 2){
iphase = events[i].phase * 2;
outchanL[j] += processed_drum[iphase] * events[i].gainL;
outchanR[j] += processed_drum[iphase+1] * events[i].gainR;
}
events[i].phase++;
if(events[i].phase >= events[i].sample_frames){
events[i].status = INACTIVE;
break;
}
}
}
}
}
/* now check for initiation click. If found,
add to list. If necessary, steal a note
*/
for(i=0; i<n; i++){
if(trigger_vec[i]){
gain = trigger_vec[i];
/*look for an open slot*/
insert_success = 0;
for(j=0; j<overlap_max; j++){
if(events[j].status == INACTIVE){
events[j].status = ACTIVE;
events[j].gain = gain;
insert_success = 1;
new_insert = j;
break;
}
}
if(!insert_success){ /* steal a note if necessary*/
maxphase = 0;
theft_candidate = 0;
for(k = 0; k < overlap_max; k++){
if(events[k].phase > maxphase){
maxphase = events[k].phase;
theft_candidate = k;
}
}
if(x->verbose){
post("stealing note at slot %d", theft_candidate);
}
post("stealing a note at %d for buffer %s", theft_candidate, sound_name);
new_insert = theft_candidate;
events[new_insert].gain = gain;
insert_success = 1;
}
events[new_insert].countdown = x->latency_samples;
x->new_slot = new_insert;
x->new_gain = gain;
bashfest_deploy_dsp(x);
/* now begin output from the new note */
out_channels = events[new_insert].out_channels;
processed_drum = events[new_insert].workbuffer + events[new_insert].in_start;
/* processed_drum = events[new_insert].workbuffer; */
for(j = i; j < n; j++){
if(events[new_insert].countdown > 0){
--events[new_insert].countdown;
} else{
iphase = events[new_insert].phase;
if(x->grab){
x->grab = 0;
// if too slow, defend with defer_low()
bashfest_copy_to_MSP_buffer(x,i);
}
if(out_channels == 1){
outchanL[j] += processed_drum[iphase] * events[new_insert].gainL;
outchanR[j] += processed_drum[iphase] * events[new_insert].gainR;
} else if(out_channels == 2){
iphase = events[i].phase * 2;
outchanL[j] += processed_drum[iphase] * events[new_insert].gainL;
outchanR[j] += processed_drum[iphase+1] * events[new_insert].gainR;
}
events[new_insert].phase++;
if(events[new_insert].phase >= events[new_insert].sample_frames){
events[new_insert].status = INACTIVE;
break;
}
}
}
}
}
return (w+6);
}
void bashfest_copy_to_MSP_buffer(t_bashfest *x, int slot)
{
int i; //,j;
t_event *events = x->events;
long b_nchans = x->b_nchans;
long b_frames = x->b_frames;
t_word *b_samples = x->b_samples;
float *processed_drum;
processed_drum = events[slot].workbuffer + events[slot].in_start;
if(events[slot].out_channels == b_nchans){
if(b_nchans == 1){
for(i=0;i<b_frames;i++){
b_samples[i].w_float = processed_drum[i];
}
} else if(b_nchans == 2){
/*for(i=0;i<b_frames*2;i+=2){
b_samples[i].w_float = processed_drum[i];
b_samples[i+1] = processed_drum[i+1];
}*/
}else{
error("bashfest copy: channel mismatch");
//fixable but first let's try these
}
}
}
void bashfest_deploy_dsp(t_bashfest *x)
{
float *b_samples = (float*)x->b_samples;
long b_nchans = x->b_nchans;
long b_frames = x->b_frames;
t_event *events = x->events;
float pan;
int i; //,j;
float *params = x->params;
int pcount;
int buf_samps = x->buf_samps;
int curarg = 0;
float maxamp;
float rescale;
float *inbuf;
int slot = x->new_slot;
float gain = x->new_gain;
events[slot].completed = 1;// for testing only
if(b_nchans <1 || b_nchans > 2){
error("illegal channels in buffer:%d",b_nchans);
return;
x->hosed = 1;
}
if(b_frames > x->buf_frames / 2){
error("sample in buffer %s is to large for work buffer",x->sound_name);
return;
x->hosed = 1;
}
pan = boundrand(0.1, 0.9);
events[slot].gainL = cos(PIOVERTWO * pan) * gain;
events[slot].gainR = sin(PIOVERTWO * pan) * gain;
events[slot].phase = 0;
events[slot].status = ACTIVE;
/* if(x->verbose)
post("initiating note at slot %d, gain %f, pan %f,inchans %d",slot,gain,pan,b_nchans);
*/
if(x->sound_lock){
return;// of course should finally copy good stuff to MSP buffer
}
events[slot].out_channels = b_nchans;
events[slot].sample_frames = b_frames;
for(i=0; i<b_frames*b_nchans; i++){
events[slot].workbuffer[i] = b_samples[i];
}
// clean rest of work buffer
for(i=b_frames*b_nchans; i<buf_samps; i++){
events[slot].workbuffer[i] = 0.0;
}
events[slot].in_start = 0;
events[slot].out_start = x->halfbuffer;
pcount = bashfest_set_parameters(x, params);
while(curarg < pcount){
if(params[curarg] == TRANSPOSE){
transpose(x, slot, &curarg);
}
else if(params[curarg] == RINGMOD){
ringmod(x, slot, &curarg);
}
else if(params[curarg] == RETRO){
retrograde(x, slot, &curarg);
}
else if(params[curarg] == COMB){
comber(x, slot, &curarg);
}
else if(params[curarg] == FLANGE){
flange(x, slot, &curarg);
}
else if(params[curarg] == BUTTER){
butterme(x, slot, &curarg);
}
else if(params[curarg] == TRUNCATE){
truncateme(x, slot, &curarg);
}
else if(params[curarg] == SWEEPRESON){
sweepreson(x, slot, &curarg);
}
else if(params[curarg] == SLIDECOMB){
slidecomb(x, slot, &curarg);
}
else if(params[curarg] == REVERB1){
reverb1(x, slot, &curarg);
}
else if(params[curarg] == ELLIPSE){
ellipseme(x, slot, &curarg);
}
else if(params[curarg] == FEED1){
feed1me(x, slot, &curarg);
}
else if(params[curarg] == FLAM1){
flam1(x, slot, &curarg);
}
else if(params[curarg] == FLAM2){
flam2(x, slot, &curarg);
}
else if(params[curarg] == EXPFLAM){
expflam(x, slot, &curarg);
}
else if(params[curarg] == COMB4){
comb4(x, slot, &curarg);
}
else if(params[curarg] == COMPDIST){
compdist(x, slot, &curarg);
}
else if(params[curarg] == RINGFEED){
ringfeed(x, slot, &curarg);
}
else if(params[curarg] == RESONADSR){
resonadsr(x, slot, &curarg);
}
else if(params[curarg] == STV){
stv(x, slot, &curarg);
}
else {
error("deploy missing branch");
}
}
maxamp = 0.0;
inbuf = events[slot].workbuffer + events[slot].in_start;
b_nchans = events[slot].out_channels;
b_frames = events[slot].sample_frames;
for(i=0; i< b_frames * b_nchans; i++){
if(maxamp < fabs(inbuf[i])){
maxamp = fabs(inbuf[i]);
}
}
if(maxamp>0){
rescale = 1.0/maxamp;
for(i=0; i< b_frames * b_nchans; i++){
inbuf[i] *= rescale;
}
}
else{
if(x->verbose)
error("zero maxamp detected");
}
if(events[slot].countdown <= 0)
error("deploy_dsp: failed to conclude in time; need more latency");
}
int bashfest_set_parameters(t_bashfest *x,float *params)
{
float rval;
int pcount = 0;
int events;
int i, j;
int type;
float cf;//, bw;
float *odds = x->odds;
int maxproc = x->max_process_per_note;
int minproc = x->min_process_per_note;
float tval;
t_cycle tcycle = x->tcycle;
/* preliminary transposition will be set here */
if(tcycle.len > 0){
params[pcount++] = TRANSPOSE;
params[pcount++] = tcycle.data[tcycle.p++];
if(tcycle.p >= tcycle.len){
tcycle.p = 0;
}
x->tcycle.p = tcycle.p;
}
if(maxproc <= 0){
return pcount;
}
events = minproc + rand() % (1+(maxproc-minproc));
for(i = 0; i < events; i++){
rval = boundrand(0.0,1.0);
j = 0;
while(rval > odds[j]){
j++;
}
if(j == RETRO){
params[pcount++] = RETRO;
}
else if(j == COMB){
params[pcount++] = COMB;
params[pcount++] = boundrand(.001,.035);// delaytime
params[pcount++] = boundrand(.25,.98);//feedback
params[pcount++] = boundrand(.05,.5);//hangtime
}
else if(j == RINGMOD) {
params[pcount++] = RINGMOD;
params[pcount++] = boundrand(100.0,2000.0); //need a log version
}
else if(j == TRANSPOSE){
params[pcount++] = TRANSPOSE;
params[pcount++] = boundrand(0.25,3.0);
}
else if(j == FLANGE){
params[pcount++] = FLANGE;
params[pcount++] = boundrand(100.0,400.0);
params[pcount++] = boundrand(600.0,4000.0);
params[pcount++] = boundrand(0.1,2.0);
params[pcount++] = boundrand(0.1,0.95);
params[pcount++] = boundrand(0.0,0.9);
}
else if(j == BUTTER){
params[pcount++] = BUTTER;
type = rand() % 3;
params[pcount++] = type;
cf = boundrand(70.0,3000.0);
params[pcount++] = cf;
if(type == BANDPASS){
params[pcount++] = cf * boundrand(0.05,0.6);
}
}
else if(j == TRUNCATE){
params[pcount++] = TRUNCATE;
params[pcount++] = boundrand(.05,.15);
params[pcount++] = boundrand(.01,.05);
}
else if(j == SWEEPRESON){
params[pcount++] = SWEEPRESON;
params[pcount++] = boundrand(100.0,300.0);
params[pcount++] = boundrand(600.0,6000.0);
params[pcount++] = boundrand(0.01,0.2);
params[pcount++] = boundrand(0.05,2.0);
params[pcount++] = boundrand(0.0,1.0);
}
else if(j == SLIDECOMB){
params[pcount++] = SLIDECOMB;
params[pcount++] = boundrand(.001,.03);
params[pcount++] = boundrand(.001,.03);
params[pcount++] = boundrand(0.05,0.95);
params[pcount++] = boundrand(0.05,0.5);
}
else if(j == REVERB1){
params[pcount++] = REVERB1;
params[pcount++] = boundrand(0.25,0.99);
params[pcount++] = boundrand(0.1,1.0);
params[pcount++] = boundrand(0.2,0.8);
}
else if(j == ELLIPSE){
params[pcount++] = ELLIPSE;
params[pcount++] = rand() % ELLIPSE_FILTER_COUNT;
}
else if(j == FEED1){
params[pcount++] = FEED1;
tval = boundrand(.001,0.1);
params[pcount++] = tval;
params[pcount++] = boundrand(tval,0.1);
tval = boundrand(.01,0.5);
params[pcount++] = tval;
params[pcount++] = boundrand(tval,0.5);
params[pcount++] = boundrand(.05,1.0);
}
else if(j == FLAM1){
params[pcount++] = FLAM1;
params[pcount++] = 4 + (rand() % 20);
params[pcount++] = boundrand(0.3,0.8);
params[pcount++] = boundrand(0.5,1.2);
params[pcount++] = boundrand(.025,0.15);
}
else if(j == FLAM2){
params[pcount++] = FLAM2;
params[pcount++] = 4 + (rand() % 20);
params[pcount++] = boundrand(0.1,0.9);
params[pcount++] = boundrand(0.2,1.2);
params[pcount++] = boundrand(.025,0.15);
params[pcount++] = boundrand(.025,0.15);
}
else if(j == EXPFLAM){
params[pcount++] = EXPFLAM;
params[pcount++] = 4 + (rand() % 20);
params[pcount++] = boundrand(0.1,0.9);
params[pcount++] = boundrand(0.2,1.2);
params[pcount++] = boundrand(.025,0.15);
params[pcount++] = boundrand(.025,0.15);
params[pcount++] = boundrand(-5.0,5.0);
}
else if(j == COMB4){
params[pcount++] = COMB4;
params[pcount++] = boundrand(100.0,900.0);
params[pcount++] = boundrand(100.0,900.0);
params[pcount++] = boundrand(100.0,900.0);
params[pcount++] = boundrand(100.0,900.0);
tval = boundrand(.5,0.99);
params[pcount++] = tval;
params[pcount++] = tval;
}
else if(j == COMPDIST){
params[pcount++] = COMPDIST;
params[pcount++] = tval = boundrand(.01,.25);
params[pcount++] = boundrand(tval,.9);
params[pcount++] = 1;
}
else if(j == RINGFEED){
params[pcount++] = RINGFEED;
params[pcount++] = boundrand(90.0,1500.0);
params[pcount++] = boundrand(90.0,1500.0);
params[pcount++] = boundrand(0.2,0.95);
params[pcount++] = boundrand(90.0,1500.0);
params[pcount++] = boundrand(.01,.4);
params[pcount++] = boundrand(.05,1.0);
}
else if(j == RESONADSR){
params[pcount++] = RESONADSR;
params[pcount++] = boundrand(.01,.1);
params[pcount++] = boundrand(.01,.05);
params[pcount++] = boundrand(.05,.5);
params[pcount++] = boundrand(150.0,4000.0);
params[pcount++] = boundrand(150.0,4000.0);
params[pcount++] = boundrand(150.0,4000.0);
params[pcount++] = boundrand(150.0,4000.0);
params[pcount++] = boundrand(.03,.7);
}
else if(j == STV){
params[pcount++] = STV;
params[pcount++] = boundrand(.025,0.5);
params[pcount++] = boundrand(.025,0.5);
params[pcount++] = boundrand(.001,.01);
}
else {
error("could not find a process for %d",j);
return 0;
}
}
return pcount;
}
void bashfest_dsp_free(t_bashfest *x)
{
int i;
t_freebytes(x->sinewave, x->sinelen * sizeof(float));
t_freebytes(x->params, MAX_PARAMETERS * sizeof(float));
t_freebytes(x->odds, 64 * sizeof(float));
t_freebytes(x->delayline1, x->maxdelay * x->sr * sizeof(float));
t_freebytes(x->delayline2, x->maxdelay * x->sr * sizeof(float));
for(i=0;i<x->overlap_max;i++){
t_freebytes(x->events[i].workbuffer, x->buf_samps * sizeof(float));
}
t_freebytes(x->events, x->overlap_max * sizeof(t_event));
t_freebytes(x->eel,MAXSECTS * sizeof(LSTRUCT));
for( i = 0; i < 4 ; i++ ){
t_freebytes(x->mini_delay[i], ((int)(x->sr * x->max_mini_delay) + 1) * sizeof(float));
}
t_freebytes(x->reverb_ellipse_data, 16 * sizeof(float));
for(i=0;i<MAXFILTER;i++){
t_freebytes(x->ellipse_data[i], MAX_COEF * sizeof(float));
}
t_freebytes(x->ellipse_data, MAXFILTER * sizeof(float *));
t_freebytes(x->transfer_function,x->tf_len * sizeof(float));
t_freebytes(x->feedfunc1, x->feedfunclen * sizeof(float));
t_freebytes(x->feedfunc2, x->feedfunclen * sizeof(float));
t_freebytes(x->feedfunc3, x->feedfunclen * sizeof(float));
t_freebytes(x->feedfunc4, x->feedfunclen * sizeof(float));
t_freebytes(x->flamfunc1, x->flamfunc1len * sizeof(float));
for( i = 0; i < 4; i++ ){
t_freebytes(x->combies[i].arr, x->combies[i].len * sizeof(float));
}
t_freebytes(x->combies,4 * sizeof(CMIXCOMB));
t_freebytes(x->adsr->func, x->adsr->len * sizeof(float));
t_freebytes(x->adsr,sizeof(CMIXADSR));
t_freebytes(x->tcycle.data,CYCLE_MAX * sizeof(float));
t_freebytes(x->trigger_vec, MAX_VEC * sizeof(float));
}
void bashfest_dsp(t_bashfest *x, t_signal **sp)
{
bashfest_setbuf(x, x->wavename);
if( x->hosed ){
error("bashfest~ needs a valid buffer");
}
/* if vector size changes, we also need to deal, thanks to
the trigger buffer inter-delay
*/
if(x->sr != sp[0]->s_sr){
x->sr = sp[0]->s_sr;
if(!x->sr){
post("warning: zero sampling rate!");
x->sr = 44100;
}
}
if(x->b_frames <= 0){
post("empty buffer, hosing down");
x->hosed = 1;
}
if(x->hosed){
dsp_add(bashfest_perform_hosed, 5, x,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, (t_int)sp[0]->s_n);
} else {
dsp_add(bashfest_perform, 5, x,
sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, (t_int)sp[0]->s_n);
}
}
/*
void bashfest_assist (t_bashfest *x, void *b, long msg, long arg, char *dst)
{
if (msg==1) {
switch (arg) {
case 0: sprintf(dst,"(signal) Click Trigger"); break;
}
}
else if (msg==2) {
switch(arg){
case 0: sprintf(dst,"(signal) Channel 1 Output"); break;
case 1: sprintf(dst,"(signal) Channel 2 Output"); break;
}
}
}
*/
#include "fftease.h" void bloscbank( float *S, float *O, int D, float iD, float *lf, float *la, float *index, float *tab, int len, float synt, int lo, int hi ) { int amp,freq,chan, i; float a,ainc,f,finc,address; for ( chan = lo; chan < hi; chan++ ) { freq = ( amp = ( chan << 1 ) ) + 1; if ( S[amp] > synt ){ finc = ( S[freq] - ( f = lf[chan] ) )* iD; ainc = ( S[amp] - ( a = la[chan] ) )* iD; address = index[chan]; for ( i = 0; i < D ; i++ ) { O[i] += a*tab[ (int) address ]; address += f; while ( address >= len ) address -= len; while ( address < 0 ) address += len; a += ainc; f += finc; } lf[chan] = S[freq]; la[chan] = S[amp]; index[chan] = address; } } }
\ No newline at end of file
#N canvas 586 296 617 462 10;
#N canvas 0 22 450 300 (subpatch) 0;
#X array dopey 62079 float 2;
#X coords 0 1 62079 -1 200 140 1;
#X restore 34 65 graph;
#N canvas 742 412 538 388 load-samples 0;
#X obj 36 151 soundfiler;
#X msg 36 83 bang;
#X obj 36 109 openpanel;
#X obj 144 37 loadbang;
#X msg 36 131 read -resize \$1 dopey;
#X obj 117 17 inlet;
#X msg 117 64 read -resize sound/voice.wav dopey;
#X connect 1 0 2 0;
#X connect 2 0 4 0;
#X connect 3 0 6 0;
#X connect 4 0 0 0;
#X connect 5 0 6 0;
#X connect 6 0 0 0;
#X restore 245 110 pd load-samples;
#X obj 222 241 buffet~ dopey 100 300;
#X obj 222 288 bng 15 100 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X floatatom 365 270 5 0 0 0 - - -, f 5;
#N canvas 0 22 450 300 (subpatch) 0;
#X array soapy 22050 float 2;
#X coords 0 1 22050 -1 100 70 1;
#X restore 34 234 graph;
#N canvas 171 294 544 498 processing 0;
#X obj 44 402 s buffet-msgs;
#X msg 203 208 reverse;
#X msg 171 150 normalize 0.95;
#X msg 173 176 killdc;
#X text 43 34 Destructive Buffer Edits;
#X msg 182 386 autoredraw \$1;
#X obj 182 364 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
1;
#X text 199 363 turn off if redraw hurts performance;
#X msg 182 345 1;
#X obj 182 329 loadbang;
#X msg 43 67 fadein 100;
#X msg 89 92 fadeout 500;
#X msg 112 121 rotatetozero 300;
#X msg 221 247 erase 300 460;
#X msg 223 285 internal_fadeout 500 800;
#X msg 251 309 internal_fadein 200 500;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 5 0;
#X connect 8 0 6 0;
#X connect 9 0 8 0;
#X connect 10 0 0 0;
#X connect 11 0 0 0;
#X connect 12 0 0 0;
#X connect 13 0 0 0;
#X connect 14 0 0 0;
#X connect 15 0 0 0;
#X coords 0 0 1 1 85 60 0;
#X restore 33 341 pd processing;
#X obj 222 214 r buffet-msgs;
#N canvas 574 418 474 306 copying 0;
#X obj 48 70 buffet~ soapy 100 200;
#X text 46 30 clear receiver (optional);
#X obj 50 236 s buffet-msgs;
#X text 156 162 too long requests are truncated;
#X msg 270 53 normalize 1;
#X msg 47 50 erase 0 500;
#X msg 49 112 copy_to_buffer soapy 0 500;
#X msg 62 135 copy_to_buffer soapy 500 1000;
#X msg 154 181 copy_to_buffer soapy 300 1200;
#X connect 4 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 2 0;
#X connect 7 0 2 0;
#X connect 8 0 2 0;
#X restore 34 314 pd copying;
#X text 229 301 operation completion indicator;
#X text 412 269 rms report;
#N canvas 151 375 470 320 analysis 0;
#X obj 65 188 s buffet-msgs;
#X text 66 88 get rms reading from a specified segment of buffer;
#X msg 120 145 pevents 50 0.05;
#X text 117 130 look for percussive events;
#X msg 64 112 rmschunk 200 300;
#X connect 2 0 0 0;
#X connect 4 0 0 0;
#X restore 33 393 pd analysis;
#X obj 294 344 print;
#X text 334 347 list of estimated onsets in buffer;
#X obj 391 204 dac~;
#X floatatom 416 151 5 0 1 0 - - -, f 5;
#X obj 391 178 *~ 0;
#X obj 419 138 hsl 32 8 0 1 0 0 empty empty empty -2 -8 0 10 -261197
-1 -1 0 1;
#X text 458 150 playback gain;
#X obj 391 118 player~ dopey 1;
#X msg 245 78 bang;
#X text 282 80 reload;
#X text 29 420 buffet~ - Various operations on contents of an array
;
#N canvas 34 269 705 565 scrambler 0;
#X obj 57 356 s buffet-msgs;
#X msg 57 153 minswap \$1;
#X floatatom 57 123 5 0 0 0 - - -, f 5;
#X floatatom 147 121 5 0 0 0 - - -, f 5;
#X msg 146 151 maxswap \$1;
#X floatatom 144 223 5 0 0 0 - - -, f 5;
#X msg 143 253 overlap \$1;
#X msg 145 194 30;
#X msg 224 256 retroblock;
#X msg 314 276 swap;
#X msg 172 335 specswap 0 1000 250;
#X obj 59 57 t b b b;
#X obj 58 28 loadbang;
#X text 187 120 minimum and maximum swap times in ms.;
#X text 155 209 fade time for tapering swap blocks (20 ms. by default)
;
#X text 226 240 reverse a piece of the buffer;
#X text 354 276 swap two pieces of the buffer;
#X text 177 357 specify which parts of buffer to exchange. arguments
are skip1 \, skip2 and duration. In this example the first 250 ms block
of the buffer is swapped with the 250 ms block beginning 1000 ms into
the buffer.;
#X text 165 26 Destructive rearrangement of buffer;
#X msg 200 479 autoredraw \$1;
#X obj 200 453 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
1;
#X text 217 452 turn off if redraw hurts performance;
#X msg 200 434 1;
#X obj 200 418 loadbang;
#X obj 316 141 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 315 164 metro 250;
#X msg 58 94 100;
#X msg 148 92 200;
#X obj 237 158 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X obj 236 181 metro 500;
#X connect 1 0 0 0;
#X connect 2 0 1 0;
#X connect 3 0 4 0;
#X connect 4 0 0 0;
#X connect 5 0 6 0;
#X connect 6 0 0 0;
#X connect 7 0 5 0;
#X connect 8 0 0 0;
#X connect 9 0 0 0;
#X connect 10 0 0 0;
#X connect 11 0 26 0;
#X connect 11 1 27 0;
#X connect 11 2 7 0;
#X connect 12 0 11 0;
#X connect 19 0 0 0;
#X connect 20 0 19 0;
#X connect 22 0 20 0;
#X connect 23 0 22 0;
#X connect 24 0 25 0;
#X connect 25 0 9 0;
#X connect 26 0 2 0;
#X connect 27 0 3 0;
#X connect 28 0 29 0;
#X connect 29 0 8 0;
#X restore 33 367 pd scrambler;
#N canvas 0 22 470 320 playback-controls 0;
#X obj 18 59 impulse~;
#X msg 19 31 bang;
#X text 57 31 retrigger;
#X msg 95 54 pause;
#X msg 144 55 resume;
#X msg 204 56 stop;
#X obj 18 129 outlet~;
#X obj 203 130 outlet;
#X msg 238 103 static_increment 1;
#X obj 238 84 loadbang;
#X obj 18 89 samm~ 40 1;
#X connect 0 0 10 0;
#X connect 1 0 0 0;
#X connect 3 0 10 0;
#X connect 4 0 10 0;
#X connect 5 0 7 0;
#X connect 8 0 7 0;
#X connect 9 0 8 0;
#X connect 10 0 6 0;
#X restore 391 74 pd playback-controls;
#X obj 23 13 cnv 15 160 25 empty empty LyonPotpourri 20 12 1 18 -260097
-204786 0;
#X connect 2 0 3 0;
#X connect 2 1 12 0;
#X connect 2 2 4 0;
#X connect 7 0 2 0;
#X connect 15 0 16 1;
#X connect 16 0 14 0;
#X connect 16 0 14 1;
#X connect 17 0 15 0;
#X connect 19 0 16 0;
#X connect 20 0 1 0;
#X connect 24 0 19 0;
#X connect 24 0 19 1;
#X connect 24 1 19 0;