Commit 529ee797 authored by ericlyon's avatar ericlyon

reinitialized files

parents
#include <math.h>
#include "PenroseOscil.h"
float frequencyToIncrement( float samplingRate, float frequency, int bufferLength ) {
return (frequency / samplingRate) * (float) bufferLength;
}
void makeSineBuffer( float *buffer, int bufferLength ) {
int i;
float myTwoPi = 8. * atan(1.);
for ( i=0; i <= bufferLength; i++ )
*(buffer+i) = sin( myTwoPi * ((float) i / (float) bufferLength) );
return;
}
float bufferOscil( float *phase, float increment, float *buffer,
int bufferLength )
{
float sample;
while ( *phase > bufferLength )
*phase -= bufferLength;
while ( *phase < 0. )
*phase += bufferLength;
sample = *( buffer + (int) (*phase) );
*phase += increment;
return sample;
}
#include "PenroseRand.h"
float rrand(int *seed)
{
int i = ((*seed = *seed * 1103515245 + 12345)>>16) & 077777;
return((float)i/16384. - 1.);
}
float prand(int *seed)
{
int i = ((*seed = *seed * 1103515245 + 12345)>>16) & 077777;
return((float)i/32768.);
}
Welcome to LyonPotpourri, version 3.0.
http://disis.music.vt.edu/eric/LyonSoftware/Pd/
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
- greater~ compares two signals on a per-sample basis
- 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
#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 = 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, sp[0]->s_n);
}
#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_float *a_samples;
t_int a_frames;
} 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, t_symbol *arrayname);
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"));
arrayname = atom_getsymbolarg(0, argc, argv);
arrayfilt_setarray(x,arrayname);
return x;
}
void arrayfilt_setarray(t_arrayfilt *x, t_symbol *arrayname)
{
t_garray *a;
if (!(a = (t_garray *)pd_findbyclass(arrayname, garray_class))) {
if (*arrayname->s_name) pd_error(x, "player~: %s: no such array", arrayname->s_name);
}
else {
garray_usedindsp(a);
if (!garray_getfloatarray(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_float *a_samples = x->a_samples;
t_int a_frames = x->a_frames;
int n = w[6];
int N2 = n / 2;
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];
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, sp[0]->s_n);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#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
This diff is collapsed.
#include "MSPd.h"
static t_class *bvplay_class;
#define OBJECT_NAME "bvplay~"
typedef struct {
float *b_samples;
long b_valid;
long b_nchans;
long b_frames;
} t_guffer; // stuff we care about from garrays and buffers
typedef struct _bvplay
{
t_object x_obj;
float x_f;
t_symbol *sfname; // name of soundfile
t_guffer *wavebuf; // store needed buffer or garray data
long object_chans; // number of channels for a given instantiation
float taper_dur;
int R;
int framesize;
float *notedata;
int active;
float buffer_duration;
int taper_frames;
float amp;
int start_frame;
int note_frames;
int end_frame;
float increment;
float findex;
int index ;
short verbose;
short mute;
} t_bvplay;
t_int *bvplay_perform_mono(t_int *w);
t_int *bvplay_perform_stereo(t_int *w);
void bvplay_dsp(t_bvplay *x, t_signal **sp);
void bvplay_set(t_bvplay *x, t_symbol *s);
void *bvplay_new(t_symbol *s, t_floatarg chan, t_floatarg taperdur);
void bvplay_notelist(t_bvplay *x, t_symbol *msg, short argc, t_atom *argv );
void bvplay_verbose(t_bvplay *x, t_floatarg t);
void bvplay_mute(t_bvplay *x, t_floatarg t);
void bvplay_taper(t_bvplay *x, t_floatarg t);
void bvplay_dsp_free(t_bvplay *x);
void bvplay_tilde_setup(void)
{
bvplay_class = class_new(gensym("bvplay~"),(t_newmethod)bvplay_new,
(t_method)bvplay_dsp_free, sizeof(t_bvplay), 0, A_SYMBOL, A_FLOAT, A_FLOAT,0);
CLASS_MAINSIGNALIN(bvplay_class,t_bvplay, x_f);
class_addmethod(bvplay_class,(t_method)bvplay_dsp,gensym("dsp"),A_CANT,0);
class_addmethod(bvplay_class,(t_method)bvplay_notelist,gensym("list"),A_GIMME,0);
class_addmethod(bvplay_class,(t_method)bvplay_verbose,gensym("verbose"),A_FLOAT,0);
class_addmethod(bvplay_class,(t_method)bvplay_mute,gensym("mute"),A_FLOAT,0);
class_addmethod(bvplay_class,(t_method)bvplay_taper,gensym("taper"),A_FLOAT,0);
potpourri_announce(OBJECT_NAME);
}
void bvplay_taper(t_bvplay *x, t_floatarg t)
{
if(t>0){
x->taper_dur = (float)t/1000.0;
x->taper_frames = x->R * x->taper_dur;
}
}
void bvplay_mute(t_bvplay *x, t_floatarg f)
{
x->mute = (short)f;
}
void bvplay_verbose(t_bvplay *x, t_floatarg f)
{
x->verbose = (short)f;
}
void bvplay_notelist(t_bvplay *x, t_symbol *msg, short argc, t_atom *argv)
{
if( x->active ){
if( x->verbose )
error("object still playing - cannot add note!");
return;
}
bvplay_set(x, x->sfname);
if(! x->wavebuf->b_valid){
post("%s: no valid buffer yet",OBJECT_NAME);
return;
}
// read note data
if( argc != 4 ){
if( x->verbose ){
post("improper note data");
post("notelist parameters: skiptime, duration, increment, amplitude");
}
}
x->notedata[0] = atom_getfloatarg(0,argc,argv) / 1000.0;
x->notedata[1] = atom_getfloatarg(1,argc,argv) / 1000.0;
x->notedata[2] = atom_getfloatarg(2,argc,argv);
x->notedata[3] = atom_getfloatarg(3,argc,argv);
x->start_frame = x->notedata[0] * x->R;
x->increment = x->notedata[2];
x->index = x->findex = x->start_frame;
if( x->increment == 0.0 ){
if( x->verbose )
post("zero increment!");
return;
}
x->note_frames = x->notedata[1] * x->increment * x->R;
x->end_frame = x->start_frame + x->note_frames;
x->amp = x->notedata[3];
if( x->start_frame < 0 || x->start_frame >= x->wavebuf->b_frames){
if( x->verbose )
post("%s: bad start time",OBJECT_NAME);
return;
}
if( x->end_frame < 0 || x->end_frame >= x->wavebuf->b_frames){
if( x->verbose )
post("%s: bad end time",OBJECT_NAME);
return;
}
x->active = 1;
}
t_int *bvplay_perform_mono(t_int *w)
{
t_bvplay *x = (t_bvplay *)(w[1]);
t_float *out = (t_float *)(w[2]);
t_int n = w[3];
float *tab;