DevGIS.cpp
gehe zur Dokumentation dieser Datei
00001 
00026 // #################################################################
00027 // Mutabor, GIS - Devices
00028 // #################################################################
00029 
00030 #include "DevGIS.h"
00031 #include "GSP.h"
00032 #include <math.h>
00033 #include "MidiKern.h"
00034 #include "GrafKern.h"
00035 
00036 #ifdef RTMIDI
00037 #else
00038 #ifndef MMSYSTEM_H
00039 #define MMSYSTEM_H
00040 //  #define WINVER 0x030a
00041 #include <mmsystem.h>
00042 #endif
00043 #endif
00044 #include "Execute.h"
00045 
00046 //int ausgabe_instrument[16][4];
00047 
00048 mutString CurrentId;
00049 mutString CurrentSep;
00050 
00051 #define ROUND_FACTOR 1000000
00052 #define ROUND(x) x = (floor(x*ROUND_FACTOR+0.5)) / ROUND_FACTOR
00053 //#define ROUND(x) x=x
00054 
00055 void GetKeyPitch(int taste, tone_system *tonsystem, int &key, double &pitch)
00056 {
00057         int Index = (taste - tonsystem->anker) % tonsystem->breite;
00058         int Abstand = (taste - tonsystem->anker) / tonsystem->breite;
00059 
00060         if ( Index < 0 ) {
00061                 Index += tonsystem->breite;
00062                 Abstand--;
00063         }
00064 
00065         long Tone = (tonsystem)->ton[Index];
00066 
00067         if ( !Tone ) {
00068                 key = NO_KEY;
00069                 pitch = 0;
00070                 return;
00071         }
00072 
00073         pitch = ((double)(tonsystem)->periode) / 0x01000000 * Abstand + ((double)Tone) / 0x01000000;
00074 
00075         key = (int) pitch;
00076         pitch -= key;
00077 
00078         if ( pitch < -0.5 ) {
00079                 pitch++;
00080                 key--;
00081         } else if ( pitch > 0.5 ) {
00082                 pitch--;
00083                 key++;
00084         }
00085 
00086         ROUND(pitch);
00087 }
00088 
00089 // ##################################################################
00090 // OutGis
00091 /*
00092 void OutGis::NoteOn(int instr, ton_system * tonsys, int taste, int velo)
00093 {
00094   int Key;
00095   double Pitch;
00096   GetKeyPitch(taste, tonsys, Key, Pitch);
00097   GisWriteHead *h = GetMatchingHeader(&Head, CurrentId);
00098   if ( !h ) return ;
00099   h->CommaAtEnd = 0;
00100   ChordNote *ANote = h->GetFreeNote();
00101   ANote->CheckCloseTie();
00102   ANote->MutNoteOn(Key, Pitch, instr, taste, CurrentSep);
00103 }
00104 
00105 void OutGis::NoteOff(int instr, int taste, int velo)
00106 {
00107   GisWriteHead *h = GetMatchingHeader(&Head, CurrentId);
00108   if ( !h ) return;
00109   ChordNote *ANote = h->GetNote(instr, taste);
00110   if ( !ANote )
00111          return;
00112   ANote->MutNoteOff();
00113   ANote->CheckCloseTie();
00114   if ( !ANote->Boss->NoteOn ) ANote->Boss->WriteChord();
00115 }
00116 
00117 void OutGis::NotesCorrect(int instr, ton_system * tonsys)
00118 {
00119   // search sounding notes of instrument instr
00120   for (GisWriteHead *h = Head; h; h = h->Next)
00121          for (ChordNote *ANote = h->ChordNotes; ANote; ANote = ANote->Next)
00122                 if ( ANote->InstrId == instr && ANote->Status & CNNoteOn )
00123                 {
00124                   // check, wether pitch has changed
00125                   int Key;
00126                   double Pitch;
00127                   GetKeyPitch(ANote->Taste, tonsys, Key, Pitch);
00128                   if ( ANote->Cmp(Key, Pitch) )
00129                          continue;
00130                   // look for the old key
00131                   int OldKey = ANote->Key;
00132                   char *OldSep = (*ANote->Cursor)->Sep;
00133                   (*ANote->Cursor)->Sep = strdup(" ");
00134                   int Taste = ANote->Taste;
00135                   // insert tie
00136                   ANote->nTie++;
00137                   // finish the note
00138                   ANote->MutNoteOff();
00139                   // calculate new values
00140                   if ( Key != NO_KEY )
00141                   {
00142                          Pitch += (Key - OldKey);
00143                          Key = OldKey;
00144                   }
00145                   // start the new note
00146                   ANote->MutNoteOn(Key, Pitch, instr, Taste, OldSep);
00147                   // correct nTie (MutNoteOn does nTie++)
00148                   ANote->nTie--;
00149                   // clear old separator
00150                   if ( OldSep )
00151                          free(OldSep);
00152                 }
00153 }
00154 */
00155 void OutGis::Gis(GisToken *token, char turn)
00156 {
00157         GisWriteHeadGis(&Head, CurrentId, token, turn);
00158         STUBC;
00159 }
00160 
00161 // InGis ------------------------------------------------------------
00162 /*
00163 void CALLBACK _export GisTimeFunc(UINT wTimerID, UINT wMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
00164 {
00165   ((InGis*)dwUser)->IncDelta();
00166 }
00167 */
00168 
00170 
00172 void OutGis::Save (tree_storage & config) 
00173 {
00174         config.Write(_T("File Name"),Name);
00175 }
00176 
00178 
00183 void OutGis::Save (tree_storage & config, const Route * route)
00184 {
00185         STUBC;
00186 }
00187 
00188 
00190 
00192 void OutGis::Load (tree_storage & config)
00193 {
00194         Name = config.Read(_T("File Name"), mutEmptyString);
00195 }
00196 
00198 
00203 void OutGis::Load (tree_storage & config, Route * route)
00204 {
00205         STUBC;
00206 }
00207 
00208 
00210 
00212 void InGis::Save (tree_storage & config) 
00213 {
00214         config.Write(_T("File Name"),Name);
00215 }
00216 
00218 
00223 void InGis::Save (tree_storage & config, const Route * route)
00224 {
00225 }
00226 
00227 
00229 
00231 void InGis::Load (tree_storage & config)
00232 {
00233         Name = config.Read(_T("File Name"),mutEmptyString);
00234 }
00235 
00237 
00242 void InGis::Load (tree_storage & config, Route * route)
00243 {
00244 }
00245 
00246 
00247 bool InGis::Open()
00248 {
00249         DEBUGLOG (other, _T(""));
00250         Data = GisParse(Name);
00251 
00252         if ( GspError ) {
00253                 /* //4    *Echo << "\n  Parsing interupted !\n";
00254                     *Echo << "  ErrorNr: " << GspError << " - " << GspErrorText[GspError] << "\n";
00255                     *Echo << "  Line: " << GspErrorLineNr << ", " << GspErrorPos << "\n";
00256                     *Echo << "  " << GspErrorLine << "\n  "; */
00257 
00258                 DEBUGLOG (other, _T("Issuing Compiler warning 9..."));
00259 
00260                 compiler_warning(9, C_STR(Name), GspErrorLineNr, GspErrorPos, mutC_STR(GspErrorText[GspError]));
00261 
00262                 DEBUGLOG (other, _T("... done"));
00263                 Mode = MutaborDeviceCompileError;
00264                 InDevChanged = 1;
00265                 return false;
00266         }
00267 
00268         /*  Head = new GisReadArtHead(NULL, Data, Id);
00269         DEBUGLOG (other, _T("Head = %p"),Head);
00270         Head->Box = 0; /// hier mufl noch was hin
00271         Head->PrevPtr = (GisReadHead **)&Head;
00272         //  Head->Prev = Head;
00273         DEBUGLOG (other, _T("Head = %p"),Head);
00274         // Mode setzen
00275         Mode = MutaborDeviceStop; 
00276         */
00277         // initialisieren
00278         Stop();
00279 
00280         DEBUGLOG (other, _T("Head = %p"),Head);
00281 
00282         return true;
00283 }
00284 
00285 void InGis::Close()
00286 {
00287         Stop();
00288         // Speicher freigeben
00289 
00290         if ( Mode == MutaborDeviceCompileError )
00291                 return;
00292 
00293         if ( Head ) {
00294                 delete Head;
00295                 Head = 0;
00296         }
00297 
00298         if ( Data ) {
00299                 delete Data;
00300                 Data = 0;
00301         }
00302 
00303         delete Data;
00304 }
00305 
00306 void InGis::Stop()
00307 {
00308         if ( Mode == MutaborDevicePlay || Mode == MutaborDeviceTimingError )
00309                 Pause();
00310 
00311         // OK ?
00312         if ( Mode == MutaborDeviceCompileError )
00313                 return;
00314 
00315         // Header auf Start setzen
00316         if ( Head ) {
00317                 delete Head;
00318                 Head = 0;
00319         }
00320 
00321         Head = new GisReadArtHead(NULL, Data, Id);
00322 
00323         DEBUGLOG (other, _T("Head = %p"),Head);
00324         Head->Box = 0; 
00325         DEBUGLOG (other, _T("Head = %p"),Head);
00326         //  Head->Prev = Head;
00327         Head->PrevPtr = (GisReadHead**)&Head;
00328         DEBUGLOG (other, _T("Head = %p"),Head);
00329         // Delta-Times lesen
00330         minDelta = 0;
00331         actDelta = -1;
00332         Mode = MutaborDeviceStop;
00333 }
00334 
00335 /* Shall GIS support batch processing? */
00336 void InGis::Play()
00337 {
00338         timer.Start(2,wxTIMER_CONTINUOUS);
00339         Busy = FALSE;
00340         Mode = MutaborDevicePlay;
00341 }
00342 
00343 void InGis::Pause()
00344 {
00345         timer.Stop();
00346         Mode = MutaborDevicePause;
00347         Quite();
00348 }
00349 
00350 
00351 // Gis arbeitet auf "tick" - Basis, ein tick = 2ms
00352 void InGis::IncDelta()
00353 {
00354         actDelta++;
00355 
00356         if ( Busy )
00357                 return;
00358 
00359         if ( actDelta < minDelta )
00360                 return;
00361 
00362         // Zeitpunkt ist ran, also verarbeiten
00363         Busy = TRUE;
00364 
00365         DEBUGLOG (other, _T("Next tone. Mindelta = %d"),minDelta);
00366 
00367         minDelta = ReadOn(actDelta);
00368 
00369         // while ((minDelta = ReadOn(actDelta)) == -1)
00370         //  if (!(Head->Cursor)) break;
00371 
00372         DEBUGLOG (other, _T("Calculating next step"));
00373 
00374         actDelta = 0;
00375 
00376         if ( minDelta == -1 ) {
00377                 DEBUGLOG (other, _T("Stopping"));
00378                 Mode = MutaborDeviceTimingError;
00379                 Stop();
00380                 InDevChanged = 1;
00381         }
00382 
00383         Busy = FALSE;
00384 }
00385 
00386 void MutaborTag(GisReadArtHead *h, GisToken *Para, int box)
00387 {
00388         if ( !Para || Para->Type() != GTParaStr )
00389                 return; // strange parameters
00390 
00391         mutString ParaName = ((GisParaStr*)Para)->s;
00392 
00393         Para = Para->Next;
00394 
00395         if ( mutStrEq(ParaName, mutT("key")) ) {
00396                 if ( GetGisType(Para) == GTParaStr )
00398                         KeyboardIn(box, ((GisParaStr*)Para)->s);
00399         }
00400 
00401         if ( mutStrEq(ParaName, mutT("box")) || mutStrEq(ParaName, mutT("instrument")) ) {
00402                 if ( GetGisType(Para) == GTParaInt )
00403                         h->Box = ((GisParaInt*)Para)->i;
00404         }
00405 }
00406 
00407 ChannelData Cd(0, 0);
00408 
00409 void InGis::Proceed(GisReadArtHead *h, char turn, Route *route)
00410 {
00411         wxASSERT(h->Cursor);
00412         CurrentId = h->Id;
00413         CurrentSep = h->Cursor->Sep;
00414         // calculate box
00415         int Box = route->Box;
00416 
00417         if ( Box == -1 )
00418                 Box = h->Box;
00419 
00420         DEBUGLOG (other, _T("Id: %s, Box: %d, Sep: %s"),
00421                  CurrentId.c_str(), Box, CurrentSep.c_str());
00422 
00423         OutDevice *out = route->GetOutDevice();
00424 
00425         // check wether no box should be used
00426         if ( Box == -2 ) {
00427                 if ( out )
00428                         out->Gis(h->Cursor, turn);
00429 
00430                 return;
00431         }
00432 
00433         // proceed the token
00434         int Key;
00435 
00436         switch ( GetGisType(h->Cursor)) {
00437 
00438         case GTTag:
00439 
00440         case GTTagBegin:
00441                 if ( ((GisTag*)(h->Cursor))->Id == TTmutabor )
00442                         MutaborTag(h, ((GisTag*)(h->Cursor))->Para, Box);
00443 
00444                 if ( ((GisTag*)(h->Cursor))->Id == TTalter ) return;
00445 
00446                 if ( out ) out->Gis(h->Cursor, turn);
00447 
00448                 break;
00449 
00450         case GTTagEnd:
00451                 if ( (((GisTagEnd*)(h->Cursor))->Begin)->Id == TTalter ) return;
00452 
00453                 if ( out )out->Gis(h->Cursor, turn);
00454 
00455                 break;
00456 
00457         case GTNote:
00458                 Key = ((GisNote*)(h->Cursor))->GetKey();
00459 
00460                 if ( Key == -1 ) return ;
00461 
00462                 Key += h->GetOctave()*12;
00463 
00464                 if ( turn != 1 && route->Active ) {
00465                         if ( turn )
00466                                 DeleteKey(Box, Key, route->GetId());
00467                         else
00468 
00469                                 AddKey(Box, Key, route->GetId());
00470                 }
00471 
00472                 if ( turn != 2 && route->GetOutDevice() ) {
00473                         if ( turn )
00474                                 route->GetOutDevice()->NoteOff(Box, Key, h->GetIntensity(turn), route, 0); //4 ?? channelid aus staff
00475                         else {
00476                                 Cd.Sound = h->GetInstr();
00477                                 route->GetOutDevice()->NoteOn(Box, Key, h->GetIntensity(turn), route, 0, &Cd);
00478                         }
00479                 }
00480 
00481                 break;
00482 
00483         default:
00484                 if ( out ) out->Gis(h->Cursor, turn);
00485         }
00486 }
00487 
00488 void InGis::ProceedRoute(GisReadArtHead *h, char turn)
00489 {
00490         wxASSERT(h);
00491         wxASSERT(h->Cursor);
00492         DEBUGLOG (other, _T("h->Id = '%s' (%d), Id = '%s' (%d)"),
00493                  (h->Id).c_str(),(h->Id).Len(), Id.c_str(), Id.Len());
00494         mutChar staff = h->Id[mutLen(Id)];
00495         bool DidOut = false;
00496         DEBUGLOG (other, _T("staff: %d, DidOut: %d"),staff, DidOut);
00497 
00498         for (Route *R = GetRoutes(); R; R = R->GetNext()) {
00499                 DEBUGLOG (other, _T("Route type: %d, DidOut: %d"),R->Type, DidOut);
00500 
00501                 switch ( R->Type ) {
00502 
00503                 case RTstaff:
00504                         if ( R->Check(staff) ) {
00505                                 Proceed(h, turn, R);
00506                                 DidOut = true;
00507                         }
00508 
00509                         break;
00510 
00511                 case RTchannel:
00512                         if ( R->Check(h->Box) ) {
00513                                 Proceed(h, turn, R);
00514                                 DidOut = true;
00515                         }
00516 
00517                         break;
00518 
00519                 case RTelse:
00520                         if ( DidOut )
00521                                 break;
00522 
00523                 case RTall:
00524                         Proceed(h, turn, R);
00525                 }
00526         }
00527 }
00528 
00529 
00530 #ifdef DEBUG
00531 
00532 static void printHeadChain(std::ostream & f,GisReadHead *H)
00533 {
00534         f << "  ";
00535 
00536         if (H)
00537                 if (H->PrevPtr) {
00538                         f << "[" << (void *)(H->PrevPtr) << std::flush;
00539 
00540                         if (*(H->PrevPtr)) {
00541                                 f << "->(" << std::flush
00542                                 << (void *)(*(H->PrevPtr)) << ")" << std::flush;
00543                         }
00544 
00545                         f << "]";
00546                 }
00547 
00548         while (H) {
00549                 f << "->" << typeid(*H).name() << "(" << (void *)H << ")" << std::flush;
00550                 H = H->Next;
00551         }
00552 
00553         f << std::endl;
00554 }
00555 
00556 #else
00557 #define printHeadChain(a,b)
00558 #endif
00559 // return -1 heißt Ende der GMN
00560 // ein und ausgabe in ticks
00561 // Sinn der ticks: verschiedene Tempi in den Spuren
00562 long InGis::ReadOn(long delta)
00563 {
00564         GisReadHead **H = (GisReadHead **)&Head;
00565         long MinDelta = -1;
00566 
00567 beginloop:
00568 
00569         //  printHeadChain(DEBUGLOG (other, _T("Head Chain:")), *H);
00570 
00571         while ( *H ) {
00572 
00573                 GisReadArtHead *h = dynamic_cast<GisReadArtHead *> (*H);
00574                 DEBUGLOG (other, _T("H = %p; h = %p"),H,
00575                          dynamic_cast<GisReadArtHead *>(*H));
00576 
00577                 wxASSERT(h);
00578                 DEBUGLOG (other, _T("h->nSub = %d"),h->nSub);
00579 
00580                 if ( h->nSub > 0) { // header has subsGisReadHead
00581                         H =  &(h->Next);
00582                         continue;
00583                 }
00584 
00585                 // printHeadChain(DEBUGLOG (other, _T("Working Chain:")), *H);
00586                 //DEBUGLOG (other, _T("Reading on with %p\n%s"), *H, (GISPrettyPrint(*Head).c_str()));
00587 
00588                 if ( h->nSub == 0 ) { // all subs has finished
00589                         ProceedRoute(h, h->Turn++);   // end of segment or sequenz
00590                         DEBUGLOG (other, _T("CursorNext()"));
00591                         h->CursorNext();
00592                         h->Time = 0;
00593                         h->Delta = 0;
00594                 }
00595 
00596                 DEBUGLOG (other, _T("h->Delta = %d"),h->Delta);
00597 
00598                 if ( h->Delta > 0 ) {// header in normal state
00599                         DEBUGLOG (other, _T("Time: %d/%d, delta: %d, speed: %d"),
00600                                  h->Time.numerator(),h->Time.denominator(), delta,
00601                                  h->GetSpeedFactor());
00602                         h->Time -= frac(delta, h->GetSpeedFactor());
00603                         h->Delta -= delta;
00604 
00605                         if ( h->Delta <= 0 ) {
00606                                 ProceedRoute(h, h->Turn++);
00607 
00608                                 if ( h->Turn == 2 ) {
00609                                         h->Time = h->Time2;
00610                                         h->Time2 = 0;
00611                                 }
00612 
00613                                 if ( h->Turn > 2 ) {
00614                                         DEBUGLOG (other, _T("CursorNext()"));
00615                                         h->CursorNext();
00616                                 }
00617                         }
00618 
00619                         h->Delta = (h->GetSpeedFactor() * h->Time.numerator())
00620 
00621                                    / h->Time.denominator();
00622                         DEBUGLOG (other, _T("Time: %d/%d, Time2: %d/%d, delta: %d, speed: %d"),
00623                                  h->Time.numerator(),h->Time.denominator(),
00624                                  h->Time2.numerator(),h->Time2.denominator(),
00625                                  delta,
00626                                  h->GetSpeedFactor());
00627                 }
00628 
00629                 h->nSub = -1; // normal header
00630 
00631                 // now check, wether count down Time is 0
00632                 // if h->time = 0 then h->Cursor points to the GisToken next to proceed
00633 
00634                 DEBUGLOG (other, _T("h->Delta = %d"),h->Delta);
00635 
00636                 while ( h->Delta == 0 ) { // read next tokens
00637                         DEBUGLOG (other, _T("h->Turn = %d"),h->Turn);
00638 
00639                         if ( h->Turn) {
00640                                 ProceedRoute(h, h->Turn++);
00641                                 DEBUGLOG (other, _T("h->Delta = %d, h->Turn = %d"),h->Delta, h->Turn);
00642 
00643                                 if ( h->Turn == 2 ) {
00644                                         h->Time = h->Time2;
00645                                         h->Time2 = 0;
00646                                         h->Delta = (h->GetSpeedFactor() * h->Time.numerator())
00647                                                    / h->Time.denominator();
00648                                         DEBUGLOG (other, _T("h->Delta = %d * %d / %d = %d"), h->GetSpeedFactor(),
00649                                                  h->Time.numerator(), h->Time.denominator(), h->Delta);
00650                                 }
00651 
00652                                 if ( h->Turn > 2 ) {
00653                                         h->CursorNext();
00654                                 } else {
00655                                         DEBUGLOG2(other,_T("continue loop"));
00656                                         continue;
00657                                 }
00658                         }
00659 
00660                         if ( !h->Cursor ) { // header finished, kick away
00661                                 h->CutOut();
00662 
00663                                 if ( h->Boss ) h->Boss->nSub--; // inform the boss
00664 
00665                                 delete h;
00666 
00667                                 DEBUGLOG2(other,_T("goto beginloop"));
00668 
00669                                 goto beginloop;
00670                         }
00671 
00672                         // proceed
00673                         DEBUGLOG (other, _T("Proceed with Turn 0"));
00674 
00675                         ProceedRoute(h, 0);
00676 
00677                         DEBUGLOG (other, _T("h->Read()"));
00678 
00679                         h->Read();
00680 
00681                         DEBUGLOG (other, _T("Time: %d/%d, Time2: %d/%d, delta: %d"),
00682                                  h->Time.numerator(),h->Time.denominator(),
00683                                  h->Time2.numerator(),h->Time2.denominator(),
00684                                  delta);
00685 
00686                         h->Delta = (h->GetSpeedFactor() * h->Time.numerator())
00687                                    / h->Time.denominator();
00688 
00689                         DEBUGLOG (other, _T("h->Delta = %d * %d / %d = %d"), h->GetSpeedFactor(),
00690                                  h->Time.numerator(), h->Time.denominator(), h->Delta);
00691 
00692                         DEBUGLOG (other, _T("Time: %d/%d, Time2: %d/%d, delta: %d, speed: %d"),
00693                                  h->Time.numerator(),h->Time.denominator(),
00694                                  h->Time2.numerator(),h->Time2.denominator(),
00695                                  delta,
00696                                  h->GetSpeedFactor());
00697 
00698                         if ( h->nSub != -1 ) {
00699                                 DEBUGLOG2(other,_T("goto beginloop"));
00700                                 goto beginloop;
00701                         }
00702 
00703                         if ( !(h->Time) ) {// token without duration
00704                                 DEBUGLOG (other, _T("CursorNext()"));
00705                                 h->CursorNext();
00706                         }
00707                 }
00708 
00709                 // check MinTime
00710                 DEBUGLOG (other, _T("h->Delta = %d, MinDelta = %d"),h->Delta,MinDelta);
00711 
00712                 if ( MinDelta == -1 || h->Delta < MinDelta )
00713                         MinDelta = h->Delta;
00714 
00715                 // next Header
00716                 H = &(h->Next);
00717         }
00718 
00719         DEBUGLOG2(other,_T("returning %d"),MinDelta);
00720 
00721         return MinDelta;
00722 }
00723 
00724 
00725 
00726 
00727 
00728 

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