GIS_Head.cpp
gehe zur Dokumentation dieser Datei
00001 
00028 // #################################################################
00029 // provides read header for GIS (GMN Intern Structur)
00030 // ##################################################################
00031 
00032 #include "GIS_Head.h"
00033 #include <stdlib.h>
00034 
00035 #if defined(WX)
00036 #include "wx/string.h"
00037 #else
00038 #include <string.h>
00039 #define muT(x) x
00040 #endif
00041 
00042 char ArticulationHold[5] = { 80, 100, 90, 90, 60 }; // range: 0-100
00043 char ArticulationOff[5] = { 80, 80, 60, 127, 127 }; // range: 0-127
00044 
00045 // ------------------------------------------------------------------
00046 // help functions
00047 
00048 double GetReal(GisToken *token)
00049 {
00050         if ( GetGisType(token) == GTParaInt )
00051                 return (double) ((GisParaInt*)token)->i;
00052         else if ( GetGisType(token) == GTParaReal )
00053                 return ((GisParaReal*)token)->x;
00054 
00055         return 0;
00056 }
00057 
00058 char GetMidiInstrument(GisToken *token)
00059 {
00060         if ( token && GetGisType(token) == GTParaStr ) {
00061                 mutString t;
00062 #if defined(WX)
00063                 mutString v;
00064                 long value;
00065                 t=(((GisParaStr*)token)->s).Upper();
00066                 DEBUGLOG2(other,_T("t= %s"), t.c_str());
00067 
00068                 if (t.StartsWith(mutT("MIDI"),&v)) {
00069                         v.ToLong(&value);
00070                         DEBUGLOG2(other,_T("v= %s"), v.c_str());
00071                         return (char) value;
00072                 }
00073 
00074 #else
00075                 strncpy(t, ((GisParaStr*)token)->s, 30);
00076 
00077                 strupr(t);
00078 
00079                 if ( !strncmp(t, "MIDI", 4) )
00080                         return atoi(&t[4]);
00081 
00082 #endif
00083         }
00084 
00085         return 0;
00086 }
00087 
00088 #define ZIFFER (mutT('0') <= t[i] && t[i] <= mutT('9'))
00089 int GetTheSpeedFactor(GisToken *token)
00090 {
00091         DEBUGLOG2(other,_T("%p"),token);
00092 
00093         if ( token && GetGisType(token) == GTParaStr ) {
00094                 const mutString &t = ((GisParaStr*) token) -> s;
00095 
00096                 DEBUGLOG2(other,_T("%s"),t.c_str());
00097 
00098                 int i = 0;
00099 
00100                 long n=0, d=0, bpm=0;
00101 
00102                 while ( !ZIFFER && t[i] )
00103                         i++;
00104 
00105                 while ( ZIFFER )
00106                         n = n*10 + (t[i++]-mutT('0'));
00107 
00108                 while ( !ZIFFER && t[i] )
00109                         i++;
00110 
00111                 while ( ZIFFER )
00112                         d = d*10 + (t[i++]-mutT('0'));
00113 
00114                 while ( !ZIFFER && t[i] )
00115                         i++;
00116 
00117                 while ( ZIFFER )
00118                         bpm = bpm*10 + (t[i++]-mutT('0'));
00119 
00120                 DEBUGLOG2(other,_T("%d * 30000 / %d / %d"),d,n,bpm);
00121 
00122                 if ( !n || !d || bpm < 4 )
00123                         return 2000;
00124                 else
00125                         return d * 30000 / n / bpm;
00126         }
00127 
00128         return 2000;
00129 }
00130 
00131 // ##################################################################
00132 // methods of GisReadHead
00133 
00134 GisReadHead* GisReadHead::InsertInfrontOf(GisReadHead *position)
00135 {
00136         DEBUGLOG (other, _T("pos = %p; this = %p"),position,this);
00137 
00138         if ( !position ) {
00139                 Next = NULL;
00140                 Prev = this;
00141                 return this;
00142         }
00143 
00144 #if 0
00145         // *(position->Prev) == position
00146         if ( *(position->PrevPtr) == position ) { // first position
00147                 DEBUGLOG (other, _T("first position %p, Prev: %p, Next: %p, cmp: %p"),
00148                          position,
00149                          position->Prev,
00150                          position->Next,
00151                          *((position->PrevPtr))
00152                         );
00153                 *(position->PrevPtr) = this;
00154         } else { // normal position in list
00155                 DEBUGLOG (other, _T("first position %p, Prev: %p, Next: %p, cmp: %p"),
00156                          position,
00157                          position->Prev,
00158                          position->Next,
00159                          *((GisReadHead**)(position->PrevPtr))
00160                         );
00161                 (*(position->PrevPtr))->Next = this;
00162         }
00163 
00164         PrevPtr = position->PrevPtr;
00165 
00166         Next = position;
00167         *(position->PrevPtr) = this;
00168         return this;
00169 #else
00170         // *(position->Prev) == position
00171 
00172         if ( *(position->PrevPtr) == position ) { // first position
00173                 DEBUGLOG (other, _T("first position %p, Prev: %p, Next: %p, cmp: %p"),
00174                          position,
00175                          position->Prev,
00176                          position->Next,
00177                          *((position->PrevPtr))
00178                         );
00179                 *(position->PrevPtr) = this;
00180                 PrevPtr = position->PrevPtr;
00181                 position->PrevPtr = &(position->Prev);
00182         } else { // normal position in list
00183                 DEBUGLOG (other, _T("first position %p, Prev: %p, Next: %p, cmp: %p"),
00184                          position,
00185                          position->Prev,
00186                          position->Next,
00187                          *((GisReadHead**)(position->PrevPtr))
00188                         );
00189 
00190                 position->Prev->Next = this;
00191                 wxASSERT(position->PrevPtr == &(position->Prev));
00192         }
00193 
00194         Prev = position->Prev;
00195 
00196         Next = position;
00197         position->Prev = this;
00198 
00199         return this;
00200 #endif
00201 }
00202 
00203 GisReadHead* GisReadHead::CutOut()
00204 {
00205 #if 0
00206 
00207         if ( *(PrevPtr) == this ) // first of list
00208         {
00209                 *PrevPtr = Next;
00210         } else // normal list postition
00211         {
00212                 (*PrevPtr)->Next = Next;
00213         }
00214 
00215         if ( Next ) Next->PrevPtr = PrevPtr;
00216 
00217         Next = NULL;
00218 
00219         PrevPtr = &Prev;
00220 
00221         return this;
00222 
00223 #else
00224         if ( *(PrevPtr) == this ) // first of list
00225         {
00226                 *PrevPtr = Next;
00227 
00228                 if (Next) {
00229                         Next->PrevPtr = PrevPtr;
00230                         Next->Prev = NULL;
00231                 }
00232         }
00233         else // normal list postition
00234         {
00235                 Prev->Next = Next;
00236 
00237                 if (Next) {
00238                         Next->Prev = Prev;
00239                         wxASSERT(Next->PrevPtr == &(Next->Prev));
00240                 }
00241         }
00242 
00243         Next = NULL;
00244 
00245         PrevPtr = &Prev;
00246         Prev = NULL;
00247         return this;
00248 #endif
00249 }
00250 
00251 // create segment subs, insert infront of this
00252 void GisReadHead::CreateSegmentSubs()
00253 {
00254         GisSegment *Seg = (GisSegment*)Cursor;
00255         GisToken *Cont = Seg->Contents;
00256 #ifdef WX
00257         mutString id = Id + mutT("*");
00258 #else
00259         char *id = (char*)malloc(strlen(Id)+2);
00260         strcpy(id, Id);
00261         strcat(id, "*");
00262 #endif
00263         nSub = 0;
00264 
00265         while ( Cont ) // create the single token subs
00266         {
00267                 nSub++;
00268                 id[mutLen(Id)] = nSub;
00269                 DEBUGLOG (other, _T("Creating Sub for %p (%d, %s)"),Cont,nSub,id.c_str());
00270 
00271                 GisReadHead *Sub = Build(this, Cont, id, 1);
00272                 Cont = Cont->Next;
00273 
00274                 while ( Cont ) // read until end or comma
00275                 {
00276 
00277                         if ( Cont->Type() == GTComma )
00278                         {
00279                                 Cont = Cont->Next;
00280                                 break;
00281                         }
00282 
00283                         Cont = Cont->Next;
00284                 }
00285         }
00286 }
00287 
00288 // create sequenz subs, insert infront of this
00289 void GisReadHead::CreateSequenzSubs()
00290 {
00291         GisSegment *Seq = (GisSegment*)Cursor;
00292 #ifdef WX
00293         mutString id = Id + mutT("\x01");
00294 #else
00295         char *id = (char*)malloc(strlen(Id)+2);
00296         strcpy(id, Id);
00297         strcat(id, "\x01");
00298 #endif
00299         nSub = 1;
00300         GisReadHead *Sub = Build(this, Seq->Contents, id);
00301 }
00302 
00303 // reading the token at the cursor
00304 void GisReadHead::Read()
00305 {
00306         DEBUGLOG (other, _T("Cursor: %p"),Cursor);
00307 
00308         if ( !Cursor ) return;
00309 
00310         switch ( Cursor->Type() ) {
00311 
00312         case GTSegment:
00313                 CreateSegmentSubs();
00314 
00315                 break;
00316 
00317         case GTSequenz:
00318                 CreateSequenzSubs();
00319 
00320                 break;
00321 
00322         case GTNote:
00323                 DEBUGLOG (other, _T("Setting time"));
00324 
00325                 Time = ((GisNote*)Cursor)->Duration;
00326 
00327                 break;
00328         }
00329 
00330         // the other tokens dont influenz the way of reading
00331 }
00332 
00333 #ifdef WX
00334 wxString GisReadHead::ToString()
00335 {
00336         wxString ret = wxString::Format(_T("GisReadHead: {\nthis: %p; Boss: %p; Next: %p; Prev: %p; PrevPtr: %p; *PrevPtr: %p;\n"
00337                                            "nSub: %d; Cursor: {\n"),
00338                                         this, Boss, Next, Prev,
00339                                         PrevPtr, *PrevPtr, nSub) +
00340                        (Cursor?((wxString) *Cursor):wxString(_T(""))) + _T("}\nTime: ") + (TowxString(Time)) +
00341                        wxString::Format(_T("; Id: '%s'; Turn: %d; SingleToken: %d\n}\n"),
00342                                         Id.c_str(), Turn, SingleToken);
00343         return ret;
00344 }
00345 
00346 #endif
00347 
00348 // ##################################################################
00349 // procedures with GisReadHead
00350 
00351 // dummy procedure for GisReadHeadOn
00352 void GisReadDummy(GisReadHead*, char)
00353 {
00354         // just a dummy
00355 }
00356 
00357 // ReadOn the GisReadHead, chained
00358 frac GisReadHeadOn(GisReadHead **Head, frac dTime, GisReadProceed *proceed)
00359 {
00360         frac MinTime = frac(-1, 1);
00361 
00362 beginloop:
00363 
00364         while ( *Head ) {
00365                 GisReadHead *h = *Head;
00366 
00367                 if ( h->nSub > 0 ) // header has subs
00368                 {
00369                         Head = &(h->Next);
00370                         continue;
00371                 }
00372                 if ( h->nSub == 0 ) // all subs has finished
00373                 {
00374                         proceed(h, 1);
00375                         h->CursorNext();
00376                         h->Time = 0;
00377                 }
00378                 if ( h->Time != frac(0, 1) ) // header in normal state
00379                 {
00380                         h->Time -= dTime;
00381 
00382                         if ( h->Time <= frac(0, 1) )
00383                         {
00384                                 proceed(h, 1);
00385                                 h->CursorNext();
00386                         }
00387                 }
00388 
00389                 h->nSub = -1; // normal header
00390                 // now check, wether count down Time is 0
00391                 // if h->time = 0 then h->Cursor points to the GisToken next to proceed
00392 
00393                 while ( !(h->Time) ) // read next tokens
00394                 {
00395 
00396                         if ( !h->Cursor ) // header finished, kick away
00397                         {
00398                                 h->CutOut();
00399 
00400                                 if ( h->Boss ) h->Boss->nSub--; // inform the boss
00401 
00402                                 delete h;
00403 
00404                                 goto beginloop;
00405                         }
00406                         // proceed
00407                         proceed(h, 0);
00408 
00409                         h->Read();
00410 
00411                         if ( h->nSub != -1 ) goto beginloop;
00412 
00413                         if ( !(h->Time) ) // token without duration
00414                                 h->CursorNext();
00415                 }
00416                 // check MinTime
00417                 if ( MinTime == frac(-1,1) || h->Time < MinTime )
00418                         MinTime = h->Time;
00419 
00420                 // next Header
00421                 Head = &(h->Next);
00422         }
00423 
00424         return MinTime;
00425 }
00426 
00427 // ##################################################################
00428 // GisReadArtHead
00429 
00430 // TagList ----------------------------------------------------------
00431 
00432 TagList *Copy(TagList *list)
00433 {
00434         if ( !list ) return 0;
00435 
00436         TagList *List = new TagList;
00437 
00438         List->Next = 0;
00439 
00440         List->Tag = list->Tag;
00441 
00442         List->Data = list->Data;
00443 
00444         return List;
00445 }
00446 
00447 void Erase(TagList *list)
00448 {
00449         while ( list ) {
00450                 TagList *TopTag = list;
00451                 list = TopTag->Next;
00452                 delete TopTag;
00453         }
00454 }
00455 
00456 TagList *RemoveTag(TagList **list)
00457 {
00458         if ( *list ) {
00459                 TagList *TopTag = *list;
00460                 *list = TopTag->Next;
00461                 delete TopTag;
00462         }
00463 
00464         return *list;
00465 }
00466 
00467 TagList *AddTag(TagList **list, GisTag *tag)
00468 {
00469         if ( *list && (*list)->Tag->Type() == GTTag && tag->Type() == GTTag )
00470                 RemoveTag(list);
00471 
00472         TagList *TopTag = new TagList;
00473 
00474         TopTag->Next = *list;
00475 
00476         TopTag->Tag = tag;
00477 
00478         *list = TopTag;
00479 
00480         return *list;
00481 }
00482 
00483 TagList *EndTag(TagList **list, GisTagEnd *tagEnd)
00484 {
00485         TagList *Pos = *list;
00486 
00487         if ( Pos && Pos->Tag->Type() == GTTag )
00488                 Pos = Pos->Next;
00489 
00490         if ( Pos && tagEnd->Begin == Pos->Tag ) {
00491                 if ( Pos != *list )
00492                         RemoveTag(list);
00493 
00494                 RemoveTag(list);
00495         }
00496 
00497         return *list;
00498 }
00499 
00500 #define TAG ((GisTag*)Cursor)
00501 #define TAGEND ((GisTagEnd*)Cursor)
00502 // reading the token at the cursor
00503 void GisReadArtHead::Read()
00504 {
00505         int Id = 0;
00506         DEBUGLOG (other, _T("Id: %d; Cursor: %p"), Id, Cursor);
00507 
00508         if ( !Cursor ) return;
00509 
00510         Turn = 3;
00511 
00512         DEBUGLOG (other, _T("Cursor->Type %d"), Cursor->Type());
00513 
00514         switch ( Cursor->Type() ) {
00515 
00516         case GTSegment:
00517                 CreateSegmentSubs();
00518 
00519                 Turn = 2;
00520 
00521                 break;
00522 
00523         case GTSequenz:
00524                 CreateSequenzSubs();
00525 
00526                 Turn = 2;
00527 
00528                 break;
00529 
00530         case GTNote:
00531                 Time2 = ((GisNote*)Cursor)->Duration;
00532 
00533                 Time = Time2 * frac(ArticulationHold[GetArticulation()], 100);
00534 
00535                 DEBUGLOG (other, _T("Time: %d/%d; Time2: %d/%d"),
00536                          Time.numerator(),Time.denominator(),Time2.numerator(),Time2.denominator());
00537 
00538                 Time2 -= Time;
00539 
00540                 DEBUGLOG (other, _T("Time: %d/%d; Time2: %d/%d"),
00541                          Time.numerator(),Time.denominator(),Time2.numerator(),Time2.denominator());
00542 
00543                 Turn = 1;
00544 
00545                 break;
00546 
00547         case GTTag:
00548 
00549         case GTTagBegin:
00550                 Id = TAG->Id;
00551 
00552                 if ( Id == TTintens ) {
00553                         if ( TAG->GetParaType(2) == GTParaInt || TAG->GetParaType(2) == GTParaReal)
00554                                 AddTag(&Intensity, TAG)->Data.ch = (char) (GetReal(TAG->GetPara(2)) * 127);
00555                 } else if ( Id == TTaccent ) {
00556                         AddTag(&Intensity, TAG)->Data.ch = 120; // ???  what value
00557                 } else if ( Id == TTstacc ) {
00558                         AddTag(&Articulation, TAG)->Data.ch = ARStaccatto;
00559                 } else if ( Id == TTten ) {
00560                         AddTag(&Articulation, TAG)->Data.ch = ARTenuto;
00561                 } else if ( Id == TToct ) {
00562                         if ( TAG->GetParaType(1) == GTParaInt )
00563                                 AddTag(&Octave, TAG)->Data.i = ((GisParaInt*)TAG->GetPara(1))->i;
00564                 } else if ( Id == TTalter ) {
00565                         if ( TAG->GetParaType(1) != GTParaStr )
00566                                 AddTag(&Alter, TAG)->Data.i = (int) (GetReal(TAG->GetPara(1)) * 0x1FFF) ;
00567                 } else if ( Id == TTinstr ) {
00568                         if ( TAG->GetParaType(2) == GTParaStr )
00569                                 AddTag(&Instr, TAG)->Data.ch = GetMidiInstrument(TAG->GetPara(2));
00570                 } else if ( Id == TTtempo ) {
00571                         if ( TAG->GetParaType(2) == GTParaStr ) {
00572                                 long int speed =
00573                                         (AddTag(&Tempo, TAG)->Data.i =
00574                                                  GetTheSpeedFactor(TAG->GetPara(2)));
00575                                 DEBUGLOG (other, _T("Got speed factor %ld"),speed);
00576                         }
00577                 }
00578 
00579                 break;
00580 
00581         case GTTagEnd:
00582                 DEBUGLOG (other, _T("Ended tag."));
00583 
00584                 if ( !TAGEND->Begin )
00585                         break;
00586 
00587                 DEBUGLOG (other, _T("Tag Id was %d."),TAGEND->Begin->Id);
00588 
00589                 Id = TAGEND->Begin->Id;
00590 
00591                 if ( Id == TTintens || Id == TTaccent )
00592                         EndTag(&Intensity, TAGEND);
00593                 else if ( Id == TTstacc || Id == TTten )
00594                         EndTag(&Articulation, TAGEND);
00595                 else if ( Id == TToct )
00596                         EndTag(&Octave, TAGEND);
00597                 else if ( Id == TTalter )
00598                         EndTag(&Alter, TAGEND);
00599                 else if ( Id == TTinstr )
00600                         EndTag(&Instr, TAGEND);
00601                 else if ( Id == TTtempo )
00602                         EndTag(&Tempo, TAGEND);
00603         }
00604 
00605         // the other tokens don't influenz the way of reading
00606 }
00607 
00608 #ifdef WX
00609 wxString GisReadArtHead::ToString()
00610 {
00611         wxString ret = _T("GisReadArtHead: {\n") ;
00612         ret += GisReadHead::ToString();
00613         ret += _T("Time2: ") + (TowxString(Time2));
00614         ret +=
00615                 wxString::Format(_T("; Delta: %ld; Box: %d\n"
00616                                     "Intensity: %p; Articulation: %p; Octave: %p\n"
00617                                     "Alter: %p; Instr: %p; Tempo: %p\n"
00618                                     "}\n"),
00619                                  Delta,Box,
00620                                  Intensity,Articulation,Octave,Alter,Instr,Tempo);
00621         return ret;
00622 }
00623 
00624 #endif
00625 
00626 
00627 // ##################################################################
00628 // procedures with GisReadHead
00629 
00630 // dummy procedure for GisReadArtHeadOn
00631 void GisReadArtDummy(GisReadArtHead*, char)
00632 {
00633         // just a dummy
00634 }
00635 
00636 // ReadOn the GisReadArtHead, chained
00637 frac GisReadArtHeadOn(GisReadArtHead **Head, frac dTime, GisReadArtProceed *proceed)
00638 {
00639         DEBUGLOG2(other,_T(""));
00640         frac MinTime = frac(-1, 1);
00641 
00642 beginloop:
00643 
00644         while ( *Head ) {
00645                 GisReadArtHead *h = *Head;
00646 
00647                 if ( h->nSub > 0 ) // header has subs
00648                 {
00649                         Head = (GisReadArtHead**)&(h->Next);
00650                         continue;
00651                 }
00652                 if ( h->nSub == 0 ) // all subs has finished
00653                 {
00654                         proceed(h, h->Turn++);   // end of segment or sequenz
00655                         h->CursorNext();
00656                         h->Time = 0;
00657                 }
00658                 if ( h->Time != frac(0, 1) ) // header in normal state
00659                 {
00660                         h->Time -= dTime;
00661 
00662                         if ( h->Time <= frac(0, 1) )
00663                         {
00664                                 proceed(h, h->Turn++);
00665 
00666                                 if ( h->Turn == 2 ) {
00667                                         h->Time = h->Time2;
00668                                         h->Time2 = 0;
00669                                 }
00670 
00671                                 if ( h->Turn > 2 )
00672                                         h->CursorNext();
00673                         }
00674                 }
00675 
00676                 h->nSub = -1; // normal header
00677                 // now check, wether count down Time is 0
00678                 // if h->time = 0 then h->Cursor points to the GisToken next to proceed
00679 
00680                 while ( !(h->Time) ) // read next tokens
00681                 {
00682 
00683                         if ( h->Turn)
00684                         {
00685                                 proceed(h, h->Turn++);
00686 
00687                                 if ( h->Turn == 2 ) {
00688                                         h->Time = h->Time2;
00689                                         h->Time2 = 0;
00690                                 }
00691 
00692                                 if ( h->Turn > 2 )
00693                                         h->CursorNext();
00694                                 else
00695                                         continue;
00696                         }
00697 
00698                         if ( !h->Cursor ) // header finished, kick away
00699                         {
00700                                 h->CutOut();
00701 
00702                                 if ( h->Boss ) h->Boss->nSub--; // inform the boss
00703 
00704                                 delete h;
00705 
00706                                 goto beginloop;
00707                         }
00708                         // proceed
00709                         proceed(h, 0);
00710 
00711                         h->Read();
00712 
00713                         if ( h->nSub != -1 ) goto beginloop;
00714 
00715                         if ( !(h->Time) ) // token without duration
00716                                 h->CursorNext();
00717                 }
00718                 // check MinTime
00719                 if ( MinTime == frac(-1,1) || h->Time < MinTime )
00720                         MinTime = h->Time;
00721 
00722                 // next Header
00723                 Head = (GisReadArtHead**)&(h->Next);
00724         }
00725 
00726         return MinTime;
00727 }
00728 
00729 // ##################################################################
00730 // help procedures
00731 
00732 #define NOTE1 ((GisNote*)note1)
00733 #define NOTE2 ((GisNote*)note2)
00734 
00735 #ifdef WX
00736 
00737 int StrCmp(const mutString &s1, const mutString &s2)
00738 {
00739         return s1.Cmp(s2);
00740 }
00741 
00742 #else
00743 char StrCmp(const char *s1, const char *s2)
00744 {
00745         if ( s1 ) {
00746                 if ( s2 )
00747                         return strcmp(s1, s2);
00748                 else
00749                         return 1;
00750         } else
00751                 return s2 != 0;
00752 }
00753 
00754 #endif
00755 
00756 
00757 int CmpNote(GisToken *note1, GisToken *note2)
00758 {
00759         if ( note1->Type() != GTNote || note2->Type() != GTNote )
00760                 return 0;
00761 
00762         if ( StrCmp(NOTE1->Name, NOTE2->Name)
00763                         || StrCmp(NOTE1->Accedentials, NOTE2->Accedentials)
00764                         || NOTE1->Octave != NOTE2->Octave )
00765                 return 0;
00766 
00767         return 1;
00768 
00769 }
00770 
00771 // ##################################################################
00772 // ChordNote
00773 
00774 ChordNote::ChordNote(ChordNote *first) // not the first ChordNote
00775 {
00776         // copy data from first
00777         Boss = first->Boss;
00778         BossPos = first->BossPos;
00779         Next = 0;
00780         Data = 0;
00781         Cursor = &Data;
00782         TotalTime = Boss->TotalTime;
00783 
00784         if ( TotalTime )
00785                 AddGis(new GisNote(mutT("_"), mutEmptyString, 0, TotalTime, mutT(" "), 0));
00786 
00787         CurrentTime = 0;
00788 
00789         Boss->ChordPos = Boss->Cursor;
00790 
00791         Status =0;
00792 
00793         TieBegin = 0;
00794 
00795         nTie = 0;
00796 
00797         LastSep = 0;
00798 
00799         InstrId = -1;
00800 
00801         Taste = NO_KEY;
00802 
00803         Key = NO_KEY;
00804 
00805         Pitch = 0;
00806 }
00807 
00808 void ChordNote::CountOnTime(frac dTime)
00809 
00810 {
00811         CurrentTime += dTime;
00812         TotalTime += dTime;
00813 
00814         if ( Next ) Next->CountOnTime(dTime);
00815 }
00816 
00817 #define NOTE ((GisNote*)note)
00818 void ChordNote::SetNoteOn(GisToken *note) // returns 1, when note was added; else 0
00819 {
00820         *Cursor = new GisNote(NOTE->Name, NOTE->Accedentials, NOTE->Octave,
00821                               frac(0, 1), NOTE->Sep, 0);
00822         Status += CNNoteOn;
00823         Boss->NoteOn++;
00824 }
00825 
00826 int ChordNote::SetNoteOff(GisToken *note) // returns 1, when note was finished, else 0
00827 {
00828 
00829         if ( (Status & CNNoteOn) && CmpNote(*Cursor, note) )
00830         {
00831                 ((GisNote*)*Cursor)->Duration = CurrentTime;
00832                 Cursor = &((*Cursor)->Next);
00833                 CurrentTime = frac(0,1);
00834                 Status -= CNNoteOn;
00835                 Boss->NoteOn--;
00836                 return 1;
00837         }
00838 
00839         if ( Next ) return Next->SetNoteOff(note);
00840 
00841         return 0;
00842 }
00843 
00844 void ChordNote::AddGis(GisToken *token)
00845 {
00846         *Cursor = token;
00847         Cursor = &((*Cursor)->Next);
00848         LastSep = &(token->Sep);
00849         CurrentTime = 0;
00850 }
00851 
00852 void ChordNote::CheckCloseAlter()
00853 {
00854         if ( Status & CNAlter ) {
00855                 mutString s = mutEmptyString;
00856                 mutString *Sep = LastSep;
00857 
00858                 if ( !LastSep ) Sep = &s;
00859 
00860                 AddGis(new GisTagEnd((GisTagBegin*)*AlterBegin, *Sep));
00861 
00862 #ifdef WX
00863                 if ( Sep->size() ) {
00864                         *Sep = wxEmptyString;
00865                 }
00866 
00867 #else
00868                 if ( *Sep.length() ) {
00869                         free(*Sep);
00870                         *Sep = 0;
00871                 }
00872 
00873 #endif
00874                 Status -= CNAlter;
00875 
00876                 Pitch = 0;
00877         }
00878 }
00879 
00880 void ChordNote::CheckCloseTie()
00881 {
00882         if ( nTie > 1 ) {
00883                 // close alter
00884                 CheckCloseAlter();
00885                 // insert begin range
00886                 *TieBegin = new GisTagBegin(TTtie, 0, 0, mutT("("), *TieBegin);
00887                 // add end range
00888                 mutString s = mutEmptyString;
00889                 mutString *Sep = LastSep;
00890 
00891                 if ( !LastSep ) Sep = &s;
00892 
00893                 AddGis(new GisTagEnd((GisTagBegin*)*TieBegin, *Sep));
00894 
00895 #ifdef WX
00896                 if ( Sep->size() ) {
00897                         *Sep=mutEmptyString;
00898                 }
00899 
00900 #else
00901                 if ( *Sep ) {
00902                         free(*Sep);
00903                         *Sep = 0;
00904                 }
00905 
00906 #endif
00907         }
00908 
00909         TieBegin = Cursor;
00910 
00911         nTie = 0;
00912 }
00913 
00914 int ChordNote::MutNoteOn(int key, double pitch, int instrId, int taste, mutString sep)
00915 {
00916         if ( Status & CNNoteOn )
00917                 return 1;
00918 
00919         if ( pitch != Pitch && key != NO_KEY ) {
00920                 CheckCloseAlter();
00921                 AlterBegin = Cursor;
00922                 AddGis(new GisTagBegin(TTalter, 0, new GisParaReal(pitch, mutT(">(")), mutT("<"), 0));
00923                 Status |= CNAlter;
00924                 Pitch = pitch;
00925         }
00926 
00927         GisToken *Note = new GisNote(key, Boss->GetOctave(), Boss->GetKey(), sep);
00928 
00929         *Cursor = Note;
00930         LastSep = &Note->Sep;
00931         InstrId = instrId;
00932         Taste = taste;
00933         Key = key;
00934         Status |= CNNoteOn;
00935         Boss->NoteOn++;
00936 
00937         if ( nTie ) nTie++;
00938 
00939         return 0;
00940 }
00941 
00942 int ChordNote::MutNoteOff()
00943 {
00944         if ( !(Status & CNNoteOn) )
00945                 return 1;
00946 
00947         if ( GetGisType(*Cursor) != GTNote )
00948                 return 1;
00949 
00950         if ( CurrentTime ) {
00951                 ((GisNote*)(*Cursor))->Duration = CurrentTime;
00952                 Cursor = &(*Cursor)->Next;
00953         } else // note with no duration
00954         {
00955                 // delete empty note
00956                 delete *Cursor;
00957                 *Cursor = 0;
00958                 // delete alter
00959 
00960                 if ( Status & CNAlter && !(*AlterBegin)->Next ) {
00961                         delete *AlterBegin;
00962                         Cursor = AlterBegin;
00963                         *Cursor = 0;
00964                         Status -= CNAlter;
00965                 }
00966 
00967                 LastSep = 0;
00968 
00969                 if ( nTie ) nTie--;
00970         }
00971 
00972         CurrentTime = 0;
00973 
00974         Status -= CNNoteOn;
00975         Boss->NoteOn--;
00976         return 0;
00977 }
00978 
00979 // ##################################################################
00980 // methods of GisWriteHead
00981 
00982 GisWriteHead *GisWriteHead::InsertAfter(GisWriteHead *position)
00983 {
00984         if ( !position ) {
00985                 Next = 0;
00986                 Prev = 0;
00987                 return this;
00988         }
00989 
00990         if ( position->Next ) // not last position
00991                 position->Next->Prev = this;
00992 
00993         Next = position->Next;
00994 
00995         Prev = position;
00996 
00997         position->Next = this;
00998 
00999         return this;
01000 }
01001 
01002 GisWriteHead *GisWriteHead::CutOut()
01003 {
01004         if ( *(GisWriteHead**)Prev == this ) // first of list
01005         {
01006                 *(GisWriteHead**)Prev = Next;
01007         } else // normal list postition
01008         {
01009                 Prev->Next = Next;
01010         }
01011 
01012         if ( Next ) Next->Prev = Prev;
01013 
01014         Next = 0;
01015 
01016         Prev = 0;
01017 
01018         return this;
01019 }
01020 
01021 // get free chord note
01022 ChordNote *GisWriteHead::GetFreeNote()
01023 {
01024         if ( !ChordNotes )
01025                 return ChordNotes = new ChordNote(this);
01026 
01027         ChordNote **ANote = &ChordNotes;
01028 
01029         while ( *ANote ) {
01030                 if ( !((*ANote)->Status & CNNoteOn) ) {
01031                         if ( (*ANote)->CurrentTime )
01032                                 (*ANote)->AddGis(new GisNote(mutT("_"), mutEmptyString, 0, (*ANote)->CurrentTime, mutT(" "), 0));
01033 
01034                         return *ANote;
01035                 }
01036 
01037                 ANote = &(*ANote)->Next;
01038         }
01039 
01040         *ANote = new ChordNote(ChordNotes);
01041 
01042         return *ANote;
01043 }
01044 
01045 
01046 ChordNote *GisWriteHead::GetNote(int instrId, int taste)
01047 {
01048         ChordNote *ANote = ChordNotes;
01049 
01050         while ( ANote ) {
01051                 if ( ANote->CheckId(instrId, taste) )
01052                         break;
01053 
01054                 ANote = ANote->Next;
01055         }
01056 
01057         return ANote;
01058 }
01059 
01060 
01061 // prepare for taking over by boss
01062 int GisWriteHead::ReadyForBoss()
01063 {
01064         CloseCurrentToken(0); //+ zu hart: bei Unknown muß keine Note eingefügt werden (zumindest nur beim ersten
01065         // put in Sequenz, when single token mode
01066 #ifdef GMN_STRICT
01067 
01068         if ( SingleToken && Data && &Data->Next != Cursor && Data->Type() != GTSequenz ) {
01069                 char isSingle = 2;
01070                 GisToken *Token = Data, LastToken = 0;
01071 
01072                 while ( 1 ) {
01073                         if ( Token->Type() == GTNote )
01074                                 if ( isSingle ) isSingle--;
01075 
01076                         if ( Token->Next )
01077                                 Token = Token->Next;
01078                         else
01079                                 break;
01080                 }
01081 
01082                 if ( !isSingle ) {
01083                         GisToken **Comma = 0;
01084 
01085                         if ( CommaAtEnd ) // get right position
01086                         {
01087                                 Comma = &Data;
01088                                 GisToken **Comma = &Data;
01089 
01090                                 while ( (*Comma)->Next )
01091                                         Comma = &((*Comma)->Next);
01092 
01093                                 *Comma = 0;
01094                         }
01095                         Data = new GisSequenz(Data, " ");
01096 
01097                         Cursor = &Data->Next;
01098 
01099                         if ( Comma ) {
01100                                 *Cursor = *Comma;
01101                                 Cursor = &(*Comma)->Next;
01102                         }
01103                 }
01104         }
01105 
01106 #endif
01107         return 0;
01108 }
01109 
01110 void GisWriteHead::RemoveComma()
01111 {
01112         if ( CommaAtEnd ) {
01113                 GisToken **H = &Data;
01114 
01115                 while ( &(*H)->Next != Cursor )
01116                         H = &(*H)->Next;
01117 
01118                 GisToken *SaveNext = (*H)->Next;
01119 
01120                 delete *H;
01121 
01122                 *H = SaveNext;
01123 
01124                 Cursor = H;
01125         }
01126 }
01127 
01128 
01129 // end of segment or sequenz, close all corresponding subs
01130 int GisWriteHead::CloseSubs(GisToken **cont)
01131 {
01132         GisWriteHead *h = Next;
01133         GisToken **Cont = &(((GisSegment*)*Cursor)->Contents);
01134 
01135         if ( cont ) Cont = cont;
01136 
01137         while ( h && nSub > 0 && h->Boss == this ) {
01138                 h->ReadyForBoss();
01139 
01140                 if ( nSub == 1 && h->CommaAtEnd )
01141                         h->RemoveComma();
01142 
01143                 *Cont = h->Data;
01144 
01145                 if ( Data )
01146                         Cont = h->Cursor;
01147 
01148                 if ( nSub > 1 && !h->CommaAtEnd ) {
01149                         *Cont = new GisComma(mutT(" "), 0);
01150                         Cont = &((*Cont)->Next);
01151                 }
01152 
01153                 nSub--;
01154 
01155                 h->CutOut();
01156                 delete h;
01157                 h = Next;
01158         }
01159 
01160         return nSub;
01161 }
01162 
01163 // closes current token automaticaly, to be ready for a new
01164 int GisWriteHead::CloseCurrentToken(char insertRest)
01165 {
01166         if ( ChordNotes ) {
01167                 WriteChord();
01168                 return 0;
01169         }
01170 
01171         switch ( State() ) {
01172 
01173         case GTNull:
01174                 if ( insertRest && CurrentTime ) // write a rest
01175                 {
01176                         *Cursor = new GisNote(mutT("_"), mutT(""), 0, CurrentTime, mutT(" "));
01177                         Cursor = &((*Cursor)->Next);
01178                         CurrentTime = 0;
01179                 }
01180                 break;
01181 
01182         case GTUnknown:
01183                 return 1; // impossible
01184 
01185         case GTSequenz:
01186                 CloseSubs();
01187 
01188                 CurrentTime = 0;
01189 
01190                 Cursor = &((*Cursor)->Next);
01191 
01192                 break;
01193 
01194         case GTSegment:
01195                 CloseSubs();
01196 
01197                 CurrentTime = 0;
01198 
01199                 Cursor = &((*Cursor)->Next);
01200 
01201                 break;
01202 
01203         case GTTag:
01204                 return 1; // impossible
01205 
01206         case GTTagBegin:
01207                 return 1; // impossible
01208 
01209         case GTTagEnd:
01210                 return 1; // impossible
01211 
01212                 /*    case GTNote:
01213                                 ((GisNote*)(*Cursor))->Duration = CurrentTime;
01214                                 Cursor = &(*Cursor)->Next;
01215                                 CurrentTime = frac(0, 1);
01216                                 // das hier muß anders sein, um mehrere Noten gleichzeitig zu schaffen
01217                                 break;  */
01218 
01219         case GTParaInt:
01220                 return 1; // impossible
01221 
01222         case GTParaReal:
01223                 return 1; // impossible
01224 
01225         case GTParaStr:
01226                 return 1; // impossible
01227         }
01228 
01229         return 0;
01230 }
01231 
01232 #define WTAG    ((GisTag*)(*Cursor))
01233 #define WTAGEND ((GisTagEnd*)token)
01234 
01235 int GisWriteHead::ProceedGis(GisToken *token, char turn)
01236 {
01239         int Res = 0;
01240         int Id;
01241 
01242         if ( turn == 1 ) return 0;
01243 
01244         CommaAtEnd = 0;
01245 
01246         if ( !turn ) // this token first time
01247         {
01248                 Res = CloseCurrentToken(); // close the current Token
01249 
01250                 if ( Res ) return Res;
01251 
01252                 switch ( token->Type() )
01253                 {
01254 
01255                 case GTNull:
01256                         return 3; // impossible
01257 
01258                 case GTUnknown:
01259                         *Cursor = new GisToken(token->Sep);
01260 
01261                         Cursor = &((*Cursor)->Next);
01262 
01263                         break;
01264 
01265                 case GTSequenz:
01266                         *Cursor = new GisSequenz(0, token->Sep);
01267 
01268                         ((GisSequenz*)*Cursor)->Sep2 = ((GisSequenz*)token)->Sep2;
01269 
01270                         break;
01271 
01272                 case GTSegment:
01273                         *Cursor = new GisSegment(0, token->Sep);
01274 
01275                         ((GisSegment*)*Cursor)->Sep2 = ((GisSegment*)token)->Sep2;
01276 
01277                         break;
01278 
01279                 case GTTag:
01280 
01281                 case GTTagBegin:
01282                         /*                if ( token->Type() == GTTag )
01283                                                  *Cursor = new GisTag(((GisTag*)token)->Name, ((GisTag*)token)->Para,
01284                                                         token->Sep);
01285                                           else
01286                                                  *Cursor = new GisTagBegin(((GisTag*)token)->Name, ((GisTag*)token)->Para,
01287                                                         token->Sep); */
01288                         *Cursor = token->Copy();
01289 
01290                         Id = WTAG->Id;
01291 
01292                         if ( Id == TToct ) {
01293                                 if ( WTAG->GetParaType(1) == GTParaInt )
01294                                         AddTag(&Octave, WTAG)->Data.i = ((GisParaInt*)WTAG->GetPara(1))->i;
01295                         } else if ( Id == TTkey ) {
01296                                 if ( WTAG->GetParaType(1) == GTParaInt )
01297                                         AddTag(&Key, WTAG)->Data.i = ((GisParaInt*)WTAG->GetPara(1))->i;
01298                         }
01299 
01300                         Cursor = &((*Cursor)->Next);
01301 
01302                         break;
01303 
01304                 case GTTagEnd:
01305                         *Cursor = new GisTagEnd(0, token->Sep);
01306 
01307                         Cursor = &((*Cursor)->Next);
01308 
01309                         if ( WTAGEND->Begin ) {
01310                                 Id = WTAGEND->Begin->Id;
01311 
01312                                 if ( Id == TToct )
01313                                         EndTag(&Octave, WTAGEND);
01314                                 else if ( Id == TTkey )
01315                                         EndTag(&Key, WTAGEND);
01316                         }
01317 
01318                         break;
01319 
01320                 case GTParaInt:
01321 
01322                 case GTParaReal:
01323 
01324                 case GTParaStr:
01325                         return 4;
01326 
01327                 case GTComma:
01328                         *Cursor = new GisComma(token->Sep);
01329 
01330                         Cursor = &((*Cursor)->Next);
01331 
01332                         CommaAtEnd = 1;
01333 
01334                         break;
01335 
01336                 case GTNote:
01337                         ChordNote *ANote = GetFreeNote();
01338 
01339                         if ( ANote )
01340                                 ANote->SetNoteOn(token);
01341                         else
01342                                 return 1;
01343 
01344                         break;
01345                 }
01346         }
01347         else // second call
01348         {
01349                 if ( State() != token->Type() && token->Type() != GTNote) return 2;
01350 
01351                 if ( token->Type() != GTNote )
01352                         Res = CloseCurrentToken();
01353                 else {
01354                         if ( ChordNotes ) {
01355                                 Res = !ChordNotes->SetNoteOff(token);
01356                         }
01357 
01358                         if ( !NoteOn ) // write the Chord
01359                                 WriteChord();
01360                 }
01361         }
01362 
01363         return Res;
01364 }
01365 
01366 void GisWriteHead::WriteChord()
01367 {
01368         if ( !ChordNotes ) return;
01369 
01370         // close open ties
01371         ChordNote *ANote = ChordNotes;
01372 
01373         while ( ANote ) {
01374                 ANote->CheckClose();
01375                 ANote = ANote->Next;
01376         }
01377 
01378         char BossLine = 1; // wether in Boss data also data for Chord;
01379 
01380         char SingleLine = 0; // wether there is in fact only one Line (no real chord)
01381 
01382         if ( Cursor == ChordPos )
01383                 BossLine = 0;
01384 
01385         if ( !ChordNotes->Next && !BossLine )
01386                 SingleLine = 1;
01387 
01388 #ifdef CHORDS_WITH_REST
01389         ChordNotes->AddRest();
01390 
01391 #endif
01392         if ( SingleLine ) // only one line (no real chord)
01393         {
01394                 *(ChordNotes->Cursor) = *ChordPos;
01395                 *ChordPos = ChordNotes->Data;
01396 
01397                 if ( Cursor == ChordPos )
01398                         Cursor = ChordNotes->Cursor;
01399 
01400                 ChordNotes->Data = 0;
01401         } else {}
01402 
01403         delete ChordNotes;
01404 
01405         ChordNotes = 0;
01406         CurrentTime = 0;
01407 }
01408 
01409 void GisWriteHead::AddTime(frac dTime)
01410 {
01411         TotalTime += dTime;
01412         CurrentTime += dTime;
01413 
01414         if ( ChordNotes ) ChordNotes->CountOnTime(dTime);
01415 
01416         if ( Next ) Next->AddTime(dTime);
01417 }
01418 
01419 
01420 // ##################################################################
01421 // procedures with GisWriteHead
01422 
01423 // search the header with the matching Id
01424 
01425 GisWriteHead *GetMatchingHeader(GisWriteHead **head, const mutString id)
01426 {
01427         GisWriteHead *h = *head, *LastHead = 0;
01428         GisWriteHead *Boss = h;
01429         size_t  BossIdLength = mutLen(h->Id);
01430         char CmpRes = 0;
01431         // search header
01432 
01433         while ( h ) {
01434 
01435 #ifdef WX
01436 
01437                 if ( (id.StartsWith(h->Id)) && (mutLen(h->Id) >= BossIdLength) ) {
01438                         Boss = h;
01439                         BossIdLength = mutLen(h->Id) + 1;
01440                 }
01441 
01442                 CmpRes = mutStrCmp(h->Id, id);
01443 
01444                 if ( CmpRes >= 0 ) break;
01445 
01446 #else
01447                 if ( !strncmp(h->Id, id, strlen(h->Id)) && (strlen(h->Id) >= BossIdLength) ) {
01448                         Boss = h;
01449                         BossIdLength = strlen(h->Id) + 1;
01450                 }
01451 
01452                 CmpRes = strcmp(h->Id, id);
01453 
01454                 if ( CmpRes >= 0 ) break;
01455 
01456 #endif
01457                 LastHead = h;
01458 
01459                 h = h->Next;
01460         }
01461 
01462         if ( CmpRes ) // insert a new header
01463         {
01464                 h = new GisWriteHead(Boss, id);
01465 
01466                 if ( LastHead ) // not at the first position
01467                         h->InsertAfter(LastHead);
01468                 else // first position in header list
01469                 {
01470                         h->Prev = (GisWriteHead*)head;
01471                         h->Next = *head;
01472 
01473                         if ( *head ) (*head)->Prev = h;
01474 
01475                         *head = h;
01476                 }
01477         }
01478 
01479         return h;
01480 }
01481 
01482 // write from a GisToken
01483 int GisWriteHeadGis(GisWriteHead **head,  mutString id, GisToken *token, char turn)
01484 {
01485         return GetMatchingHeader(head, id)->ProceedGis(token, turn);
01486 }
01487 
01488 // close subheads
01489 void CloseAllSubs(GisWriteHead *head)
01490 {
01491         while ( 1 ) {
01492                 // search the lowest boss
01493                 GisWriteHead *Boss = 0;
01494 
01495                 for (GisWriteHead *H = head; H; H = H->Next)
01496                         if ( H->nSub > 0 )
01497                                 Boss = H;
01498 
01499                 if ( !Boss ) break;
01500 
01501                 // check for "empty" boss
01502                 if ( !Boss->Data && Boss->nSub == 1 ) {
01503                         GisWriteHead *h = Boss->Next;
01504                         Boss->Data = h->Data;
01505                         Boss->nSub = 0;
01506                         h->Data = 0;
01507                         h->CutOut();
01508                         delete h;
01509                         continue;
01510                 }
01511 
01512                 // check for segment
01513                 if ( GetGisType(*Boss->Cursor) != GTSegment ) {
01514                         if ( Boss->Data && !Boss->CommaAtEnd ) {
01515                                 *Boss->Cursor = new GisComma(mutT(" "), 0);
01516                                 Boss->Cursor = &((*Boss->Cursor)->Next);
01517                         }
01518 
01519                         Boss->Data = new GisSegment(Boss->Data, mutT(" "), 0);
01520 
01521                         GisToken **Cont = Boss->Cursor;
01522 
01523                         if ( Boss->Cursor == &Boss->Data )
01524                                 Cont = 0;
01525 
01526                         Boss->Cursor = &Boss->Data;
01527 
01528                         Boss->CloseSubs(Cont);
01529                 } else
01530                         Boss->CloseSubs();
01531         }
01532 
01533         /*  // check wether there are parallel heads
01534           if ( head->Next ) */
01535         // remove comma at end
01536         head->RemoveComma();
01537 }
01538 
01539 /*
01540 #define zugriff  ((unsigned char*) &freq)
01541 
01542 int GisWriteAlteredNoteOn(GisWriteHead **head,  char *id, long freq, int noteId,
01543   int octave, int acc, char *Sep)
01544 {
01545   GisWriteHead *h = GetMatchingHeader(head, id);
01546   if ( !h ) return 1;
01547   h->CommaAtEnd = 0;
01548   GisToken *Note = new GisNote(zugriff[3]&0x7f, octave, acc, Sep);
01549   ChordNote *ANote = h->GetFreeNote();
01550   ANote->CheckCloseTie();
01551   ANote->TieBegin = ANote->Cursor;
01552   double pitch = (double)(freq & 0x00FFFFFF) / 0x01000000;
01553   if ( pitch != 0.0 )
01554   {
01555          ANote->AddGis(new GisTagBegin(TTalter, 0, new GisParaReal(pitch, ">( "), "<", 0));
01556          ANote->Status |= CNAlter;
01557   }
01558   *(ANote->Cursor) = Note;
01559   ANote->LastSep = &Note->Sep;
01560   ANote->Id = noteId;
01561   ANote->Status |= CNNoteOn;
01562   ANote->Boss->NoteOn++;
01563   return 0;
01564 }
01565 
01566 int GisWriteAlteredNoteOff(GisWriteHead **head,  char *id, int noteId)
01567 {
01568   GisWriteHead *h = GetMatchingHeader(head, id);
01569   if ( !h ) return 1;
01570   ChordNote *ANote = h->GetNoteId(noteId);
01571   if ( !ANote )
01572          return 1;
01573   if ( !(ANote->Status & CNNoteOn) )
01574          return 1;
01575   if ( GetGisType(*ANote->Cursor) != GTNote )
01576          return 1;
01577   ((GisNote*)(*ANote->Cursor))->Duration = ANote->CurrentTime;
01578   char **Sep = &(*ANote->Cursor)->Sep;
01579   ANote->Cursor = &((*ANote->Cursor)->Next);
01580   ANote->CurrentTime = 0;
01581   ANote->Status -= CNNoteOn;
01582   ANote->Boss->NoteOn--;
01583   if ( ANote->Status & CNAlter )
01584   {
01585          ANote->AddGis(new GisTagEnd(0, *Sep));
01586          if ( *Sep )
01587          {
01588                 free(*Sep);
01589                 *Sep = strdup(" ");
01590          }
01591          ANote->Status -= CNAlter;
01592   }
01593   if ( !ANote->Boss->NoteOn ) ANote->Boss->WriteChord();
01594   return 0;
01595 } */
01596 /*
01597 // write from midi
01598 int GisWriteHeadMis(GisWriteHead **head,  char *id, DWORD midi, MisTrack* track)
01599 {
01600   GisToken *Token = 0;
01601   int Turn = 0;
01602   BYTE StatusByte = midi & 0xFF;
01603   if ( StatusByte < 0xF0 )
01604          StatusByte = StatusByte & 0xF0;
01605   switch ( StatusByte )
01606   {
01607   }
01608   return GetMatchingHeader(head, id)->ProceedGis(Token, Turn);
01609 }
01610 ;
01611   switch ( StatusByte )
01612   {
01613   }
01614   return GetMatchingHeader(head, id)->ProceedGis(Token, Turn);
01615 } */
01616 

Erzeugt am Sun Aug 21 2011 10:51:53 für Mutabor von doxygen 1.7.4