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; }
void TRACK_make_monophonic_destructively(struct Tracks *track){ struct Tracker_Windows *window = root->song->tracker_windows; struct WBlocks *wblock = window->wblock; struct Notes *note = track->notes; bool have_made_undo = false; while(note!=NULL){ struct Notes *next = NextNote(note); if (next==NULL) break; if (PlaceGreaterThan(¬e->end, &next->l.p)){ PLAYER_lock();{ if (PlaceEqual(¬e->l.p, &next->l.p)) { ListRemoveElement3(&track->notes, &next->l); } else { PlaceCopy(¬e->end, &next->l.p); note = next; } }PLAYER_unlock(); if (have_made_undo==false){ ADD_UNDO(Notes(window, wblock->block, track, wblock->curr_realline ) ); have_made_undo = true; } } else { note = next; } } if (have_made_undo==false) GFX_Message(NULL, "Track is already monophonic"); else window->must_redraw = true; }
bool NOTES_sorted_by_pitch_questionmark(struct Notes *notes){ while(notes != NULL){ struct Notes *next = NextNote(notes); if (next==NULL) return true; if (PlaceEqual(¬es->l.p, &next->l.p)) if (notes->note > next->note) return false; notes = next; } return true; }
/********************************************************************** FUNCTION Set the end attributes of all notes that previously was stopped at position 'placement' to the next stop wherever that may be. **********************************************************************/ void LengthenNotesTo( struct Blocks *block, struct Tracks *track, Place *placement ){ struct Notes *note=track->notes; while(note!=NULL){ if(PlaceGreaterThan(¬e->l.p,placement)) break; if(PlaceEqual(¬e->end,placement)) SetEndAttributes(block,track,note); note=NextNote(note); } }
/***************************************************************************** FUNCTION Adds an element only if the list doesn't allready contain an element with the same placement attributes. ******************************************************************************/ int ListAddElement3_ns( void *voidlistroot, struct ListHeader3 *element ){ if(element==NULL) return -1; struct ListHeaderPointer3 *listroot=voidlistroot; ListAddElement3(listroot,element); if(element->next!=NULL) if(PlaceEqual(&element->p,&element->next->p)){ ListRemoveElement3(listroot,element); return -1; } struct ListHeader3 *list=listroot->root; return ListPosition3(list,element); }
/********************************************************************** FUNCTION Set the end attributes of all notes that previously was stopped at position 'old_placement' to 'new_placement'. **********************************************************************/ void ReplaceNoteEnds( struct Blocks *block, struct Tracks *track, Place *old_placement, Place *new_placement, int polyphony_num ){ struct Notes *note=track->notes; while(note!=NULL){ if (note->polyphony_num == polyphony_num) { if(PlaceGreaterThan(¬e->l.p,old_placement)) break; if(PlaceEqual(¬e->end,old_placement)) { note->end = *new_placement; NOTE_validate(block, track, note); } } note=NextNote(note); } }
struct Signatures *SetSignature( struct Blocks *block, const Place *place, Ratio ratio ){ struct Signatures *signature=(struct Signatures *)ListFindElement3(&block->signatures->l,place); if(signature!=NULL && PlaceEqual(&signature->l.p,place)){ signature->signature=ratio; }else{ signature=(struct Signatures*)talloc(sizeof(struct Signatures)); PlaceCopy(&signature->l.p,place); signature->signature=ratio; ListAddElement3(&block->signatures,&signature->l); } //UpdateSTimes(block); UpdateBeats(block); return signature; }
static struct Notes *sort_notes_by_pitch_a_little_bit(struct Notes *notes){ struct Notes *ret = notes; struct Notes *note_to_place_after = NULL; while(notes != NULL){ struct Notes *next = NextNote(notes); R_ASSERT_RETURN_IF_FALSE2(next!=NULL, NULL); if (PlaceEqual(¬es->l.p, &next->l.p)) if (notes->note > next->note) { note_to_place_after = notes; break; } notes = next; } ListRemoveElement3(&ret, ¬e_to_place_after->l); ListAddElement3_a(&ret, ¬e_to_place_after->l); return ret; }
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); } }
void Block_Set_num_lines( struct Blocks *block, int num_lines ){ Place lastplace1,lastplace; struct Tracker_Windows *window=root->song->tracker_windows; struct WBlocks *wblock; struct LocalZooms *localzoom; struct Tracks *track=block->tracks; struct Notes *note; struct FXs *fxs; int org_num_lines=block->num_lines; int lokke; if(org_num_lines==num_lines || num_lines<2) return; PlaceSetLastPos(block,&lastplace1); block->num_lines=num_lines; PlaceSetLastPos(block,&lastplace); if(num_lines<org_num_lines){ CutListAt_a(&block->lpbs,&lastplace); CutListAt_a(&block->tempos,&lastplace); CutListAt_a(&block->temponodes,&lastplace); PlaceSetLastPos(block,&block->lasttemponode->l.p); ListAddElement3(&block->temponodes,&block->lasttemponode->l); while(track!=NULL){ CutListAt_a(&track->notes,&lastplace); note=track->notes; while(note!=NULL){ CutListAt(¬e->velocities,&lastplace); CutListAt(¬e->pitches,&lastplace); if(PlaceEqual(¬e->end,&lastplace1) && note->noend==1){ PlaceCopy(¬e->end,&lastplace); } note=NextNote(note); } LegalizeNotes(block,track); CutListAt_a(&track->stops,&lastplace); fxs=track->fxs; while(fxs!=NULL){ CutListAt_a(&fxs->fxnodelines,&lastplace); fxs=NextFX(fxs); } LegalizeFXlines(block,track); track=NextTrack(track); } while(window!=NULL){ wblock=ListFindElement1(&window->wblocks->l,block->l.num); CutListAt_a(&wblock->localzooms,&lastplace); window=NextWindow(window); } }else{ PlaceSetLastPos(block,&block->lasttemponode->l.p); while(track!=NULL){ note=track->notes; while(note!=NULL){ if(PlaceEqual(¬e->end,&lastplace1) && note->noend==1){ PlaceSetLastPos(block,¬e->end); } note=NextNote(note); } LegalizeNotes(block,track); track=NextTrack(track); } while(window!=NULL){ wblock=ListFindElement1(&window->wblocks->l,block->l.num); for(lokke=org_num_lines;lokke<num_lines;lokke++){ localzoom=talloc(sizeof(struct LocalZooms)); localzoom->Tline=lokke; localzoom->Tdividor=1; localzoom->zoomline=lokke; ListAddElement3(&wblock->localzooms,&localzoom->l); } window=NextWindow(window); } } window=root->song->tracker_windows; while(window!=NULL){ wblock=ListFindElement1(&window->wblocks->l,block->l.num); UpdateWBlockWidths(window,wblock); UpdateRealLines(window,wblock); window=NextWindow(window); } UpdateSTimes(block); UpdateBeats(block); }