Commit 33a8ddbc authored by porres's avatar porres
Browse files

raw midi

parent 47e64243
#N canvas 701 73 586 493 10;
#X obj 117 354 else/out~;
#X obj 114 318 else/fluidsynth~ sf2/Famicom.sf2, f 16;
#X obj 114 74 else/keyboard 17 80 3 3 0 0 empty empty;
#X obj 217 268 else/bend.out -raw;
#X floatatom 217 240 0 0 0 0 - - -;
#X obj 220 213 hsl 128 15 0 16383 0 0 empty empty empty -2 -8 0 10
-228856 -1 -1 5400 1;
#X connect 1 0 0 0;
#X connect 1 1 0 1;
#X connect 2 0 1 0;
#X connect 3 0 1 0;
#X connect 4 0 3 0;
#X connect 5 0 4 0;
......@@ -23,16 +23,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <fluidsynth.h>
#include <string.h>
#include <unistd.h>
#define MAXSYSEXSIZE 1024 // Size of sysex data list (excluding the F0 [240] and F7 [247] bytes)
static t_class *fluid_tilde_class;
typedef struct _fluid_tilde{
t_object x_obj;
fluid_synth_t *x_synth;
fluid_settings_t *x_settings;
t_outlet *x_out_left;
t_outlet *x_out_right;
t_canvas *x_canvas;
t_object x_obj;
fluid_synth_t *x_synth;
fluid_settings_t *x_settings;
t_outlet *x_out_left;
t_outlet *x_out_right;
t_canvas *x_canvas;
int x_sysex;
int x_ready;
t_atom x_at;
unsigned char x_type;
unsigned char x_data;
unsigned char x_channel;
}t_fluid_tilde;
t_int *fluid_tilde_perform(t_int *w){
......@@ -155,9 +163,6 @@ static void fluid_polytouch(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
}
}
// Maximum size of sysex data (excluding the f0 and f7 bytes)
#define MAXSYSEXSIZE 1024
static void fluid_sysex(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
s = NULL;
if(x->x_synth == NULL)
......@@ -176,6 +181,33 @@ static void fluid_sysex(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
}
}
static void fluid_float(t_fluid_tilde *x, t_float f){
if(f >= 0 && f <= 255){
unsigned char val = (unsigned char)f;
if(val > 128){ // not a data type
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_ready){
switch(x->x_type){
case 0xE0: // pitch bend
post("pitch bend %d", (val << 7) + x->x_data, x->x_channel);
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;
}
}
else
x->x_type = x->x_ready = 0; // clear
}
static void fluid_load(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
s = NULL;
if(x->x_synth == NULL){
......@@ -230,10 +262,11 @@ 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_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);
x->x_canvas = canvas_getcurrent();
float sr = sys_getsr();
x->x_settings = new_fluid_settings();
if(x->x_settings == NULL){
pd_error(x, "[fluidsynth~]: couldn't create synth settings\n");
......@@ -243,7 +276,7 @@ static void *fluid_tilde_new(t_symbol *s, int ac, t_atom *av){
fluid_settings_setnum(x->x_settings, "synth.midi-channels", 16);
fluid_settings_setnum(x->x_settings, "synth.polyphony", 256);
fluid_settings_setnum(x->x_settings, "synth.gain", 0.600000);
fluid_settings_setnum(x->x_settings, "synth.sample-rate", sr != 0 ? sr : 44100.000000);
fluid_settings_setnum(x->x_settings, "synth.sample-rate", sys_getsr());
fluid_settings_setstr(x->x_settings, "synth.chorus.active", "no");
fluid_settings_setstr(x->x_settings, "synth.reverb.active", "no");
fluid_settings_setstr(x->x_settings, "synth.ladspa.active", "no");
......@@ -262,6 +295,7 @@ void fluidsynth_tilde_setup(void){
fluid_tilde_class = class_new(gensym("fluidsynth~"), (t_newmethod)fluid_tilde_new,
(t_method)fluid_tilde_free, sizeof(t_fluid_tilde), CLASS_DEFAULT, A_GIMME, 0);
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_bank, gensym("bank"), A_GIMME, 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);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment