void Invert_notes( struct Notes *note, Place *p1, Place *p2, bool firsttime, int last ){ int next=0; if(note==NULL) return; if(PlaceGreaterOrEqual(¬e->l.p,p1)){ if(PlaceGreaterOrEqual(¬e->l.p,p2)) return; next=note->note; if(firsttime==false){ note->note=R_MAX(1,R_MIN(127,2*last-note->note)); }else{ firsttime=false; } } Invert_notes(NextNote(note),p1,p2,firsttime,next); }
void RA_addNote_FloatPlace( int blocknum, int tracknum, float start, int notenum, float volume, float end) { struct Blocks *block=SWIG_getBlock(blocknum); struct Tracks *track=SWIG_getTrack(blocknum,tracknum); struct Notes *note; Place p2; if(track==NULL) return; note=NewNote(); Float2Placement(start,¬e->l.p); Float2Placement(end,¬e->end); PlaceSetLastPos(block,&p2); if(PlaceGreaterOrEqual(¬e->l.p,&p2)) return; if(PlaceGreaterOrEqual(¬e->end,&p2)){ PlaceCopy(¬e->end,&p2); } note->note=notenum; note->velocity=boundaries( volume*(*track->instrument->getMaxVelocity)(track), 0, (*track->instrument->getMaxVelocity)(track) ); ListAddElement3(&track->notes,¬e->l); }
void CopyRange_stops( struct Stops **tostop, struct Stops *fromstop, Place *p1, Place *p2 ){ struct Stops *stop; if(fromstop==NULL) return; if(PlaceLessThan(&fromstop->l.p,p1)){ CopyRange_stops(tostop,NextStop(fromstop),p1,p2); return; } if(PlaceGreaterOrEqual(&fromstop->l.p,p2)) return; stop=talloc(sizeof(struct Stops)); memcpy(stop, fromstop, sizeof(struct Stops)); PlaceSub(&stop->l.p,p1); ListAddElement3(tostop,&stop->l); CopyRange_stops(tostop,NextStop(fromstop),p1,p2); }
void InsertLines_notes( void *tonote, struct ListHeader3 *l, int line, int toinsert ){ struct Notes *note=(struct Notes *)l; struct Blocks *block=blocktobelongtoforinsertlines_notes_a_terrible_hack; Place p2; PlaceSetLastPos(block,&p2); // p2.line-=toinsert; // printf("toinsert: %d, note->end.line: %d, p2->line: %d\n",toinsert,note->end.line,p2.line); if(note->end.line>=line){ // printf("block: %d, note->end.line: %d, p2->line: %d\n",block->l.num,note->end.line,p2.line); if(PlaceGreaterOrEqual(¬e->end,&p2) && note->l.p.line<line){ PlaceSetLastPos(block,&p2); PlaceCopy(¬e->end,&p2); note->noend=1; }else{ note->end.line+=toinsert; note->end.line=R_MAX(note->end.line,line); } List_InsertLines3(¬e->velocities,¬e->velocities->l,line,toinsert,NULL); List_InsertLines3(¬e->pitches,¬e->pitches->l,line,toinsert,NULL); } }
static struct Velocities *add_velocity( int velocityvelocity, const Place *placement, struct Notes *note, int *pos ) { *pos = -1; if(PlaceLessOrEqual(placement, ¬e->l.p)) return NULL; if(PlaceGreaterOrEqual(placement, ¬e->end)) return NULL; struct Velocities *velocity=(struct Velocities*)talloc(sizeof(struct Velocities)); PlaceCopy(&velocity->l.p,placement); velocity->velocity=R_BOUNDARIES(0,velocityvelocity,MAX_VELOCITY); /* ListAddElement3_ns returns -1 (and doesnt do anything else) if there allready is an element with the same placement. */ PLAYER_lock();{ *pos = ListAddElement3_ns(¬e->velocities,&velocity->l); }PLAYER_unlock(); if (*pos==-1) return NULL; else return velocity; }
Place STime2Place( const struct Blocks *block, STime time ) { Place place; Place *firstplace = PlaceGetFirstPos(); Place lastplace; PlaceSetLastPos(block, &lastplace); if (time < 0) { return *firstplace; } if (time >= getBlockSTimeLength(block)){ PlaceTilLimit(&place,&lastplace); return place; } double place_f = STime2Place_f(block,time); Double2Placement(place_f, &place); if (PlaceGreaterOrEqual(&place, &lastplace)) PlaceTilLimit(&place,&lastplace); else if (PlaceLessThan(&place,firstplace)) place = *firstplace; //if (place.line==64) // abort(); return place; }
/****************************************************************************** SHORT Add an Element to a list. NAME ListAddElement SYNOPSIS void ListAddElement( struct ListHeaderPointer *listroot, struct ListHeader *element ) FUNCTION Reads element->place, element->counter and element->dividor and puts the element before before that in the list. ******************************************************************************/ void ListAddElement3( void *voidlistroot, struct ListHeader3 *element ){ struct ListHeaderPointer3 *listroot=voidlistroot; struct ListHeader3 *prev=NULL; struct ListHeader3 *temp=listroot->root; if(element==NULL) return; /* According to profiling, this function used quite a bit of time, and by adding the next four lines, it seems to be a bit better. */ while(temp!=NULL && temp->p.line < element->p.line){ prev=temp; temp=temp->next; } while(temp!=NULL){ if(PlaceGreaterOrEqual(&temp->p,&element->p)) break; prev=temp; temp=temp->next; } if(prev==NULL){ R_ASSERT_RETURN_IF_FALSE(element!=NULL); element->next=listroot->root; listroot->root=element; }else{ R_ASSERT_RETURN_IF_FALSE(element!=NULL); element->next=prev->next; prev->next=element; } }
void Transpose_notes( struct Notes *note, Place *p1, Place *p2, int trans ){ if(note==NULL) return; if(PlaceGreaterOrEqual(¬e->l.p,p1)){ if(PlaceGreaterOrEqual(¬e->l.p,p2)) return; Transpose_note(note,trans); } Transpose_notes(NextNote(note),p1,p2,trans); }
/****************************************************************************** FUNCTION Remove all elements that is placed after or has the same position as 'placement'. ******************************************************************************/ void CutListAt(void *listroot,Place *place){ struct ListHeaderPointer3 *root=(struct ListHeaderPointer3 *)listroot; struct ListHeader3 *element=root->root; if(element==NULL) return; if(PlaceGreaterOrEqual(&element->p,place)){ root->root=NULL; return; } for(;element!=NULL;element=element->next){ if( element->next!=NULL && PlaceGreaterOrEqual(&element->next->p,place) ){ element->next=NULL; break; } } }
struct Notes *FindNextNote( struct Tracks *track, Place *placement ) { struct Notes *note = track->notes; while(note != NULL) { if (PlaceGreaterOrEqual(¬e->l.p, placement)) break; note = NextNote(note); } return note; }
static int FindFirstFreePolyphony_num(Place *p){ int i; for(i=0 ; i < end_places_size ; i++){ if (i==last_free_polyphony_num) { last_free_polyphony_num++; return i; } if (PlaceGreaterOrEqual(p, end_places[i])) return i; } return 0; // A polyphony of 32*1024 voices. Impressive. }
void CutNoteAt(struct Blocks *block, struct Tracks *track,struct Notes *note, Place *place){ R_ASSERT(PLAYER_current_thread_has_lock() || is_playing()==false); if (PlaceGreaterOrEqual(place, ¬e->end)){ RError("Illegal argument for CutNoteAt 1. %f >= %f\n",GetfloatFromPlacement(place),GetfloatFromPlacement(¬e->end)); return; } if (PlaceLessOrEqual(place, ¬e->l.p)){ RError("Illegal argument for CutNoteAt 2. %f <= %f\n",GetfloatFromPlacement(place),GetfloatFromPlacement(¬e->l.p)); return; } CutListAt(¬e->velocities,place); CutListAt(¬e->pitches,place); PlaceCopy(¬e->end,place); }
void cutNote(float floatplace, int notenum, int tracknum, int blocknum, int windownum){ struct Tracker_Windows *window; struct WBlocks *wblock; struct WTracks *wtrack; struct Notes *note = getNoteFromNumA(windownum, &window, blocknum, &wblock, tracknum, &wtrack, notenum); if (note==NULL) return; Place place; Float2Placement(floatplace, &place); if (PlaceGreaterOrEqual(&place, ¬e->end)) return; if (PlaceLessOrEqual(&place, ¬e->l.p)) return; CutNoteAt(wblock->block, wtrack->track, note, &place); }
void CopyRange_pitches( struct Pitches **topitch, struct Pitches *frompitch, Place *p1, Place *p2 ){ struct Pitches *pitch; if(frompitch==NULL) return; if(PlaceGreaterOrEqual(&frompitch->l.p,p2)) return; pitch=tcopy(frompitch, sizeof(struct Pitches)); PlaceSub(&pitch->l.p,p1); ListAddElement3(topitch,&pitch->l); CopyRange_pitches(topitch,NextPitch(frompitch),p1,p2); }
void CopyRange_velocities( struct Velocities **tovelocity, struct Velocities *fromvelocity, Place *p1, Place *p2 ){ struct Velocities *velocity; if(fromvelocity==NULL) return; if(PlaceGreaterOrEqual(&fromvelocity->l.p,p2)) return; velocity=talloc(sizeof(struct Velocities)); memcpy(velocity, fromvelocity, sizeof(struct Velocities)); PlaceSub(&velocity->l.p,p1); ListAddElement3(tovelocity,&velocity->l); CopyRange_velocities(tovelocity,NextVelocity(fromvelocity),p1,p2); }
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); }
void StopVelocityCurrPos(struct Tracker_Windows *window,int noend){ struct WBlocks *wblock; struct WTracks *wtrack; int reallinerealline; struct LocalZooms *realline; struct Notes *note; int subtrack; wblock=window->wblock; wtrack=wblock->wtrack; reallinerealline=wblock->curr_realline; realline=wblock->reallines[reallinerealline]; subtrack=window->curr_track_sub; note=FindNoteOnSubTrack(wtrack,subtrack,&realline->l.p); if(note==NULL) return; ADD_UNDO(Notes_CurrPos(window)); PLAYER_lock();{ if(PlaceGreaterOrEqual(¬e->l.p,&realline->l.p)){ RemoveNote(wblock->block,wtrack->track,note); SetNotePolyphonyAttributes(wtrack->track); ValidateCursorPos(window); }else{ CutNoteAt(wblock->block, wtrack->track, note, &realline->l.p); } note->noend=noend; }PLAYER_unlock(); window->must_redraw=true; }
void CopyRange_notes( struct Notes **tonote, struct Notes *fromnote, Place *p1, Place *p2 ){ struct Notes *note; if(fromnote==NULL){ return; } if(PlaceLessThan(&fromnote->l.p,p1)){ CopyRange_notes(tonote,NextNote(fromnote),p1,p2); return; } if(PlaceGreaterOrEqual(&fromnote->l.p,p2)){ return; } note=CopyNote(fromnote); note->pitches = NULL; note->velocities = NULL; NOTE_init(note); PlaceSub(¬e->l.p,p1); PlaceSub(¬e->end,p1); ListAddElement3(tonote,¬e->l); CopyRange_velocities(¬e->velocities,fromnote->velocities,p1,p2); CopyRange_pitches(¬e->pitches,fromnote->pitches,p1,p2); CopyRange_notes(tonote,NextNote(fromnote),p1,p2); }
static void set_legal_start_and_end_pos(const struct Blocks *block, struct Tracks *track, struct Notes *note){ Place *start = ¬e->l.p; Place *end = ¬e->end; Place endplace; PlaceSetLastPos(block,&endplace); if(PlaceGreaterOrEqual(start,&endplace)) { RError("note is placed after block end. start: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(¬e->end)); set_new_position(track, note, PlaceCreate(block->num_lines - 2, 0, 1), NULL); start = ¬e->l.p; } if (start->line < 0) { RError("note is placed before block start. start: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(¬e->end)); set_new_position(track, note, PlaceCreate(0,1,1), NULL); start = ¬e->l.p; } if(PlaceGreaterThan(end,&endplace)) { RError("note end is placed after block end. start: %f, end: %f. block end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(¬e->end), GetfloatFromPlace(&endplace)); set_new_position(track, note, NULL, &endplace); end = ¬e->end; } if (note->velocities != NULL) { { struct Velocities *first_velocity = note->velocities; if(PlaceGreaterThan(start, &first_velocity->l.p)){ RError("note start is placed after first velocity. start: %f, first: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(&first_velocity->l.p), GetfloatFromPlace(¬e->end)); float e = p_float(first_velocity->l.p); e -= 0.01; e = R_MAX(0.0, e); Place new_start; Float2Placement(e, &new_start); set_new_position(track, note, &new_start, NULL); start = ¬e->l.p; } } struct Velocities *last_velocity = (struct Velocities*)ListLast3(¬e->velocities->l); if(PlaceLessThan(end, &last_velocity->l.p)){ RError("note end is placed before last velocity. start: %f, last: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(&last_velocity->l.p), GetfloatFromPlace(¬e->end)); float e = p_float(last_velocity->l.p); e += 0.01; Place new_end; Float2Placement(e, &new_end); set_new_position(track, note, NULL, &new_end); end = ¬e->end; } } if (note->pitches != NULL) { { struct Pitches *first_pitch = note->pitches; if(PlaceGreaterThan(start, &first_pitch->l.p)){ RError("note start is placed after first pitch. start: %f, first: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(&first_pitch->l.p), GetfloatFromPlace(¬e->end)); float e = p_float(first_pitch->l.p); e -= 0.01; e = R_MAX(0.0, e); Place new_start; Float2Placement(e, &new_start); set_new_position(track, note, &new_start, NULL); start = ¬e->l.p; } } struct Pitches *last_pitch = (struct Pitches*)ListLast3(¬e->pitches->l); if(PlaceLessThan(end, &last_pitch->l.p)){ RError("note end is placed before last pitch. start: %f, last: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(&last_pitch->l.p), GetfloatFromPlace(¬e->end)); float e = p_float(last_pitch->l.p); e += 0.01; Place new_end; Float2Placement(e, &new_end); set_new_position(track, note, NULL, &new_end); end = ¬e->end; } } if(PlaceLessOrEqual(end,start)) { RError("note end is placed before (or on) note start. start: %f, end: %f", GetfloatFromPlace(¬e->l.p), GetfloatFromPlace(¬e->end)); float e = p_float(*start); e += 0.01; Place new_end; Float2Placement(e, &new_end); set_new_position(track, note, NULL, &new_end); } }