// per ora si devono aprire due file: // 1° header: numero di colonne, numero di righe, profondità dell'analisi, // 2° probabilità #define INVALID_SET_FILE_POINTER 0xFFFFFFFF //aggiunto il 6/6/2007 #define MAXROW 1000 #define MAXCOLSEQ 24 #define MAXCOL 48 #include #include #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; 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 long p_value1; // int value - received from the right inlet and stored internally for each object instance } 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_close(t_leggimarkovmax *x); void leggimarkovmax_open(t_leggimarkovmax *x, t_symbol *s); void leggimarkovmax_read(t_leggimarkovmax *x); void leggimarkovmax_doread(t_leggimarkovmax *x); void leggimarkovmax_init(t_leggimarkovmax *x); void leggimarkovmax_doopen(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_generaSporco(void); Byte data; long count, err, type, n; int r, c, righe, colonne, livello,startPoint=0; short int startSeq=0,seq[16000]; //inizializzazione del vettore dimensionato //float matrice[MAXROW][MAXCOL],ripartizione[MAXROW][MAXCOL]; //era **matrice,**ripartizione, puntatore a puntatori (un vettore di puntatori) //short int sequenze[MAXROW][MAXCOLSEQ]; // era **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); // genera uno stato sulla base della matrice di probabilità. the method it uses when it gets a bang in the left inlet addint((method)leggimarkovmax_in); addinx((method)leggimarkovmax_in1,1); addmess((method)leggimarkovmax_close, "fclose", 0); addmess((method)leggimarkovmax_read, "read", 0); addmess((method)leggimarkovmax_init, "init", 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, lunghezza; HANDLE htemp, htemp1; //apriamo entrambi i 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) ps= contiene stringa con nome file da aprire 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; } lunghezza=strlen(ps)-3; ps[lunghezza]=0; sprintf(ps, "%stxt", ps); post(ps); // htemp1 = 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_fh1 = 0; // secondo file err = GetLastError(); } else err = 0; if (err) { x->f_fh1 = 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) { x->f_fh = htemp; x->f_open = TRUE; x->f_fh1 = htemp1; x->f_open1 = TRUE; } } void leggimarkovmax_read(t_leggimarkovmax *x) { long n = 0; defer_low(x,(method)leggimarkovmax_doread,ps_nothing,0,0L); // trick. passing int as symbol } void leggimarkovmax_init(t_leggimarkovmax *x) { int i; startSeq = (short int)x->p_value1; // for(i=0;if_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 = 3 * sizeof(short int); //lettura dei primi tre valori: righe colonne livello if (ReadFile(x->f_fh,(void *)pippo,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 { righe = pippo[0]; colonne = pippo[1]; livello = pippo[2]; post("Header (file .hdr):"); sprintf(num,"righe=%d, colonne=%d, livello=%d",righe,colonne,livello); post(num); // Allocazione del'array sequenze // sequenze = (short int **) calloc(righe,sizeof(short int *)); //alloca spazio per il vettore di puntatori // for (r=0; rf_fh,(void *)pippo,count,(LPDWORD)&count,NULL); for (c=0; cp_value1 = n; // just store right operand value in instance's data structure and do nothing else //post("Inlet 2 OK!!!"); } void leggimarkovmax_close(t_leggimarkovmax *x) { if (x->f_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 { // short int startSeq[3] = {2},seq[100]; //inizializzazione del vettore dimensionato a 1 elemento int stato,seqlen=100,i,j; // Lettura file sequenze long count; int r,c,k,h; short int sequenze[MAXROW][MAXCOLSEQ],pippo[3]; float matrice[MAXROW][MAXCOL],ripartizione[MAXROW][MAXCOL]; float numero; int fattore; float accu; short int buf[MAXCOL]; char num[80]; x->f_flag = 0; // HDR ACCESS if (x->f_open) { SetFilePointer(x->f_fh,0,NULL,FILE_BEGIN); count = 3 * sizeof(short int); ReadFile(x->f_fh,pippo,count,(LPDWORD)&count,NULL); //lettura dei primi tre valori: righe colonne livello righe = pippo[0]; colonne = pippo[1]; livello = pippo[2]; count = livello * sizeof(short int); for (r=0; rf_fh,pippo,count,(LPDWORD)&count,NULL); for (c=0; cf_flag = 1; // OCCURRENCES ACCESS if (x->f_open1) { SetFilePointer(x->f_fh1,0,NULL,FILE_BEGIN); count = colonne * sizeof(short int); for (r=0; rf_fh1,buf,count,(LPDWORD)&count,NULL); for (c=0; cp_value1; // for(i=0;i= numero) { stato = k; break;// se lo trova non va avanti } } seq[startPoint++] = stato;//leggimarkovmax_calcolaNuovoStato(stato,x);//caricamento del nuovo stato in modo che parta dalla sequenza successiva outlet_int(x->f_out, stato);//stato); } 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 e occorrenze"); break; case 1: sprintf(s,"(int) stato (sequenza) iniziale"); 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_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_generaSporco() { short int indice; indice = rand() % colonne; return(indice); }