static double wiimote_timestamp2logicaltime(t_wiimote*x, struct timespec*timestamp) { double pddelay=clock_gettimesince(x->baselogicaltime); /* how long in logical time since we have connected to the wii */ double realdelay=0.; /* how long (in ms) after we connected to the wiimote this timestamp appeared */ double delay=0.; if(NULL==timestamp || NULL==x->basetime) return 0.; /* immediately */ realdelay= (timestamp->tv_sec - x->basetime->tv_sec) * 1000. + (timestamp->tv_nsec - x->basetime->tv_nsec) / 1000000.; delay=realdelay-pddelay; #if 0 print_timestamp(timestamp, x->basetime); post("logical time: %f = %f - %f", clock_gettimesince(x->baselogicaltime), now, x->baselogicaltime); #endif //post("diff = %f = %f - %f", realdelay-pddelay, realdelay, pddelay); if(delay<0) { return 0.; } return realdelay; }
/* main processing function */ static void rhythm_float(t_rhythm *x, t_floatarg f) { t_int velo = x->x_velo; double time = clock_gettimesince(x->x_last_input); x->x_pitch = (t_int)f; if(velo != 0) /* note-on received */ { if (x->x_startTime == 0) { x->x_startTime = time; return; } if (x->x_period < 2.0) { x->x_period = (t_float)(time - x->x_startTime); x->x_phiVel_at_pulse = 1000.0 / x->x_period; } rhythm_move(x, 1, time); if (x->x_lastPulseTime >= 0) { x->x_lastIoi = time - x->x_lastPulseTime; } x->x_lastPulseTime = time; x->x_last_input = clock_getlogicaltime(); outlet_float(x->x_out_period, x->x_period); outlet_float(x->x_out_bpm, 60000.0/x->x_period); } return; }
static void mtrack_tempo(t_mtrack *tp, t_floatarg f) { float newtempo; static int warned = 0; if (fittermax_get() && !warned) { fittermax_warning(mtr_class, "no 'tempo' control in Max"); warned = 1; } if (f < 1e-20) f = 1e-20; else if (f > 1e20) f = 1e20; newtempo = 1. / f; if (tp->tr_prevtime > 0.) { tp->tr_clockdelay -= clock_gettimesince(tp->tr_prevtime); tp->tr_clockdelay *= newtempo / tp->tr_tempo; if (tp->tr_clockdelay < 0.) tp->tr_clockdelay = 0.; clock_delay(tp->tr_clock, tp->tr_clockdelay); tp->tr_prevtime = clock_getlogicaltime(); } tp->tr_tempo = newtempo; }
static void tabwrite_float(t_tabwrite *x, t_float f) { #ifdef ROCKBOX int vecsize; #else int i, vecsize; #endif t_garray *a; t_sample *vec; if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) pd_error(x, "%s: no such array", x->x_arrayname->s_name); else if (!garray_getfloatarray(a, &vecsize, &vec)) pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name); else { int n = x->x_ft1; double timesince = clock_gettimesince(x->x_updtime); if (n < 0) n = 0; else if (n >= vecsize) n = vecsize-1; vec[n] = ftofix(f); if (timesince > 1000) { tabwrite_tick(x); } else { if (x->x_set == 0) { clock_delay(x->x_clock, 1000 - timesince); x->x_set = 1; } } } }
void sys_pollmidioutqueue( void) { #ifdef TEST_DEJITTER static int db = 0; #endif double midirealtime = sys_getmidioutrealtime(); #ifdef TEST_DEJITTER if (midi_outhead == midi_outtail) db = 0; #endif while (midi_outhead != midi_outtail) { #ifdef TEST_DEJITTER if (!db) { post("out: del %f, midiRT %f logicaltime %f, RT %f dacminusRT %f", (midi_outqueue[midi_outtail].q_time - midirealtime), midirealtime, .001 * clock_gettimesince(sys_midiinittime), sys_getrealtime(), sys_dactimeminusrealtime); db = 1; } #endif if (midi_outqueue[midi_outtail].q_time <= midirealtime) sys_putnext(); else break; } }
static void zeroCrossing_tilde_bang(t_zeroCrossing_tilde *x) { int i, j, window, bang_sample; float crossings; t_sample *signal_R; double current_time; window = x->window; signal_R = (t_sample *)getbytes(0); signal_R = (t_sample *)t_resizebytes(signal_R, 0, window * sizeof(t_sample)); current_time = clock_gettimesince(x->last_dsp_time); bang_sample = (int)(((current_time/1000.0)*x->sr)+0.5); // round if (bang_sample < 0) bang_sample = 0; else if ( bang_sample >= x->n ) bang_sample = x->n - 1; // construct analysis window using bang_sample as the end of the window for(i=0, j=bang_sample; i<window; i++, j++) signal_R[i] = x->signal_R[j]; crossings=0; crossings = zeroCrossing_tilde_zero_crossing_rate(window, signal_R); outlet_float(x->x_crossings, crossings); // free local memory t_freebytes(signal_R, window*sizeof(t_sample)); }
// called when a new event occours void add_event(t_rhythms_memory *x, unsigned short int voice) { event *newEvent, *currEvent, *lastEvent; double when; when = clock_gettimesince(x->measure_start_time); newEvent = (event *) malloc(sizeof(event)); newEvent->when = when; newEvent->voice = voice; newEvent->next = 0; currEvent = x->events; if (currEvent) { // this is not the first event while(currEvent) { lastEvent = currEvent; currEvent = currEvent->next; } lastEvent->next = newEvent; } else { // this is the first event x->events = newEvent; } post("event added"); }
/* CHECKED refman's error: ``if the number received in the left inlet specifies a sample index that does not exist in the buffer~ object's currently allocated memory, nothing happens.'' This is plainly wrong, at least for max/msp 4.0.7 bundle: the index is clipped (just like in tabread/tabwrite). As a kind of an experiment, lets make this the refman's way... */ static void peek_float(t_peek *x, t_float f) { t_arsic *sic = (t_arsic *)x; t_word *vp; arsic_validate(sic, 0); /* LATER rethink (efficiency, and complaining) */ if ((vp = sic->s_vectors[x->x_effchannel])) { int ndx = (int)f; if (ndx >= 0 && ndx < sic->s_vecsize) { if (x->x_pokemode) { double timesince; t_float f = x->x_value; vp[ndx].w_float = (x->x_clipmode ? peek_doclip(f) : f); x->x_pokemode = 0; timesince = clock_gettimesince(x->x_clocklasttick); if (timesince > 1000) peek_tick(x); else if (!x->x_clockset) { clock_delay(x->x_clock, 1000 - timesince); x->x_clockset = 1; } } /* CHECKED: output not clipped */ else outlet_float(((t_object *)x)->ob_outlet, vp[ndx].w_float); } } }
static void Borax_delta(t_Borax *x) { /* CHECKME first note */ float dtime = clock_gettimesince(x->x_onset); /* CHECKME */ outlet_float(x->x_dtimeout, dtime); outlet_float(x->x_ndtimesout, ++x->x_ndtimes); /* CHECKME */ }
static void specBrightness_tilde_bang(t_specBrightness_tilde *x) { int i, j, window, window_half, bang_sample, bin_boundary; float dividend, divisor, brightness; t_sample *signal_R, *signal_I; double current_time; window = x->window; window_half = window*0.5; // create local memory signal_R = (t_sample *)getbytes(0); signal_I = (t_sample *)getbytes(0); signal_R = (t_sample *)t_resizebytes(signal_R, 0, window*sizeof(t_sample)); signal_I = (t_sample *)t_resizebytes(signal_I, 0, window_half*sizeof(t_sample)); bin_boundary = specBrightness_tilde_nearest_bin_index(x->freq_boundary, x->bin_freqs); // hard-coded based on 1200, but can use nearest_bin_freq function later current_time = clock_gettimesince(x->last_dsp_time); bang_sample = (int)(((current_time/1000.0)*x->sr)+0.5); // round if (bang_sample < 0) bang_sample = 0; else if ( bang_sample >= x->n ) bang_sample = x->n - 1; // construct analysis window using bang_sample as the end of the window for(i=0, j=bang_sample; i<window; i++, j++) signal_R[i] = x->signal_R[j]; specBrightness_tilde_hann(window, signal_R, x->hann); mayer_realfft(window, signal_R); specBrightness_tilde_realfft_unpack(window, window_half, signal_R, signal_I); specBrightness_tilde_abs(window_half, signal_R, signal_I); // if(x->normalize) // specBrightness_tilde_normal(window_half, signal_R); dividend=0; divisor=0; brightness=0; for(i=bin_boundary; i<window_half; i++) dividend += signal_R[i]; for(i=0; i<window_half; i++) divisor += signal_R[i]; if(divisor==0) divisor=1; brightness = dividend/divisor; outlet_float(x->x_brightness, brightness); // free local memory t_freebytes(signal_R, window * sizeof(t_sample)); t_freebytes(signal_I, window_half * sizeof(t_sample)); }
static void vline_tilde_float(t_vline *x, t_float f) { t_time timenow = clock_gettimesince(x->x_referencetime); t_sample inlet1 = (x->x_inlet1 < 0 ? 0 : (t_sample)x->x_inlet1); t_sample inlet2 = (t_sample) x->x_inlet2; t_time starttime = timenow + inlet2; t_vseg *s1, *s2, *deletefrom = 0, *snew = (t_vseg *)t_getbytes(sizeof(*snew)); if (PD_BADFLOAT(f)) f = 0; /* negative delay input means stop and jump immediately to new value */ if (inlet2 < 0) { vline_tilde_stop(x); x->x_value = ftofix(f); return; } /* check if we supplant the first item in the list. We supplant an item by having an earlier starttime, or an equal starttime unless the equal one was instantaneous and the new one isn't (in which case we'll do a jump-and-slide starting at that time.) */ if (!x->x_list || x->x_list->s_starttime > starttime || (x->x_list->s_starttime == starttime && (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0))) { deletefrom = x->x_list; x->x_list = snew; } else { for (s1 = x->x_list; (s2 = s1->s_next); s1 = s2) { if (s2->s_starttime > starttime || (s2->s_starttime == starttime && (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) { deletefrom = s2; s1->s_next = snew; goto didit; } } s1->s_next = snew; deletefrom = 0; didit: ; } while (deletefrom) { s1 = deletefrom->s_next; t_freebytes(deletefrom, sizeof(*deletefrom)); deletefrom = s1; } snew->s_next = 0; snew->s_target = f; snew->s_starttime = starttime; snew->s_targettime = starttime + inlet1; x->x_inlet1 = x->x_inlet2 = 0; }
static void cepstrum_tilde_bang(t_cepstrum_tilde *x) { int i, j, window, window_half, bang_sample; t_atom *listOut; t_sample *signal_R, *signal_I; double current_time; window = x->window; window_half = window*0.5; signal_R = (t_sample *)getbytes(0); signal_I = (t_sample *)getbytes(0); listOut = (t_atom *)getbytes(0); signal_R = (t_sample *)t_resizebytes(signal_R, 0, window*sizeof(t_sample)); signal_I = (t_sample *)t_resizebytes(signal_I, 0, window_half*sizeof(t_sample)); listOut = (t_atom *)t_resizebytes(listOut, 0, ((int)x->window*0.5)*sizeof(t_atom)); current_time = clock_gettimesince(x->last_dsp_time); bang_sample = (int)(((current_time/1000.0)*x->sr)+0.5); // round if (bang_sample < 0) bang_sample = 0; else if ( bang_sample >= x->n ) bang_sample = x->n - 1; // construct analysis window using bang_sample as the end of the window for(i=0, j=bang_sample; i<window; i++, j++) signal_R[i] = x->signal_R[j]; cepstrum_tilde_hann(window, signal_R, x->hann); mayer_realfft(window, signal_R); cepstrum_tilde_realfft_unpack(window, window_half, signal_R, signal_I); cepstrum_tilde_abs(window_half, signal_R, signal_I); if(x->normalize) cepstrum_tilde_normal(window_half, signal_R); cepstrum_tilde_log(window_half, signal_R); // fill out the negative frequencies for(i=0; i<window_half; i++) signal_I[i] = signal_R[i]; // signal_I[i] = 0.0; // or we could zero them out... cepstrum_tilde_realifft(window, window_half, signal_R, signal_I); for(i=0; i<window_half; i++) SETFLOAT(listOut+i, signal_R[i]); outlet_list(x->x_featureList, 0, window_half, listOut); t_freebytes(signal_R, window * sizeof(t_sample)); t_freebytes(signal_I, window_half * sizeof(t_sample)); t_freebytes(listOut, window_half * sizeof(t_atom)); }
static void specCentroid_tilde_bang(t_specCentroid_tilde *x) { int i, j, window, window_half, bang_sample; float dividend, divisor, centroid; t_sample *signal_R, *signal_I; double current_time; window = x->window; window_half = window*0.5; // create local memory signal_R = (t_sample *)getbytes(0); signal_I = (t_sample *)getbytes(0); signal_R = (t_sample *)t_resizebytes(signal_R, 0, window*sizeof(t_sample)); signal_I = (t_sample *)t_resizebytes(signal_I, 0, window_half*sizeof(t_sample)); current_time = clock_gettimesince(x->last_dsp_time); bang_sample = (int)(((current_time/1000.0)*x->sr)+0.5); // round if (bang_sample < 0) bang_sample = 0; else if ( bang_sample >= x->n ) bang_sample = x->n - 1; // construct analysis window using bang_sample as the end of the window for(i=0, j=bang_sample; i<window; i++, j++) signal_R[i] = x->signal_R[j]; specCentroid_tilde_hann(window, signal_R, x->hann); mayer_realfft(window, signal_R); specCentroid_tilde_realfft_unpack(window, window_half, signal_R, signal_I); specCentroid_tilde_abs(window_half, signal_R, signal_I); // if(x->normalize) // specCentroid_tilde_normal(window_half, signal_R); dividend=0; divisor=0; centroid=0; for(i=0; i<window_half; i++) dividend += signal_R[i]*(i*(x->sr/window)); // weight by bin freq for(i=0; i<window_half; i++) divisor += signal_R[i]; if(divisor==0) divisor = 1; // don't divide by zero centroid = dividend/divisor; outlet_float(x->x_centroid, centroid); // free local memory t_freebytes(signal_R, window * sizeof(t_sample)); t_freebytes(signal_I, window_half * sizeof(t_sample)); }
static void record_tick(t_record *x) { double timesince = clock_gettimesince(x->x_clocklasttick); if (timesince >= RECORD_REDRAWPAUSE) { arsic_redraw((t_arsic *)x); x->x_clocklasttick = clock_getlogicaltime(); } else clock_delay(x->x_clock, RECORD_REDRAWPAUSE - timesince); }
static void velocity_bang(t_velocity *x) { double thistime; t_float vel; thistime = clock_getlogicaltime(); vel = (1000 * (x->x_xn - x->x_xn1) ) / (clock_gettimesince(x->x_lasttime)); x->x_lasttime = thistime; outlet_float(x->x_out, vel); }
static t_int *vline_tilde_perform(t_int *w) { t_vline *x = (t_vline *)(w[1]); t_sample *out = (t_sample *)(w[2]); int n = (int)(w[3]), i; t_sample f = x->x_value; t_sample inc = x->x_inc; t_time msecpersamp = x->x_msecpersamp; #ifndef ROCKBOX t_time samppermsec = x->x_samppermsec; #endif t_time timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp; t_vseg *s = x->x_list; for (i = 0; i < n; i++) { t_time timenext = timenow + msecpersamp; checknext: if (s) { /* has starttime elapsed? If so update value and increment */ if (s->s_starttime < timenext) { if (x->x_targettime <= timenext) f = x->x_target, inc = 0; /* if zero-length segment bash output value */ if (s->s_targettime <= s->s_starttime) { f = s->s_target; inc = 0; } else { t_time incpermsec = idiv((s->s_target - f), (s->s_targettime - s->s_starttime)); f = mult(f + incpermsec,(timenext - s->s_starttime)); inc = mult(incpermsec,msecpersamp); } x->x_inc = inc; x->x_target = s->s_target; x->x_targettime = s->s_targettime; x->x_list = s->s_next; t_freebytes(s, sizeof(*s)); s = x->x_list; goto checknext; } } if (x->x_targettime <= timenext) f = x->x_target, inc = 0; *out++ = f; f = f + inc; timenow = timenext; } x->x_value = f; return (w+4); }
/* this is called from the OS dependent code from time to time when we think we know the delay (outbuftime) in seconds, at which the last-output audio sample will go out the door. */ void sys_setmiditimediff(double inbuftime, double outbuftime) { double dactimeminusrealtime = .001 * clock_gettimesince(sys_midiinittime) - outbuftime - sys_getrealtime(); double adctimeminusrealtime = .001 * clock_gettimesince(sys_midiinittime) + inbuftime - sys_getrealtime(); if (dactimeminusrealtime > sys_newdactimeminusrealtime) sys_newdactimeminusrealtime = dactimeminusrealtime; if (adctimeminusrealtime > sys_newadctimeminusrealtime) sys_newadctimeminusrealtime = adctimeminusrealtime; if (sys_getrealtime() > sys_whenupdate) { sys_dactimeminusrealtime = sys_newdactimeminusrealtime; sys_adctimeminusrealtime = sys_newadctimeminusrealtime; sys_newdactimeminusrealtime = -1e20; sys_newadctimeminusrealtime = -1e20; sys_whenupdate = sys_getrealtime() + 1; } }
static void mtrack_doadd(t_mtrack *tp, int ac, t_atom *av) { if (tp->tr_prevtime > 0.) { t_binbuf *bb = tp->tr_binbuf; t_atom at; float elapsed = clock_gettimesince(tp->tr_prevtime); SETFLOAT(&at, elapsed); binbuf_add(bb, 1, &at); binbuf_add(bb, ac, av); SETSEMI(&at); binbuf_add(bb, 1, &at); tp->tr_prevtime = clock_getlogicaltime(); } }
static void vsnapshot_tilde_bang(t_vsnapshot *x) { t_sample val; if (x->x_gotone) { int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec; if (indx < 0) indx = 0; else if (indx >= x->x_n) indx = x->x_n - 1; val = x->x_vec[indx]; } else val = 0; outlet_float(x->x_obj.ob_outlet, val); }
void sys_poll_midi(void) { static EVENT msw_nextevent; static int msw_isnextevent; static double msw_nexteventtime; while (1) { if (!msw_isnextevent) { if (!GetEvent(lpInputBuffer, &msw_nextevent)) break; msw_isnextevent = 1; #ifdef MIDI_TIMESTAMP msw_nexteventtime = msw_midigettimefor(&foo.timestamp); #endif } #ifdef MIDI_TIMESTAMP if (0.001 * clock_gettimesince(initsystime) >= msw_nexteventtime) #endif { int msgtype = ((msw_nextevent.data & 0xf0) >> 4) - 8; int commandbyte = msw_nextevent.data & 0xff; int byte1 = (msw_nextevent.data >> 8) & 0xff; int byte2 = (msw_nextevent.data >> 16) & 0xff; int portno = msw_nextevent.dwDevice; switch (msgtype) { case 0: case 1: case 2: case 3: case 6: sys_midibytein(portno, commandbyte); sys_midibytein(portno, byte1); sys_midibytein(portno, byte2); break; case 4: case 5: sys_midibytein(portno, commandbyte); sys_midibytein(portno, byte1); break; case 7: sys_midibytein(portno, commandbyte); break; } msw_isnextevent = 0; } }
static void nt_midisync(void) { double jittersec, diff; if (initsystime == -1) nt_resetmidisync(); jittersec = (nt_dacjitterbufsallowed > nt_adcjitterbufsallowed ? nt_dacjitterbufsallowed : nt_adcjitterbufsallowed) * nt_realdacblksize / sys_getsr(); diff = sys_getrealtime() - 0.001 * clock_gettimesince(initsystime); if (diff > nt_hibuftime) nt_hibuftime = diff; if (diff < nt_hibuftime - jittersec) { post("jitter excess %d %f", dac, diff); nt_resetmidisync(); } }
static void qlist_tempo(t_qlist *x, t_float f) { t_float newtempo; if (f < 1e-20) f = 1e-20; else if (f > 1e20) f = 1e20; newtempo = 1./f; if (x->x_whenclockset != 0) { t_float elapsed = clock_gettimesince(x->x_whenclockset); t_float left = x->x_clockdelay - elapsed; if (left < 0) left = 0; left *= newtempo / x->x_tempo; clock_delay(x->x_clock, left); } x->x_tempo = newtempo; }
static void msw_midisync(void) { double jittersec, diff; if (initsystime == -1) msw_resetmidisync(); jittersec = (msw_dacjitterbufsallowed > msw_adcjitterbufsallowed ? msw_dacjitterbufsallowed : msw_adcjitterbufsallowed) * REALDACBLKSIZE / sys_getsr(); diff = sys_getrealtime() - 0.001 * clock_gettimesince(initsystime); if (diff > msw_hibuftime) msw_hibuftime = diff; if (diff < msw_hibuftime - jittersec) { post("jitter excess %d %f", dac, diff); msw_resetmidisync(); } }
void xeq_stop(t_xeq *x) { x->x_autoit.i_restarted = 1; /* LATER rethink */ if (x->x_clock) clock_unset(x->x_clock); if (x->x_whenclockset != 0) { float elapsed = clock_gettimesince(x->x_whenclockset); float left = x->x_clockdelay - elapsed; if (left < 0) left = 0; x->x_autoit.i_playloc.l_delay = left / x->x_tempo; #if 0 post("stop: delay set to %f (user %f)", x->x_autoit.i_playloc.l_delay, left); #endif x->x_whenclockset = 0; } }
static void line_tick(t_line *x) { double timenow = clock_getsystime(); double msectogo = - clock_gettimesince(x->x_targettime); if (msectogo < 1E-9) { outlet_float(x->x_obj.ob_outlet, x->x_targetval); } else { outlet_float(x->x_obj.ob_outlet, x->x_setval + x->x_1overtimediff * (timenow - x->x_prevtime) * (x->x_targetval - x->x_setval)); clock_delay(x->x_clock, (x->x_grain > msectogo ? msectogo : x->x_grain)); } }
void xeq_tempo(t_xeq *x, t_floatarg f) { float newtempo; if (f == 0) f = 1; /* tempo message without argument (FIXME) */ else if (f < 1e-20) f = 1e-20; else if (f > 1e20) f = 1e20; newtempo = 1./f; if (x->x_whenclockset != 0) { float elapsed = clock_gettimesince(x->x_whenclockset); float left = x->x_clockdelay - elapsed; if (left < 0) left = 0; else left *= newtempo / x->x_tempo; clock_delay(x->x_clock, x->x_clockdelay = left); x->x_whenclockset = clock_getsystime(); } x->x_tempo = newtempo; }
static void wiimote_dequeue(void*nada) { /* get all the messages from the queue that are scheduled until now */ const int dyndelay=0; /* set this to 1 use dynamic delays for compensation of asynchronicity */ t_wiimoteMsgList*wl=g_wiimoteMsgList; t_wiimoteMsgList*next=NULL; double now=0; double nexttime=0.; if(NULL==wl) { /* no messages to dequeue; this should never happen */ } while(wl) { if(dyndelay) { now=clock_gettimesince(wl->x->baselogicaltime); if(now+1.<wl->timestamp) { /* no more messages to do for now, aborting */ break; } } next=wl->next; wiimote_cwiid_message(wl->x, wl->mesg); wl->x=NULL; wl->timestamp=0.; freebytes(wl->mesg, sizeof( union cwiid_mesg)); wl->mesg=NULL; wl->next=NULL; freebytes(wl, sizeof(t_wiimoteMsgList)); wl=next; } g_wiimoteMsgList=wl; /* reschedule clock */ if(dyndelay) { if(wl) { double delay=wl->timestamp - now; if(delay<1.)delay=1.; clock_delay(g_clock, delay); } } }
static void sys_queuemidimess(int portno, int onebyte, int a, int b, int c) { t_midiqelem *midiqelem; int newhead = midi_outhead +1; if (newhead == MIDIQSIZE) newhead = 0; /* if FIFO is full flush an element to make room */ if (newhead == midi_outtail) sys_putnext(); midi_outqueue[midi_outhead].q_portno = portno; midi_outqueue[midi_outhead].q_onebyte = onebyte; midi_outqueue[midi_outhead].q_byte1 = a; midi_outqueue[midi_outhead].q_byte2 = b; midi_outqueue[midi_outhead].q_byte3 = c; midi_outqueue[midi_outhead].q_time = .001 * clock_gettimesince(sys_midiinittime); midi_outhead = newhead; sys_pollmidioutqueue(); }
/* CHECKED: no float-to-signal conversion. 'Float' message is ignored when dsp is on -- whether a signal is connected to the left inlet, or not (if not, current index is set to zero). Incompatible (revisit LATER) */ static void poke_float(t_poke *x, t_float f) { t_arsic *sic = (t_arsic *)x; t_float *vp; arsic_validate(sic, 0); /* LATER rethink (efficiency, and complaining) */ if (vp = sic->s_vectors[x->x_effchannel]) { int ndx = (int)*x->x_indexptr; if (ndx >= 0 && ndx < sic->s_vecsize) { double timesince; vp[ndx] = f; timesince = clock_gettimesince(x->x_clocklasttick); if (timesince > 1000) poke_tick(x); else if (!x->x_clockset) { clock_delay(x->x_clock, 1000 - timesince); x->x_clockset = 1; } } } }
/*! \param tm absolute time (in seconds) \param data user data \param dopast if set events with times lying in the past will be triggered immediately, if not set they are ignored \return true on success */ bool flext::Timer::At(double tm,void *data,bool dopast) { userdata = data; period = 0; #if FLEXT_SYS == FLEXT_SYS_PD const double systm = clock_gettimesince(0); double df = tm*1000.-systm; if(dopast && df < 0) df = 0; if(df >= 0) clock_delay(clk,df); #elif FLEXT_SYS == FLEXT_SYS_MAX const double ms = tm*1000.; double cur; clock_getftime(&cur); if(cur <= ms) clock_fdelay(clk,ms-cur); else if(dopast) // trigger timer is past clock_fdelay(clk,0); #else #error Not implemented #endif return true; }