void List_InsertPlaceLen3( struct Blocks *block, void *to, struct ListHeader3 *l, float place, float toplace, void (*Insert_PlaceLen_extra)(struct Blocks *block,void *to,struct ListHeader3 *l,float place,float toplace) ){ while(l!=NULL){ struct ListHeader3 *next = l->next; if(Insert_PlaceLen_extra!=NULL){ (*Insert_PlaceLen_extra)(block,to,l,place,toplace); } if(GetfloatFromPlacement(&l->p)>=place){ if(GetfloatFromPlacement(&l->p)<place-toplace){ ListRemoveElement3(to,l); }else{ PlaceAddfloat(&l->p,toplace); if( ! PlaceLegal(block,&l->p)){ ListRemoveElement3(to,l); } } } l = next; } }
void RemoveNoteCurrPos(struct Tracker_Windows *window){ struct WBlocks *wblock = window->wblock; struct WTracks *wtrack = wblock->wtrack; struct Tracks *track = wtrack->track; struct LocalZooms *realline = wblock->reallines[wblock->curr_realline]; int curr_realline = wblock->curr_realline; const Trs &trs = TRS_get(wblock, wtrack, curr_realline); ADD_UNDO(Notes_CurrPos(window)); if (trs.size()==0) { InsertStop(window,wblock,wtrack,&realline->l.p); maybe_scroll_down(window); return; } const TrackRealline2 &tr2 = trs[0]; if (tr2.pitch != NULL) { DeletePitch(track, tr2.note, tr2.pitch); if (trs.size()==1) maybe_scroll_down(window); return; } if (tr2.is_end_pitch) { struct Pitches *pitch = (struct Pitches*)ListLast3(&tr2.note->pitches->l); if (pitch!=NULL) tr2.note->pitch_end = pitch->note; else tr2.note->pitch_end = 0; return; } if (tr2.note != NULL) { PLAYER_lock();{ ListRemoveElement3(&track->notes,&tr2.note->l); LengthenNotesTo(wblock->block,track,&realline->l.p); }PLAYER_unlock(); SetNotePolyphonyAttributes(wtrack->track); ValidateCursorPos(window); if (trs.size()==1) maybe_scroll_down(window); return; } const struct Stops *stop = tr2.stop; PLAYER_lock();{ ListRemoveElement3(&track->stops, &stop->l); LengthenNotesTo(wblock->block,track,&realline->l.p); }PLAYER_unlock(); if (trs.size()==1) maybe_scroll_down(window); }
static void set_new_position(struct Tracks *track, struct Notes *note, Place *start, Place *end){ bool has_lock = PLAYER_current_thread_has_lock(); if (track==NULL && has_lock) RError("track==NULL && has_lock"); if (track!=NULL) { if (has_lock==false) PLAYER_lock(); ListRemoveElement3(&track->notes, ¬e->l); } if (start!=NULL && start!=¬e->l.p) note->l.p = *start; if (end!=NULL && end!=¬e->end) note->end = *end; if (track!=NULL){ ListAddElement3(&track->notes, ¬e->l); if (has_lock==false) PLAYER_unlock(); } }
void List_InsertLines3( void *to, struct ListHeader3 *l, int line, int toinsert, void (*Insert_Lines_extra)(void *to,struct ListHeader3 *l,int line,int toinsert) ){ struct ListHeader3 *temp; while(l!=NULL){ if(Insert_Lines_extra!=NULL){ (*Insert_Lines_extra)(to,l,line,toinsert); } if(l->p.line>=line){ if(l->p.line<line-toinsert){ R_ASSERT_RETURN_IF_FALSE(l!=NULL); temp=l->next; ListRemoveElement3(to,l); l=temp; continue; } l->p.line+=toinsert; } l=l->next; } }
// TODO/FIX: Implement void RemoveAllTempoNodesOnReallineCurrPos(struct Tracker_Windows *window){ #if !USE_OPENGL struct WBlocks *wblock=window->wblock; WTempoNodes *wtemponode; int realline=wblock->curr_realline; PlayStop(); Undo_TempoNodes_CurrPos(window); wtemponode=wblock->wtemponodes[realline]; while(wtemponode!=NULL){ if(wtemponode->type==TEMPONODE_NODE) ListRemoveElement3(&wblock->block->temponodes,(struct ListHeader3 *)wtemponode->pointer); wtemponode=wtemponode->next; } LegalizeTempoNodes(wblock->block); UpdateWTempoNodes(window,wblock); DrawUpWTempoNodes(window,wblock); UpdateSTimes(wblock->block); #endif }
void RemoveNote( struct Blocks *block, struct Tracks *track, struct Notes *note ){ ListRemoveElement3(&track->notes,¬e->l); LengthenNotesTo(block,track,¬e->l.p); }
void InsertNoteCurrPos(struct Tracker_Windows *window, float notenum, bool polyphonic, float velocity){ if(notenum<0.001 || notenum>127.9) return; ADD_UNDO(Notes_CurrPos(window)); struct WBlocks *wblock = window->wblock; struct WTracks *wtrack = wblock->wtrack; struct Tracks *track = wtrack->track; int curr_realline = wblock->curr_realline; const Trs &trs = TRS_get(wblock, wtrack, curr_realline); if (polyphonic==false && trs.size() > 0) { const TrackRealline2 &tr2 = trs[0]; if (tr2.pitch != NULL) { tr2.pitch->note = notenum; // lock not necessary maybe_scroll_down(window); return; } if (tr2.note != NULL) { // lock not necessary if (tr2.is_end_pitch) tr2.note->pitch_end = notenum; else tr2.note->note = notenum; maybe_scroll_down(window); return; } const struct Stops *stop = tr2.stop; PLAYER_lock();{ ListRemoveElement3(&track->stops, &stop->l); }PLAYER_unlock(); } struct LocalZooms *realline = wblock->reallines[curr_realline]; InsertNote( wblock,wtrack,&realline->l.p,NULL,notenum, velocity < 0.0 ? NOTE_get_velocity(wtrack->track) : velocity*MAX_VELOCITY, polyphonic ); if(wtrack->l.num==wblock->right_track && polyphonic) UpdateAllWTracksCoordinates(window,wblock); if (!polyphonic) maybe_scroll_down(window); }
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; }
/***************************************************************************** FUNCTION Removes all elements in a list that is greater or equal to p1, and less than p2. ******************************************************************************/ void ListRemoveElements3( void *voidlistroot, Place *p1, Place *p2 ){ struct ListHeaderPointer3 *listroot=voidlistroot; struct ListHeader3 *l=listroot->root; struct ListHeader3 *temp; while(l!=NULL){ temp=l->next; if(PlaceIsBetween2(&l->p,p1,p2)){ ListRemoveElement3(voidlistroot,l); } l=temp; } }
/***************************************************************************** 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); }
void DeleteFxNodeLine(struct WTracks *wtrack, struct FXs *fxs, struct FXNodeLines *fxnodeline){ R_ASSERT(ListFindNumElements3(&fxs->fxnodelines->l)>1); PLAYER_lock();{ ListRemoveElement3(&fxs->fxnodelines,&fxnodeline->l); }PLAYER_unlock(); if (ListFindNumElements3(&fxs->fxnodelines->l) <= 1 ){ PlayStop(); struct FX *fx = fxs->fx; struct Tracks *track = wtrack->track; OS_SLIDER_release_automation_pointers(track->patch,fx->effect_num); (*fx->closeFX)(fx,track); ListRemoveElement1(&track->fxs,&fxs->l); } }
void CutRange_stops( struct Stops **tostop, struct Stops *fromstop, Place *p1, Place *p2 ){ struct Stops *next; if(fromstop==NULL) return; next=NextStop(fromstop); if(PlaceLessThan(&fromstop->l.p,p1)){ CutRange_stops(tostop,next,p1,p2); return; } if(PlaceGreaterOrEqual(&fromstop->l.p,p2)) return; ListRemoveElement3(tostop,&fromstop->l); CutRange_stops(tostop,next,p1,p2); }
void CutRange_notes( struct Notes **tonote, struct Notes *fromnote, Place *p1, Place *p2 ){ struct Notes *next; if(fromnote==NULL) return; next=NextNote(fromnote); if(PlaceLessThan(&fromnote->l.p,p1)){ CutRange_notes(tonote,next,p1,p2); return; } if(PlaceGreaterOrEqual(&fromnote->l.p,p2)) return; ListRemoveElement3(tonote,&fromnote->l); CutRange_notes(tonote,next,p1,p2); }
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; }
void TRACK_split_into_monophonic_tracks(struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack){ PlayStop(); // This function is too chaotic. Don't bother pausing player. vector_t notesvector = {0}; struct Tracks *track = wtrack->track; struct Notes *notes = track->notes; struct Notes *notes_nexttrack = NULL; bool have_made_undo = false; if (NOTES_sorted_by_pitch_questionmark(track->notes)==false) { ADD_UNDO(Block_CurrPos(window)); have_made_undo = true; notes = NOTES_sort_by_pitch(notes); } while(notes != NULL){ struct Notes *notes_root = notes; while(notes != NULL) { struct Notes *next = NextNote(notes); if (next==NULL) break; if (PlaceGreaterThan(¬es->end, &next->l.p)){ if (have_made_undo==false) { have_made_undo=true; } ListRemoveElement3(¬es, &next->l); ListAddElement3_a(¬es_nexttrack, &next->l); } else notes = next; } VECTOR_push_back(¬esvector, notes_root); notes = notes_nexttrack; notes_nexttrack = NULL; } if (have_made_undo==false){ GFX_Message(NULL, "Track is already monophonic"); return; } int num_tracks = notesvector.num_elements; track->notes = NULL; struct WTracks *wtrack_copy = CB_CopyTrack(wblock,wtrack); VECTOR_clean(&wtrack_copy->track->fxs); InsertTracks(window, wblock, wtrack->l.num+1, num_tracks-1); printf("Vector length: %d\n",num_tracks); int i; for(i=0;i<num_tracks;i++){ struct Notes *notes = notesvector.elements[i]; printf(" %d: %d\n", i, ListFindNumElements3(¬es->l)); while(notes != NULL){ printf(" %s\n",NotesTexts3[(int)notes->note]); notes = NextNote(notes); } struct WTracks *towtrack = ListFindElement1(&wblock->wtracks->l, wtrack->l.num+i); if (i>0) co_CB_PasteTrack(wblock, wtrack_copy, towtrack); towtrack->track->notes = notesvector.elements[i]; } window->must_redraw = true; }
void ListRemoveElement1( void *voidlistroot, struct ListHeader1 *element ){ ListRemoveElement3(voidlistroot,(struct ListHeader3 *)element); }
void DeletePitch(struct Tracks *track, struct Notes *note, struct Pitches *pitch){ PLAYER_lock();{ ListRemoveElement3(¬e->pitches, &pitch->l); }PLAYER_unlock(); }