static void STP_Constructor(STimePlace *stp,struct Blocks *block){ /* Misc */ PlaceSetFirstPos(&stp->firstplace); PlaceSetLastPos(block,&stp->lastplace); stp->btempo=false; stp->blpb=false; stp->breltempo=false; /* Times */ stp->times = talloc(sizeof(struct STimes)*(block->num_lines+1)); /* Tempos */ stp->tempo=root->tempo; stp->stempo= block->tempos; if(stp->stempo!=NULL && PlaceEqual(&stp->firstplace,&stp->stempo->l.p)){ stp->tempo=stp->stempo->tempo; stp->stempo=NextTempo(stp->stempo); } /* LBPs */ stp->lpb=root->lpb; stp->slpb=block->lpbs; if(stp->slpb!=NULL && PlaceEqual(&stp->firstplace,&stp->slpb->l.p)){ stp->lpb=stp->slpb->lpb; stp->slpb=NextLPB(stp->slpb); } /* TempoNodes */ stp->temponode=block->temponodes; stp->relp1=GetDoubleFromPlace(&stp->temponode->l.p); // first temponode is allways at firstplace (just try dragging down the highest temponode). stp->reltempo1=stp->temponode->reltempo; stp->temponode=NextTempoNode(stp->temponode); stp->relp2=GetDoubleFromPlace(&stp->temponode->l.p); // There is allways at least two temponode objects for each block. stp->reltempo2=stp->temponode->reltempo; /* Placements */ stp->p1= &stp->firstplace; stp->p2=&stp->temponode->l.p; if(stp->stempo!=NULL){ stp->p2=PlaceMin(stp->p2,&stp->stempo->l.p); } if(stp->slpb!=NULL){ stp->p2=PlaceMin(stp->p2,&stp->slpb->l.p); } /* bools */ if(stp->stempo!=NULL && PlaceEqual(stp->p2,&stp->stempo->l.p)) stp->btempo=true; if(stp->slpb!=NULL && PlaceEqual(stp->p2,&stp->slpb->l.p)) stp->blpb=true; if(PlaceEqual(stp->p2,&stp->temponode->l.p)) stp->breltempo=true; /* time */ stp->nexttime=0; }
/* A debugging function. */ void PrintSTimes(struct Blocks *block){ struct WBlocks *wblock; struct LocalZooms **reallines; const struct STimes *stime; const struct STimeChanges *timechanges; int lasttime=0; int nowtime; int line,realline; for(line=0;line<=block->num_lines;line++){ stime= &block->times[line]; timechanges=stime->timechanges; nowtime=stime->time; printf("%d. %d. Delta: %d, Ch: %p\n",line,nowtime,nowtime-lasttime,timechanges); while(timechanges!=NULL){ printf(" place: %f, time: %" PRId64 ", tempo1: %f, rel: %f, deltarel: %f\n", GetDoubleFromPlace(&timechanges->l.p), timechanges->time, timechanges->tempo1, timechanges->rel, timechanges->deltarel ); timechanges=NextSTimeChange(timechanges); } lasttime=nowtime; } printf("--------reallines:----------\n"); if(root->song->tracker_windows!=NULL){ wblock=root->song->tracker_windows->wblock; if(wblock!=NULL){ reallines=wblock->reallines; if (reallines!=NULL){ lasttime=0; for(realline=0;realline<wblock->num_reallines;realline++){ nowtime=Place2STime(block,&reallines[realline]->l.p); printf("realline: %d, Place: %f, time: %d, delta: %d,\n",realline,GetDoubleFromPlace(&reallines[realline]->l.p),nowtime,nowtime-lasttime); lasttime=nowtime; } } } } }
static void set_iterator_data2(LPB_Iterator *iterator, const struct Blocks *block, Place p1, int lpb_value, const struct LPBs *next_lpb){ iterator->lpb_value = lpb_value; iterator->place1 = p1; iterator->place1_f = GetDoubleFromPlace(&p1); if (next_lpb==NULL) { SetAbsoluteLastPlace(&iterator->place2, block); iterator->place2_f = block->num_lines; } else { iterator->place2 = next_lpb->l.p; iterator->place2_f = GetDoubleFromPlace(&next_lpb->l.p); } set_num_beats_between_place1_and_place2(iterator); print_lpb_iterator_status(block, iterator); }
STime Place2STime_from_times( const struct STimes *times, const Place *p ) { if(0==p->counter){ int line1 = p->line; const struct STimes *stime= ×[line1]; STime time1=stime->time; return time1; } return Place2STime_from_times2(times, GetDoubleFromPlace(p)); }
static double Place2STime_from_times2( const struct STimes *times, double fp ) { int line1 = (int)fp; int line2 = line1+1; const struct STimes *stime= ×[line1]; // printf("P2ST, block: %x, stime: %x, line: %d\n",block,stime,line); double time1=stime->time; double time2=times[line2].time; double fp1 = line1; double fp2 = fp1+1.0; if (fabs(fp1 - fp) < 0.0000001) return time1; const struct STimeChanges *stc = stime->timechanges; if(stc!=NULL){ double orgfp2 = fp2; struct STimeChanges *next=NextSTimeChange(stc); while(next!=NULL){ double maybe_new_fp2 = GetDoubleFromPlace(&next->l.p); if (maybe_new_fp2 >= fp) { fp2=maybe_new_fp2; time2=next->time; break; } stc=next; next=NextSTimeChange(next); } fp1=GetDoubleFromPlace(&stc->l.p); time1=stc->time; if(stc->tempo1!=0.0f){ double tempo=stc->tempo1 * ( RelTempo2RealRelTempo( (double) ( stc->rel + (stc->deltarel*(fp-fp1)/(2*(fp2-fp1))) // i.e. stc->rel + scale(fp, fp1, fp2, 0, stc->deltarel / 2.0f), )) ); return (double) ( time1 + ( pc->pfreq*60*(fp-fp1)/tempo ) ); } if(next!=NULL){ time2=next->time; }else{ fp2=orgfp2; } } return scale_double(fp, fp1, fp2, time1, time2); }
static bool STP_getNextTimePlace(STimePlace *stp){ stp->p1=stp->p2; if(stp->btempo){ stp->tempo=stp->stempo->tempo; stp->stempo=NextTempo(stp->stempo); stp->btempo=false; } if(stp->blpb){ stp->lpb=stp->slpb->lpb; stp->slpb=NextLPB(stp->slpb); stp->blpb=false; } if(stp->breltempo){ stp->relp1=stp->relp2; stp->reltempo1=stp->reltempo2; stp->temponode=NextTempoNode(stp->temponode); if(stp->temponode!=NULL){ stp->relp2=GetDoubleFromPlace(&stp->temponode->l.p); stp->reltempo2=stp->temponode->reltempo; } stp->breltempo=false; } if(stp->temponode==NULL){ if(stp->stempo==NULL){ if(stp->slpb==NULL){ if(PlaceEqual(&stp->lastplace,stp->p2)){ return false; }else{ stp->p2= &stp->lastplace; } }else{ STP_NextLPB(stp); } }else{ switch(PlaceCmp(&stp->stempo->l.p,&stp->slpb->l.p)){ case -1: STP_NextTempo(stp); break; case 0: STP_cNextTempo(stp); STP_NextLPB(stp); break; case 1: STP_NextLPB(stp); break; } } }else{ if(stp->stempo==NULL){ if(stp->slpb==NULL){ STP_NextTempoNode(stp); }else{ switch(PlaceCmp(&stp->slpb->l.p,&stp->temponode->l.p)){ case -1: STP_NextLPB(stp); break; case 0: STP_cNextLPB(stp); STP_NextTempoNode(stp); break; case 1: STP_NextTempoNode(stp); break; } } }else{ if(stp->slpb==NULL){ switch(PlaceCmp(&stp->temponode->l.p,&stp->stempo->l.p)){ case -1: STP_NextTempoNode(stp); break; case 0: STP_cNextTempoNode(stp); STP_NextTempo(stp); break; case 1: STP_NextTempo(stp); break; } }else{ switch(PlaceCmp(&stp->temponode->l.p,&stp->stempo->l.p)){ case -1: switch(PlaceCmp(&stp->temponode->l.p,&stp->slpb->l.p)){ case -1: STP_NextTempoNode(stp); break; case 0: STP_cNextTempoNode(stp); STP_NextLPB(stp); break; case 1: STP_NextLPB(stp); break; } break; case 0: switch(PlaceCmp(&stp->temponode->l.p,&stp->slpb->l.p)){ case -1: STP_cNextTempoNode(stp); STP_NextTempo(stp); break; case 0: STP_cNextTempoNode(stp); STP_cNextTempo(stp); STP_NextLPB(stp); break; case 1: STP_NextLPB(stp); break; } break; case 1: switch(PlaceCmp(&stp->stempo->l.p,&stp->slpb->l.p)){ case -1: STP_NextTempo(stp); break; case 0: STP_cNextTempo(stp); STP_NextLPB(stp); break; case 1: STP_NextLPB(stp); break; } break; } } } } // STP_setSTPtempos(stp); return true; }
static void STP_fillinSTimes2( STimePlace *stp, Place *p1, Place *p2 ){ bool tchange=false; bool rchange=false; double tfp1,tfp2; double reltempo1=stp->reltempo1; double reltempo2=stp->reltempo2; struct STimeChanges *timechange=NULL; if(PlaceEqual(p1,p2)){ return; } if(reltempo1!=reltempo2) rchange=true; if(rchange || p1->counter>0) tchange=true; if(tchange){ timechange=talloc(sizeof(struct STimeChanges)); timechange->time=stp->nexttime; timechange->tempo1=0.0f; } if(0==p1->counter){ stp->times[p1->line].time = stp->nexttime; } tfp1=GetDoubleFromPlace(p1); tfp2=GetDoubleFromPlace(p2); if(rchange){ timechange->rel= reltempo1 + ( (reltempo2-reltempo1)*(tfp1-stp->relp1)/(stp->relp2-stp->relp1) ) ; timechange->deltarel = ( reltempo1 + ( (reltempo2-reltempo1)*(tfp2-stp->relp1)/(stp->relp2-stp->relp1) ) ) - timechange->rel; timechange->tempo1 = stp->lpb * stp->tempo; stp->nexttime = ( stp->nexttime + ( pc->pfreq*60*(tfp2-tfp1)/( (timechange->tempo1*FindAverageRealRelTempo(timechange->rel,(double)(timechange->rel+timechange->deltarel))) ) ) ); }else{ stp->nexttime = ( stp->nexttime + ( pc->pfreq*60*(tfp2-tfp1)/(stp->tempo*stp->lpb*RelTempo2RealRelTempo(stp->reltempo1)) ) ); } if(tchange){ PlaceCopy(&timechange->l.p,p1); ListAddElement3(&stp->times[p1->line].timechanges,&timechange->l); } }