void RT_schedule_LPBs_newblock(struct SeqTrack *seqtrack, const struct SeqBlock *seqblock, const Place start_place) { LPB_Iterator *iterator = &seqtrack->lpb_iterator; // Null out all fields, except num_beats_played_so_far. double num_beats_played_so_far = iterator->num_beats_played_so_far + iterator->num_beats_between_place1_and_place2; memset(iterator, 0, sizeof(LPB_Iterator)); iterator->num_beats_played_so_far = num_beats_played_so_far; const struct Blocks *block = seqblock->block; const struct LPBs *lpb = block->lpbs; if (lpb==NULL) { set_iterator_data2(iterator, block, PlaceFirstPos, root->lpb, NULL); } else if (PlaceGreaterThan(&lpb->l.p, &start_place)){ set_iterator_data2(iterator, block, PlaceFirstPos, root->lpb, lpb); schedule_next_LPB(seqtrack, seqblock, lpb); } else { const struct LPBs *next_lpb = NextLPB(lpb); // spool forward to the 'lpb' that is used by 'start_place' // while(next_lpb != NULL){ if (PlaceGreaterThan(&next_lpb->l.p, &start_place)) break; lpb = next_lpb; next_lpb = NextLPB(lpb); } set_iterator_data(iterator, block, lpb); if (next_lpb != NULL) schedule_next_LPB(seqtrack, seqblock, next_lpb); } R_ASSERT(iterator->lpb_value != 0); }
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; }
static int64_t RT_scheduled_LPB(struct SeqTrack *seqtrack, int64_t time, union SuperType *args){ const struct SeqBlock *seqblock = args[0].const_pointer; LPB_Iterator *iterator = &seqtrack->lpb_iterator; iterator->num_beats_played_so_far += iterator->num_beats_between_place1_and_place2; const struct LPBs *lpb = iterator->next_lpb; set_iterator_data(iterator, seqblock->block, lpb); const struct LPBs *next_lpb = NextLPB(lpb); if (next_lpb != NULL) schedule_next_LPB(seqtrack, seqblock, next_lpb); return DONT_RESCHEDULE; }
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 set_iterator_data(LPB_Iterator *iterator, const struct Blocks *block, const struct LPBs *lpb){ R_ASSERT_RETURN_IF_FALSE(lpb != NULL); set_iterator_data2(iterator, block, lpb->l.p, lpb->lpb, NextLPB(lpb)); }