Commit 15b8e729 authored by porres's avatar porres
Browse files

why channel becomes 0?

parent 33a8ddbc
#N canvas 701 73 586 493 10;
#X obj 117 354 else/out~;
#X obj 114 318 else/fluidsynth~ sf2/Famicom.sf2, f 16;
#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 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 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 0 1;
#X obj 108 202 else/note.out;
#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 489 342 else/hex2dec 0x80;
#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 obj 175 255 print;
#X msg 175 304 128 \, 60 \, 0;
#X connect 1 0 5 0;
#X connect 2 0 7 0;
#X connect 3 0 2 0;
#X connect 4 0 3 0;
#X connect 5 0 4 0;
#X connect 5 0 7 0;
#X connect 5 0 12 0;
#X connect 6 0 8 0;
#X connect 7 0 0 0;
#X connect 7 1 0 1;
#X connect 8 0 7 0;
#X connect 9 0 11 0;
#X connect 10 0 9 0;
#X connect 13 0 7 0;
......@@ -37,7 +37,7 @@ typedef struct _fluid_tilde{
t_canvas *x_canvas;
int x_sysex;
int x_ready;
t_atom x_at;
t_atom x_at[MAXSYSEXSIZE];
unsigned char x_type;
unsigned char x_data;
unsigned char x_channel;
......@@ -73,10 +73,12 @@ static void fluid_note(t_fluid_tilde *x, t_symbol *s, int ac, t_atom *av){
s = NULL;
if(x->x_synth == NULL)
return;
post("ac = %d (%d %d %d)", ac, atom_getintarg(0, ac, av), atom_getintarg(1, ac, av), atom_getintarg(2, ac, av));
if(ac == 2 || ac == 3){
int key = atom_getintarg(0, ac, av);
int vel = atom_getintarg(1, ac, av);
int chan = ac > 2 ? atom_getintarg(2, ac, av) : 1;
post("key (%d) vel (%d) chan (%d)", key, vel, chan);
fluid_synth_noteon(x->x_synth, chan-1, key, vel);
}
}
......@@ -184,15 +186,31 @@ 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
if(val > 127){ // 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 0x80: // NOTE OFF
SETFLOAT(&x->x_at[0], (t_float)x->x_data);
SETFLOAT(&x->x_at[1], 0); // make it note on with velocity 0
SETFLOAT(&x->x_at[3], (t_float)x->x_channel);
post("OFF x->x_data (%d) val (%d) x->x_channel (%d)", (int)x->x_data, (int)val, (int)x->x_channel);
fluid_note(x, &s_list, 2, 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);
SETFLOAT(&x->x_at[3], (t_float)x->x_channel);
post("ON x->x_data (%d) val (%d) x->x_channel (%d)", (int)x->x_data, (int)val, (int)x->x_channel);
fluid_note(x, &s_list, 2, x->x_at);
break;
case 0xE0: // pitch bend
post("pitch bend %d", (val << 7) + x->x_data, x->x_channel);
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;
......
/* 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 */
}
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