lua markov generator
i build a lua markov generator inspired from this python code with the idea to use it with pure data / ofelia: https://eli.thegreenplace.net/2018/elegant-python-code-for-a-markov-chain-text-generator/
finally the code works fine with the eclipse lua ide or with this ide https://studio.zerobrane.com/, but somehow not yet with pure data / ofelia.
here is the (not yet working) patch: ofelia_markov.pd
and here the lua code: markov_pd.lua
math.randomseed(os.time()- os.clock() * 1000);
-- make dictionary;
function defaultdict(default_value_factory);
local t = {};
local metatable = {};
metatable.__index = function(t, key);
if not rawget(t, key) then;
rawset(t, key, default_value_factory(key));
end;
return rawget(t, key);
end;
return setmetatable(t, metatable);
end;
;
;
-- make markov matrix;
print('Learning model...')
;
STATE_LEN = 3;
print ("markov order: " , STATE_LEN)
model = defaultdict(function() return {} end)
data = "00001111010100700111101010000005000700111111177111111";
datasize = #data;
print("data: ", data);
print("datasize: ", #data);
data = data .. data:sub(1, STATE_LEN);
print("altered data: ", data);
print("altered datasize: ", #data);
for i = 1, (#data - STATE_LEN) do;
state = data:sub(i, i + STATE_LEN-1);
-- print("state: ", state)
local next = data:sub(i + STATE_LEN, i + STATE_LEN);
-- print("next: ", next);
model[state][next] = (model[state][next] or 0)+1;
end;
;
;
-- make markov chain;
print('Sampling...');
;
local keyTbl = {};
local nexTbl = {};
local prbTbl = {};
for key, value in pairs(model) do;
for k, v in pairs(value) do;
table.insert(keyTbl, key);
table.insert(nexTbl, k);
table.insert(prbTbl, v);
end;
end;
print ("keyTbl: ", table.unpack(keyTbl));
print ("nexTbl: ", table.unpack(nexTbl));
print ("prbTbl: ", table.unpack(prbTbl));
;
;
-- make random key;
local randomKey = keyTbl[math.random(#keyTbl)];
state = randomKey;
print("RandomKey: ", randomKey);
;
-- make table from random key;
local str = state;
local stateTable = {};
for i = 1, #str do;
stateTable[i] = str:sub(i, i);
end;
;
out = stateTable;
print ("random key as table: ", table.unpack(out));
;
-- make markov chain;
for i = 1, datasize do;
;
-- weighted random choices;
local choices = {};
local weights = {};
for j = 1, #keyTbl do;
if state == keyTbl[j] then;
table.insert(choices, nexTbl[j]);
table.insert(weights, prbTbl[j]);
end;
end;
-- print ("choices:",table.unpack(choices));
-- print ("weights:",table.unpack(weights));
;
local totalWeight = 0;
for _, weight in pairs(weights) do;
totalWeight = totalWeight + weight;
end;
rand = math.random() * totalWeight;
local choice = nil;
for i, weight in pairs(weights) do;
if rand < weight then;
choice = choices[i];
choice = choice:sub(1,1);
break;
else;
rand = rand - weight;
end;
end;
;
table.insert(out, choice);
state = string.sub(state, 2, #state) .. out[#out];
-- print("choice", choice);
-- print ("state", state);
end;
;
print("markov chain: ", table.concat(out));
somehow pure data / ofelia interprets the nexTbl values as a functions while they are strings?
this is part of what the pure data console prints: nexTbl: function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30 function: 0000000003B9BF30
ofelia: [string "package.preload['#d41b70'] = nil package.load..."]:93: attempt to index a function value (local 'choice')
and this ist the output from the lua ide:
Program 'lua.exe' started in 'C:\Users\Jonat\Downloads\ZeroBraneStudio\myprograms' (pid: 220).
Learning model...
markov order: 1
data: 00001111010100700111101010000005000700111111177111111
datasize: 53
altered data: 000011110101007001111010100000050007001111111771111110
altered datasize: 54
Sampling...
keyTbl: 5 7 7 7 1 1 1 0 0 0 0
nexTbl: 0 0 1 7 7 1 0 5 7 1 0
prbTbl: 1 2 1 1 1 17 7 1 2 7 13
RandomKey: 1
random key as table: 1
markov chain: 111111000077701111100070001100000001100017011171111117
Program completed in 0.06 seconds (pid: 220).
[small job offer] porting max external to pd
Edit 1: Took a shot porting it in this little textarea. Probably doesn't compile yet...
Edit 2: Ok, this should compile now. I haven't actually tried to instantiate it yet, though. It's possible I set it up with the wrong number of xlets.
Edit 3: Seems to instantiate ok. It appears it doesn't take signal input so the CLASS_MAINSIGNALIN macro is neccessary. Just comment that part out to make it a control signal.
Note-- in my port it's called [vb_fourses~]
for the reason noted below.
I have no idea if the algorithm behaves correctly, but it does output sound.
Btw-- AFAICT you should be able to compile this external for the 64-bit version of Purr Data and it should work properly. It doesn't require a special 64-bit codepath in Pd so I commented that part out.
Btw 2-- there should probably be a "best practices" rule that states you can only name your class something that is a legal C function name. Because this class doesn't follow that practice I made a mistake in the port. Further, the user will make a mistake because I had to change the class name. If I had instead made the setup function a different name than the creator I would create an additional problem that would force users to declare the lib before using it. Bad all around, and not worth whatever benefit there is to naming a class "foo.bar" instead of "foo_bar"
/*
#include "ext.h"
#include "ext_obex.h"
#include "z_dsp.h"
#include "ext_common.h"
*/
#include "m_pd.h"
#include "math.h"
/*
a chaotic oscillator network
based on descriptions of the 'fourses system' by ciat-lonbarde
www.ciat-lonbarde.net
07.april 2013, volker b?hm
*/
#define NUMFOURSES 4
static void *myObj_class;
typedef struct {
// this is a horse... basically a ramp generator
double val;
double inc;
double dec;
double adder;
double incy, incym1; // used for smoothing
double decy, decym1; // used for smoothing
} t_horse;
typedef struct {
t_object x_obj;
double r_sr;
t_horse fourses[NUMFOURSES+2]; // four horses make a fourse...
double smoother;
t_sample x_f;
} t_myObj;
// absolute limits
static void myObj_hilim(t_myObj *x, t_floatarg input);
static void myObj_lolim(t_myObj *x, t_floatarg input);
// up and down freqs for all oscillators
static void myObj_upfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4);
static void myObj_downfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4);
static void myObj_smooth(t_myObj *x, t_floatarg input);
static void myObj_info(t_myObj *x);
// DSP methods
static void myObj_dsp(t_myObj *x, t_signal **sp);
static t_int *myObj_perform(t_int *w);
//void myObj_dsp64(t_myObj *x, t_object *dsp64, short *count, double samplerate,
// long maxvectorsize, long flags);
//void myObj_perform64(t_myObj *x, t_object *dsp64, double **ins, long numins,
// double **outs, long numouts, long sampleframes, long flags, void *userparam);
//
static void *myObj_new( t_symbol *s, int argc, t_atom *argv);
//void myObj_assist(t_myObj *x, void *b, long m, long a, char *s);
void vb_fourses_tilde_setup(void) {
t_class *c;
myObj_class = class_new(gensym("vb_fourses~"), (t_newmethod)myObj_new, 0, sizeof(t_myObj),
0, A_GIMME, NULL);
c = myObj_class;
class_addmethod(c, (t_method)myObj_dsp, gensym("dsp"), A_CANT, 0);
// class_addmethod(c, (t_method)myObj_dsp64, gensym("dsp64"), A_CANT, 0);
class_addmethod(c, (t_method)myObj_smooth, gensym("smooth"), A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_hilim, gensym("hilim"), A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_lolim, gensym("lolim"), A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_upfreq, gensym("upfreq"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_downfreq, gensym("downfreq"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_info, gensym("info"), 0);
//class_addmethod(c, (t_method)myObj_assist, "assist", A_CANT,0);
CLASS_MAINSIGNALIN(myObj_class, t_myObj, x_f);
// class_dspinit(c);
// class_register(CLASS_BOX, c);
post("vb_fourses~ by volker b?hm\n");
// return 0;
}
static void myObj_smooth(t_myObj *x, t_floatarg input) {
// input = CLAMP(input, 0., 1.);
if (input < 0.) input = 0;
if (input > 1.) input = 1;
x->smoother = 0.01 - pow(input,0.2)*0.01;
}
static void myObj_hilim(t_myObj *x, t_floatarg input) {
x->fourses[0].val = input; // store global high limit in fourses[0]
}
static void myObj_lolim(t_myObj *x, t_floatarg input) {
x->fourses[5].val = input; // store global low limit in fourses[5]
}
static void myObj_upfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4) {
x->fourses[1].inc = fabs(freq1)*4*x->r_sr;
x->fourses[2].inc = fabs(freq2)*4*x->r_sr;
x->fourses[3].inc = fabs(freq3)*4*x->r_sr;
x->fourses[4].inc = fabs(freq4)*4*x->r_sr;
}
static void myObj_downfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4) {
x->fourses[1].dec = fabs(freq1)*-4*x->r_sr;
x->fourses[2].dec = fabs(freq2)*-4*x->r_sr;
x->fourses[3].dec = fabs(freq3)*-4*x->r_sr;
x->fourses[4].dec = fabs(freq4)*-4*x->r_sr;
}
//#pragma mark 64bit dsp-loop ------------------
//void myObj_dsp64(t_myObj *x, t_object *dsp64, short *count, double samplerate,
// long maxvectorsize, long flags) {
// object_method(dsp64, gensym("dsp_add64"), x, myObj_perform64, 0, NULL);
//
// if(samplerate<=0) x->r_sr = 1.0/44100.0;
// else x->r_sr = 1.0/samplerate;
//
//
//}
//static void myObj_perform64(t_myObj *x, t_object *dsp64, double **ins, long numins,
// double **outs, long numouts, long sampleframes, long flags, void *userparam){
//
// t_double **output = outs;
// int vs = sampleframes;
// t_horse *fourses = x->fourses;
// double val, c, hilim, lolim;
// int i, n;
//
// if (x->x_obj.z_disabled)
// return;
//
// c = x->smoother;
// hilim = fourses[0].val;
// lolim = fourses[5].val;
//
// for(i=0; i<vs; i++)
// {
// for(n=1; n<=NUMFOURSES; n++) {
// // smoother
// fourses[n].incy = fourses[n].inc*c + fourses[n].incym1*(1-c);
// fourses[n].incym1 = fourses[n].incy;
//
// fourses[n].decy = fourses[n].dec*c + fourses[n].decym1*(1-c);
// fourses[n].decym1 = fourses[n].decy;
//
// val = fourses[n].val;
// val += fourses[n].adder;
//
// if(val <= fourses[n+1].val || val <= lolim ) {
// fourses[n].adder = fourses[n].incy;
// }
// else if( val >= fourses[n-1].val || val >= hilim ) {
// fourses[n].adder = fourses[n].decy;
// }
//
// output[n-1][i] = val;
//
// fourses[n].val = val;
// }
// }
//
// return;
//
//}
//#pragma mark 32bit dsp-loop ------------------
static void myObj_dsp(t_myObj *x, t_signal **sp)
{
dsp_add(myObj_perform, 6, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
if(sp[0]->s_sr<=0)
x->r_sr = 1.0/44100.0;
else x->r_sr = 1.0/sp[0]->s_sr;
}
static t_int *myObj_perform(t_int *w)
{
t_myObj *x = (t_myObj*)(w[1]);
t_float *out1 = (float *)(w[2]);
t_float *out2 = (float *)(w[3]);
t_float *out3 = (float *)(w[4]);
t_float *out4 = (float *)(w[5]);
int vs = (int)(w[6]);
// Hm... not sure about this member. I don't think we can disable individual
// objects in Pd...
// if (x->x_obj.z_disabled)
// goto out;
t_horse *fourses = x->fourses;
double val, c, hilim, lolim;
int i, n;
c = x->smoother;
hilim = fourses[0].val;
lolim = fourses[5].val;
for(i=0; i<vs; i++)
{
for(n=1; n<=NUMFOURSES; n++) {
// smoother
fourses[n].incy = fourses[n].inc*c + fourses[n].incym1*(1-c);
fourses[n].incym1 = fourses[n].incy;
fourses[n].decy = fourses[n].dec*c + fourses[n].decym1*(1-c);
fourses[n].decym1 = fourses[n].decy;
val = fourses[n].val;
val += fourses[n].adder;
if(val <= fourses[n+1].val || val <= lolim ) {
fourses[n].adder = fourses[n].incy;
}
else if( val >= fourses[n-1].val || val >= hilim ) {
fourses[n].adder = fourses[n].decy;
}
fourses[n].val = val;
}
out1[i] = fourses[1].val;
out2[i] = fourses[2].val;
out3[i] = fourses[3].val;
out4[i] = fourses[4].val;
}
//out:
return w+7;
}
static void myObj_info(t_myObj *x) {
int i;
// only fourses 1 to 4 are used
post("----- fourses.info -------");
for(i=1; i<=NUMFOURSES; i++) {
post("fourses[%ld].val = %f", i, x->fourses[i].val);
post("fourses[%ld].inc = %f", i, x->fourses[i].inc);
post("fourses[%ld].dec = %f", i, x->fourses[i].dec);
post("fourses[%ld].adder = %f", i, x->fourses[i].adder);
}
post("------ end -------");
}
void *myObj_new(t_symbol *s, int argc, t_atom *argv)
{
t_myObj *x = (t_myObj *)pd_new(myObj_class);
// dsp_setup((t_pxobject*)x, 0);
outlet_new((t_object *)x, &s_signal);
outlet_new((t_object *)x, &s_signal);
outlet_new((t_object *)x, &s_signal);
outlet_new((t_object *)x, &s_signal);
x->r_sr = 1.0/sys_getsr();
if(sys_getsr() <= 0)
x->r_sr = 1.0/44100.f;
int i;
for(i=1; i<=NUMFOURSES; i++) {
x->fourses[i].val = 0.;
x->fourses[i].inc = 0.01;
x->fourses[i].dec = -0.01;
x->fourses[i].adder = x->fourses[i].inc;
}
x->fourses[0].val = 1.; // dummy 'horse' only used as high limit for fourses[1]
x->fourses[5].val = -1.; // dummy 'horse' only used as low limit for fourses[4]
x->smoother = 0.01;
return x;
}
//void myObj_assist(t_myObj *x, void *b, long m, long a, char *s) {
// if (m==1) {
// switch(a) {
// case 0: sprintf (s,"message inlet"); break;
// }
// }
// else {
// switch(a) {
// case 0: sprintf (s,"(signal) signal out osc1"); break;
// case 1: sprintf(s, "(signal) signal out osc2"); break;
// case 2: sprintf(s, "(signal) signal out osc3"); break;
// case 3: sprintf(s, "(signal) signal out osc4"); break;
// }
//
// }
//}
Purr Data 2.5.0
ok dependencies seems to be ok...this is my log
fremen@fremenCPU MINGW64 ~
$ pacman -S autoconf automake git libtool \
make mingw-w64-x86_64-dlfcn mingw-w64-x86_64-fftw
mingw-w64-x86_64-fluidsynth
mingw-w64-x86_64-ftgl mingw-w64-x86_64-fribidi
mingw-w64-x86_64-ladspa-sdk mingw-w64-x86_64-lame
mingw-w64-x86_64-libsndfile mingw-w64-x86_64-libvorbis
mingw-w64-x86_64-lua mingw-w64-x86_64-toolchain
mingw-w64-x86_64-libjpeg-turbo
rsync unzip wget
warning: autoconf-2.69-3 is up to date -- reinstalling
warning: automake-wrapper-10-1 is up to date -- reinstalling
warning: git-2.10.1-1 is up to date -- reinstalling
warning: libtool-2.4.6-2 is up to date -- reinstalling
warning: make-4.2.1-1 is up to date -- reinstalling
:: There are 16 members in group mingw-w64-x86_64-toolchain:
:: Repository mingw64
- mingw-w64-x86_64-binutils 2) mingw-w64-x86_64-crt-git
- mingw-w64-x86_64-gcc 4) mingw-w64-x86_64-gcc-ada
- mingw-w64-x86_64-gcc-fortran 6) mingw-w64-x86_64-gcc-libgfortran
- mingw-w64-x86_64-gcc-libs
mingw-w64-x86_64-gcc-objc
- mingw-w64-x86_64-gdb 10) mingw-w64-x86_64-headers-git
- mingw-w64-x86_64-libmangle-git 12) mingw-w64-x86_64-libwinpthread-git
- mingw-w64-x86_64-make 14) mingw-w64-x86_64-pkg-config
- mingw-w64-x86_64-tools-git 16) mingw-w64-x86_64-winpthreads-git
Enter a selection (default=all):
warning: mingw-w64-x86_64-binutils-2.27-2 is up to date -- reinstalling
warning: mingw-w64-x86_64-crt-git-5.0.0.4745.d2384c2-1 is up to date -- reinstal ling
warning: mingw-w64-x86_64-gcc-6.2.0-2 is up to date -- reinstalling
warning: mingw-w64-x86_64-gcc-libgfortran-6.2.0-2 is up to date -- reinstalling
warning: mingw-w64-x86_64-gcc-libs-6.2.0-2 is up to date -- reinstalling
warning: mingw-w64-x86_64-headers-git-5.0.0.4747.0f8f626-1 is up to date -- rein stalling
warning: mingw-w64-x86_64-libwinpthread-git-5.0.0.4741.2c8939a-1 is up to date - - reinstalling
warning: mingw-w64-x86_64-winpthreads-git-5.0.0.4741.2c8939a-1 is up to date -- reinstalling
warning: unzip-6.0-2 is up to date -- reinstalling
warning: wget-1.18-1 is up to date -- reinstalling
resolving dependencies...
looking for conflicting packages...
warning: dependency cycle detected:
warning: mingw-w64-x86_64-gcc-libgfortran will be installed before its mingw-w64 -x86_64-gcc-libs dependency
warning: dependency cycle detected:
warning: mingw-w64-x86_64-harfbuzz will be installed before its mingw-w64-x86_64 -freetype dependency
warning: dependency cycle detected:
warning: mingw-w64-x86_64-cairo will be installed before its mingw-w64-x86_64-fr eetype dependency
warning: dependency cycle detected:
warning: mingw-w64-x86_64-fontconfig will be installed before its mingw-w64-x86_ 64-freetype dependency
Packages (58) mingw-w64-x86_64-cairo-1.15.2-4 mingw-w64-x86_64-flac-1.3.1-2
mingw-w64-x86_64-fontconfig-2.12.0-2
mingw-w64-x86_64-freetype-2.7-1 mingw-w64-x86_64-gdbm-1.12-1
mingw-w64-x86_64-glib2-2.50.1-2
mingw-w64-x86_64-graphite2-1.3.8-5
mingw-w64-x86_64-harfbuzz-1.3.2-1
mingw-w64-x86_64-libogg-1.3.2-2 mingw-w64-x86_64-libpng-1.6.26-1
mingw-w64-x86_64-ncurses-6.0.20161001-1
mingw-w64-x86_64-pcre-8.38-1 mingw-w64-x86_64-pixman-0.34.0-3
mingw-w64-x86_64-portaudio-19_20140130-2
mingw-w64-x86_64-python2-2.7.12-1
mingw-w64-x86_64-readline-6.3.008-1
mingw-w64-x86_64-speex-1.2rc2-2
mingw-w64-x86_64-speexdsp-1.2rc3-2 mingw-w64-x86_64-tcl-8.6.6-1
mingw-w64-x86_64-termcap-1.3.1-2 mingw-w64-x86_64-tk-8.6.6-1
mingw-w64-x86_64-wineditline-2.101-4 winpty-0.4.0-2
autoconf-2.69-3 automake-wrapper-10-1 git-2.10.1-1
libtool-2.4.6-2 make-4.2.1-1 mingw-w64-x86_64-binutils-2.27-2
mingw-w64-x86_64-crt-git-5.0.0.4745.d2384c2-1
mingw-w64-x86_64-dlfcn-1.0.0-2 mingw-w64-x86_64-fftw-3.3.5-1
mingw-w64-x86_64-fluidsynth-1.1.6-3
mingw-w64-x86_64-fribidi-0.19.7-1
mingw-w64-x86_64-ftgl-2.1.3rc5-2 mingw-w64-x86_64-gcc-6.2.0-2
mingw-w64-x86_64-gcc-ada-6.2.0-2
mingw-w64-x86_64-gcc-fortran-6.2.0-2
mingw-w64-x86_64-gcc-libgfortran-6.2.0-2
mingw-w64-x86_64-gcc-libs-6.2.0-2
mingw-w64-x86_64-gcc-objc-6.2.0-2 mingw-w64-x86_64-gdb-7.12-1
mingw-w64-x86_64-headers-git-5.0.0.4747.0f8f626-1
mingw-w64-x86_64-ladspa-sdk-1.13-2
mingw-w64-x86_64-lame-3.99.5-4
mingw-w64-x86_64-libjpeg-turbo-1.5.1-1
mingw-w64-x86_64-libmangle-git-5.0.0.4669.7de6266-1
mingw-w64-x86_64-libsndfile-1.0.26-1
mingw-w64-x86_64-libvorbis-1.3.5-1
mingw-w64-x86_64-libwinpthread-git-5.0.0.4741.2c8939a-1
mingw-w64-x86_64-lua-5.3.3-1
mingw-w64-x86_64-make-4.1.2351.a80a8b8-1
mingw-w64-x86_64-pkg-config-0.29.1-2
mingw-w64-x86_64-tools-git-5.0.0.4669.7de6266-1
mingw-w64-x86_64-winpthreads-git-5.0.0.4741.2c8939a-1
rsync-3.1.2-2 unzip-6.0-2 wget-1.18-1
Total Download Size: 76.81 MiB
Total Installed Size: 749.00 MiB
Net Upgrade Size: 369.69 MiB
:: Proceed with installation? [Y/n] Y
:: Retrieving packages...
mingw-w64-x86_64-dl... 9.6 KiB 9.41M/s 00:00 [#####################] 100%
mingw-w64-x86_64-ff... 4.0 MiB 1146K/s 00:04 [#####################] 100%
mingw-w64-x86_64-wi... 32.7 KiB 6.39M/s 00:00 [#####################] 100%
mingw-w64-x86_64-pc... 859.1 KiB 1252K/s 00:01 [#####################] 100%
mingw-w64-x86_64-gl... 2.9 MiB 1247K/s 00:02 [#####################] 100%
mingw-w64-x86_64-li... 191.2 KiB 7.18M/s 00:00 [#####################] 100%
mingw-w64-x86_64-fl... 582.7 KiB 1588K/s 00:00 [#####################] 100%
mingw-w64-x86_64-li... 331.2 KiB 1761K/s 00:00 [#####################] 100%
mingw-w64-x86_64-sp... 472.2 KiB 1349K/s 00:00 [#####################] 100%
mingw-w64-x86_64-sp... 519.0 KiB 1458K/s 00:00 [#####################] 100%
mingw-w64-x86_64-li... 359.9 KiB 1874K/s 00:00 [#####################] 100%
mingw-w64-x86_64-po... 143.6 KiB 7.01M/s 00:00 [#####################] 100%
mingw-w64-x86_64-fl... 252.2 KiB 1425K/s 00:00 [#####################] 100%
mingw-w64-x86_64-fo... 220.8 KiB 1284K/s 00:00 [#####################] 100%
mingw-w64-x86_64-pi... 289.5 KiB 1591K/s 00:00 [#####################] 100%
mingw-w64-x86_64-ca... 755.8 KiB 1423K/s 00:01 [#####################] 100%
mingw-w64-x86_64-gr... 167.0 KiB 7.09M/s 00:00 [#####################] 100%
mingw-w64-x86_64-ha... 314.4 KiB 1700K/s 00:00 [#####################] 100%
mingw-w64-x86_64-li... 285.9 KiB 1571K/s 00:00 [#####################] 100%
mingw-w64-x86_64-fr... 503.3 KiB 1422K/s 00:00 [#####################] 100%
mingw-w64-x86_64-ft... 118.8 KiB 7.25M/s 00:00 [#####################] 100%
mingw-w64-x86_64-fr... 93.4 KiB 7.02M/s 00:00 [#####################] 100%
mingw-w64-x86_64-la... 8.3 KiB 8.13M/s 00:00 [#####################] 100%
mingw-w64-x86_64-la... 373.9 KiB 1928K/s 00:00 [#####################] 100%
mingw-w64-x86_64-lu... 269.6 KiB 1506K/s 00:00 [#####################] 100%
mingw-w64-x86_64-gc... 18.0 MiB 1203K/s 00:15 [#####################] 100%
mingw-w64-x86_64-gc... 8.1 MiB 1209K/s 00:07 [#####################] 100%
mingw-w64-x86_64-gc... 13.6 MiB 1202K/s 00:12 [#####################] 100%
mingw-w64-x86_64-gd... 164.1 KiB 6.97M/s 00:00 [#####################] 100%
mingw-w64-x86_64-nc... 1697.2 KiB 1237K/s 00:01 [#####################] 100%
mingw-w64-x86_64-te... 12.6 KiB 12.3M/s 00:00 [#####################] 100%
mingw-w64-x86_64-re... 327.4 KiB 1732K/s 00:00 [#####################] 100%
mingw-w64-x86_64-tc... 2.9 MiB 1242K/s 00:02 [#####################] 100%
mingw-w64-x86_64-tk... 1873.6 KiB 1218K/s 00:02 [#####################] 100%
mingw-w64-x86_64-py... 11.2 MiB 1216K/s 00:09 [#####################] 100%
mingw-w64-x86_64-gd... 2.9 MiB 1234K/s 00:02 [#####################] 100%
mingw-w64-x86_64-li... 26.7 KiB 6.51M/s 00:00 [#####################] 100%
mingw-w64-x86_64-ma... 103.2 KiB 7.20M/s 00:00 [#####################] 100%
mingw-w64-x86_64-pk... 237.5 KiB 1357K/s 00:00 [#####################] 100%
mingw-w64-x86_64-to... 257.4 KiB 1446K/s 00:00 [#####################] 100%
mingw-w64-x86_64-li... 379.7 KiB 1957K/s 00:00 [#####################] 100%
winpty-0.4.0-2-x86_64 495.6 KiB 1404K/s 00:00 [#####################] 100%
rsync-3.1.2-2-x86_64 259.9 KiB 1460K/s 00:00 [#####################] 100%
wget-1.18-1-x86_64 582.1 KiB 1595K/s 00:00 [#####################] 100%
(58/58) checking keys in keyring [#####################] 100%
(58/58) checking package integrity [#####################] 100%
(58/58) loading package files [#####################] 100%
(58/58) checking for file conflicts [#####################] 100%
(58/58) checking available disk space [#####################] 100%
warning: could not get file information for usr/share/man/man3/Git::I18N.3pm.gz
warning: could not get file information for usr/share/man/man3/Git::SVN::Editor. 3pm.gz
warning: could not get file information for usr/share/man/man3/Git::SVN::Fetcher .3pm.gz
warning: could not get file information for usr/share/man/man3/Git::SVN::Memoize ::YAML.3pm.gz
warning: could not get file information for usr/share/man/man3/Git::SVN::Prompt. 3pm.gz
warning: could not get file information for usr/share/man/man3/Git::SVN::Ra.3pm. gz
warning: could not get file information for usr/share/man/man3/Git::SVN::Utils.3 pm.gz
:: Processing package changes...
( 1/58) reinstalling autoconf [#####################] 100%
( 2/58) reinstalling automake-wrapper [#####################] 100%
( 3/58) reinstalling git [#####################] 100%
( 4/58) reinstalling libtool [#####################] 100%
( 5/58) reinstalling make [#####################] 100%
( 6/58) reinstalling mingw-w64-x86_64-libwinpt... [#####################] 100%
( 7/58) reinstalling mingw-w64-x86_64-gcc-libg... [#####################] 100%
( 8/58) reinstalling mingw-w64-x86_64-gcc-libs [#####################] 100%
( 9/58) installing mingw-w64-x86_64-dlfcn [#####################] 100%
(10/58) installing mingw-w64-x86_64-fftw [#####################] 100%
(11/58) installing mingw-w64-x86_64-wineditline [#####################] 100%
(12/58) installing mingw-w64-x86_64-pcre [#####################] 100%
(13/58) installing mingw-w64-x86_64-glib2 [#####################] 100%
No schema files found: doing nothing.
(14/58) installing mingw-w64-x86_64-libogg [#####################] 100%
(15/58) installing mingw-w64-x86_64-flac [#####################] 100%
(16/58) installing mingw-w64-x86_64-libvorbis [#####################] 100%
(17/58) installing mingw-w64-x86_64-speexdsp [#####################] 100%
(18/58) installing mingw-w64-x86_64-speex [#####################] 100%
(19/58) installing mingw-w64-x86_64-libsndfile [#####################] 100%
(20/58) installing mingw-w64-x86_64-portaudio [#####################] 100%
(21/58) installing mingw-w64-x86_64-fluidsynth [#####################] 100%
(22/58) installing mingw-w64-x86_64-fontconfig [#####################] 100%
Fontconfig configuration is done via /mingw64/etc/fonts/conf.avail and conf.d.
Read /mingw64/etc/fonts/conf.d/README for more information.
updating font cache... C:/msys64/mingw64/bin/fc-cache.exe: error while loading s hared libraries: ?: cannot open shared object file: No such file or directory
done.
(23/58) installing mingw-w64-x86_64-pixman [#####################] 100%
(24/58) installing mingw-w64-x86_64-cairo [#####################] 100%
Optional dependencies for mingw-w64-x86_64-cairo
mingw-w64-x86_64-glib2: libcairo-gobject [installed]
(25/58) installing mingw-w64-x86_64-graphite2 [#####################] 100%
(26/58) installing mingw-w64-x86_64-harfbuzz [#####################] 100%
Optional dependencies for mingw-w64-x86_64-harfbuzz
mingw-w64-x86_64-icu: harfbuzz-icu support
(27/58) installing mingw-w64-x86_64-libpng [#####################] 100%
(28/58) installing mingw-w64-x86_64-freetype [#####################] 100%
(29/58) installing mingw-w64-x86_64-ftgl [#####################] 100%
(30/58) installing mingw-w64-x86_64-fribidi [#####################] 100%
(31/58) installing mingw-w64-x86_64-ladspa-sdk [#####################] 100%
(32/58) installing mingw-w64-x86_64-lame [#####################] 100%
(33/58) installing winpty [#####################] 100%
(34/58) installing mingw-w64-x86_64-lua [#####################] 100%
(35/58) reinstalling mingw-w64-x86_64-binutils [#####################] 100%
(36/58) reinstalling mingw-w64-x86_64-headers-git [#####################] 100%
(37/58) reinstalling mingw-w64-x86_64-crt-git [#####################] 100%
(38/58) reinstalling mingw-w64-x86_64-winpthre... [#####################] 100%
(39/58) reinstalling mingw-w64-x86_64-gcc [#####################] 100%
(40/58) installing mingw-w64-x86_64-gcc-ada [#####################] 100%
(41/58) installing mingw-w64-x86_64-gcc-fortran [#####################] 100%
(42/58) installing mingw-w64-x86_64-gcc-objc [#####################] 100%
(43/58) installing mingw-w64-x86_64-gdbm [#####################] 100%
(44/58) installing mingw-w64-x86_64-ncurses [#####################] 100%
(45/58) installing mingw-w64-x86_64-termcap [#####################] 100%
(46/58) installing mingw-w64-x86_64-readline [#####################] 100%
(47/58) installing mingw-w64-x86_64-tcl [#####################] 100%
(48/58) installing mingw-w64-x86_64-tk [#####################] 100%
(49/58) installing mingw-w64-x86_64-python2 [#####################] 100%
(50/58) installing mingw-w64-x86_64-gdb [#####################] 100%
(51/58) installing mingw-w64-x86_64-libmangle-git [#####################] 100%
(52/58) installing mingw-w64-x86_64-make [#####################] 100%
(53/58) installing mingw-w64-x86_64-pkg-config [#####################] 100%
(54/58) installing mingw-w64-x86_64-tools-git [#####################] 100%
(55/58) installing mingw-w64-x86_64-libjpeg-turbo [#####################] 100%
(56/58) installing rsync [#####################] 100%
(57/58) reinstalling unzip [#####################] 100%
(58/58) reinstalling wget [#####################] 100%
Build a MIDI controller with the Arduino, Firmata and Pure Data
Time to start contributing some knowledge back to the wonderful world that is the internet; today, a step by step nice and easy tutorial on getting started to building your own MIDI controllers with the arduino.
When researching for my ableton controller project, I didn’t find much out there about using firmata on an arduino to send data to software. The standard approach just seemed to be create the code in the arduino language, upload it to your board and hack one of those MIDI to USB cables as a bodge job way of getting the MIDI out of the arduino.
So why firmata and pure data? Well the whole idea of firmata is that you flash it to your arduino, and it throws out serial about whats going on with the arduino inputs and outputs, then you decide how the software treats the readings coming in and going out.
Theory out the way, lets build some controllers. You’ll need a few things…
HARDWARE:
An arduino and something to wire into it (for this i’ll be using a pot)
A USB cable for your arduino
SOFTWARE:
Arduino – http://arduino.cc/en/Main/Software
Pure Data – http://puredata.info/downloads
Firmata – http://at.or.at/hans/pd/objects.html#pduino
Something to patch your new controller into; like Reason or Ableton Live
- SETTING UP FIRMATA AND PURE DATA
Install Pure Data and create a folder to store all your patches somewhere. Unzip Firmata and add the files ‘arduino.pd’, ‘arduino-test.pd’ and ‘arduino-help.pd’ to your new Pure Data folder. The ‘arduino.pd’ file is the object that we use in PD for opening up communication with your arduino and routing it to PD. Done? Awesome, your software is almost set up.
- FLASHING FIRMATA TO YOUR ARDUINO
Install the latest version of arduino and open it up. Connect your arduino with the USB cable to your laptop (i’m using a macbook for this by the way). In the example patches, open up “Standard Firmata”, select your board (im using an arduino mega), and your serial port (look for tty.usbserial for use with a USB cable). Then compile and hit the upload button and your arduino is now ready to use firmata and communicate with Pure Data!
- WIRING UP A POT
Potentiometers are cool, and theres a great arduino tutorial of how to wire one up here: http://www.arduino.cc/en/Tutorial/Potentiometer
Basically, all you need to know is that there are three pins; your two outer pins govern voltage flow across the pot, meaning one has to be 5V and the other has to be ground. It doesn’t matter which, but your 5v pin is going to be where your pot reads maximum, so convention dictates this should be the right hand pin. The center pin needs to be connected to an analog in on the arduino and will read the value of the pot as it sweeps from ground (0v) to 5v.
All wired up? Plug it into your laptop and open Pure Data, we’re ready to get things talking.
- SETTING UP OUR PATCH
Open the example “arduino-test.pd” Pure Data patch you copied over earlier. It should look like this one…
The test patch has everything we need to open a connection and enable pins. Firstly, lets delete a bunch of stuff and make our window a bit bigger. Hit Command + E to enter edit mode in Pure Data.
Ok a quick explaination; the key component here is the ‘arduino’ object. This is being drawn from the file you copied in earlier, and is what communicated with your arduino. Here we can do everything to control the arduino from opening a connection, to receiving data.
The large grid allows us to set the mode of each pin on the arduino. Remember pins 0 and 1 are reserved for Rx and Tx. I’m using analog pin 4 for this demo, so I’ve set my pin mode for pin 4 to ‘analog’.
Now we can plug our arduino in and get a reading from the potentiometer.
- ARDUINO INTO PURE DATA
With your arduino plugged in, hit command and E to bring us out of edit mode. In our patch, click on ‘Devices’ above the arduino object and open up the pure data terminal. (That other thing that loads with PD that has all the scary code in)
The “Devices” message connected to the arduino object pings your computer to find what devices are connected and on what serial ports. Since we’re using a USB cable to connect our arduino, we’re looking for something with ‘usbserial’ in it, in this case; port 2.
Select the relevent port in the green box at the top (remember the first box is ‘0’, second is ‘1’ and so forth) and hit ‘Open’ to establish a connection. Check the terminal to see if the connection was sucessful.
Now lets check we’re getting something in. Create a number box (Command + 3) and connect it to the relevent pin on the ‘Route analog’ box at the bottom. In this case, pin 4.
One more thing; if you’re not getting any readings in, you’ll need to click on ‘pd old analog/digital controls’ and enable your pins here too. What I tend to do in my patches is just not include the large grid but make my own ‘old pd’ controls custom to what i’m enabling/disabling to save space.
Here’s what the ‘old analog/digital controls’ subpatch looks like (pin 4 enabled)…
Come out of edit mode and check that you’ve got readings. If so congratulations! If not, troubleshoot, start with making sure your usb connection is opened, make sure all the correct pins are enabled (remember you’re counting from 0 not 1 on most of these buttons in PD, it’s just the way computers work).
- SCALING READINGS TO MIDI
So we’ve got a reading and chances are it’s to 3 decimal places between 0 to 1. No problem, create a new object (Command + 1) and type “autoscale 0 127”. This allows us to scale the input to a min and max value, in this case 0 to 127 of MIDI. Next, lets get things looking nice, create a new object and type “knob”. Connect this AFTER the autoscale object. (the knob is default set to read inputs from 0 to 127. Then create another number to display the scaled MIDI data coming out, and finally a new object and type “ctlout 1”.
It should look something like this…
The second box should be outputing values from 0 – 127 now, and the knob giving a visual representation of your potentiometer.
Now lets patch it into ableton…
- PURE DATA TO ABLETON LIVE
Firstly, you’ll need to set up your macs IAC driver if you’ve not done this. Basically you’ll need to go into Audio/MIDI preferences and enable your IAC driver. Then create a new input and output. One for input to DAW and one for output from DAW. Google around for a tutorial on this, its really simple, a 30 second job.
After you’ve set up your IAC driver, go back to PD and go to preferences > MIDI Settings, and connect your IAC driver.
Open ableton and go to its MIDI preferences. Create a device listing for your IAC driver and enable its ins and outs into ableton like so…
And thats it! Create an instrument and try to assign something! I’ve got it controlling the brightness of a bass sound here.
Shout out for Facu who requested this tutorial. Hopefully it’ll help some of you looking to get into this stuff and start building things but with no idea where to start.
Drawing scalars freaks out when GOP is turned on
@th8a Very interesting. i opened your patch with Pd-L2ork and first thing i must say the graphics look very beautiful in Purr Data!
i still don't understand how you got the scalars into the patch without any [append] object?
Is it not possible to use [draw] onto a subpatch? It would solve the graphics all over the place issue to just put the scalars into a subpatch with gop on.
i put some comments to my button example from above that hopefully give a somewhat comprehensive overview of the basic concepts of data structures in pd and how to use [append] to add scalars:
button-data-structures-mini-tutorial.pd (updated)
i also added an example on how you can safely use dynamic patching with data structures without any crashes and without any delays.
Purr Data finally released
Purr Data is finally released!
Purr Data inherits the goodness of Pd-l2ork and runs on Gnu/Linux, Windows, and OSX. Infinite undo, enhanced editing and 2d drawing, and most of the the externals from Pd-extended (plus more from Pd-l2ork).
[Edit]
2.2.4:
- fix
[wrap~]
inconsistency - port mouse events from
[hcs/cursor]
- fix bug with dollarsigns in struct names
- add some "legacy_mouse" classes to support externals that report mouse events: "legacy_mousemotion", "legacy_mouseclick" and "legacy_mousewheel"
- fix bug loading default libs on OSX
2.2.3:
- fixed overallocation bug that made loading soundfiles into arrays take up unnecessary amount of memory (4x-8x overallocation)
- fix some utf8 string handling routines
- port fixes for
[soundfiler]
from Pd Vanilla - fix bug with "$@" that could cause invalid reads in some cases
- fix
[initbang]
functionality - fix crasher in
[pdinfo]
New in 2.2.2:
- fixed usability issues with the dropdown object
New in 2.2.1:
- fix stray GUI bugs
- fix some external libs that weren't building under Windows
- fix some OSX key event bugs
New in 2.2.0:
- fix GOP sizing algo to accommodate small GOP abstractions
- turn off anoying Gnome-keyring popup that appears on some systems
- bump nw.js GUI toolkit to 0.22.1
- fix arrow-key navigation-- use arrow keys for scrollbar navigation in runmode, turn off in editmode
- ignore iemgui label in bbox computation for "-legacy" mode
- fix OSCx library on arm builds
- guard against more out-of-order messages from Pd to GUI
- clean up and simplify build instructions
- leave enough space in GOP abstractions to accommodate all xlets
- fix search path bug
- update some of the documentation, removing old "messageoddness" patches that no longer apply to Purr Data
- update unauthorized library
- clean up and simplify the repository code/structure
New in 2.1.2:
- minor bugfix in the console (duplicate messages weren't printed after clearing)
- some minor fixes in the default startup configuration
- some cosmetic changes in the accompanying README and license information
- various bugfixes in objects and internal API functions (message boxes, dropdown atom, loadbang-related issues)
- updated lyonpotpourri to the latest 3.0 version to fix various 64 bit issues on Linux and macOS
- saving the preferences is much faster on the Mac now
- new animated "About Pd-L2ork" popup; also, the proper version is now shown in the generic "About" box on the Mac
New in 2.1.1:
- normalized range for
[bendin]
(keep old behavior under legacy flag) - added "mouseenter" and "mouseleave" events for data structures
- fixed "Recent Files" under Windows
- cleaned up documentation in repo
- fix for
[midiclkin]
(#255) - added "l2ork_version" message for
[pdinfo]
- make loader search order the same as Pd Vanilla
- fixed cord inspector font size
- silence spurious error when autopatching a signal object
- added a
[dropdown]
object for choosing a value for an atom box (interface not stable yet) - made gatom resizable by click-dragging in edit mode
- added "<ctrl-mousewheel>" for zooming
- added solarized and inverted solarized gui presets
- fixed mycanvas stroke color updates
- improvements to mode 4 of intelligent patching
- fixed "<Delete>" not deleting a selected object on some systems
New since rc5:
- fixed display bug with [vu] on graph-on-parent canvas
- fix documentation for timer-help.pd
- fix "open" method for [ggee/image]
- default to the user's home directory on OSX app bundle
- open the help browser file browser in the doc folder
- add a canvas "Print" menu item (under "File" menu)
- allow option to save the zoom level with the canvas
- fix a data structure crasher
please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data rc5
Purr Data release candidate 5!
- small fixes to OSX app bundle name and build instructions
- fixed OSX app bundle name
- fixed GUI errors with some GUI objects on GOP
- use cat icon for patches
- fixed a [grid] crasher with binding symbol leak
- fixed [grid] line drawing bug and GOP xlet display
- added dialog and scale handle for [grid]
- ported moonlib/knob
- get rid of some extraneous debugging messages
- allow to install Purr Data alongside Pd-l2ork
- Scope~ code cleanup
- fixes for arm build
- added some OSX app bundle dependencies for [fluid~] and others
- fix saving preferences under OSX
- added startup paths and libs to preferences dialog
- use "Purr Data" in OSX menu app
- help browser fixes
- fixed MIDI preference saving on OSX and Windows
- added a "Recent Files" menu to the "File" menu
- get consistent behavior for present working directory when opening/saving files
- fix Volume name for OSX dmg installer
- try to standardize a deterministic package name when compiling Purr Data
- add a Pd-l2ork-specific version number
- add command line open args to "Recent Files" list
- fixed crasher with ds "canvas" field
- allow saving the zoom level per canvas
please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data rc4
Edit: Windows binary is now up
Purr Data release candidate 4!
- fixed race when opening pd file in OSX
- partial fix for midi prefs not getting saved under Windows
- fixed #194: saving a loaded abstraction gives errors
- fixed for #201: new subcanvas position isn't saved with patch
- sync the ALSA sequencer port state with the GUI
- reset ALSA MIDI device handles and event buffers when closing
- got rid of more debugging output
- go ahead and allow curly braces in Pd messages
- replace the Pd-extended output~ abstraction with Alexandre Porres' improved version
- report userful value for "dsp-status" method of [pdinfo] by ignorning suspend/resume
- fixed display of dollar signs in properties dialogs
- fixed loading of lyonpotpourri and disis libraries
please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data rc3
Purr Data release candidate 3!
- fixed race with [dsp-state(--[pdinfo]
- fixed preference saving on Windows 10
- small fix to the prepend.pd abstraction for cyclone to take variable number
- fixed receive symbol in number box
- fixed help menu links
- fixed vu scale font size
- fixed [table] default array display
- improved canvas find
- fixed problem with resizing [cnv] label
- fixed scalar bbox calculation for [plot] et al
- fixed stray errors with ds fields
- fixed openpanel/savepanel GUI errors
please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data rc2
Purr Data release candidate 2!
- add delread4~ alias for vd~
- load Gem dependencies properly under Windows
- add help menu item for list of internal classes
- various help patch cleanups and fixes
- change zoom/fit keyboard shortcuts so they work on all platforms
- localize the canvas right-click menu
- small fixes to prefs menu and edit menu
- fix bug with color updates for iemguis
- zoom correctly on OSX 10.8
please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
OSX 64-bit Caught in a Trap Edition (10.8)
[Edit: typo in the name of the Elvis tune]