#define INVALID_SET_FILE_POINTER 0xFFFFFFFF //aggiunto il 6/6/2007 #include #include "ext.h" #include "ext_path.h" // if defined, use windows calls, otherwise use max's cross platform "sysfile" API #define READFILE_WINDOWS_SPECIFIC void *leggimarkovmax_class; typedef struct leggimarkovmax { t_object f_ob; // void *f_proxy[2]; /* 3 inlets requires 2 proxy */ // long m_inletNumber; /* where proxy will put inlet number */ HANDLE f_fh; HANDLE f_fh1; short f_open; short f_open1; void *f_out; int f_flag; // 0 se proviene da inlet 0, 1 se da inlet 1 } t_leggimarkovmax; t_symbol *ps_nothing; void leggimarkovmax_bang(t_leggimarkovmax *x); //genera uno stato void leggimarkovmax_dobang(t_leggimarkovmax *x); void leggimarkovmax_in(t_leggimarkovmax *x, long n); void leggimarkovmax_doin(t_leggimarkovmax *x, long n);//inlet per il file HDR delle sequenze void leggimarkovmax_in1(t_leggimarkovmax *x, long n);// void leggimarkovmax_doin1(t_leggimarkovmax *x, long n);//inlet per il file TXT delle sequenze void leggimarkovmax_close(t_leggimarkovmax *x); void leggimarkovmax_doopen(t_leggimarkovmax *x, t_symbol *s); void leggimarkovmax_open(t_leggimarkovmax *x, t_symbol *s); void leggimarkovmax_free(t_leggimarkovmax *x); void leggimarkovmax_assist(t_leggimarkovmax *x, void *b, long m, long a, char *s); void *leggimarkovmax_new(t_symbol *fn); int leggimarkovmax_searchSeq(short int *); int leggimarkovmax_generaSporco(void); short int leggimarkovmax_calcolaNuovoStato(int); void leggimarkovmax_creaRipartizione(void); void leggimarkovmax_normalizza(void); Byte data; long count, err, type, n; int r, c, righe, colonne, livello; float **matrice,**ripartizione; //puntatore a puntatori (un vettore di puntatori) short int **sequenze; void main() { setup((t_messlist **)&leggimarkovmax_class, (method)leggimarkovmax_new, (method)leggimarkovmax_free, (short)sizeof(t_leggimarkovmax), 0L, A_DEFSYM, 0); addbang((method)leggimarkovmax_bang); // the method it uses when it gets a bang in the left inlet addint((method)leggimarkovmax_in); addinx((method)leggimarkovmax_in,1); addmess((method)leggimarkovmax_close, "fclose", 0); addmess((method)leggimarkovmax_open, "open", A_DEFSYM,0); addmess((method)leggimarkovmax_assist,"assist", A_CANT,0); ps_nothing = gensym(""); post("leggimarkovmax object loaded...",0); // post any important info to the max window when our object is loaded } void leggimarkovmax_open(t_leggimarkovmax *x, t_symbol *s) { defer_low(x,(method)leggimarkovmax_doopen,s,0,0L); // defer_low serve a non bloccare il tempo reale, mettendo il sottoprogramma a un livello di priorità più basso } void leggimarkovmax_free(t_leggimarkovmax *x) { leggimarkovmax_close(x); } void leggimarkovmax_doopen(t_leggimarkovmax *x, t_symbol *s) //sottoprogramma che apre i o il file ?? { short path; char ps[256],ps2[256]; long type,err; int r, c; HANDLE htemp;//apriamo il file con htemp leggimarkovmax_close(x); if (s==ps_nothing) { // ps_nothing è una stringa vuota quindi vuol dire che ci vuole il dialogo di apertura del file open_dialog if (open_dialog(ps,&path,&type,0L,0)) // opendialog è una funzione di libreria di max sdk (apre una finestra di dialogo per apertura file) return; } else // se no apre il file il cui nome sta dentro la variabile "s" { strcpy(ps,s->s_name); // -> = estrazione del campo s_name dalla struttura di cui abbiamo il puntatore "s" if (locatefile_extended(ps,&path,&type,&type,-1)) { // rutine che servono per la compatibilità tra nomi e path mac & PC error("leggimarkovmax: %s: can't find file",ps); return; } } path_topathname(path,ps,ps2); // convert path + name to pathname path_nameconform(ps2,ps,PATH_STYLE_NATIVE,PATH_TYPE_ABSOLUTE); // convert max style pathname to native pathname. Converti il path e nome in formato nativo htemp = CreateFile(ps,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); // CreateFile è la rutine di apertura di file dell'api di windows perché Max è un ambiente multitrading al posto di fopen per il tempo reale if (htemp==INVALID_HANDLE_VALUE) { x->f_fh = 0; err = GetLastError(); } else err = 0; if (err) { x->f_fh = 0; error("leggimarkovmax: %s: error %d opening file",ps,err); return; } else //superata la fase degli errori assegniamo a HANDLE fh o fh1 a seconda dell'inlet che sono i campi della struttura MAX legata all'oggetto contenenti gli handle file (numero che identifica il file) { if(x->f_flag == 0) { x->f_fh = htemp; x->f_open = TRUE; } else { x->f_fh1 = htemp; x->f_open1 = TRUE; } } } void leggimarkovmax_in(t_leggimarkovmax *x, long n) { defer_low(x,(method)leggimarkovmax_doin,(t_symbol *)n,0,0L); // trick. passing int as symbol } void leggimarkovmax_doin(t_leggimarkovmax *x, long n) { //Byte data; //long count; //long err; int i, pippo[3]; x->f_flag = 0; // HDR ACCESS if (x->f_open) { if (INVALID_SET_FILE_POINTER!=SetFilePointer(x->f_fh,n,NULL,FILE_BEGIN)) err = 0; else err = GetLastError(); if (err) error("leggimarkovmax: seek err %d",err); else { count = 1; if (ReadFile(x->f_fh,&data,count,(LPDWORD)&count,NULL)) // Funzione API di windows che pertemette l'apertura del file in multithreading err = 0; else err = GetLastError(); if (err) error("readfile: read err %d",err); else { //*lettura dei primi tre valori: righe colonne livello for (i=0; if_flag = 1; // OCCURRENCES ACCESS if (x->f_open1) { if (INVALID_SET_FILE_POINTER!=SetFilePointer(x->f_fh1,n,NULL,FILE_BEGIN)) err = 0; else err = GetLastError(); if (err) error("leggimarkovmax: seek err %d",err); else { count = 1; if (ReadFile(x->f_fh1,&data,count,(LPDWORD)&count,NULL)) err = 0; else err = GetLastError(); if (err) error("leggimarkovmax: read err %d",err); else { //**ALLOCAZIONE DINAMICA dello spazio per le due matrici matrice = (float **) calloc(righe,sizeof(float *)); //alloca spazio per il vettore di puntatori ripartizione = (float **) calloc(righe,sizeof(float *)); //alloca spazio per il vettore di puntatori for (r=0; rf_open) { CloseHandle(x->f_fh); x->f_fh = 0; x->f_open = FALSE; } if (x->f_open1) { CloseHandle(x->f_fh1); x->f_fh1 = 0; x->f_open1 = FALSE; } } void leggimarkovmax_bang(t_leggimarkovmax *x) // x = reference to this instance of the object { defer_low(x,(method)leggimarkovmax_dobang,ps_nothing,0,0L); // trick. passing int as symbol } void leggimarkovmax_dobang(t_leggimarkovmax *x) // x = reference to this instance of the object { //char filename[80]="greg.txt",filehdr[80]="greg.hdr",fileout[80]; //puntatore di gets e short int startSeq[] = {2},seq[100]; //inizializzazione del vettore dimensionato a 1 elemento int stato,seqlen=100,startPoint,i, pippo[3]; //GENERAZIONE DELLE SEQUENZE for(i=0;if_out, seq[i]);//stato); } //else error("readfile: no open file"); //} void leggimarkovmax_assist(t_leggimarkovmax *x, void *b, long m, long a, char *s) { if (m == ASSIST_OUTLET) { sprintf(s,"(int) stati output"); } else if (m == ASSIST_INLET) { switch (a) { case 0: sprintf(s,"(int) file sequenze"); break; case 1: sprintf(s,"(int) file occorrenze"); break; } } } void *leggimarkovmax_new(t_symbol *fn) { t_leggimarkovmax *x; srand((unsigned int)time(NULL)); //inizializzazione seme gen. casuale (nel main per non cambiare ogni volta seme, come succederebbe nel sottoprogramma) x = (t_leggimarkovmax *)newobject(leggimarkovmax_class); intin(x,1); // create a second int inlet (leftmost inlet is automatic - all objects have one inlet by default) // x->f_proxy[1] = proxy_new(x,2,&x->m_inletNumber); x->f_out = intout(x); x->f_open = FALSE; x->f_fh = 0; x->f_open1 = FALSE; x->f_fh1 = 0; if (fn != ps_nothing) { leggimarkovmax_doopen(x,fn); } post(" new leggimarkovmax object instance added to patch...",0); // post important info to the max window when new instance is created return (x); } //**************************** //**************************** // sottopogrammi specifici int leggimarkovmax_searchSeq(short int *seq) //cerca la sequenza nella matrice delle sequenze { int i,j; for(i=0;i= numero) { stato = i; break;// se lo trova non va avanti } } return(i); } void leggimarkovmax_creaRipartizione() { int i,j; float accu; for(i=0;i