Ejemplo n.º 1
0
int prTempoClock_SetTempoAtBeat(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
	if (!clock) {
		error("clock is not running.\n");
		return errFailed;
	}

	double tempo, beat;
	int err = slotDoubleVal(b, &tempo);
	if (err) return errFailed;
	if (tempo <= 0.) {
		error("invalid tempo %g\n", tempo);
		return errFailed;
	}

	err = slotDoubleVal(c, &beat);
	if (err) return errFailed;

	clock->SetTempoAtBeat(tempo, beat);

	return errNone;
}
Ejemplo n.º 2
0
int prTempoClock_Sched(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;
	double delta, beats;
	int err;

	TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
	if (!clock) {
		error("clock is not running.\n");
		return errFailed;
	}

	if (!SlotEq(&g->thread->clock, a)) {
		beats = clock->ElapsedBeats();
		//post("shouldn't call TempoClock-sched from a different clock. Use schedAbs.\n");
		//return errFailed;
	} else {
		err = slotDoubleVal(&g->thread->beats, &beats);
		if (err) return errNone; // return nil OK, just don't schedule
	}

	err = slotDoubleVal(b, &delta);
	if (err) return errNone; // return nil OK, just don't schedule
	beats += delta;
	if (beats == dInfinity)
		return errNone; // return nil OK, just don't schedule

	clock->Add(beats, c);

	return errNone;
}
Ejemplo n.º 3
0
int mathFoldInt(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b, *c;
	int err;

	a = g->sp - 2;
	b = g->sp - 1;
	c = g->sp;

	if (IsSym(b)) {
		*a = *b;
	} else if (IsSym(c)) {
		*a = *c;
	} else if (IsInt(b) && IsInt(c)) {
		SetRaw(a, sc_fold(slotRawInt(a), slotRawInt(b), slotRawInt(c)));
	} else {
		double x, lo, hi;
		x = slotRawInt(a);
		err = slotDoubleVal(b, &lo);
		if (err) return err;
		err = slotDoubleVal(c, &hi);
		if (err) return err;
		SetFloat(a, sc_fold(x, lo, hi));
	}
	return errNone;
}
Ejemplo n.º 4
0
int prTempoClock_New(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 3;
	PyrSlot *b = g->sp - 2;
	PyrSlot *c = g->sp - 1;
	PyrSlot *d = g->sp;

	double tempo;
	int err = slotDoubleVal(b, &tempo);
	if (err) tempo = 1.;
	if (tempo <= 0.) {
		error("invalid tempo %g\n", tempo);
		SetPtr(slotRawObject(a)->slots+1, NULL);
		return errFailed;
	}

	double beats;
	err = slotDoubleVal(c, &beats);
	if (err) beats = 0.;

	double seconds;
	err = slotDoubleVal(d, &seconds);
	if (err) seconds = elapsedTime();

	TempoClock* clock = new TempoClock(g, slotRawObject(a), tempo, beats, seconds);
	SetPtr(slotRawObject(a)->slots+1, clock);
	return errNone;
}
Ejemplo n.º 5
0
int prTempoClock_SetAll(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 3;
	PyrSlot *b = g->sp - 2;
	PyrSlot *c = g->sp - 1;
	PyrSlot *d = g->sp;

	TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
	if (!clock) {
		error("clock is not running.\n");
		return errFailed;
	}

	double tempo, beat, secs;
	int err = slotDoubleVal(b, &tempo);
	if (err) return errFailed;

	err = slotDoubleVal(c, &beat);
	if (err) return errFailed;

	err = slotDoubleVal(d, &secs);
	if (err) return errFailed;

	clock->SetAll(tempo, beat, secs);

	return errNone;
}
Ejemplo n.º 6
0
int mathWrapInt(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b, *c;
	int err;

	a = g->sp - 2;
	b = g->sp - 1;
	c = g->sp;

	if (IsSym(b)) {
		*a = *b;
	} else if (IsSym(c)) {
		*a = *c;
	} else if (IsInt(b) && IsInt(c)) {
		SetRaw(a, sc_mod((int)(slotRawInt(a) - slotRawInt(b)), (int)(slotRawInt(c) - slotRawInt(b) + 1)) + slotRawInt(b));
	} else {
		double x, lo, hi;
		x = slotRawInt(a);
		err = slotDoubleVal(b, &lo);
		if (err) return err;
		err = slotDoubleVal(c, &hi);
		if (err) return err;
		SetFloat(a, sc_mod(x - lo, hi - lo) + lo);
	}
	return errNone;
}
Ejemplo n.º 7
0
int prSignalAddHarmonic(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b, *c, *d;
	int err;
	float harmonic, amp;
	double phase, step;
	PyrObject *signal;
	float *out;

	a = g->sp - 3;
	b = g->sp - 2;
	c = g->sp - 1;
	d = g->sp;

	err = slotFloatVal(b, &harmonic);
	if (err) return errWrongType;
	err = slotFloatVal(c, &amp);
	if (err) return errWrongType;
	err = slotDoubleVal(d, &phase);
	if (err) return errWrongType;

	signal = slotRawObject(a);
	out = (float*)(signal->slots) - 1;
	step = twopi * harmonic / signal->size;
	UNROLL_CODE(signal->size, out, *++out += sin(phase) * amp; phase += step; );
Ejemplo n.º 8
0
int makeSynthBundle(big_scpacket *packet, PyrSlot *slots, int size, bool useElapsed)
{
	double time;
	int err;
	int64 oscTime;

	err = slotDoubleVal(slots, &time);
	if (!err) {
		if (useElapsed) {
			oscTime = ElapsedTimeToOSC(time);
		} else {
			oscTime = (int64)(time * kSecondsToOSC);
		}
	} else {
		oscTime = 1;	// immediate
	}
	packet->OpenBundle(oscTime);

	for (int i=1; i<size; ++i) {
		if (isKindOfSlot(slots+i, class_array)) {
			PyrObject *obj = slots[i].uo;
			makeSynthMsgWithTags(packet, obj->slots, obj->size);
		}
	}
	packet->CloseBundle();
	return errNone;
}
Ejemplo n.º 9
0
bool SC_LanguageClient::tickLocked( double * nextTime )
{
	if (isLibraryCompiled()) {
		::runLibrary(s_tick);
	}

	return slotDoubleVal( &gMainVMGlobals->result, nextTime ) == errNone;
}
Ejemplo n.º 10
0
int prSystemClock_Sched(struct VMGlobals *g, int numArgsPushed)
{
	//PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	double delta, seconds;
	int err = slotDoubleVal(b, &delta);
	if (err) return errNone; // return nil OK, just don't schedule
	err = slotDoubleVal(&g->thread->seconds, &seconds);
	if (err) return errNone; // return nil OK, just don't schedule
	seconds += delta;
	if (seconds == dInfinity) return errNone; // return nil OK, just don't schedule
	PyrObject* inQueue = slotRawObject(&g->process->sysSchedulerQueue);

	schedAdd(g, inQueue, seconds, c);

	return errNone;
}
Ejemplo n.º 11
0
int prPriorityQueuePostpone(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 1;	// priority queue
	PyrSlot *b = g->sp;		// time

	double time;
	int err = slotDoubleVal(b, &time);
	if (err) return err;

	PyrObject *queueobj = slotRawObject(a);
	PriorityQueuePostpone(queueobj, time);
	return errNone;
}
Ejemplo n.º 12
0
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, key, dur, stretch, delta;
	double fdur, fstretch;
	int err;

	a = g->sp;  // dict

	SetSymbol(&key, s_delta);
	identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta);

	if (NotNil(&delta)) {
		slotCopy(a,&delta);
	} else {
		SetSymbol(&key, s_dur);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur);

		err = slotDoubleVal(&dur, &fdur);
		if (err) {
			if (NotNil(&dur)) return err;
			SetNil(a);
			return errNone;
		}

		SetSymbol(&key, s_stretch);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch);

		err = slotDoubleVal(&stretch, &fstretch);
		if (err) {
			if (NotNil(&stretch)) return err;
			SetFloat(a, fdur);
			return errNone;
		}

		SetFloat(a, fdur * fstretch );
	}

	return errNone;
}
Ejemplo n.º 13
0
int prTempoClock_Beats(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp;
	double beats, seconds;

	if (SlotEq(&g->thread->clock, a)) {
		int err = slotDoubleVal(&g->thread->beats, &beats);
		if (err) return errWrongType;
	} else {
		TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
		if (!clock) {
			error("clock is not running.\n");
			return errFailed;
		}

		int err = slotDoubleVal(&g->thread->seconds, &seconds);
		if (err) return errWrongType;

		beats = clock->SecsToBeats(seconds);
	}
	SetFloat(a, beats);
	return errNone;
}
Ejemplo n.º 14
0
int prPriorityQueueAdd(struct VMGlobals *g, int numArgsPushed)
{

	PyrSlot *a = g->sp - 2;	// priority queue
	PyrSlot *b = g->sp - 1;	// time
	PyrSlot *c = g->sp;		// item

	double time;
	int err = slotDoubleVal(b, &time);
	if (err) return errNone;	// nil is OK, nothing gets added

	PriorityQueueAdd(g, slotRawObject(a), c, time);
	return errNone;
}
Ejemplo n.º 15
0
int mathWrapFloat(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b, *c;
	double lo, hi;
	int err;

	a = g->sp - 2;
	b = g->sp - 1;
	c = g->sp;

	if (IsSym(b)) {
		*a = *b;
	} else if (IsSym(c)) {
		*a = *c;
	} else {
		err = slotDoubleVal(b, &lo);
		if (err) return err;
		err = slotDoubleVal(c, &hi);
		if (err) return err;
		SetRaw(a, sc_mod(slotRawFloat(a) - lo, hi - lo) + lo);
	}
	return errNone;
}
Ejemplo n.º 16
0
int prSetSpeechVolume(struct VMGlobals *g, int numArgsPushed) {

	OSErr theErr = noErr;
	//PyrSlot *a = g->sp-2;
	PyrSlot *b = g->sp-1;
	PyrSlot *c = g->sp;
	double val;
	int chan;
	slotIntVal(b, &chan);
	slotDoubleVal(c, &val);
	Fixed newVal = (Fixed)(val * 65536.0);
//	if(!fCurSpeechChannel) theErr = NewSpeechChannel( NULL, &fCurSpeechChannel );
    theErr = SetSpeechInfo (fCurSpeechChannel[chan], soVolume, &newVal);
	return errNone;
}
Ejemplo n.º 17
0
int prSystemClock_SchedAbs(struct VMGlobals *g, int numArgsPushed)
{
	//PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	double time;
	int err = slotDoubleVal(b, &time) || (time == dInfinity);
	if (err) return errNone; // return nil OK, just don't schedule
	PyrObject* inQueue = slotRawObject(&g->process->sysSchedulerQueue);

	schedAdd(g, inQueue, time, c);

	return errNone;
}
Ejemplo n.º 18
0
int prHIDRunEventLoop(VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 1; //class
	PyrSlot *b = g->sp; //num
	double eventtime;
	int err = slotDoubleVal(b, &eventtime);
	if (err) return err;
	if(gTimer)
	{
        RemoveEventLoopTimer(gTimer);
		gTimer = NULL;
	}
	InstallEventLoopTimer (GetCurrentEventLoop(), 0, (EventTimerInterval) eventtime, GetTimerUPP (), 0, &gTimer);
	//HIDSetQueueCallback(pCurrentHIDDevice, callback);
	return errNone;
}
Ejemplo n.º 19
0
int prNetAddr_SendBundle(VMGlobals *g, int numArgsPushed)
{
	PyrSlot* netAddrSlot = g->sp - numArgsPushed + 1;
	PyrSlot* args = netAddrSlot + 1;
	big_scpacket packet;

	double time;
	int err = slotDoubleVal(args, &time);
	if (!err) {
		time += g->thread->seconds.uf;
		SetFloat(args, time);
	}
	int numargs = numArgsPushed - 1;
	makeSynthBundle(&packet, args, numargs, true);

	//for (int i=0; i<packet.size()/4; i++) post("%d %08X\n", i, packet.buf[i]);

	return netAddrSend(netAddrSlot->uo, packet.size(), (char*)packet.buf);
}
Ejemplo n.º 20
0
int prTempoClock_SecsToBeats(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 1;
	PyrSlot *b = g->sp;

	TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
	if (!clock) {
		error("clock is not running.\n");
		return errFailed;
	}

	double secs;
	int err = slotDoubleVal(b, &secs);
	if (err) return errFailed;

	SetFloat(a, clock->SecsToBeats(secs));

	return errNone;
}
Ejemplo n.º 21
0
int prTempoClock_SchedAbs(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	TempoClock *clock = (TempoClock*)slotRawPtr(&slotRawObject(a)->slots[1]);
	if (!clock) {
		error("clock is not running.\n");
		return errFailed;
	}

	double beats;
	int err = slotDoubleVal(b, &beats) || (beats == dInfinity);
	if (err) return errNone; // return nil OK, just don't schedule

	clock->Add(beats, c);

	return errNone;
}
Ejemplo n.º 22
0
int prFilePutDoubleLE(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b;
	PyrFile *pfile;
	FILE *file;

	a = g->sp - 1;
	b = g->sp;

	pfile = (PyrFile*)slotRawObject(a);
	file = (FILE*)slotRawPtr(&pfile->fileptr);
	if (file == NULL) return errFailed;


	double val;
	int err = slotDoubleVal(b, &val);
	if (err) return err;

	SC_IOStream<FILE*> scio(file);
	scio.writeDouble_le(val);

	return errNone;
}
Ejemplo n.º 23
0
int prAsFraction(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	double mediant_num, lower_num, upper_num, temp_num;
	double mediant_den, lower_den, upper_den, temp_den;
	double x, d;
	int k, k1;
	int maxDenominator;
	int err;
	bool neg = false;

	err = slotDoubleVal(a, &x);
	if (err) return err;

	err = slotIntVal(b, &maxDenominator);
	if (err) return err;

	bool faster = IsTrue(c);

	PyrObject *obj = newPyrArray(g->gc, 2, 0, true);
	obj->size = 2;
	PyrSlot *slots = obj->slots;
	SetObject(a, obj);

	if (x < 0.0) {
		x = -x;
		neg = true;
	}

	if (x < 1.0) {
		upper_num = 1.0;
		upper_den = floor(1./x);
		lower_num = 1.0;
		lower_den = upper_den + 1.;
	} else {
		lower_num = floor(x);
		lower_den = 1.0;
		upper_num = lower_num + 1.;
		upper_den = 1.0;
	}

	while (true) {
		mediant_num = lower_num + upper_num;
		mediant_den = lower_den + upper_den;
		//post("  md %g %g    %g %g    %g %g\n", mediant_num, mediant_den, lower_num, lower_den, upper_num, upper_den);

		if (x * mediant_den > mediant_num) {
			d = upper_num - (x * upper_den);
			if (maxDenominator < mediant_den || fabs(d) < 1e-5) {
				if (neg) upper_num = -upper_num;
				SetInt(slots+0, (int)upper_num);
				SetInt(slots+1, (int)upper_den);
				return errNone;
			}
			lower_num = mediant_num;
			lower_den = mediant_den;
			if (faster) {
				k = (int)floor(((x * lower_den) - lower_num) / d);
				if (k < 10000) {
					k1 = k + 1;
					temp_num = lower_num + (k1 * upper_num);
					temp_den = lower_den + (k1 * upper_den);
					lower_num = lower_num + (k * upper_num);
					lower_den = lower_den + (k * upper_den);
					upper_num = temp_num;
					upper_den = temp_den;
				}
			}
		} else if (x * mediant_den == mediant_num) {
			if (maxDenominator >= mediant_den) {
				if (neg) mediant_num = -mediant_num;
				SetInt(slots+0, (int)mediant_num);
				SetInt(slots+1, (int)mediant_den);
				return errNone;
			} else if (lower_den < upper_den) {
				if (neg) lower_num = -lower_num;
				SetInt(slots+0, (int)lower_num);
				SetInt(slots+1, (int)lower_den);
				return errNone;
			} else {
				if (neg) upper_num = -upper_num;
				SetInt(slots+0, (int)upper_num);
				SetInt(slots+1, (int)upper_den);
				return errNone;
			}
		} else {
			d = lower_num - (x * lower_den);
			if (maxDenominator < mediant_den || fabs(d) < 1e-5) {
				if (neg) lower_num = -lower_num;
				SetInt(slots+0, (int)lower_num);
				SetInt(slots+1, (int)lower_den);
				return errNone;
			}
			upper_num = mediant_num;
			upper_den = mediant_den;
			if (faster) {
				k = (int)floor(((x * upper_den) - upper_num) / d);
				if (k < 10000) {
					k1 = k + 1;
					temp_num = (k1 * lower_num) + upper_num;
					temp_den = (k1 * lower_den) + upper_den;
					upper_num = (k * lower_num) + upper_num;
					upper_den = (k * lower_den) + upper_den;
					lower_num = temp_num;
					lower_den = temp_den;
				}
			}
		}
	}
}
Ejemplo n.º 24
0
int prSimpleNumberSeries(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	int err, size;

	if (IsInt(a) && (IsInt(b) || IsNil(b)) && IsInt(c)) {
		int first, second, last, step;
		first = slotRawInt(a);
		last = slotRawInt(c);
		second = IsInt(b) ? slotRawInt(b) : (first < last ? first + 1 : first - 1);
		step = second - first;

		if ( step == 0 )
			size = 1;
		else
			size = ((last - first) / step) + 1;
		if(size<1 || size > INT_MAX_BY_PyrSlot){
			post("prSimpleNumberSeries: array size %i exceeds limit (%i)\n", size, INT_MAX_BY_PyrSlot);
			return errFailed;
		}

		PyrObject *obj = newPyrArray(g->gc, size, 0, true);
		obj->size = size;
		PyrSlot *slots = obj->slots;
		if(step==1){
			// Faster iteration for common case
			if(first==0){
				for (int i=0; i<size; ++i) {
					SetInt(slots+i, i);
				}
			}else{
				for (int i=0; i<size; ++i) {
					SetInt(slots+i, first++);
				}
			}
		}else{
			int val = first;
			for (int i=0; i<size; ++i) {
				SetInt(slots+i, val);
				val += step;
			}
		}
		SetObject(a, obj);
	} else {
		double first, second, last, step;
		err = slotDoubleVal(a, &first);
		if (err) return err;
		err = slotDoubleVal(c, &last);
		if (err) return err;
		err = slotDoubleVal(b, &second);
		if (err) {
			if (first < last) second = first + 1.;
			else second = first - 1.;
		}

		step = second - first;
		size = (int)floor((last - first) / step + 0.001) + 1;
		if(size<1 || size > INT_MAX_BY_PyrSlot){
			post("prSimpleNumberSeries: array size %i exceeds limit (%i)\n", size, INT_MAX_BY_PyrSlot);
			return errFailed;
		}
		PyrObject *obj = newPyrArray(g->gc, size, 0, true);
		obj->size = size;
		PyrSlot *slots = obj->slots;
		if(first==0. && step==1.){
			// Faster iteration for common case
			for (long i=0; i<size; ++i) {
				SetFloat(slots+i, i);
			}
		}else{
			double val = first;
			for (long i=0; i<size; ++i) {
				val = first + step * i;
				SetFloat(slots+i, val);
			}
		}
		SetObject(a, obj);
	}
	return errNone;

}
Ejemplo n.º 25
0
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, key, dur, stretch, delta;
	double fdur, fstretch;
	int err;
	PyrClass *restClass = getsym("Rest")->u.classobj;
	PyrSlot *slot;

	a = g->sp;  // dict

	SetSymbol(&key, s_delta);
	identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta);

	if (NotNil(&delta)) {
		if (isKindOfSlot(&delta, restClass)) {
			slot = slotRawObject(&delta)->slots;
			err = slotDoubleVal(slot, &fdur);
		} else {
			err = slotDoubleVal(&delta, &fdur);
		}
		if (err) {
			return err;
		} else {
			SetFloat(a, fdur);
			return errNone;
		}
	} else {
		SetSymbol(&key, s_dur);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur);
		err = slotDoubleVal(&dur, &fdur);
		if (err) {
			if (IsNil(&dur)) {
				SetNil(g->sp);
				return errNone;
			} else if (isKindOfSlot(&dur, restClass)) {
				slot = slotRawObject(&dur)->slots;
				err = slotDoubleVal(slot, &fdur);
				if (err)
					return err;
			} else {
				return errWrongType;
			}
		}
		SetSymbol(&key, s_stretch);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch);

		err = slotDoubleVal(&stretch, &fstretch);
		if (err) {
			if (NotNil(&stretch)) {
				if (isKindOfSlot(&stretch, restClass)) {
					slot = slotRawObject(&stretch)->slots;
					err = slotDoubleVal(slot, &fstretch);
					if (err) return err;
				} else {
					return errWrongType;
				}
			} else {
				SetFloat(a, fdur);
				return errNone;
			}
		}

		SetFloat(a, fdur * fstretch);
	}

	return errNone;
}
Ejemplo n.º 26
0
 static double safeRead( PyrSlot *slot )
 {
   double val;
   if (slotDoubleVal(slot, &val)) return 0.0;
   return val;
 }
Ejemplo n.º 27
0
void* schedRunFunc(void* arg)
{
	pthread_mutex_lock (&gLangMutex);


	VMGlobals *g = gMainVMGlobals;
	PyrObject* inQueue = slotRawObject(&g->process->sysSchedulerQueue);
	//dumpObject(inQueue);

	gRunSched = true;
	while (true) {
		assert(inQueue->size);

		//postfl("wait until there is something in scheduler\n");
		// wait until there is something in scheduler
		while (inQueue->size == 1) {
			//postfl("wait until there is something in scheduler\n");
			pthread_cond_wait (&gSchedCond, &gLangMutex);
			if (!gRunSched) goto leave;
		}
		//postfl("wait until an event is ready\n");

		// wait until an event is ready
		double elapsed;
		do {
			elapsed = elapsedTime();
			if (elapsed >= slotRawFloat(inQueue->slots + 1)) break;
			struct timespec abstime;
			//doubleToTimespec(inQueue->slots->uf, &abstime);
			ElapsedTimeToTimespec(slotRawFloat(inQueue->slots + 1), &abstime);
			//postfl("wait until an event is ready\n");
			pthread_cond_timedwait (&gSchedCond, &gLangMutex, &abstime);
			if (!gRunSched) goto leave;
			//postfl("time diff %g\n", elapsedTime() - inQueue->slots->uf);
		} while (inQueue->size > 1);

		//postfl("perform all events that are ready %d %.9f\n", inQueue->size, elapsed);

		// perform all events that are ready
		//postfl("perform all events that are ready\n");
		while ((inQueue->size > 1) && elapsed >= slotRawFloat(inQueue->slots + 1)) {
			double schedtime, delta;
			PyrSlot task;

			//postfl("while %.6f >= %.6f\n", elapsed, inQueue->slots->uf);

			getheap(g, inQueue, &schedtime, &task);

			if (isKindOfSlot(&task, class_thread)) {
				SetNil(&slotRawThread(&task)->nextBeat);
			}

			slotCopy((++g->sp), &task);
			SetFloat(++g->sp, schedtime);
			SetFloat(++g->sp, schedtime);
			++g->sp;	SetObject(g->sp, s_systemclock->u.classobj);

			runAwakeMessage(g);
			long err = slotDoubleVal(&g->result, &delta);
			if (!err) {
				// add delta time and reschedule
				double time = schedtime + delta;

				schedAdd(g, inQueue, time, &task);
			}
		}
		//postfl("loop\n");
	}
	//postfl("exitloop\n");
leave:
	pthread_mutex_unlock (&gLangMutex);
	return 0;
}
Ejemplo n.º 28
0
void* TempoClock::Run()
{
	//printf("->TempoClock::Run\n");
	pthread_mutex_lock (&gLangMutex);
	while (mRun) {
		assert(mQueue->size);
		//printf("tempo %g  dur %g  beats %g\n", mTempo, mBeatDur, mBeats);
		//printf("wait until there is something in scheduler\n");
		// wait until there is something in scheduler
		while (mQueue->size == 1) {
			//printf("wait until there is something in scheduler\n");
			pthread_cond_wait (&mCondition, &gLangMutex);
			//printf("mRun a %d\n", mRun);
			if (!mRun) goto leave;
		}
		//printf("wait until an event is ready\n");

		// wait until an event is ready
		double elapsedBeats;
		do {
			elapsedBeats = ElapsedBeats();
			if (elapsedBeats >= slotRawFloat(mQueue->slots)) break;
			struct timespec abstime;
			//doubleToTimespec(mQueue->slots->uf, &abstime);
			//printf("event ready at %g . elapsed beats %g\n", mQueue->slots->uf, elapsedBeats);
			double wakeTime = BeatsToSecs(slotRawFloat(mQueue->slots));
			ElapsedTimeToTimespec(wakeTime, &abstime);
			//printf("wait until an event is ready. wake %g  now %g\n", wakeTime, elapsedTime());
			pthread_cond_timedwait (&mCondition, &gLangMutex, &abstime);
			//printf("mRun b %d\n", mRun);
			if (!mRun) goto leave;
			//printf("time diff %g\n", elapsedTime() - mQueue->slots->uf);
		} while (mQueue->size > 1);
		//printf("perform all events that are ready %d %.9f\n", mQueue->size, elapsedBeats);

		// perform all events that are ready
		//printf("perform all events that are ready\n");
		while (mQueue->size > 1 && elapsedBeats >= slotRawFloat(mQueue->slots)) {
			double delta;
			PyrSlot task;

			//printf("while %.6f >= %.6f\n", elapsedBeats, mQueue->slots->uf);

			getheap(g, (PyrObject*)mQueue, &mBeats, &task);

			if (isKindOfSlot(&task, class_thread)) {
				SetNil(&slotRawThread(&task)->nextBeat);
			}

			slotCopy((++g->sp), &task);
			SetFloat(++g->sp, mBeats);
			SetFloat(++g->sp, BeatsToSecs(mBeats));
			++g->sp;	SetObject(g->sp, mTempoClockObj);

			runAwakeMessage(g);
			long err = slotDoubleVal(&g->result, &delta);
			if (!err) {
				// add delta time and reschedule
				double beats = mBeats + delta;
				Add(beats, &task);
			}
		}
	}
leave:
	//printf("<-TempoClock::Run\n");
	pthread_mutex_unlock (&gLangMutex);
	return 0;
}