void PlayRangeCurrPos(struct Tracker_Windows *window){ struct WBlocks *wblock; Place *place; PlayStopReally(false); wblock=window->wblock; if( ! wblock->isranged) return; root->setfirstpos=false; if(wblock->rangey1==0) root->setfirstpos=true; place=getRangeStartPlace(wblock); pc->seqtime=-Place2STime(wblock->block,place); // printf("playrange, time: %d\n",pc->seqtime); Place *place_start = getRangeStartPlace(wblock); Place *place_end = getRangeEndPlace(wblock); pc->range_duration = Place2STime(wblock->block, place_end) - Place2STime(wblock->block, place_start); pc->is_playing_range = true; PlayBlock(wblock->block,place,true); }
float lineDuration(int line, int tracknum, int blocknum, int windownum){ struct Tracker_Windows *window; struct WBlocks *wblock; struct WTracks *wtrack = getWTrackFromNumA(windownum, &window, blocknum, &wblock, tracknum); if (wtrack==NULL) return 1.0; struct Blocks *block = wblock->block; if (line < 0){ RError("lineDuration: Line must be 0 or larger: %d",line); return 1.0; } if (line >= block->num_lines){ RError("lineDuration: Line must be less than the number of lines: %d >= %d or larger: %d",line, block->num_lines); return 1.0; } Place p1 = {line, 0, 1}; Place p2 = {line+1, 0, 1}; STime s1 = Place2STime(block, &p1); STime s2 = Place2STime(block, &p2); return (double)(s2-s1) / (double)MIXER_get_sample_rate(); }
void InitPEQpitches( const struct Blocks *block, const struct Tracks *track, struct Notes *note, int playlistaddpos ){ if(track->patch==NULL) return; struct Pitches *pitch=note->pitches; if(pitch==NULL && note->pitch_end==0.0) return; struct PEventQueue *peq=GetPEQelement(); peq->block=block; peq->track=track; peq->note=note; peq->pitch=pitch; peq->time1=Place2STime(block,¬e->l.p); if (pitch==NULL) { peq->nextpitch = NULL; peq->time2=Place2STime(block,¬e->end); peq->TreatMe=PE_ChangePitchToEnd; } else { pitch->doit = pitch->chance==0x100 || pitch->chance > rnd(0x100); peq->nextpitch = pitch; peq->time2=Place2STime(block,&pitch->l.p); peq->TreatMe=PE_ChangePitch; } int x; PC_InsertElement( peq,playlistaddpos, PEQ_CalcNextEvent( peq->time1, peq->time1, peq->time2, 1, &x, 20000000, note->pitch_first_logtype ) ); }
void PlaySongCurrPos(struct Tracker_Windows *window){ struct Blocks *block; struct WBlocks *wblock; Place *place; int playpos; bool changeblock=false; wblock=window->wblock; PlayStopReally(false); root->setfirstpos=false; playpos=root->curr_playlist; block=BL_GetBlockFromPos(playpos); if(block==NULL) return; if(wblock->l.num!=block->l.num){ wblock=ListFindElement1(&window->wblocks->l,block->l.num); changeblock=true; root->setfirstpos=true; } if( ! changeblock && playpos==root->song->length-1 && wblock->curr_realline==wblock->num_reallines // ??. Never supposed to happen. ){ return; } if(wblock->curr_realline==0) root->setfirstpos=true; debug("contsong, playpos: %d , root->curr_block: %d\n",playpos,root->curr_block); if(changeblock){ place=PlaceGetFirstPos(); pc->seqtime=0; }else{ place=&wblock->reallines[wblock->curr_realline]->l.p; pc->seqtime=-Place2STime(wblock->block,place); } debug("contsong, time: %d, playpos: %d , root->curr_block: %d\n",pc->seqtime,playpos,root->curr_block); place->line++; debug("nextline: %d\n",Place2STime(wblock->block,place)); place->line--; PlaySong(place,playpos); }
static void InitPEQfxs( const struct Blocks *block, const struct Tracks *track, struct FXs *fxs ){ struct PEventQueue *peq=GetPEQelement(); peq->TreatMe=PE_HandleFirstFX; peq->block=block; peq->track=track; peq->fxs=fxs; peq->fxnodeline=fxs->fxnodelines; peq->nextfxnodeline=NextFXNodeLine(peq->fxnodeline); peq->time1=Place2STime(block,&peq->fxnodeline->l.p); peq->time2=Place2STime(block,&peq->nextfxnodeline->l.p); PC_InsertElement(peq,0,peq->time1); }
void InitPEQpitches( const struct Blocks *block, const struct Tracks *track, const struct Notes *note, int playlistaddpos ){ struct PEventQueue *peq; struct Pitches *pitch=note->pitches; if(track->patch==NULL) return; if(pitch==NULL) return; peq=GetPEQelement(); peq->block=block; peq->track=track; peq->note=note; peq->pitch=pitch; peq->time1=Place2STime(block,¬e->l.p); peq->nextpitch = pitch; peq->time2=Place2STime(block,&pitch->l.p); peq->TreatMe=PE_ChangePitch; int x; PC_InsertElement( peq,playlistaddpos, PEQ_CalcNextEvent( peq->time1, peq->time1, peq->time2, 1, &x, 20000000 ) ); }
void PE_HandleFirstFX(struct PEventQueue *peq,int doit){ int x; STime ntime,btime; struct FXNodeLines *next; // Pdebug("fx, start: %d\n",peq->fxnodeline->val); if(doit){ fxhandle(peq->fxnodeline->val,peq,0,FX_start); } btime=PC_TimeToRelBlockStart(pc->end_time); peq->TreatMe=PE_HandleFX; if(btime>=peq->time2){ next=NextFXNodeLine(peq->nextfxnodeline); if(next==NULL){ // Pdebug("fx, slutt: %d\n",peq->nextfxnodeline->val); if(doit){ fxhandle(peq->nextfxnodeline->val,peq,0,FX_end); } ReturnPEQelement(peq); }else{ peq->fxnodeline=peq->nextfxnodeline; peq->nextfxnodeline=next; peq->time1=peq->time2; peq->time2=Place2STime(peq->block,&next->l.p); PE_HandleFX(peq,doit); } return; } ntime=PEQ_CalcNextEvent( peq->time1, btime, peq->time2, peq->fxnodeline->val, &x, peq->nextfxnodeline->val ); if(ntime>peq->time2) ntime=peq->time2; PC_InsertElement(peq,0,ntime); return; }
/* A debugging function. */ void PrintSTimes(struct Blocks *block){ struct WBlocks *wblock; struct LocalZooms **reallines; const struct STimes *stime; const struct STimeChanges *timechanges; int lasttime=0; int nowtime; int line,realline; for(line=0;line<=block->num_lines;line++){ stime= &block->times[line]; timechanges=stime->timechanges; nowtime=stime->time; printf("%d. %d. Delta: %d, Ch: %p\n",line,nowtime,nowtime-lasttime,timechanges); while(timechanges!=NULL){ printf(" place: %f, time: %" PRId64 ", tempo1: %f, rel: %f, deltarel: %f\n", GetDoubleFromPlace(&timechanges->l.p), timechanges->time, timechanges->tempo1, timechanges->rel, timechanges->deltarel ); timechanges=NextSTimeChange(timechanges); } lasttime=nowtime; } printf("--------reallines:----------\n"); if(root->song->tracker_windows!=NULL){ wblock=root->song->tracker_windows->wblock; if(wblock!=NULL){ reallines=wblock->reallines; if (reallines!=NULL){ lasttime=0; for(realline=0;realline<wblock->num_reallines;realline++){ nowtime=Place2STime(block,&reallines[realline]->l.p); printf("realline: %d, Place: %f, time: %d, delta: %d,\n",realline,GetDoubleFromPlace(&reallines[realline]->l.p),nowtime,nowtime-lasttime); lasttime=nowtime; } } } } }
void PlayBlockCurrPos(struct Tracker_Windows *window){ struct WBlocks *wblock; Place *place; PlayStopReally(false); root->setfirstpos=false; wblock=window->wblock; if(wblock->curr_realline==0) root->setfirstpos=true; place = &wblock->reallines[wblock->curr_realline]->l.p; pc->seqtime = -Place2STime(wblock->block,place); // printf("contblock, time: %d\n",pc->seqtime); PlayBlock(wblock->block,place,true); }
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 create_peaks( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack) { struct Blocks *block = wblock->block; int realline; for(realline=0;realline<wblock->num_reallines;realline++){ struct TrackRealline *trackrealline= &wtrack->trackreallines[realline]; struct TrackReallineElements *element; for(element=trackrealline->trackreallineelements;element!=NULL;element=element->next){ if(element->type==TRE_VELLINE){ if(TRACK_has_peaks(wtrack->track)==true && (element->y2-element->y1)>0.001){ struct Patch *patch = wtrack->track->patch; struct Notes *note=element->pointer; float note_time = Place2STime(block, ¬e->l.p); element->num_peaks = ((element->y2-element->y1)*NUM_PEAKS_PER_LINE)+1; if(element->num_peaks<0){ RError("element->num_peaks<0: %d",element->num_peaks); element->num_peaks=0; } if(element->num_peaks>0){ element->num_peaks++; // We're generating coordinates for a polygon, and it needs to stretch to the start of the next node. float time1 = Place2STime(block, &wblock->reallines[realline]->l.p) - note_time; float time2; if(realline<wblock->num_reallines-1){ time2 = Place2STime(block, &wblock->reallines[realline+1]->l.p); }else{ time2 = block->times[block->num_lines].time; } time2 = time2 - note_time; const int num_channels=PATCH_get_peaks(patch, 0, -1, wtrack->track, 0,0, NULL,NULL); int ch; for(ch=0;ch<num_channels;ch++){ APoint *peaks=talloc_atomic(element->num_peaks*2*sizeof(APoint)); element->peaks[ch] = peaks; int i; for(i=0;i<element->num_peaks;i++){ float y1 = scale(i,0,element->num_peaks-1,element->y1,element->y2); // -1 is here since we generate 2 points for each node. float y2 = scale(i+1,0,element->num_peaks-1,element->y1,element->y2); float track_volume = wtrack->track->volumeonoff ? (float)wtrack->track->volume / MAXTRACKVOL : 1.0f; float velocity = scale(y2,element->y1,element->y2,element->x1,element->x2); float min,max; PATCH_get_peaks(patch, note->note, ch, wtrack->track, scale(y1,0,1,time1,time2) / block->reltempo, scale(y2,0,1,time1,time2) / block->reltempo, &min, &max); float bound_x1 = scale(ch,0,num_channels,0.0f,velocity); float bound_x2 = scale(ch+1,0,num_channels,0.0f,velocity); peaks[i].x = R_MAX(bound_x1, scale(min*track_volume,-1,1, bound_x1, bound_x2)); peaks[i].y = y1; peaks[element->num_peaks*2 - 1 - i].x = R_MIN(bound_x2, scale(max*track_volume,-1,1, bound_x1, bound_x2)); peaks[element->num_peaks*2 - 1 - i].y = y1; //max } } } } element->velocity_polygon=talloc_atomic(2*2*sizeof(APoint)); element->velocity_polygon[0].x = 0.0f; element->velocity_polygon[0].y = element->y1; element->velocity_polygon[1].x = 0.0f; element->velocity_polygon[1].y = element->y2; element->velocity_polygon[2].x = element->x2; element->velocity_polygon[2].y = element->y2; element->velocity_polygon[3].x = element->x1; element->velocity_polygon[3].y = element->y1; } } } }
void P2MUpdateSongPosCallBack(void){ struct Tracker_Windows *window=root->song->tracker_windows; bool setfirstpos=ATOMIC_GET(root->setfirstpos); NInt curr_block=ATOMIC_GET(root->curr_blocknum); struct WBlocks *wblock; int till_curr_realline; if(scrolls_per_second==-1) scrolls_per_second = SETTINGS_read_int("scrolls_per_second", default_scrolls_per_second); if(pc->playtype==PLAYSONG) BS_SelectPlaylistPos(root->curr_playlist); while(window!=NULL){ if(window->playalong==true){ DO_GFX({ wblock=ListFindElement1(&window->wblocks->l,curr_blocknum); till_curr_realline=ATOMIC_GET(wblock->till_curr_realline); if(window->curr_block!=curr_block){ if(setfirstpos){ wblock->curr_realline=0; SetWBlock_Top_And_Bot_Realline(window,wblock); } SelectWBlock( window, wblock ); } if(setfirstpos){ // The player routine (PEQblock.c) sets this one. ATOMIC_SET(wblock->till_curr_realline, 0); till_curr_realline=0; } //fprintf(stderr,"tilline: %d\n",till_curr_realline); #if 0 if(wblock->curr_realline != till_curr_realline) ScrollEditorToRealLine(window,wblock,till_curr_realline); #else { bool do_scrolling = false; if(wblock != last_wblock) do_scrolling = true; else if (last_time > ATOMIC_GET(pc->therealtime)) do_scrolling = true; else if(till_curr_realline < wblock->curr_realline) do_scrolling = true; else if(till_curr_realline > wblock->curr_realline){ STime from_time = (STime) ((double)Place2STime(wblock->block, &wblock->reallines[wblock->curr_realline]->l.p) / wblock->block->reltempo); STime to_time = (STime) ((double)Place2STime(wblock->block, &wblock->reallines[till_curr_realline]->l.p) / wblock->block->reltempo); STime time = to_time - from_time; STime time_necessary_to_scroll = pc->pfreq / scrolls_per_second; if(time>=time_necessary_to_scroll) do_scrolling = true; } if(do_scrolling==true) { ScrollEditorToRealLine(window,wblock,till_curr_realline); last_time = ATOMIC_GET(pc->therealtime); last_wblock = wblock; } } #endif }); }