float TRACK_get_max_pitch(const struct Tracks *track){ float max_pitch = -1; int num_pitches = 0; { struct Notes *note = track->notes; while(note!=NULL){ max_pitch = R_MAX(note->note, max_pitch); num_pitches ++; struct Pitches *pitch = note->pitches; while(pitch != NULL){ max_pitch = R_MAX(pitch->note, max_pitch); num_pitches ++; pitch = NextPitch(pitch); } note = NextNote(note); } } if (num_pitches==0) return -1; else return max_pitch; }
static void RT_scheduled_hold_pitch_do(struct SeqTrack *seqtrack, int64_t time, const struct SeqBlock *seqblock, const struct Tracks *track, const struct Notes *note, const struct Pitches *pitch1, bool doit ) { struct Patch *patch = track->patch; if (patch!=NULL && pitch1!=NULL && doit) { float val = pitch1->note; #if DO_DEBUG printf(" Sending HOLD pitch %f at %d\n",val,(int)time); #endif RT_PATCH_change_pitch(seqtrack, patch, create_note_t2(seqblock,note->id, val), time ); } const struct Pitches *pitch2 = pitch1==NULL ? note->pitches : NextPitch(pitch1); if (pitch2 != NULL) RT_schedule_pitch(seqtrack, time, seqblock, track, note, pitch2, false); }
static int64_t RT_scheduled_glide_pitch(struct SeqTrack *seqtrack, int64_t time, union SuperType *args){ const struct SeqBlock *seqblock = args[0].const_pointer; const struct Tracks *track = args[1].const_pointer; const struct Notes *note = args[2].pointer; const struct Pitches *pitch1 = args[3].pointer; int64_t time1 = args[4].int_num; int64_t time2 = args[5].int_num; bool doit = args[6].bool_num; struct Patch *patch = track->patch; if (patch==NULL) return DONT_RESCHEDULE; #if !defined(RELEASE) if (time < time1 || time>time2) RError("RT_scheduled_glide_pitch: time: %d, time1: %d, time2: %d", time, time1, time2); #endif if (time < time1) time = time1; if (time > time2) time = time2; const struct Pitches *pitch2 = pitch1==NULL ? note->pitches : NextPitch(pitch1); if (doit) { float val1 = pitch1==NULL ? note->note : pitch1->note; float val2 = pitch2==NULL ? note->pitch_end : pitch2->note; float val = time1==time2 ? val2 : scale(time, time1, time2, val1, val2); // We get divide by zero in scale() if time1==time2 #if DO_DEBUG printf(" Sending pitch %f at %d\n",val,(int)time); #endif if (time==time1 || val1!=val2) RT_PATCH_change_pitch(seqtrack, patch, create_note_t2(seqblock,note->id, val), time ); } if (time >= time2) { if (pitch2 != NULL) RT_schedule_pitch(seqtrack, time, seqblock, track, note, pitch2, true); return DONT_RESCHEDULE; } else { return R_MIN(time2, time + RADIUM_BLOCKSIZE); } }
static void add_note(const struct WBlocks *wblock, vector_t *trs, struct Notes *note){ TrackRealline2 *tr = talloc(sizeof(TrackRealline2)); tr->p = note->l.p; tr->note = note; add_tr(wblock, trs, tr); struct Pitches *pitch = note->pitches; while(pitch != NULL){ add_pitch(wblock, trs, note, pitch); pitch = NextPitch(pitch); } }
void Transpose_note( struct Notes *note, int trans ){ note->note = getTransposed(note->note, trans); if (note->pitch_end > 0) note->pitch_end = getTransposed(note->pitch_end, trans); struct Pitches *pitch = note->pitches; while(pitch!=NULL){ pitch->note = getTransposed(pitch->note, trans); pitch = NextPitch(pitch); } }
void AddPitchElements( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack ){ float min_pitch = 10000.0f; float max_pitch = -10000.0f; TRACK_get_min_and_max_pitches(wtrack->track,&min_pitch, &max_pitch); struct Notes *note=wtrack->track->notes; while(note!=NULL){ struct Pitches *pitch=note->pitches; int realline = 0; while(pitch!=NULL){ realline=FindRealLineFor(wblock,R_MAX(pitch->Tline,realline),&pitch->l.p); int subrealline=FindSubRealLine(window,wblock,realline,&pitch->l.p); InsertTRLElementS( wtrack, note, realline, TRE_THISPITCHLINES,0, (float)subrealline,(float)subrealline,0.0f,(float)(wtrack->fxwidth-2), pitch ); if (wtrack->trackreallines[realline].note!=0) { wtrack->trackreallines[realline].note=NOTE_MUL; wtrack->trackreallines[realline].dasnote=NULL; } else { wtrack->trackreallines[realline].note=pitch->note; wtrack->trackreallines[realline].daspitch=pitch; } pitch=NextPitch(pitch); } #if !USE_OPENGL UpdateWPitches(window, wblock, wtrack, note, min_pitch, max_pitch); #endif note=NextNote(note); } }
bool TRACK_get_min_and_max_pitches(const struct Tracks *track, float *ret_min_pitch, float *ret_max_pitch){ float min_pitch = 10000.0f; float max_pitch = -10000.0f; int num_pitches = 0; // find min_pitch and max_pitch { struct Notes *note = track->notes; while(note!=NULL){ min_pitch = R_MIN(note->note, min_pitch); max_pitch = R_MAX(note->note, max_pitch); num_pitches ++; struct Pitches *pitch = note->pitches; while(pitch != NULL){ min_pitch = R_MIN(pitch->note, min_pitch); max_pitch = R_MAX(pitch->note, max_pitch); num_pitches ++; pitch = NextPitch(pitch); } note = NextNote(note); } float pitch_range = max_pitch - min_pitch; min_pitch = min_pitch - pitch_range/8.0f; if(min_pitch < 0) min_pitch = 0; max_pitch = max_pitch + pitch_range/8.0f; if(max_pitch >127) max_pitch = 127; } if(min_pitch == 10000.0f) return false; else { if (num_pitches>3) { *ret_min_pitch = min_pitch; *ret_max_pitch = max_pitch; } else { *ret_min_pitch = 0; *ret_max_pitch = 128; } return true; } }
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); }
static void PE_ChangePitch(struct PEventQueue *peq,int doit){ float x; STime ntime,btime; struct Pitches *next; btime=PC_TimeToRelBlockStart(pc->end_time); if(btime>=peq->time2){ next=NextPitch(peq->nextpitch); peq->time1=peq->time2; peq->pitch=peq->nextpitch; if(next==NULL){ peq->time2=Place2STime(peq->block,&peq->note->end); peq->TreatMe=PE_ChangePitchToEnd; PE_ChangePitchToEnd(peq,doit); }else{ peq->nextpitch=next; peq->time2=Place2STime(peq->block,&next->l.p); PE_ChangePitch(peq,doit); } return; } float pitch1,pitch2; if(peq->pitch==peq->nextpitch){ pitch1=peq->note->note; pitch2=peq->pitch->note; }else{ pitch1=peq->pitch->note; pitch2=peq->nextpitch->note; } ntime=PEQ_CalcNextPitchEvent( peq, peq->time1, btime, peq->time2, pitch1, &x, pitch2 ); if(btime==ntime){ Pdebug("Samme, stopper, x: %d\n",x); return; } if(ntime>peq->time2) ntime=peq->time2; // Pdebug("Player vel->vel, Pitch: %d, ntime: %d, btime: %d, time1: %d, time2: %d\n",x,ntime,btime,peq->time1,peq->time2); if(doit){ SendPitchChange(x,peq); } PC_InsertElement(peq,0,ntime); return; }
static void RT_schedule_pitch(struct SeqTrack *seqtrack, int64_t current_time, const struct SeqBlock *seqblock, const struct Tracks *track, const struct Notes *note, const struct Pitches *pitch1, bool first_val_has_been_sent ) { if(note->pitches==NULL && note->pitch_end == 0.0) // In case note is changed while playing return; const struct Pitches *pitch2 = pitch1==NULL ? note->pitches : NextPitch(pitch1); Place p1 = pitch1==NULL ? note->l.p : pitch1->l.p; Place p2 = pitch2==NULL ? note->end : pitch2->l.p; int64_t time1 = get_seqblock_place_time(seqblock, p1); int64_t time2 = get_seqblock_place_time(seqblock, p2); if (pitch2==NULL) time2--; // Can not send out pitch at the same time as note_end, since note_end events has higher priority than pitch events. #if !defined(RELEASE) else R_ASSERT(time2 >= time1); #endif if (time2 < time1) return; int logtype1 = pitch1==NULL ? note->pitch_first_logtype : pitch1->logtype; if (logtype1 == LOGTYPE_HOLD){ if (current_time == time1) { RT_scheduled_hold_pitch_do(seqtrack, current_time, seqblock, track, note, pitch1, !first_val_has_been_sent); } else { const int num_args = 4; union SuperType args[num_args]; args[0].const_pointer = seqblock; args[1].const_pointer = track; args[2].const_pointer = note; args[3].const_pointer = pitch1; SCHEDULER_add_event(seqtrack, time1, RT_scheduled_hold_pitch, &args[0], num_args, SCHEDULER_PITCH_PRIORITY); } } else { //int64_t time = R_MIN(time2, time1 + RADIUM_BLOCKSIZE); bool doit; if (pitch1==NULL) doit = true; else doit = pitch1->chance==0x100 || pitch1->chance > rnd(0x100); union SuperType args[g_num_pitches_args]; args[0].const_pointer = seqblock; args[1].const_pointer = track; args[2].const_pointer = note; args[3].const_pointer = pitch1; args[4].int_num = time1; args[5].int_num = time2; args[6].bool_num = doit; #if DO_DEBUG float val1 = pitch1==NULL ? note->note : pitch1->note; float val2 = pitch2==NULL ? note->pitch_end : pitch2->note; printf(" Scheduling Pitch. %f -> %f, %d -> %d\n", val1, val2, (int)time1, (int)time2); #endif SCHEDULER_add_event(seqtrack, time1, RT_scheduled_glide_pitch, &args[0], g_num_pitches_args, SCHEDULER_PITCH_PRIORITY); } }