00001
00028
00029
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 };
00043 char ArticulationOff[5] = { 80, 80, 60, 127, 127 };
00044
00045
00046
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
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
00146 if ( *(position->PrevPtr) == 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 {
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
00171
00172 if ( *(position->PrevPtr) == 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 {
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 )
00208 {
00209 *PrevPtr = Next;
00210 } else
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 )
00225 {
00226 *PrevPtr = Next;
00227
00228 if (Next) {
00229 Next->PrevPtr = PrevPtr;
00230 Next->Prev = NULL;
00231 }
00232 }
00233 else
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
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 )
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 )
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
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
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
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
00350
00351
00352 void GisReadDummy(GisReadHead*, char)
00353 {
00354
00355 }
00356
00357
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 )
00368 {
00369 Head = &(h->Next);
00370 continue;
00371 }
00372 if ( h->nSub == 0 )
00373 {
00374 proceed(h, 1);
00375 h->CursorNext();
00376 h->Time = 0;
00377 }
00378 if ( h->Time != frac(0, 1) )
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;
00390
00391
00392
00393 while ( !(h->Time) )
00394 {
00395
00396 if ( !h->Cursor )
00397 {
00398 h->CutOut();
00399
00400 if ( h->Boss ) h->Boss->nSub--;
00401
00402 delete h;
00403
00404 goto beginloop;
00405 }
00406
00407 proceed(h, 0);
00408
00409 h->Read();
00410
00411 if ( h->nSub != -1 ) goto beginloop;
00412
00413 if ( !(h->Time) )
00414 h->CursorNext();
00415 }
00416
00417 if ( MinTime == frac(-1,1) || h->Time < MinTime )
00418 MinTime = h->Time;
00419
00420
00421 Head = &(h->Next);
00422 }
00423
00424 return MinTime;
00425 }
00426
00427
00428
00429
00430
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
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;
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
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
00629
00630
00631 void GisReadArtDummy(GisReadArtHead*, char)
00632 {
00633
00634 }
00635
00636
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 )
00648 {
00649 Head = (GisReadArtHead**)&(h->Next);
00650 continue;
00651 }
00652 if ( h->nSub == 0 )
00653 {
00654 proceed(h, h->Turn++);
00655 h->CursorNext();
00656 h->Time = 0;
00657 }
00658 if ( h->Time != frac(0, 1) )
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;
00677
00678
00679
00680 while ( !(h->Time) )
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 )
00699 {
00700 h->CutOut();
00701
00702 if ( h->Boss ) h->Boss->nSub--;
00703
00704 delete h;
00705
00706 goto beginloop;
00707 }
00708
00709 proceed(h, 0);
00710
00711 h->Read();
00712
00713 if ( h->nSub != -1 ) goto beginloop;
00714
00715 if ( !(h->Time) )
00716 h->CursorNext();
00717 }
00718
00719 if ( MinTime == frac(-1,1) || h->Time < MinTime )
00720 MinTime = h->Time;
00721
00722
00723 Head = (GisReadArtHead**)&(h->Next);
00724 }
00725
00726 return MinTime;
00727 }
00728
00729
00730
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
00773
00774 ChordNote::ChordNote(ChordNote *first)
00775 {
00776
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)
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)
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
00884 CheckCloseAlter();
00885
00886 *TieBegin = new GisTagBegin(TTtie, 0, 0, mutT("("), *TieBegin);
00887
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
00954 {
00955
00956 delete *Cursor;
00957 *Cursor = 0;
00958
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
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 )
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 )
01005 {
01006 *(GisWriteHead**)Prev = Next;
01007 } else
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
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
01062 int GisWriteHead::ReadyForBoss()
01063 {
01064 CloseCurrentToken(0);
01065
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 )
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
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
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 )
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;
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;
01205
01206 case GTTagBegin:
01207 return 1;
01208
01209 case GTTagEnd:
01210 return 1;
01211
01212
01213
01214
01215
01216
01217
01218
01219 case GTParaInt:
01220 return 1;
01221
01222 case GTParaReal:
01223 return 1;
01224
01225 case GTParaStr:
01226 return 1;
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 )
01247 {
01248 Res = CloseCurrentToken();
01249
01250 if ( Res ) return Res;
01251
01252 switch ( token->Type() )
01253 {
01254
01255 case GTNull:
01256 return 3;
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
01283
01284
01285
01286
01287
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
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 )
01359 WriteChord();
01360 }
01361 }
01362
01363 return Res;
01364 }
01365
01366 void GisWriteHead::WriteChord()
01367 {
01368 if ( !ChordNotes ) return;
01369
01370
01371 ChordNote *ANote = ChordNotes;
01372
01373 while ( ANote ) {
01374 ANote->CheckClose();
01375 ANote = ANote->Next;
01376 }
01377
01378 char BossLine = 1;
01379
01380 char SingleLine = 0;
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 )
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
01422
01423
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
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 )
01463 {
01464 h = new GisWriteHead(Boss, id);
01465
01466 if ( LastHead )
01467 h->InsertAfter(LastHead);
01468 else
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
01483 int GisWriteHeadGis(GisWriteHead **head, mutString id, GisToken *token, char turn)
01484 {
01485 return GetMatchingHeader(head, id)->ProceedGis(token, turn);
01486 }
01487
01488
01489 void CloseAllSubs(GisWriteHead *head)
01490 {
01491 while ( 1 ) {
01492
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
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
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
01534
01535
01536 head->RemoveComma();
01537 }
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616