home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * MIDIFILE.C
- *
- * fonctions de lecture d'un fichier au format MIDIFILE 1.00
- *
- * GRAME
- * sources originales développées sur Atari St D.F.
- * Octobre 91 fonctions d'écriture B. MERLIER
- * Janvier 92 refonte et redéfinition des routines de base D.F.
- * Mars 92 intégration des événements MidiFile dans MidiShare D.F.
- * Avril 92 ajout des fonction de lecture/écriture d'un événement
- * ouverture, fermeture et création de piste D.F.
- *
- */
-
- #include <Stdio.h>
- #include <StdLib.h>
- #include <String.h>
- #include <MidiShare.h>
-
- #include "MidiFile.h"
-
-
- /*--------------------------------------------------------------------------*/
- /* définition de constantes */
-
- #define MDF_MThd "MThd" /* en-tête de fichier */
- #define MDF_MTrk "MTrk" /* en-tête de piste */
-
- #define SRC_VERSION 110 /* version des sources */
- #define MDF_VERSION 100 /* version du standard MidiFile */
-
- #define offset_ntrks 10 /* offset du nombre de pistes */
- /* rel. au début du fichier */
- #define offset_trkLen 4 /* offset du la longueur de */
- /* piste, rel. au header */
-
-
- /*--------------------------------------------------------------------------*/
- /* déclaration de fonctions */
- static MidiEvPtr read_undef( midiFILE *fd, short status);
- static MidiEvPtr read_sysex( midiFILE *fd, short status);
- static MidiEvPtr read_2DataEv( midiFILE *fd, short status);
- static MidiEvPtr read_1DataEv( midiFILE *fd, short status);
- static MidiEvPtr read_0DataEv( midiFILE *fd, short status);
-
- static MidiEvPtr read_text( midiFILE *fd, long len, short type);
- static MidiEvPtr read_endTrack( midiFILE *fd, long len, short);
- static MidiEvPtr read_tempo( midiFILE *fd, long len, short);
- static MidiEvPtr read_keySign( midiFILE *fd, long len, short);
- static MidiEvPtr read_timeSign( midiFILE *fd, long len, short);
- static MidiEvPtr read_seqNum( midiFILE *fd, long len, short);
- static MidiEvPtr read_chanPref( midiFILE *fd, long len, short);
- static MidiEvPtr read_smpte( midiFILE *fd, long len, short);
-
- static Boolean write_note( midiFILE *fd, MidiEvPtr ev, short status);
- static Boolean write_2DataEv( midiFILE *fd, MidiEvPtr ev, short status);
- static Boolean write_1DataEv( midiFILE *fd, MidiEvPtr ev, short status);
- static Boolean write_0DataEv( midiFILE *fd, MidiEvPtr ev, short status);
- static Boolean dont_write( midiFILE *, MidiEvPtr , short);
- static Boolean write_sysex( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_Ctrl14b( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_RegP( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_NRegP( midiFILE *fd, MidiEvPtr ev, short);
-
- static Boolean write_SeqNum( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_texte( midiFILE *fd, MidiEvPtr ev, short status);
- static Boolean write_chanPref( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_endTrack( midiFILE *fd, MidiEvPtr, short);
- static Boolean write_tempo( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_smpte( midiFILE *fd, MidiEvPtr ev, short);
- static Boolean write_timeSign( midiFILE *fd, MidiEvPtr, short);
- static Boolean write_keySign( midiFILE *fd, MidiEvPtr, short);
-
-
- /*--------------------------------------------------------------------------*/
- /* variables globales du module */
-
- int MidiFile_errno; /* pour le gestion des erreurs */
-
-
- typedef MidiEvPtr (* ReadFunc)( midiFILE *fd, short status);
- typedef MidiEvPtr (* ReadMetaFunc)( midiFILE *fd, long len, short type);
- typedef Boolean (* WriteFunc)( midiFILE *fd, MidiEvPtr ev, short status);
-
-
- /*------------------- correspondance type/octet de status ------------------*/
- static unsigned char codeTbl[]=
- { 0x90, 0x90, 0x80, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0,
- 0xf2, 0xf3, 0xf8, 0xfa, 0xfb, 0xfc, 0xf6, 0xfe,
- 0xff, 0xf0, 0xf7
- };
-
- /*------------------- correspondance octet de status/type ------------------*/
- static char typeTbl[]=
- { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 17,130,8,9,0,0,14,18,10,0,11,12,13,0,15,16
- };
-
- /*------------------- correspondance type/méta event -----------------------*/
- /* cette table prend en charge également les événements de type QFrame */
- /* Ctrl14Bits, NonRegParam et RegParam */
-
- static char metaCodeTbl[]=
- {
- 0xf1, 0xb0, 0xb0, 0xb0,
- 0, 1, 2, 3, 4, 5, 6, 7,
- 0x20, 0x2f, 0x51, 0x54,
- 0x58, 0x59, 0x7f
- };
-
- /*------------------- correspondance méta event/type ----------------------*/
- static char metaTypeTbl[]=
- { 1,2,3,4,5,6,7,8, /* 0-7 */
- 0,0,0,0,0,0,0,0, /* 8-15 undefs */
- 0,0,0,0,0,0,0,0, /* 16-23 undefs */
- 0,0,0,0,0,0,0,0, /* 24-31 */
- 9,0,0,0,0,0,0,0, /* 32-39 undefs */
- 0,0,0,0,0,0,0,10, /* 40-47 */
- 0,0,0,0,0,0,0,0, /* 48-55 undefs */
- 0,0,0,0,0,0,0,0, /* 56-63 undefs */
- 0,0,0,0,0,0,0,0, /* 64-71 undefs */
- 0,0,0,0,0,0,0,0, /* 72-79 undefs */
- 0,11,0,0,12,0,0,0, /* 80-87 */
- 13,14,0,0,0,0,0,0, /* 88-95 */
- 0,0,0,0,0,0,0,0, /* 96-103 undefs */
- 0,0,0,0,0,0,0,0, /* 104-111 undefs */
- 0,0,0,0,0,0,0,0, /* 112-119 undefs */
- 0,0,0,0,0,0,0,15 /* 120-126 undefs */
- };
-
-
- /*------------------- les fonctions de lecture d'un événement --------------*/
- static ReadFunc ReadEvTbl[]=
- {
- read_2DataEv, /* $80 : 1 typeKeyOff */
- read_2DataEv, /* $90 : 2 typeKeyOn */
- read_2DataEv, /* $a0 : 3 typeKeyPress */
- read_2DataEv, /* $b0 : 4 typeCtrlChange */
- read_1DataEv, /* $c0 : 5 typeProgChange */
- read_1DataEv, /* $d0 : 6 typeChanPress */
- read_2DataEv, /* $e0 : 7 typePitchWheel */
-
- read_sysex, /* $f0 : 17 typeSysEx */
- read_1DataEv, /* $f1 : 130 typeQuarterFrame */
- read_2DataEv, /* $f2 : 8 typeSongPos */
- read_1DataEv, /* $f3 : 9 typeSongSel */
- read_undef, /* $f4 */
- read_undef, /* $f5 */
- read_0DataEv, /* $f6 : 14 typeTune */
- read_sysex, /* $f7 : 18 typeStream */
- read_0DataEv, /* $f8 : 10 typeClock */
- read_undef, /* $f9 */
- read_0DataEv, /* $fa : 11 typeStart */
- read_0DataEv, /* $fb : 12 typeContinue */
- read_0DataEv, /* $fc : 13 typeStop */
- read_undef, /* $fd */
- read_0DataEv, /* $fe : 15 typeActiveSens */
- read_undef, /* $ff : 16 typeReset */
- };
-
- static ReadMetaFunc ReadExtTbl[]=
- {
- read_undef, /* type non défini */
- read_seqNum, /* 134 typeSeqNum */
- read_text, /* 135 typeText */
- read_text, /* 136 typeCopyright */
- read_text, /* 137 typeSeqName */
- read_text, /* 138 typeInstrName */
- read_text, /* 139 typeLyric */
- read_text, /* 140 typeMarker */
- read_text, /* 141 typeCuePoint */
- read_chanPref, /* 142 typeChanPrefix */
- read_endTrack, /* 143 typeEndTrack */
- read_tempo, /* 144 typeTempo */
- read_smpte, /* 145 typeSMPTEOffset */
- read_timeSign, /* 146 typeTimeSign */
- read_keySign, /* 147 typeKeySign */
- read_text /* 148 typeSpecific */
- };
-
- static WriteFunc WriteEvTbl[]=
- {
- write_note, /* 0 typeNote */
- write_2DataEv, /* 1 typeKeyOn */
- write_2DataEv, /* 2 typeKeyOff */
- write_2DataEv, /* 3 typeKeyPress */
- write_2DataEv, /* 4 typeCtrlChange */
- write_1DataEv, /* 5 typeProgChange */
- write_1DataEv, /* 6 typeChanPress */
- write_2DataEv, /* 7 typePitchWheel */
- write_2DataEv, /* 8 typeSongPos */
- write_1DataEv, /* 9 typeSongSel */
- write_0DataEv, /* 10 typeClock */
- write_0DataEv, /* 11 typeStart */
- write_0DataEv, /* 12 typeContinue */
- write_0DataEv, /* 13 typeStop */
- write_0DataEv, /* 14 typeTune */
- write_0DataEv, /* 15 typeActiveSens */
- dont_write, /* 16 typeReset */
- write_sysex, /* 17 typeSysEx */
- write_sysex, /* 18 typeStream */
- };
-
-
- static WriteFunc WriteExtTbl[]=
- {
- write_1DataEv, /* 130 typeQuarterFrame */
- write_Ctrl14b, /* 131 typeCtrl14b */
- write_NRegP, /* 132 typeNonRegParam */
- write_RegP, /* 133 typeRegParam */
-
- write_SeqNum, /* 134 typeSeqNum */
- write_texte, /* 135 typeText */
- write_texte, /* 136 typeCopyright */
- write_texte, /* 137 typeSeqName */
- write_texte, /* 138 typeInstrName */
- write_texte, /* 139 typeLyric */
- write_texte, /* 140 typeMarker */
- write_texte, /* 141 typeCuePoint */
-
- write_chanPref, /* 142 typeChanPrefix */
- write_endTrack, /* 143 typeEndTrack */
- write_tempo, /* 144 typeTempo */
- write_smpte, /* 145 typeSMPTEOffset */
- write_timeSign, /* 146 typeTimeSign */
- write_keySign, /* 147 typeKeySign */
- write_texte /* 148 typeSpecific */
- };
-
-
- /*--------------------------------------------------------------------------*/
- /* Lecture et d'écriture des données codées en longueur variable */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static unsigned long ReadVarLen( register midiFILE *fd)
- {
- register FILE *fp;
- register unsigned long val;
- register short c;
-
- fp= fd->fd;
- if ((val = (unsigned long) getc(fp)) & 0x80)
- {
- val &= 0x7F;
- do {
- val= (val<< 7) + ((c= getc(fp)) & 0x7F);
- fd->_cnt--; /* m.a.j. de reste à lire */
- } while (c & 0x80 && !feof( fp));
- }
- fd->_cnt--; /* m.a.j. de reste à lire */
- return val;
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean WriteVarLen( register unsigned long val, register FILE *fd)
- {
- register unsigned long buf;
-
- buf= val & 0x7F;
- while( val >>= 7)
- {
- buf <<= 8;
- buf |= 0x80;
- buf += (val & 0x7F);
- }
- while( true)
- {
- putc( buf, fd);
- if( buf & 0x80) buf >>= 8;
- else break;
- }
- return !ferror( fd);
- }
-
-
-
- /*--------------------------------------------------------------------------*/
- /* Lecture et écriture d'un en-tête de fichier MidiFile */
- /* header = 'MThd' 00 06 format nbtracks division/battue */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static Boolean ReadMdfHeader( register midiFILE *fd)
- {
- MDF_Header h;
- register Boolean ret= true; /* code de retour */
-
- if( fread( &h, sizeof( MDF_Header),1, fd->fd)== 1) /* lit l'en-tête */
- {
- if( strncmp( h.id, MDF_MThd, 4) || h.len!= 6)
- {
- MidiFile_errno= MidiFileErrFrmt;/* erreur de format du fichier */
- ret= false;
- }
- else
- {
- fd->format= h.format; /* format du fichier */
- fd->ntrks= h.ntrks; /* nbre de pistes du fichier */
- fd->time= h.time; /* représentation du temps */
- }
- }
- else ret= false;
- return ret;
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean Create_mdfHeader( register midiFILE *fd, short format, short time)
- {
- MDF_Header h;
- register Boolean ret; /* code de retour */
-
- strcpy( h.id, MDF_MThd); /* recopie de l'en-tête */
- h.len= 6; /* longueur des données */
- h.ntrks= 0; /* nbre de pistes = 0 */
- h.format= format; /* format du fichier */
- h.time= time; /* représentation du temps */
- ret= (fwrite( &h, sizeof( MDF_Header), 1, fd->fd)== 1);
- return ret;
- }
-
-
-
- /*--------------------------------------------------------------------------*/
- /* Lecture et écriture d'un en-tête de piste */
- /* header = 'MTrk' <long len> */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static Boolean ReadTrkHeader( register FILE *fd, register MDF_Trk *h)
- {
- Boolean ret= true; /* code de retour */
-
- if( fread( h, sizeof( MDF_Trk), 1, fd)== 1) /* lecture de l'en-tête */
- {
- if( strncmp( h->id, MDF_MTrk, 4))
- {
- MidiFile_errno= MidiFileErrFrmt;/* erreur de format du fichier */
- ret= false;
- }
- }
- else ret= false;
- return ret;
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean Create_trkHeader( register FILE *fd, long len)
- {
- Boolean ret= true; /* code de retour */
- MDF_Trk h; /* en-tête de piste */
-
- strcpy( h.id, MDF_MTrk); /* recopie de l'en-tête */
- h.len= len; /* longueur des données */
- ret= (fwrite( &h, sizeof( MDF_Trk), 1, fd)== 1);
- return ret;
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* Fonction de positionnement dans un fichier */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileChooseTrack( midiFILE *fd, short numPiste)
- {
- MDF_Trk h;
-
- MidiFile_errno= MidiFileNoErr;
- if( numPiste >= fd->ntrks)
- {
- MidiFile_errno= MidiFileErrNoTrack;
- return false;
- }
- if( fseek( fd->fd, sizeof( MDF_Header), SEEK_SET)) /* pos = piste 0 */
- return false;
- while( numPiste--)
- if( !ReadTrkHeader( fd->fd, &h) || fseek( fd->fd, h.len, SEEK_CUR))
- return false;
- return true;
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* */
- /* Fonctions d'écriture des événements */
- /* */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- /* Ecriture des méta-événements */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_keySign( midiFILE *f, register MidiEvPtr ev, short)
- {
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_Ton, fd); /* type de méta evt */
- putc( MDF_TonLen, fd); /* longueur */
- putc( KSTon(ev), fd); /* les altérations */
- putc( KSMode(ev), fd); /* le mode: maj/min */
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_timeSign( midiFILE *f, register MidiEvPtr ev, short)
- {
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_Meas, fd); /* type de méta evt */
- putc( MDF_MeasLen, fd); /* longueur */
- putc( TSNum(ev), fd); /* le numerateur */
- putc( TSDenom(ev), fd); /* le dénominateur */
- putc( TSClocks(ev), fd); /* nbre de clocks */
- putc( TS32nd(ev), fd); /* nbre de 32ieme de note*/
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_smpte( midiFILE *f, register MidiEvPtr ev, short)
- {
- register unsigned long l;
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_Offset, fd); /* type de méta evt */
- putc( MDF_OffsetLen, fd); /* longueur */
- l= MidiGetField( ev, 0); /* offset temps en sec */
- putc( l/3600, fd); /* les heures */
- l%= 3600;
- putc( l/60, fd); /* les minutes */
- putc( l%60, fd); /* les secondes */
- l= MidiGetField( ev, 1); /* offset frame et div */
- putc( l/100, fd); /* la frame */
- putc( l%100, fd); /* division de la frame */
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_tempo( midiFILE *f, MidiEvPtr ev, short)
- {
- register unsigned long l;
- register unsigned short s;
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_Tempo, fd); /* type de méta evt */
- putc( MDF_TempoLen, fd); /* longueur */
- s= l= Tempo( ev);
- putc( l >> 16, fd);
- putc( s >> 8, fd);
- putc( s & 0xF, fd);
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_endTrack( midiFILE *f, MidiEvPtr, short)
- {
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_EndTrk, fd); /* type de méta evt */
- putc( MDF_EndTrkLen, fd); /* longueur */
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_chanPref( midiFILE *f, MidiEvPtr ev, short)
- {
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_ChanPref, fd); /* type de méta evt */
- putc( MDF_ChanPrefLen, fd); /* longueur */
- putc( ChanPrefix(ev), fd);
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_texte( midiFILE *f, MidiEvPtr ev, short status)
- {
- register long len, i;
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( status, fd); /* type de méta evt */
- len= MidiCountFields( ev);
- WriteVarLen( len, fd);
- for( i=0; i<len; i++)
- putc( MidiGetField( ev, i), fd);
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_SeqNum( midiFILE *f, MidiEvPtr ev, short)
- {
- register unsigned short s;
- register FILE *fd;
-
- fd= f->fd;
- putc( META, fd); /* header du méta evt */
- putc( MDF_NumSeq, fd); /* type de méta evt */
- putc( MDF_NumSeqLen, fd); /* longueur */
- s= SeqNum(ev);
- putc( s >> 8, fd);
- putc( s & 0xF, fd);
- return !ferror( fd);
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* Ecriture des événements midi */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_param( register FILE *fd, register short num, register short val, register short type)
- {
- putc( type, fd); /* NRP number msb */
- putc( num >> 7, fd); /* numéro msb valeur */
- WriteVarLen( 0, fd); /* ev suivant, status courant */
- putc( type-1, fd); /* NRP number lsb */
- putc( num & 0x7F, fd); /* numéro lsb valeur */
- WriteVarLen( 0, fd); /* ev suivant, status courant */
- putc( 6, fd); /* data entry msb */
- putc( val >> 7, fd); /* envoi msb */
- WriteVarLen( 0, fd); /* ev suivant, status courant */
- putc( 38, fd); /* data entry lsb */
- putc( val & 0x7F, fd); /* envoi lsb */
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_NRegP( register midiFILE *fd, register MidiEvPtr ev, short)
- {
- register short num, val;
-
- num= MidiGetField( ev, 0); /* num du controleur */
- val= MidiGetField( ev, 1); /* valeur sur 14 bits */
- putc( ControlChg + Canal( ev), fd->fd); /* octet de status */
- return write_param( fd->fd, num, val, 99);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_RegP( register midiFILE *fd, register MidiEvPtr ev, short)
- {
- register short num, val;
-
- num= MidiGetField( ev, 0); /* num du controleur */
- val= MidiGetField( ev, 1); /* valeur sur 14 bits */
- putc( ControlChg + Canal( ev), fd->fd); /* octet de status */
- return write_param( fd->fd, num, val, 101);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_Ctrl14b( midiFILE *f, register MidiEvPtr ev, short)
- {
- register short num, val;
- register FILE *fd;
-
- fd= f->fd;
- num= MidiGetField( ev, 0); /* num du controleur */
- val= MidiGetField( ev, 1); /* valeur sur 14 bits */
- putc( ControlChg + Canal( ev), fd); /* octet de status */
- putc( num, fd); /* envoi numéro de ctrl */
- putc( val >> 7, fd); /* envoi msb */
- WriteVarLen( 0, fd); /* ev suivant, status courant */
- putc( num+32, fd); /* num ctrl associé */
- putc( val & 0x7F, fd); /* envoi lsb */
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_sysex( midiFILE *f, register MidiEvPtr ev, short)
- {
- register short count, i;
- register FILE *fd;
-
- fd= f->fd;
- count= MidiCountFields( ev);
- if( EvType( ev)== typeSysEx) /* c'est un sysex */
- putc( 0xF0, fd); /* en tête message sysex */
- else /* c'est un stream */
- putc( 0xF7, fd); /* en tête suite de sysex */
- WriteVarLen( count, fd); /* longueur du message */
- for( i=0; i< count; i++)
- putc( MidiGetField( ev, i), fd); /* et datas */
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean dont_write( midiFILE *, MidiEvPtr , short)
- {
- return true;
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_0DataEv( register midiFILE *fd, MidiEvPtr, short status)
- {
- putc( status, fd->fd);
- return !ferror( fd->fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_1DataEv( midiFILE *f, register MidiEvPtr ev, short status)
- {
- register FILE *fd;
-
- fd= f->fd;
- putc( status, fd);
- putc( Data( ev)[0], fd);
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_2DataEv( midiFILE *f, register MidiEvPtr ev, short status)
- {
- register FILE *fd;
-
- fd= f->fd;
- putc( status, fd);
- putc( Data( ev)[0], fd);
- putc( Data( ev)[1], fd);
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean write_note( midiFILE *f, register MidiEvPtr ev, short status)
- {
- register MidiEvPtr c;
- register FILE *fd;
-
- fd= f->fd;
- if( c = MidiCopyEv( ev))
- {
- EvType(c)= typeKeyOff;
- Vel(c) = 0;
- Date(c) = Date( ev) + Dur( ev);
- Dur(c) = 0;
- MidiAddSeq( f->keyOff, c);
- putc( status, fd);
- putc( Data( ev)[0], fd);
- putc( Data( ev)[1], fd);
- }
- else
- {
- MidiFile_errno= MidiFileErrEvs;
- return false;
- }
- return !ferror( fd);
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean WriteEv( register midiFILE *fd, register MidiEvPtr ev)
- {
- register short type;
- register Boolean ret= true;
-
- type= EvType( ev);
- if( type < typePrivate)
- ret= (* WriteEvTbl[type])( fd, ev, (type < typeSongPos ? codeTbl[type]+Canal(ev) : codeTbl[type]));
- else if( type >= typeQuarterFrame && type < typeReserved)
- {
- type-= typeQuarterFrame;
- ret= (* WriteExtTbl[type])( fd, ev, metaCodeTbl[type]);
- }
- return ret;
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean FlushKeyOff( register midiFILE *fd)
- {
- register MidiSeqPtr seq;
- register MidiEvPtr ev;
- register Boolean ret= true;
- register long date;
-
- seq= fd->keyOff; /* la séquence des key off */
- ev= seq->first; /* son premier événement */
- date= fd->curDate; /* date courante */
- while( ev && ret)
- {
- seq->first= Link(ev); /* premier = suivant */
- ret= (WriteVarLen( Date( ev)- date, fd->fd)
- && WriteEv( fd, ev)); /* écrit l'événement */
- date= Date( ev); /* m.a.j. date courante */
- MidiFreeEv( ev); /* le libère */
- ev= seq->first; /* événement suivant */
- }
- if( ret) seq->last= nil; /* maj de la séquence */
- fd->curDate= date; /* m.a.j. date courante */
- return ret;
- }
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileNewTrack( midiFILE *fd)
- {
- MidiFile_errno= MidiFileNoErr;
- if( isTrackOpen( fd) && !MidiFileCloseTrack( fd)) /* piste ouverte */
- return false; /* on la referme */
- if( fseek( fd->fd, 0, SEEK_END)) /* position en fin de fichier */
- return false;
- if( !Create_trkHeader( fd->fd, 0)) /* écriture en-tête de piste */
- return false;
- if( fgetpos(fd->fd,&fd->trkHeadOffset)) /* position de début de piste */
- return false;
- fd->curDate= 0; /* date courante = 0 */
- return true;
- }
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileOpenTrack( register midiFILE *fd)
- {
- MDF_Trk h;
-
- MidiFile_errno= MidiFileNoErr;
- if( fd->mode)
- {
- MidiFile_errno= MidiFileErrNoTrack;
- return false;
- }
- if( isTrackOpen( fd)) /* piste déja ouverte */
- return true;
- if( ReadTrkHeader( fd->fd, &h)) /* on lit l'en-tête de piste */
- {
- fd->_cnt= h.len; /* longueur de piste=0 => fin */
- fd->curDate= 0; /* date courante = 0 */
- fd->trkHeadOffset= true; /* signale piste ouverte */
- }
- else return false;
- return true;
- }
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileCloseTrack( register midiFILE *fd)
- {
- fpos_t offset1, offset2; /* offset début et fin de piste */
- long trkLen; /* longueur de la piste */
- register Boolean ret;
-
- MidiFile_errno= MidiFileNoErr;
- offset1= fd->trkHeadOffset;
- if( fd->mode ) /* fichier en écriture */
- {
- if( offset1= fd->trkHeadOffset) /* piste ouverte */
- {
- ret= FlushKeyOff( fd); /* écrit les keyOff restants */
- if( fgetpos( fd->fd, &offset2)) /* position de fin de piste */
- return false;
- trkLen= offset2- offset1; /* calcule la longueur */
- offset1-= offset_trkLen;
- if( fsetpos( fd->fd, &offset1)) /* pos = longueur de piste */
- return false;
- /* m.a.j. longueur de la piste */
- if( fwrite( &trkLen, sizeof( trkLen), 1, fd->fd)!= 1)
- return false;
- if( fseek( fd->fd, offset_ntrks, SEEK_SET)) /* pos = nbre de pistes */
- return false;
- fd->ntrks++; /* incrémente nbre de pistes */
- /* m.a.j. du nombre de pistes */
- if( fwrite( &fd->ntrks, sizeof( fd->ntrks), 1, fd->fd)!= 1)
- return false;
- }
- }
- else if( isTrackOpen( fd)) /* fichier en lecture */
- /* position = début piste suivante */
- ret= ( fseek( fd->fd, fd->_cnt, SEEK_CUR)== 0);
- fd->trkHeadOffset= nil; /* signale piste fermée */
- return ret;
- }
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileWriteEv( register midiFILE *fd, MidiEvPtr ev)
- {
- register MidiSeqPtr seq;
- register MidiEvPtr off;
- register long date;
-
- if( fd->trkHeadOffset)
- MidiFile_errno= MidiFileNoErr;
- else
- {
- MidiFile_errno= MidiFileErrTrackClose;
- return false;
- }
- date= fd->curDate; /* date courante */
- seq= fd->keyOff; /* seq des key off */
- off= seq->first; /* prochain key off */
- while( off && (Date(ev) >= Date(off))) /* key off précède l'evt courant*/
- {
- if( !WriteVarLen( Date(off)- date, fd->fd) || /* ecrit l'offset */
- !WriteEv( fd, off)) /* et le key off */
- return false;
- date= Date( off); /* m.a.j. date courante */
- seq->first= Link(off); /* m.a.j. de la séquence*/
- MidiFreeEv( off); /* libère le key off */
- if( !(off= seq->first)) /* key off = suivant */
- seq->last= nil;
- }
- if( !WriteVarLen( Date( ev)- date, fd->fd) || /* ecrit l'offset */
- !WriteEv( fd, ev)) /* et l'evt */
- return false;
- fd->curDate= Date( ev); /* m.a.j. date courante */
- return true;
- }
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileWriteTrack( register midiFILE *fd, MidiSeqPtr seq)
- {
- register MidiEvPtr ev;
- register Boolean ret= true;
-
- MidiFile_errno= MidiFileNoErr;
- if( !MidiFileNewTrack( fd)) /* écriture en-tête de piste */
- return false;
-
- ev= seq->first;
- while( ev && ret)
- {
- ret= MidiFileWriteEv( fd, ev); /* écriture de l'evt */
- ev= Link( ev); /* evt suivant */
- }
-
- if( !MidiFileCloseTrack( fd)) /* mise à jour en-tête de piste */
- ret= false; /* et en-tête de fichier */
- return ret;
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* Lecture d'une piste */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static Boolean mdf_GetDate( register midiFILE *fd)
- {
- register long offset;
-
- offset= ReadVarLen( fd); /* lit l'offset de l'evt suivant */
- if( feof( fd->fd)) /* contrôle d'erreur de structure */
- {
- MidiFile_errno= MidiFileErrFrmt;
- return false;
- }
- if( ferror( fd->fd)) /* contrôle d'erreur */
- return false;
- fd->curDate+= offset; /* ajoute l'offset à la date courante */
- return true;
- }
-
- /*--------------------------------------------------------------------------*/
- static void mdf_ignoreEv( register midiFILE *fd, register long len)
- {
- fd->_cnt-= len;
- while( len--)
- getc( fd->fd);
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* fonctions de lecture d'un méta-événement */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_text( register midiFILE *fd, register long len, short type)
- {
- register MidiEvPtr ev=nil;
-
- if( ev= MidiNewEv( type + 133))
- {
- fd->_cnt-= len;
- while( len--)
- MidiAddField( ev, (long)getc( fd->fd));
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_endTrack( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
-
- if( len!= MDF_EndTrkLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( !(ev= MidiNewEv( typeEndTrack)))
- MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_tempo( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
- register long tempo;
-
- if (len != MDF_TempoLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( ev= MidiNewEv( typeTempo))
- {
- tempo= (long)getc(fd->fd);
- tempo <<= 8;
- tempo|= getc(fd->fd);
- tempo <<= 8;
- tempo|= getc(fd->fd);
- Tempo(ev)= tempo;
- fd->_cnt-= len;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_keySign( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
-
- if (len != MDF_TonLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( ev= MidiNewEv( typeKeySign))
- {
- KSTon( ev)= getc(fd->fd);
- KSMode( ev)= getc(fd->fd);
- fd->_cnt-= len;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_timeSign( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
-
- if (len != MDF_MeasLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( ev= MidiNewEv( typeTimeSign))
- {
- TSNum( ev)= getc(fd->fd);
- TSDenom( ev)= getc(fd->fd);
- TSClocks( ev)= getc(fd->fd);
- TS32nd( ev)= getc(fd->fd);
- fd->_cnt-= len;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_seqNum( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
- register short num;
-
- if (len != MDF_NumSeqLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( ev= MidiNewEv( typeSeqNum))
- {
- num= getc(fd->fd);
- num <<= 8;
- num|= getc(fd->fd);
- SeqNum(ev)= num;
- fd->_cnt-= len;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_chanPref( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
-
- if (len != MDF_ChanPrefLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( ev= MidiNewEv( typeChanPrefix))
- {
- ChanPrefix(ev)= getc(fd->fd);
- fd->_cnt-= len;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_smpte( register midiFILE *fd, register long len, short)
- {
- register MidiEvPtr ev=nil;
- register long tmp;
-
- if (len != MDF_OffsetLen) /* longueur du message */
- mdf_ignoreEv( fd, len);
- else if( ev= MidiNewEv( typeSMPTEOffset))
- {
- tmp= getc(fd->fd)* 3600; /* heure -> sec. */
- tmp+= getc(fd->fd)* 60; /* minutes -> sec. */
- tmp+= getc(fd->fd); /* secondes */
- MidiAddField( ev, tmp);
- tmp= getc(fd->fd)* 100; /* nbre de frame *100 */
- tmp+= getc(fd->fd); /* division de la frame */
- MidiAddField( ev, tmp);
- fd->_cnt-= len;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr mdf_read_meta( register midiFILE *fd)
- {
- register short type;
- register unsigned long len;
-
- type= getc(fd->fd); /* lit le type du message */
- fd->_cnt--; /* m.a.j. de reste à lire */
- len= ReadVarLen(fd); /* lit la longueur du message */
-
- if( type & 0x80) type=0; /* type > 127 => inconnu */
- else type= metaTypeTbl[type];
- return (*ReadExtTbl[type])( fd, len, type);
- }
-
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_undef( midiFILE *, short)
- {
- MidiFile_errno= MidiFileErrUnknow;
- return nil;
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* fonctions de lecture d'un événement midi */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_sysex( register midiFILE *fd, register short status)
- {
- register MidiEvPtr ev;
- register unsigned long len;
- register short c;
-
- if( ev= MidiNewEv( status== 0xF0 ? typeSysEx : typeStream))
- {
- len= ReadVarLen( fd); /* longueur du message */
- while( len--)
- {
- c= getc( fd->fd); /* lit les données */
- fd->_cnt--;
- MidiAddField( ev, c); /* et les range dans ev */
- }
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_2DataEv( register midiFILE *fd, register short status)
- {
- register MidiEvPtr ev;
-
- if( ev= MidiNewEv( typeTbl[status & 0x7F])) /* alloue l'événement */
- {
- Data( ev)[0]= getc( fd->fd); /* range la 1ière donnée*/
- Data( ev)[1]= getc( fd->fd); /* et la 2ième donnée */
- fd->_cnt-= 2;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_1DataEv( register midiFILE *fd, register short status)
- {
- register MidiEvPtr ev;
-
- if( ev= MidiNewEv( typeTbl[status & 0x7F])) /* alloue l'événement */
- {
- Data( ev)[0]= getc( fd->fd); /* range la donnée */
- fd->_cnt--;
- }
- else MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr read_0DataEv( midiFILE *, register short status)
- {
- register MidiEvPtr ev;
-
- if( !(ev= MidiNewEv( typeTbl[status & 0x7F])))/* alloue l'événement */
- MidiFile_errno= MidiFileErrEvs;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- static MidiEvPtr ReadEv( register midiFILE *fd)
- {
- register MidiEvPtr ev= nil;
- register short c;
- static short status= nil;
-
- c= getc( fd->fd);
- fd->_cnt--; /* m.a.j. de reste à lire */
-
- if( c== META) /* méta evt */
- {
- ev= mdf_read_meta( fd);
- c= status= nil;
- }
- else if( c & 0x80) /* octet de status */
- status= c;
- else if( status) /* status courant */
- {
- ungetc (c, fd->fd); /* rend le char */
- fd->_cnt++;
- c= status;
- }
- else
- {
- MidiFile_errno= MidiFileErrFrmt;
- c= nil;
- }
- if( c)
- {
- if( ev= (* ReadEvTbl[(c<SysEx) ? (c & 0x7F)/16 : c- SysEx+7])( fd, c))
- if( c < SysEx)
- Canal(ev)= c%16;
- }
- if( (ferror( fd->fd) || feof( fd->fd)) && ev)
- {
- MidiFreeEv( ev);
- ev= nil;
- if( feof( fd->fd))
- MidiFile_errno= MidiFileErrFrmt;
- }
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- MidiEvPtr MidiFileReadEv( register midiFILE *fd)
- {
- register MidiEvPtr ev= nil;
-
- MidiFile_errno= MidiFileNoErr;
- if( isTrackOpen( fd)) /* si la piste est ouverte */
- {
- if( fd->_cnt > 0) /* s'il reste des evts à lire */
- {
- if( mdf_GetDate( fd)) /* lit date de l'evt suivant */
- if( ev= ReadEv( fd)) /* lit l'événement */
- Date( ev)= fd->curDate; /* stocke sa date */
- }
- else fd->trkHeadOffset= 0; /* sinon on referme la piste */
- }
- else MidiFile_errno= MidiFileErrTrackClose;
- return ev;
- }
-
- /*--------------------------------------------------------------------------*/
- MidiSeqPtr MidiFileReadTrack( register midiFILE *fd)
- {
- register MidiSeqPtr seq= nil;
- register MidiEvPtr ev;
-
- MidiFile_errno= MidiFileNoErr;
- if( MidiFileOpenTrack( fd)) /* on ouvre la piste */
- {
- if( seq= MidiNewSeq()) /* alloue une séquence */
- {
- while( isTrackOpen( fd)) /* tant qu'il y a des evts */
- {
- if( ev= MidiFileReadEv( fd)) /* on lit les événements */
- {
- if( !seq->first) /* on les range dans la seq */
- seq->first= seq->last= ev;
- else
- {
- Link(seq->last)= ev;
- seq->last= ev;
- }
- }
- else if( isMidiFileError( fd)) /* sinon si erreur */
- {
- MidiFreeSeq( seq); /* libère la séquence */
- seq= nil; /* pour renvoi erreur */
- break;
- } /* sinon c'est un evt ignoré */
- }
- }
- else MidiFile_errno= MidiFileErrEvs;
- }
- return seq;
- }
-
-
-
- /*--------------------------------------------------------------------------*/
- /* Ouverture et fermeture d'un fichier MidiFile */
- /*--------------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------------*/
- static const char *mdf_getStdMode( register short mode)
- {
- switch( mode)
- {
- case MidiFileRead:
- return "r";
- case MidiFileAppend:
- return "r+";
- default:
- MidiFile_errno= MidiFileErrMode;
- return nil;
- }
- }
-
- /*--------------------------------------------------------------------------*/
- static void ErrOpen( register midiFILE *fd)
- {
- if( fd)
- {
- if( fd->fd) fclose( fd->fd); /* fichier ouvert: on ferme */
- if( fd->mode && fd->keyOff)
- MidiFreeSeq( fd->keyOff); /* seq allouée: on libère */
- free( fd);
- }
- }
-
- /*--------------------------------------------------------------------------*/
- static Boolean stdInit( register midiFILE *fd)
- {
- fd->trkHeadOffset= nil;
- fd->curDate= 0;
- if( fd->mode)
- {
- if( !(fd->keyOff= MidiNewSeq()))
- return false;
- }
- else fd->keyOff= nil;
- return true;
- }
-
- /*--------------------------------------------------------------------------*/
- midiFILE *MidiFileOpen( const char *filename, short mode)
- {
- register midiFILE *fd; /* pour le descripteur de mon fichier MidiFile */
- Boolean ok= true; /* pour savoir si tout s'est bien passé */
- const char *stdMode; /* mode d'ouverture standard */
-
- MidiFile_errno= MidiFileNoErr;
- if( fd= (midiFILE *)malloc( sizeof( midiFILE)))
- {
- fd->fd= nil;
- stdInit( fd); /* initialisation standard */
- if( (stdMode= mdf_getStdMode( mode)) && /* ctrl mode d'ouverture */
- (fd->fd= fopen( filename, stdMode))) /* ouverture du fichier */
- {
- if( ok= ReadMdfHeader( fd)) /* lit l'en-tête du fichier */
- {
- if( fd->format== midifile0 && mode== MidiFileAppend)
- { /* erreur : */
- MidiFile_errno= MidiFileErrAdd0;/* tentative d'ajout à un */
- ok= false; /* fichier au format 0 */
- }
- fd->mode= (mode== MidiFileAppend ? true : false);
- ok= stdInit( fd); /* initialisation standard */
- }
- }
- else ok= false;
- }
- if( !ok) /* il y a eut erreur */
- {
- ErrOpen( fd);
- fd= nil;
- }
- return fd;
- }
-
-
- /*--------------------------------------------------------------------------*/
- midiFILE *MidiFileCreate( const char *name, short format, short timeDef, short ticks)
- {
- register midiFILE *fd; /* pour le descripteur de mon fichier MidiFile */
- Boolean ok= true; /* pour savoir si tout s'est bien passé */
- short time; /* représentation du temps */
-
- MidiFile_errno= MidiFileNoErr;
- if( fd= (midiFILE *)malloc( sizeof( midiFILE)))
- {
- if( fd->fd= fopen( name, "w+")) /* ouverture du fichier */
- {
- fd->mode= true; /* on est en écriture */
- fd->ntrks= 0; /* nbre de pistes = 0 */
- fd->format= format; /* format du fichier */
- if( timeDef) /* temps smpte */
- {
- time= (timeDef | 0x80) << 8;
- time|= (char) ticks;
- }
- else time= ticks & 0x7FFF;
- if( ok= stdInit( fd)) /* initialisation standard */
- ok= Create_mdfHeader( fd, format, fd->time= time);
- }
- else ok= false;
- }
- if( !ok) /* il y a eut erreur */
- {
- ErrOpen( fd);
- fd= nil;
- }
- return fd;
- }
-
- /*--------------------------------------------------------------------------*/
- Boolean MidiFileClose( register midiFILE *fd)
- {
- register int ret1= true, ret2; /* codes de retour */
-
- MidiFile_errno= MidiFileNoErr;
- if( fd->mode) /* fichier en écriture */
- {
- if( fd->trkHeadOffset) /* piste encore ouverte */
- ret1= MidiFileCloseTrack( fd); /* on la referme */
- if( fd->keyOff)
- MidiFreeSeq( fd->keyOff); /* libère la séquence */
- }
- ret2= fclose( fd->fd); /* ferme le fichier */
- free( fd); /* libère la mémoire */
- return ret1 && ret2== 0;
- }
-
- /*--------------------------------------------------------------------------*/
- const MDF_versions *MidiFileGetVersion(void)
- {
- static MDF_versions versions;
-
- versions.src= SRC_VERSION;
- versions.MidiFile= MDF_VERSION;
- return (const MDF_versions *)&versions;
- }
-
- /*--------------------------------------------------------------------------*/
- /* main présent uniquement pour link -uf et élaboration de la librairie */
-
- #ifdef LIB
-
- void main()
- {
- MidiFileGetVersion();
- MidiFileOpen( nil, nil);
- MidiFileCreate( nil, nil, nil, nil);
- MidiFileClose( nil);
- MidiFileSetPos( nil, nil);
- MidiFileReadTrack( nil);
- MidiFileWriteTrack( nil, nil);
- MidiFileCloseTrack( nil);
- MidiFileNewTrack( nil);
- MidiFileWriteEv( nil, nil);
- }
-
- #endif
-
- /*********************************** fin ************************************/
-