Commit 751a3901 authored by porres's avatar porres
Browse files

gen

parent d1f84f67
#N canvas 701 73 563 556 10;
#N canvas 804 107 561 540 10;
#X obj 306 4 cnv 15 250 40 empty empty empty 12 13 0 18 -128992 -233080
0;
#N canvas 382 141 749 319 (subpatch) 0;
......@@ -50,11 +50,11 @@
-1;
#X text 96 33 load a different soundfont;
#X obj 138 171 outlet;
#X text 211 78 If no extension is given \, it searches for both ".sf2"
#X text 215 78 If no extension is given \, it searches for both ".sf2"
and ".sf3" extensions. This is the same for the argument., f 38;
#X msg 138 134 info;
#X text 171 134 <= print information on terminal window;
#X msg 89 86 symbol sf2/R-piano;
#X msg 89 86 symbol sf2/Theremin;
#X connect 0 0 4 0;
#X connect 1 0 0 0;
#X connect 2 0 1 0;
......@@ -92,22 +92,18 @@ are not familiar with it \, check <https://freepats.zenvoid.org/sf2/SF2_Intro.tx
;
#X connect 0 0 1 0;
#X restore 462 226 pd more info;
#X obj 232 160 else/fluidsynth~ sf2/Famicom.sf2, f 16;
#X text 35 84 [fluidsynth~] is a synth based on fluidsynth (see www.fluidsynth.org)
that loads soundfont files., f 74;
#X text 146 320 bend <f \, f> -;
#X text 232 392 sets sysex messages, f 51;
#X text 104 364 pgm <float \, float> -;
#X text 134 306 ctl <f \, f \, f> -;
#N canvas 928 284 519 582 Input 0;
#X floatatom 65 225 0 0 8 0 - - -;
#X floatatom 73 280 5 1 4 0 - - -;
#N canvas 928 284 755 630 Input 0;
#X floatatom 65 225 0 0 127 0 - - -;
#X obj 34 395 outlet;
#X text 41 20 These are the basic messages for setting the sounds of
the fluidsynth soundfont synthesizer. The MIDI input from Pd needs
to be configured in Preferences => MIDI., f 54;
#X text 132 281 (the loaded soundfonts loaded in this help file only
have 1 bank \, so this does nothing here), f 32;
#X text 94 225 <= change sound program directly;
#X obj 34 78 else/keyboard 17 80 3 3 0 0 empty empty;
#N canvas 1115 171 633 485 mts-tuning 0;
......@@ -129,7 +125,6 @@ below:;
#X connect 1 0 4 0;
#X restore 92 349 pd mts-tuning;
#X msg 65 249 pgm \$1;
#X msg 73 304 bank \$1;
#N canvas 964 199 329 629 MIDI-input 0;
#X obj 69 126 ctlin;
#X obj 69 147 pack f f f;
......@@ -190,16 +185,47 @@ below:;
#X obj 225 529 else/display;
#X text 297 476 <= set channel;
#X obj 225 499 else/insert 3;
#X connect 0 0 8 0;
#X connect 1 0 9 0;
#X connect 6 0 12 0;
#X connect 7 0 2 0;
#X connect 8 0 2 0;
#X connect 9 0 2 0;
#X connect 12 0 2 0;
#X connect 14 0 18 0;
#X connect 15 0 18 1;
#X msg 471 331 bend \$1;
#N canvas 627 120 491 561 bend 0;
#X obj 104 144 vsl 22 100 0 16383 0 0 empty empty empty 0 -9 0 10 -228856
-1 -1 4950 1;
#X obj 104 86 else/initmess 8192;
#X obj 187 122 else/mouse;
#X obj 187 146 sel 0;
#X obj 187 198 line;
#X msg 123 111 set \$1;
#X obj 187 225 change;
#X msg 187 168 8192 100;
#X obj 187 277 outlet;
#X obj 187 249 else/rint;
#X connect 0 0 4 0;
#X connect 1 0 0 0;
#X connect 2 0 3 0;
#X connect 3 0 7 0;
#X connect 4 0 5 0;
#X connect 4 0 6 0;
#X connect 5 0 0 0;
#X connect 6 0 9 0;
#X connect 7 0 4 0;
#X connect 9 0 8 0;
#X restore 471 271 pd bend;
#X floatatom 471 302 5 0 0 0 - - -;
#X msg 420 427 touch \$1;
#X obj 420 287 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
-1 -1 0 1;
#X connect 0 0 6 0;
#X connect 4 0 9 0;
#X connect 5 0 1 0;
#X connect 6 0 1 0;
#X connect 9 0 1 0;
#X connect 11 0 15 0;
#X connect 12 0 15 1;
#X connect 15 0 13 0;
#X connect 16 0 1 0;
#X connect 17 0 18 0;
#X connect 18 0 16 0;
#X connect 19 0 1 0;
#X connect 20 0 19 0;
#X restore 232 109 pd Input;
#X text 232 378 bank number <bank \, channel (optional)>, f 51;
#X text 232 364 program change <program \, channel (optional)>, f
......@@ -218,8 +244,8 @@ f 51;
#X text 232 292 same as "note" message, f 51;
#X text 182 262 float -;
#X text 232 262 raw MIDI input, f 51;
#X text 33 158 add raw midi;
#X connect 24 0 36 0;
#X connect 36 0 34 0;
#X connect 36 1 34 1;
#X connect 42 0 36 0;
#X obj 232 160 else/fluidsynth~ sf2/Famicom, f 16;
#X connect 24 0 54 0;
#X connect 41 0 54 0;
#X connect 54 0 34 0;
#X connect 54 1 34 1;
#N canvas 682 62 678 651 10;
#X obj 167 554 else/out~;
#X obj 114 74 else/keyboard 17 80 3 3 0 0 empty empty;
#X obj 267 468 else/bend.out -raw;
#X floatatom 267 440 0 0 0 0 - - -;
#X obj 270 413 hsl 128 15 0 16383 0 0 empty empty empty -2 -8 0 10
-228856 -1 -1 4600 1;
#X obj 203 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
127;
#X obj 164 518 ./fluidsynth~ sf2/Famicom.sf2, f 16;
#X msg 200 366 60 \$1 1;
#X obj 488 315 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
-1 -1;
#X floatatom 505 378 5 0 0 0 - - -;
#X msg 175 304 144 \, 60 \, \$1;
#X obj 180 276 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
127;
#X text 215 202 <= should not send note off (group 128);
#X obj 489 342 else/hex2dec 0xE0;
#X obj 108 202 else/note.out 1;
#X connect 1 0 14 0;
#X connect 2 0 6 0;
#X connect 3 0 2 0;
#X connect 4 0 3 0;
#X connect 5 0 7 0;
#X connect 6 0 0 0;
#X connect 6 1 0 1;
#X connect 7 0 6 0;
#X connect 8 0 13 0;
#X connect 10 0 6 0;
#X connect 11 0 10 0;
#X connect 13 0 9 0;
#X connect 14 0 6 0;
......@@ -36,6 +36,7 @@ typedef struct _fluid_tilde{
t_outlet *x_out_right;
t_canvas *x_canvas;
int x_sysex;
int x_count;
int x_ready;
t_atom x_at[MAXSYSEXSIZE];
unsigned char x_type;
......@@ -122,11 +123,12 @@ static void fluid_bank(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
if(ac == 1 || ac == 2){
int bank = atom_getintarg(0, ac, av);
int chan = ac > 1 ? atom_getintarg(1, ac, av) : 1;
// post("bank (%d) chan (%d)", bank, chan);
fluid_synth_bank_select(x->x_synth, chan-1, bank);
}
}
/*static void fluid_gen(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
static void fluid_gen(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
s = NULL;
if(x->x_synth == NULL)
return;
......@@ -138,9 +140,9 @@ static void fluid_bank(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
value = atom_getintarg(2, ac, av);
fluid_synth_set_gen(x->x_synth, chan-1, param, value);
}
}*/
}
static void fluid_touch(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
static void fluid_aftertouch(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
s = NULL;
if(x->x_synth == NULL)
return;
......@@ -185,39 +187,75 @@ static void fluid_float(t_fluid_tilde *x, t_float f){
if(f >= 0 && f <= 255){
unsigned char val = (unsigned char)f;
if(val > 127){ // not a data type
x->x_type = val & 0xF0; // get type
// post("x->x_type = %d", (int)x->x_type);
x->x_channel = (val & 0x0F) + 1; // get channel
x->x_ready = (x->x_type == 0xC0 || x->x_type == 0xD0); // ready if program or touch
if(val == 0xF0){ // start of sysex
x->x_sysex = 1;
x->x_count = 0;
}
else if(val == 0xF7){ // end of sysex
fluid_sysex(x, &s_list, x->x_count, x->x_at);
x->x_sysex = x->x_count = 0;
}
else{
x->x_type = val & 0xF0; // get type
x->x_channel = (val & 0x0F) + 1; // get channel
x->x_ready = (x->x_type == 0xC0 || x->x_type == 0xD0); // ready if program or touch
}
}
else if(x->x_sysex){
SETFLOAT(&x->x_at[x->x_count], (t_float)val);
x->x_count++;
}
else if(x->x_ready){
switch(x->x_type){
case 0x80: // group 128 (NOTE OFF)
SETFLOAT(&x->x_at[0], (t_float)x->x_data);
else{
if(x->x_ready){
switch(x->x_type){
case 0x80: // group 128-143 (NOTE OFF)
SETFLOAT(&x->x_at[0], (t_float)x->x_data); // key
SETFLOAT(&x->x_at[1], 0); // make it note on with velocity 0
SETFLOAT(&x->x_at[2], (t_float)x->x_channel);
fluid_note(x, &s_list, 3, x->x_at);
break;
case 0x90: // group 144 (NOTE ON)
SETFLOAT(&x->x_at[0], (t_float)x->x_data);
SETFLOAT(&x->x_at[1], val);
case 0x90: // group 144-159 (NOTE ON)
SETFLOAT(&x->x_at[0], (t_float)x->x_data); // key
SETFLOAT(&x->x_at[1], val); // velocity
SETFLOAT(&x->x_at[2], (t_float)x->x_channel);
fluid_note(x, &s_list, 3, x->x_at);
break;
case 0xE0: // pitch bend
case 0xA0: // group 160-175 (POLYPHONIC AFTERTOUCH)
SETFLOAT(&x->x_at[0], val); // aftertouch pressure value
SETFLOAT(&x->x_at[1], (t_float)x->x_data); // key
SETFLOAT(&x->x_at[2], (t_float)x->x_channel);
fluid_polytouch(x, &s_list, 3, x->x_at);
break;
case 0xB0: // group 176-191 (CONTROL CHANGE)
SETFLOAT(&x->x_at[0], val); // control value
SETFLOAT(&x->x_at[1], (t_float)x->x_data); // control number
SETFLOAT(&x->x_at[2], (t_float)x->x_channel);
fluid_control_change(x, &s_list, 3, x->x_at);
break;
case 0xC0: // group 192-207 (PROGRAM CHANGE)
SETFLOAT(&x->x_at[0], val); // control value
SETFLOAT(&x->x_at[1], (t_float)x->x_channel);
fluid_program_change(x, &s_list, 2, x->x_at);
break;
case 0xD0: // group 208-223 (AFTERTOUCH)
SETFLOAT(&x->x_at[0], val); // control value
SETFLOAT(&x->x_at[1], (t_float)x->x_channel);
fluid_aftertouch(x, &s_list, 2, x->x_at);
break;
case 0xE0: // group 224-239 (PITCH BEND)
SETFLOAT(&x->x_at[0], (val << 7) + x->x_data);
SETFLOAT(&x->x_at[1], x->x_channel);
fluid_pitch_bend(x, &s_list, 2, x->x_at);
break;
default:
break;
}
x->x_type = x->x_ready = 0; // clear
}
else{ // not ready, get data and make it ready
x->x_data = val;
x->x_ready = 1;
}
x->x_type = x->x_ready = 0; // clear
}
else{ // not ready, get data and make it ready
// post("x->x_data = %d", (int)x->x_data);
x->x_data = val;
x->x_ready = 1;
}
}
else
......@@ -278,7 +316,7 @@ static void *fluid_tilde_new(t_symbol *s, int ac, t_atom *av){
t_fluid_tilde *x = (t_fluid_tilde *)pd_new(fluid_tilde_class);
x->x_synth = NULL;
x->x_settings = NULL;
x->x_sysex = x->x_ready = 0;
x->x_sysex = x->x_ready = x->x_count = 0;
x->x_data = x->x_channel = x->x_type = 0;
x->x_out_left = outlet_new(&x->x_obj, &s_signal);
x->x_out_right = outlet_new(&x->x_obj, &s_signal);
......@@ -313,14 +351,14 @@ void fluidsynth_tilde_setup(void){
class_addmethod(fluid_tilde_class, (t_method)fluid_tilde_dsp, gensym("dsp"), A_CANT, 0);
class_addfloat(fluid_tilde_class, (t_method)fluid_float); // raw midi input
class_addmethod(fluid_tilde_class, (t_method)fluid_load, gensym("load"), A_GIMME, 0);
// class_addmethod(fluid_tilde_class, (t_method)fluid_gen, gensym("gen"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_gen, gensym("gen"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_bank, gensym("bank"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_note, gensym("note"), A_GIMME, 0);
class_addlist(fluid_tilde_class, (t_method)fluid_note); // same as note
class_addmethod(fluid_tilde_class, (t_method)fluid_control_change, gensym("ctl"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_program_change, gensym("pgm"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_polytouch, gensym("polytouch"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_touch, gensym("touch"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_aftertouch, gensym("touch"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_pitch_bend, gensym("bend"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_sysex, gensym("sysex"), A_GIMME, 0);
class_addmethod(fluid_tilde_class, (t_method)fluid_info, gensym("info"), 0);
......
// porres 2018
#include "m_pd.h"
#include <string.h>
typedef struct _bendin{
t_object x_ob;
t_int x_omni;
t_int x_raw;
t_float x_ch;
t_float x_ch_in;
unsigned char x_ready;
unsigned char x_status;
unsigned char x_channel;
unsigned char x_lsb;
t_outlet *x_chanout;
}t_bendin;
static t_class *bendin_class;
static void bendin_float(t_bendin *x, t_float f){
if(f < 0)
return;
t_int ch = x->x_ch_in;
if(ch != x->x_ch){
if(ch == 0){
x->x_ch = ch;
x->x_omni = 1;
}
else if(ch > 0){
x->x_ch = ch;
x->x_omni = 0;
x->x_channel = (unsigned char)--ch;
}
}
if(f < 256){
unsigned char bval = (t_int)f;
if(bval & 0x80){
unsigned char status = bval & 0xF0;
if(status == 0xF0 && bval < 0xF8)
x->x_status = x->x_ready = 0; // clear
else if(status == 0xE0){
unsigned char channel = bval & 0x0F;
if(x->x_omni)
x->x_channel = channel;
x->x_status = (x->x_channel == channel);
x->x_ready = 0;
}
else
x->x_status = x->x_ready = 0; // clear
}
else if(x->x_ready){
if(x->x_omni)
outlet_float(x->x_chanout, x->x_channel + 1);
float bend = (bval << 7) + x->x_lsb;
if(!x->x_raw){ // normalize
bend = (bend - 8192) / 8191;
if(bend < -1)
bend = -1;
}
outlet_float(((t_object *)x)->ob_outlet, bend);
x->x_ready = 0;
}
else if(x->x_status){
x->x_lsb = bval;
x->x_ready = 1;
}
}
else
x->x_status = x->x_ready = 0; // clear
}
static void *bendin_new(t_symbol *s, t_int ac, t_atom *av){
t_bendin *x = (t_bendin *)pd_new(bendin_class);
t_symbol *curarg = s; // get rid of warning
t_int channel = 0;
x->x_raw = x->x_status = x->x_ready = 0;
if(ac){
while(ac > 0){
if(av->a_type == A_FLOAT){
channel = (t_int)atom_getfloatarg(0, ac, av);
ac--;
av++;
}
else if(av->a_type == A_SYMBOL){
curarg = atom_getsymbolarg(0, ac, av);
if(!strcmp(curarg->s_name, "-raw")){
x->x_raw = 1;
ac--;
av++;
}
else
goto errstate;
}
else
goto errstate;
}
}
x->x_omni = (channel == 0);
if(!x->x_omni)
x->x_channel = (unsigned char)--channel;
floatinlet_new((t_object *)x, &x->x_ch_in);
outlet_new((t_object *)x, &s_float);
x->x_chanout = outlet_new((t_object *)x, &s_float);
return(x);
errstate:
pd_error(x, "[bendin]: improper args");
return NULL;
}
void setup_bend0x2ein(void){
bendin_class = class_new(gensym("bend.in"), (t_newmethod)bendin_new,
0, sizeof(t_bendin), 0, A_GIMME, 0);
class_addfloat(bendin_class, bendin_float);
}
/* Copyright (c) 2002-2003 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
//adding x_hires and associated bendout options - Derek Kwan 2016
//
#include "m_pd.h"
#include <common/api.h>
#include <string.h>
typedef struct _midiparse
{
t_object x_ob;
int x_hires;
unsigned char x_ready;
unsigned char x_status;
unsigned char x_channel;
unsigned char x_data1;
t_outlet *x_polyout;
t_outlet *x_ctlout;
t_outlet *x_pgmout;
t_outlet *x_touchout;
t_outlet *x_bendout;
t_outlet *x_chanout;
} t_midiparse;
static t_class *midiparse_class;
static void midiparse_hires(t_midiparse *x, t_float f){
int hires = (int) f;
if(hires < 0){
hires = 0;
}
else if(hires > 2){
hires = 2;
};
x->x_hires = hires;
}
static void midiparse_clear(t_midiparse *x)
{
x->x_status = 0;
x->x_ready = 0;
}
static void midiparse_float(t_midiparse *x, t_float f)
{
int ival = (int)f; /* CHECKED */
if (ival < 0)
{
/* CHECKME */
return;
}
if (ival < 256) /* CHECKED clear if input over 255 */
{
unsigned char bval = ival;
if (bval & 0x80)
{
unsigned char status = bval & 0xF0;
if (status == 0xF0)
{
/* CHECKED no such test in max -- this is incompatible,
but real-time messages are out-of-band, and they
should be ignored here. LATER rethink the 0xFE case. */
if (bval < 0xF8)
midiparse_clear(x);
}
else
{
x->x_status = status;
x->x_channel = bval & 0x0F;
x->x_ready = (status == 0xC0 || status == 0xD0);
}
}
else if (x->x_ready)
{
t_float bout;
t_atom at[2];
x->x_ready = 0;
outlet_float(x->x_chanout, x->x_channel + 1);
switch (x->x_status)
{
case 0x80: // NOTE OFF
SETFLOAT(&at[0], x->x_data1);
SETFLOAT(&at[1], 0);
outlet_list(((t_object *)x)->ob_outlet, 0, 2, at);
break;
case 0x90: // NOTE ON
SETFLOAT(&at[0], x->x_data1);
SETFLOAT(&at[1], bval);
outlet_list(((t_object *)x)->ob_outlet, 0, 2, at);
break;
case 0xA0: // POLYTOUCH
SETFLOAT(&at[0], bval);
SETFLOAT(&at[1], x->x_data1);
outlet_list(x->x_polyout, 0, 2, at);
break;
case 0xB0: // CTL
SETFLOAT(&at[0], bval);
SETFLOAT(&at[1], x->x_data1);
outlet_list(x->x_ctlout, 0, 2, at);
break;
case 0xC0: // PGM
outlet_float(x->x_pgmout, bval);
x->x_ready = 1;
break;
case 0xD0: // TOUCH
outlet_float(x->x_touchout, bval);
x->x_ready = 1;
break;
case 0xE0:
if(x->x_hires == 0){
/* legacy: ignores data1 */
bout=bval;
}
else{
bout = (bval << 7) + x->x_data1;
bout -= 8192; //max val of 14-bit number div 2
};
if(x->x_hires == 1){
//[-1,1) range
bout /= 8192;
};
outlet_float(x->x_bendout, bout);
break;
default:;
}
}
else if (x->x_status)
{
x->x_data1 = bval; /* CHECKED key #0 accepted */
x->x_ready = 1;
}
}
else midiparse_clear(x);
}
static void *midiparse_new(t_symbol * s, int argc, t_atom * argv)
{
t_midiparse *x = (t_midiparse *)pd_new(midiparse_class);
//defaults
t_float hires = 0;
while(argc){
if(argv -> a_type == A_SYMBOL){
if(argc >= 2){
t_symbol * cursym = atom_getsymbolarg(0, argc, argv);
t_float curfloat = atom_getfloatarg(1, argc, argv);
if(strcmp(cursym->s_name, "@hires") == 0){
hires = curfloat;
}
else{
goto errstate;
};
argc-=2;
argv+=2;
}
else{
goto errstate;
};
}
else{
goto errstate;
};
};
midiparse_hires(x, hires);
outlet_new((t_object *)x, &s_list);
x->x_polyout = outlet_new((t_object *)x, &s_list);
x->x_ctlout = outlet_new((t_object *)x, &s_list);
x->x_pgmout = outlet_new((t_object *)x, &s_float);
x->x_touchout = outlet_new((t_object *)x, &s_float);
x->x_bendout = outlet_new((t_object *)x, &s_float);
x->x_chanout = outlet_new((t_object *)x, &s_float);
midiparse_clear(x);
return (x);
errstate:
post("midiparse: improper args");
return NULL;
}
CYCLONE_OBJ_API void midiparse_setup(void)
{
midiparse_class = class_new(gensym("midiparse"),
(t_newmethod)midiparse_new, 0,
sizeof(t_midiparse), 0, A_GIMME, 0);
class_addbang(midiparse_class, midiparse_clear);
class_addfloat(midiparse_class, midiparse_float);
class_addmethod(midiparse_class, (t_method)midiparse_hires, gensym("hires"), A_FLOAT, 0);
/* CHECKED autocasting lists to floats */
}
sf2/Theremin.sf2 0 → 100644