コード例 #1
0
ファイル: PyrListPrim.cpp プロジェクト: bagong/supercollider
bool identDict_lookupNonNil(PyrObject *dict, PyrSlot *key, int hash, PyrSlot *result)
{
again:
	PyrSlot *dictslots = dict->slots;
	PyrSlot *arraySlot = dictslots + ivxIdentDict_array;

	if (isKindOfSlot(arraySlot, class_array)) {
		PyrObject *array = slotRawObject(arraySlot);

		int index = arrayAtIdentityHashInPairsWithHash(array, key, hash);
		if (SlotEq(key, array->slots + index)) {
			slotCopy(result,&array->slots[index + 1]);
			return true;
		}
	}

	PyrClass *identDictClass = s_identitydictionary->u.classobj;
	PyrSlot *parentSlot = dictslots + ivxIdentDict_parent;
	PyrSlot * protoSlot = dictslots + ivxIdentDict_proto;
	if (isKindOfSlot(parentSlot, identDictClass)) {
		if (isKindOfSlot(protoSlot, identDictClass)) {
			// recursive call.
			if (identDict_lookupNonNil(slotRawObject(protoSlot), key, hash, result)) return true;
		}

		dict = slotRawObject(parentSlot);
		goto again; // tail call
	} else {
		if (isKindOfSlot(protoSlot, identDictClass)) {
			dict = slotRawObject(protoSlot);
			goto again; // tail call
		}
	}
	return false;
}
コード例 #2
0
int prFile_PutFile(struct VMGlobals *g, int numArgsPushed)
{

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

	NavDialogOptions options;

	int err = NavGetDefaultDialogOptions(&options);
	if (err) return errFailed;

	options.dialogOptionFlags |= kNavNoTypePopup;
	options.dialogOptionFlags |= kNavDontAutoTranslate;
	options.dialogOptionFlags |= kNavDontAddTranslateItems;
	options.dialogOptionFlags |= kNavSelectDefaultLocation;
	options.dialogOptionFlags &= ~kNavAllowPreviews;
	options.dialogOptionFlags &= ~kNavAllowMultipleFiles;

	if (isKindOfSlot(b, class_string)) {
		pstringFromPyrString((PyrString*)slotRawObject(b), options.message, 256);
	}

	if (isKindOfSlot(c, class_string)) {
		pstringFromPyrString((PyrString*)slotRawObject(c), options.savedFileName, 256);
	} else {
		//pstrncpy(options.savedFileName, "\pUntitled", 255);
	}

	NavReplyRecord reply;
	err = NavPutFile(0, &reply, &options, 0, 'TEXT', 'SCjm', 0);

	if (err == noErr && reply.validRecord) {
		AEKeyword keyword;
		DescType actualType;
		Size actualSize;
		FSSpec fsspec;

		err = AEGetNthPtr(&reply.selection, 1, typeFSS, &keyword, &actualType,
							&fsspec, sizeof(FSSpec), &actualSize);

		if (err == noErr) {
			Str255 pathname;
			GetFullPathname(&fsspec, pathname);
			p2cstr(pathname);
			PyrString *string = newPyrString(g->gc, (char*)pathname, 0, true);
			SetObject(a, string);

			err = NavCompleteSave(&reply, kNavTranslateInPlace);
		} else {
			SetNil(a);
		}
		err = NavDisposeReply(&reply);
	} else {
		SetNil(a);
	}
	return errNone;
}
コード例 #3
0
int prEvent_IsRest(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *dictslots = slotRawObject(g->sp)->slots;
	PyrSlot *arraySlot = dictslots + ivxIdentDict_array;

	if (isKindOfSlot(arraySlot, class_array)) {
		PyrSlot key, typeSlot;
		static PyrSymbol *s_type = getsym("type");
		static PyrSymbol *s_rest = getsym("rest");
		PyrSymbol *typeSym;
		// test 'this[\type] == \rest' first
		SetSymbol(&key, s_type);
		identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot);
		if(!slotSymbolVal(&typeSlot, &typeSym) && typeSym == s_rest) {
			SetBool(g->sp, 1);
			return errNone;
		} else {
			PyrObject *array = slotRawObject(arraySlot);
			PyrSymbol *slotSym;
			static PyrSymbol *s_empty = getsym("");
			static PyrSymbol *s_r = getsym("r");
			static PyrClass *class_rest = getsym("Rest")->u.classobj;
			static PyrClass *class_metarest = getsym("Meta_Rest")->u.classobj;
			PyrSlot *slot;
			int32 size = array->size;
			int32 i;

			slot = array->slots + 1;  // scan only the odd items

			for (i = 1; i < size; i += 2, slot += 2) {
				if (isKindOfSlot(slot, class_rest)
				    || isKindOfSlot(slot, class_metarest)
				) {
					SetBool(g->sp, 1);
					return errNone;
				} else if(!slotSymbolVal(slot, &slotSym)) {
					if(slotSym == s_empty
						|| slotSym == s_r
						|| slotSym == s_rest
					) {
						SetBool(g->sp, 1);
						return errNone;
					}
				}  // why no 'else'?
				// slotSymbolVal nonzero return = not a symbol;
				// non-symbols don't indicate rests, so, ignore them.
			}
		}
	} else {
		return errWrongType;
	}

	SetBool(g->sp, 0);
	return errNone;
}
コード例 #4
0
int prSendSysex(VMGlobals *g, int numArgsPushed)
{
	int err, uid, size;

	if( !isKindOfSlot(g->sp, s_int8array->u.classobj) )
		return errWrongType;

	PyrInt8Array* packet = slotRawInt8Array(g->sp);
	size = packet->size;

	PyrSlot *u = g->sp - 1;
	err = slotIntVal(u, &uid);
	if (err) return err;

	MIDIEndpointRef dest;
	MIDIObjectType mtype;
	MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&dest, &mtype);
	if (mtype != kMIDIObjectType_Destination) return errFailed;
	if (!dest) return errFailed;

	MIDISysexSendRequest *pk = (MIDISysexSendRequest*) malloc (sizeof(MIDISysexSendRequest) + size);
	Byte *data = (Byte *)pk + sizeof(MIDISysexSendRequest);

	memcpy(data,packet->b, size);
	pk->complete = false;
	pk -> destination = dest;
	pk -> data = data;
	pk -> bytesToSend = size;
	pk->completionProc = freeSysex;
	pk->completionRefCon = 0;

	return ((MIDISendSysex(pk) == (OSStatus)0) ? errNone : errFailed);
}
コード例 #5
0
ファイル: PyrArchiver.cpp プロジェクト: scztt/sc-debug
int prReadArchive(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 1;
	PyrSlot *b = g->sp;

	if (!isKindOfSlot(b, class_string)) return errWrongType;

	char pathname[PATH_MAX];
	memcpy(pathname, b->uos->s, b->uo->size);
	pathname[b->uos->size] = 0;

	PyrArchiver<FILE*> arch(g);
	FILE *file = fopen(pathname, "rb");

	int err;
	if (file) {
		arch.setStream(file);
		err = arch.readArchive(a);
		fclose(file);
	} else {
		error("file open failed\n");
		err = errFailed;
	}
	return err;
}
コード例 #6
0
ファイル: SC_LID.cpp プロジェクト: danstowell/SuperCute
int prLID_GetAbsInfo(VMGlobals *g, int numArgsPushed)
{
	PyrSlot* args = g->sp - 2;
	int evtCode;
	int err;

	PyrObject* obj = SC_LID::getObject(args+0);
	if (!obj) return errWrongType;

	err = slotIntVal(args+1, &evtCode);
	if (err) return err;

	if (!isKindOfSlot(args+2, s_absInfoClass->u.classobj))
		return errWrongType;
	PyrObject* infoObj = slotRawObject(&args[2]);

	SC_LID* dev = SC_LID::getDevice(obj);
	if (!dev) return errFailed;

	struct input_absinfo info;
	err = dev->getAbsInfo(evtCode, &info);
	if (err) return err;

	SetInt(infoObj->slots+0, info.value);
	SetInt(infoObj->slots+1, info.minimum);
	SetInt(infoObj->slots+2, info.maximum);
	SetInt(infoObj->slots+3, info.fuzz);
	SetInt(infoObj->slots+4, info.flat);

	slotCopy(&args[0], &args[2]);

	return errNone;
}
コード例 #7
0
int prSFWrite(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b;

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

	SNDFILE *file = (SNDFILE*)slotRawPtr(&slotRawObject(a)->slots[0]);

	if (!isKindOfSlot(b, class_rawarray)) return errWrongType;

	switch (slotRawObject(b)->obj_format) {
		case obj_int16 :
			sf_write_short(file, (short*)slotRawInt8Array(b)->b, slotRawObject(b)->size);
			break;
		case obj_int32 :
			sf_write_int(file, (int*)slotRawInt8Array(b)->b, slotRawObject(b)->size);
			break;
		case obj_float :
			sf_write_float(file, (float*)slotRawInt8Array(b)->b, slotRawObject(b)->size);
			break;
		case obj_double :
			sf_write_double(file, (double*)slotRawInt8Array(b)->b, slotRawObject(b)->size);
			break;
		default:
			error("sample format not supported.\n");
			return errFailed;
	}

	return errNone;
}
コード例 #8
0
ファイル: OSCData.cpp プロジェクト: scztt/sc-debug
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;
}
コード例 #9
0
ファイル: OSCData.cpp プロジェクト: scztt/sc-debug
int prArray_OSCBytes(VMGlobals *g, int numArgsPushed)
{
	PyrSlot* a = g->sp;
	PyrObject *array = a->uo;
	PyrSlot* args = array->slots;
	int numargs = array->size;
	if (numargs < 1) return errFailed;
	big_scpacket packet;

	if (IsFloat(args) || IsNil(args) || IsInt(args)) {
		makeSynthBundle(&packet, args, numargs, false);
	} else if (IsSym(args) || isKindOfSlot(args, class_string)) {
		makeSynthMsgWithTags(&packet, args, numargs);
	} else {
		return errWrongType;
	}

	int size = packet.size();
	PyrInt8Array* obj = newPyrInt8Array(g->gc, size, 0, true);
	obj->size = size;
	memcpy(obj->b, packet.data(), size);
	SetObject(a, (PyrObject*)obj);
	//for (int i=0; i<packet.size()/4; i++) post("%d %08X\n", i, packet.buf[i]);

	return errNone;
}
コード例 #10
0
ファイル: PyrListPrim.cpp プロジェクト: bagong/supercollider
/// Returns whether the slot is considered a rest for \c Event.isRest.
static bool slotIsRestlike(PyrSlot* slot)
{
	PyrSymbol * slotSym;
	if (isKindOfSlot(slot, class_rest) || isKindOfSlot(slot, class_metarest)) {
		return true;
	} else if(!slotSymbolVal(slot, &slotSym)) {
		return slotSym == s_empty
			|| slotSym == s_r
			|| slotSym == s_rest;
	}
	// why no 'else'?
	// slotSymbolVal nonzero return = not a symbol;
	// non-symbols don't indicate rests, so, ignore them.

	return false;
}
コード例 #11
0
ファイル: PyrArchiver.cpp プロジェクト: scztt/sc-debug
int prUnarchive(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp;

	if (!isKindOfSlot(a, class_int8array)) return errWrongType;

	PyrArchiver<char*> arch(g);

	arch.setStream((char*)a->uo->slots);
	int err = arch.readArchive(a);
	return err;
}
コード例 #12
0
void TempoClock::Add(double inBeats, PyrSlot* inTask)
{
	double prevBeats = mQueue->size > 1 ? slotRawFloat(mQueue->slots) : -1e10;
	bool added = addheap(g, (PyrObject*)mQueue, inBeats, inTask);
	if (!added) post("scheduler queue is full.\n");
	else {
		if (isKindOfSlot(inTask, class_thread)) {
			SetFloat(&slotRawThread(inTask)->nextBeat, inBeats);
		}
		if (slotRawFloat(mQueue->slots) != prevBeats) {
			pthread_cond_signal (&mCondition);
		}
	}
}
コード例 #13
0
ファイル: QObjectProxy.cpp プロジェクト: danstowell/SuperCute
bool QObjectProxy::invokeMethod( const char *method, PyrSlot *arg )
{
  qscDebugMsg("invoking method '%s'\n", method );

  Slot argSlots[10];

  if ( isKindOfSlot( arg, class_array ) ) {
    PyrSlot *slots = slotRawObject( arg )->slots;
    int size = slotRawObject( arg )->size;
    int i;
    for( i = 0; i<size && i<10; ++i ) {
      argSlots[i].setData( slots );
      ++slots;
    }
  }
  else argSlots[0].setData( arg );

  bool success =
    QMetaObject::invokeMethod( qObject, method, Qt::QueuedConnection,
                                argSlots[0].asGenericArgument(),
                                argSlots[1].asGenericArgument(),
                                argSlots[2].asGenericArgument(),
                                argSlots[3].asGenericArgument(),
                                argSlots[4].asGenericArgument(),
                                argSlots[5].asGenericArgument(),
                                argSlots[6].asGenericArgument(),
                                argSlots[7].asGenericArgument(),
                                argSlots[8].asGenericArgument(),
                                argSlots[9].asGenericArgument());

  if( !success )
  {
    success =
      QMetaObject::invokeMethod( this, method, Qt::QueuedConnection,
                                  argSlots[0].asGenericArgument(),
                                  argSlots[1].asGenericArgument(),
                                  argSlots[2].asGenericArgument(),
                                  argSlots[3].asGenericArgument(),
                                  argSlots[4].asGenericArgument(),
                                  argSlots[5].asGenericArgument(),
                                  argSlots[6].asGenericArgument(),
                                  argSlots[7].asGenericArgument(),
                                  argSlots[8].asGenericArgument(),
                                  argSlots[9].asGenericArgument());
  }

  return success;
}
コード例 #14
0
int prFileGetcwd(struct VMGlobals *g, int numArgsPushed)
{
	//PyrSlot* a = g->sp - 1; // File
	PyrSlot* string = g->sp;

	if (!isKindOfSlot(string, class_string))  return errWrongType;

	char * cwd = getcwd(slotRawString(string)->s,255);
	if (cwd == NULL) {
		error(strerror(errno));
		return errFailed;
	}
	slotRawString(string)->size = (int)strlen(slotRawString(string)->s);

	return errNone;
}
コード例 #15
0
void schedAdd(VMGlobals *g, PyrObject* inQueue, double inSeconds, PyrSlot* inTask)
{
	// gLangMutex must be locked
	double prevTime = inQueue->size > 1 ? slotRawFloat(inQueue->slots + 1) : -1e10;
	bool added = addheap(g, inQueue, inSeconds, inTask);
	if (!added) post("scheduler queue is full.\n");
	else {
		if (isKindOfSlot(inTask, class_thread)) {
			SetFloat(&slotRawThread(inTask)->nextBeat, inSeconds);
		}
		if (slotRawFloat(inQueue->slots + 1) != prevTime) {
			//post("pthread_cond_signal\n");
			pthread_cond_signal (&gSchedCond);
		}
	}
}
コード例 #16
0
int prSFOpenRead(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b;
	char filename[PATH_MAX];
	SNDFILE *file;
	SF_INFO info;
	const char *headerstr;
	const char *sampleformatstr;

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

	PyrObject *obj1 = slotRawObject(a);

	if (!isKindOfSlot(b, class_string)) return errWrongType;
	if (slotRawObject(b)->size > PATH_MAX - 1) return errFailed;

	memcpy(filename, slotRawString(b)->s, slotRawObject(b)->size);
	filename[slotRawString(b)->size] = 0;

	info.format = 0;
	file = sf_open(filename, SFM_READ, &info);


	if (file) {
		SetPtr(obj1->slots + 0, file);
		sndfileFormatInfoToStrings(&info, &headerstr, &sampleformatstr);
		//headerFormatToString(&info, &headerstr);
		PyrString *hpstr = newPyrString(g->gc, headerstr, 0, true);
		SetObject(obj1->slots+1, hpstr);
		g->gc->GCWriteNew(obj1, (PyrObjectHdr*)hpstr); // we know hpstr is white so we can use GCWriteNew
		PyrString *smpstr = newPyrString(g->gc, sampleformatstr, 0, true);
		SetObject(obj1->slots+2, smpstr);
		g->gc->GCWriteNew(obj1, (PyrObjectHdr*)smpstr); // we know smpstr is white so we can use GCWriteNew
		SetInt(obj1->slots + 3, info.frames);
		SetInt(obj1->slots + 4, info.channels);
		SetInt(obj1->slots + 5, info.samplerate);

		SetTrue(a);
	} else {
		SetNil(a);
		SetFalse(a);
	}
	return errNone;
}
コード例 #17
0
ファイル: OSCData.cpp プロジェクト: robertol80/supercollider
static int addMsgSlot(big_scpacket *packet, PyrSlot *slot)
{
	switch (GetTag(slot)) {
		case tagInt :
			packet->addi(slotRawInt(slot));
			break;
		case tagSym :
			packet->adds(slotRawSymbol(slot)->name);
			break;
		case tagObj :
			if (isKindOf(slotRawObject(slot), class_string)) {
				PyrString *stringObj = slotRawString(slot);
				packet->adds(stringObj->s, stringObj->size);
			} else if (isKindOf(slotRawObject(slot), class_int8array)) {
				PyrInt8Array *arrayObj = slotRawInt8Array(slot);
				packet->addb(arrayObj->b, arrayObj->size);
			} else if (isKindOf(slotRawObject(slot), class_array)) {
				PyrObject *arrayObj = slotRawObject(slot);
				big_scpacket packet2;
				if (arrayObj->size > 1 && isKindOfSlot(arrayObj->slots+1, class_array)) {
					makeSynthBundle(&packet2, arrayObj->slots, arrayObj->size, true);
				} else {
					int error = makeSynthMsgWithTags(&packet2, arrayObj->slots, arrayObj->size);
					if (error != errNone)
						return error;
				}
				packet->addb((uint8*)packet2.data(), packet2.size());
			}
			break;
		case tagNil :
		case tagTrue :
		case tagFalse :
		case tagChar :
		case tagPtr :
			break;
		default :
			if (gUseDoubles) packet->addd(slotRawFloat(slot));
			else packet->addf(slotRawFloat(slot));
			break;
	}
	return errNone;
}
コード例 #18
0
ファイル: PyrUnixPrim.cpp プロジェクト: scztt/sc-debug
int prString_POpen(struct VMGlobals *g, int numArgsPushed)
{
	struct sc_process *process;
	PyrSlot *a = g->sp - 1;
	PyrSlot *b = g->sp;
	int err;

	if (!isKindOfSlot(a, class_string)) return errWrongType;

	char *cmdline = (char*)malloc(a->uo->size + 1);
	err = slotStrVal(a, cmdline, a->uo->size + 1);
	if(err) {
		free(cmdline);
		return errFailed;
	}

#ifdef SC_IPHONE
	SetInt(a, 0);
	return errNone;
#endif

	process = (struct sc_process *)malloc(sizeof(struct sc_process));
	process->stream = sc_popen(cmdline, &process->pid, "r");
	setvbuf(process->stream, 0, _IONBF, 0);

	process->postOutput = IsTrue(b);

	free(cmdline);

	if(process->stream == NULL) {
		free(process);
		return errFailed;
	}

	pthread_t thread;
	pthread_create(&thread, NULL, string_popen_thread_func, (void*)process);
	pthread_detach(thread);

	SetInt(a, process->pid);
	return errNone;
}
コード例 #19
0
ファイル: OSCData.cpp プロジェクト: scztt/sc-debug
void addMsgSlot(big_scpacket *packet, PyrSlot *slot)
{
	switch (slot->utag) {
		case tagInt :
			packet->addi(slot->ui);
			break;
		case tagSym :
			packet->adds(slot->us->name);
			break;
		case tagObj :
			if (isKindOf(slot->uo, class_string)) {
				PyrString *stringObj = slot->uos;
				packet->adds(stringObj->s, stringObj->size);
			} else if (isKindOf(slot->uo, class_int8array)) {
				PyrInt8Array *arrayObj = slot->uob;
				packet->addb(arrayObj->b, arrayObj->size);
			} else if (isKindOf(slot->uo, class_array)) {
				PyrObject *arrayObj = slot->uo;
				big_scpacket packet2;
				if (arrayObj->size > 1 && isKindOfSlot(arrayObj->slots+1, class_array)) {
					makeSynthBundle(&packet2, arrayObj->slots, arrayObj->size, true);
				} else {
					makeSynthMsgWithTags(&packet2, arrayObj->slots, arrayObj->size);
				}
				packet->addb((uint8*)packet2.data(), packet2.size());
			}
			break;
		case tagNil :
		case tagTrue :
		case tagFalse :
		case tagChar :
		case tagPtr :
			break;
		default :
			if (gUseDoubles) packet->addd(slot->uf);
			else packet->addf(slot->uf);
			break;
	}
}
コード例 #20
0
ファイル: SC_LID.cpp プロジェクト: danstowell/SuperCute
int prLID_GetInfo(VMGlobals* g, int numArgsPushed)
{
	PyrSlot* args = g->sp - 1;
	int err;

	PyrObject* obj = SC_LID::getObject(args+0);
	if (!obj) return errWrongType;

	if (!isKindOfSlot(args+1, s_inputDeviceInfoClass->u.classobj))
		return errWrongType;
	PyrObject* infoObj = slotRawObject(&args[1]);

	SC_LID* dev = SC_LID::getDevice(obj);
	if (!dev) return errFailed;

	char name[128];
	err = dev->getName(name, sizeof(name));
	if (err) return err;

	struct input_id info;
	char namePhys[128];
	char nameUniq[128];
	err = dev->getInfo(&info, namePhys, sizeof( namePhys ), nameUniq, sizeof( nameUniq ) );
	if (err) return err;

	SetSymbol(infoObj->slots+0, getsym(name));
	SetInt(infoObj->slots+1, info.bustype);
	SetInt(infoObj->slots+2, info.vendor);
	SetInt(infoObj->slots+3, info.product);
	SetInt(infoObj->slots+4, info.version);
	SetSymbol(infoObj->slots+5, getsym(namePhys));
	SetSymbol(infoObj->slots+6, getsym(nameUniq));

	slotCopy(&args[0], &args[1]);

	return errNone;
}
コード例 #21
0
ファイル: PyrListPrim.cpp プロジェクト: bagong/supercollider
int prEvent_IsRest(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *dictslots = slotRawObject(g->sp)->slots;
	PyrSlot *arraySlot = dictslots + ivxIdentDict_array;
	static int isRestCount = 0;

	if (!isKindOfSlot(arraySlot, class_array)) {
		return errWrongType;
	}

	PyrSlot key, typeSlot;
	PyrSymbol *typeSym;
	// easy tests first: 'this[\type] == \rest'
	SetSymbol(&key, s_type);
	identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot);
	if(!slotSymbolVal(&typeSlot, &typeSym) && typeSym == s_rest) {
		SetBool(g->sp, 1);
		return errNone;
	}

	// and, 'this[\isRest] == true'
	SetSymbol(&key, s_isRest);
	identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot);
	if(IsTrue(&typeSlot)) {
		if (isRestCount == 0)
			post("\nWARNING: Setting isRest to true in an event is deprecated. See the Rest helpfile for supported ways to specify rests.\n\n");
		isRestCount = (isRestCount + 1) % 100;
		SetBool(g->sp, 1);
		return errNone;
	}

	// failing those, scan slot values for something rest-like
	PyrObject *array = slotRawObject(arraySlot);
	SetBool(g->sp, dictHasRestlikeValue(array) ? 1 : 0);
	return errNone;
}
コード例 #22
0
ファイル: SC_LID.cpp プロジェクト: danstowell/SuperCute
	static PyrObject* getObject(PyrSlot* slot)
	{
		return isKindOfSlot(slot, s_inputDeviceClass->u.classobj) ? slotRawObject(slot) : 0;
	}
コード例 #23
0
int prSFOpenWrite(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b;
	char filename[PATH_MAX];
	SNDFILE *file;
	SF_INFO info;
	PyrSlot *headerSlot;
	PyrSlot *formatSlot;
	int error;


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

	headerSlot = (slotRawObject(a)->slots + 1);
	formatSlot = (slotRawObject(a)->slots + 2);


	if (!isKindOfSlot(headerSlot, class_string)) return errWrongType;
	if (!isKindOfSlot(formatSlot, class_string)) return errWrongType;

	if (!isKindOfSlot(b, class_string)) return errWrongType;
	if (slotRawObject(b)->size > PATH_MAX - 1) return errFailed;

	memcpy(filename, slotRawString(b)->s, slotRawObject(b)->size);
	filename[slotRawString(b)->size] = 0;

#ifdef SC_WIN32
	char* headerFormat = (char *)malloc(slotRawObject(headerSlot)->size);
#else
	char headerFormat[slotRawString(headerSlot)->size];
#endif
	memcpy(headerFormat, slotRawString(headerSlot)->s, slotRawObject(headerSlot)->size);
	headerFormat[slotRawString(headerSlot)->size] = 0;

#ifdef SC_WIN32
	char* sampleFormat = (char *)malloc(slotRawString(formatSlot)->size);
#else
	char sampleFormat[slotRawString(formatSlot)->size];
#endif
	memcpy(sampleFormat, slotRawString(formatSlot)->s, slotRawObject(formatSlot)->size);
	sampleFormat[slotRawString(formatSlot)->size] = 0;

	error = sndfileFormatInfoFromStrings(&info, headerFormat, sampleFormat);
	if(error) {
#ifdef SC_WIN32
		free(sampleFormat);
		free(headerFormat);
#endif
		return errFailed;
	}

	if(error) 	return errFailed;
	//slotIntVal(slotRawObject(a)->slots + 3, &info.frames);
	slotIntVal(slotRawObject(a)->slots + 4, &info.channels);
	slotIntVal(slotRawObject(a)->slots + 5, &info.samplerate);

	file = sf_open(filename, SFM_WRITE, &info);
	sf_command(file, SFC_SET_CLIPPING, NULL, SF_TRUE);

	if (file) {
		SetPtr(slotRawObject(a)->slots+0, file);
		SetTrue(a);
	} else {
		SetNil(a);
		SetFalse(a);
	}

	return errNone;
}
コード例 #24
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;
}
コード例 #25
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;
}
コード例 #26
0
ファイル: PyrListPrim.cpp プロジェクト: bagong/supercollider
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;
}
コード例 #27
0
void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector,
	long numArgsPushed)
{
	PyrSlot *qslot, *pslot, *pend;
	long i, index;
	PyrSlot *uniqueMethodSlot, *arraySlot, *recvrSlot, *selSlot, *slot;
	PyrClass *classobj;
	PyrMethod *meth;
	PyrObject *array;

#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
	// move args up by one to make room for selector
	qslot = g->sp + 1;
	pslot = g->sp + 2;
	pend = pslot - numArgsPushed + 1;
	while (pslot > pend) *--pslot = *--qslot;

	selSlot = g->sp - numArgsPushed + 2;
	SetSymbol(selSlot, selector);
	g->sp++;

	recvrSlot = selSlot - 1;

	classobj = classOfSlot(recvrSlot);

	index = slotRawInt(&classobj->classIndex) + s_nocomprendo->u.index;
	meth = gRowTable[index];


	if (slotRawClass(&meth->ownerclass) == class_object) {
		// lookup instance specific method
		uniqueMethodSlot = &g->classvars->slots[cvxUniqueMethods];
		if (isKindOfSlot(uniqueMethodSlot, class_identdict)) {
			arraySlot = slotRawObject(uniqueMethodSlot)->slots + ivxIdentDict_array;
			if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) {
				i = arrayAtIdentityHashInPairs(array, recvrSlot);
				if (i >= 0) {
					slot = array->slots + i;
					if (NotNil(slot)) {
						++slot;
						if (isKindOfSlot(slot, class_identdict)) {
							arraySlot = slotRawObject(slot)->slots + ivxIdentDict_array;
							if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) {
								i = arrayAtIdentityHashInPairs(array, selSlot);
								if (i >= 0) {
									slot = array->slots + i;
									if (NotNil(slot)) {
										++slot;
										slotCopy(selSlot, recvrSlot);
										slotCopy(recvrSlot, slot);
										blockValue(g, (int)numArgsPushed+1);
										return;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	executeMethod(g, meth, numArgsPushed+1);

#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
}
コード例 #28
0
int prFileReadRawLE(struct VMGlobals *g, int numArgsPushed)
{
	PyrFile *pfile;
	FILE *file;

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

	if (!isKindOfSlot(b, class_rawarray)
		|| isKindOfSlot(b, class_symbolarray)) return errWrongType;

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

	int elemSize = gFormatElemSize[slotRawObject(b)->obj_format];
	int numElems = slotRawObject(b)->size;
	numElems = (int)fread(slotRawString(b)->s, elemSize, numElems, file);
	slotRawObject(b)->size = numElems;

#if BYTE_ORDER == BIG_ENDIAN
	switch (elemSize) {
		case 1:
			break;
		case 2:
		{
			char *ptr = slotRawString(b)->s;
			char *ptrend = ptr + numElems*2;
			for (; ptr < ptrend; ptr+=2) {
				char temp = ptr[0];
				ptr[0] = ptr[1];
				ptr[1] = temp;
			}
			break;
		}
		case 4:
		{
			char *ptr = slotRawString(b)->s;
			char *ptrend = ptr + numElems*4;
			for (; ptr < ptrend; ptr+=4) {
				char temp = ptr[0];
				ptr[0] = ptr[3];
				ptr[3] = temp;

				temp = ptr[1];
				ptr[1] = ptr[2];
				ptr[2] = temp;
			}
			break;
		}
		case 8:
		{
			char *ptr = slotRawString(b)->s;
			char *ptrend = ptr + numElems*8;
			for (; ptr < ptrend; ptr+=8) {
				char temp = ptr[0];
				ptr[0] = ptr[7];
				ptr[7] = temp;

				temp = ptr[1];
				ptr[1] = ptr[6];
				ptr[6] = temp;

				temp = ptr[2];
				ptr[2] = ptr[5];
				ptr[5] = temp;

				temp = ptr[3];
				ptr[3] = ptr[4];
				ptr[4] = temp;
			}
			break;
		}
	}
#endif

	if (slotRawObject(b)->size==0) SetNil(a);
	else slotCopy(a,b);
	return errNone;
}
コード例 #29
0
int prString_FindRegexp(struct VMGlobals *g, int numArgsPushed)
{
	int err;

	PyrSlot *a = g->sp - 2; // source string
	PyrSlot *b = g->sp - 1; // pattern
	PyrSlot *c = g->sp;     // offset

	if (!isKindOfSlot(b, class_string) || (NotInt(c))) return errWrongType;
//	post("prString_FindRegexp\n");
	int maxfind = MAXREGEXFIND;
	int offset = slotRawInt(c);
	int stringsize = slotRawObject(a)->size + 1;
	int patternsize =  slotRawObject(b)->size + 1;
	char *string = (char*)malloc(slotRawObject(a)->size + 1);
	err = slotStrVal(a, string, slotRawObject(a)->size + 1);
	if (err){
		free(string);
		return err;
	}
	char *pattern = (char*)malloc(slotRawObject(b)->size + 1);
	err = slotStrVal(b, pattern, slotRawObject(b)->size + 1);
	if (err) return err;
	UParseError uerr;
	UErrorCode status = (UErrorCode)0;
	UChar *regexStr;
	UChar *ustring;

	regexStr =  (UChar*)malloc((patternsize)*sizeof(UChar));
	u_charsToUChars (pattern, regexStr, patternsize);

	ustring =  (UChar*)malloc((stringsize)*sizeof(UChar));
	u_charsToUChars (string+offset, ustring, stringsize-offset);


	unsigned flags = UREGEX_MULTILINE;
	int groupNumber = 0;
	SCRegExRegion * what;
	int indx = 0;
	int size = 0;

	URegularExpression *expression = uregex_open(regexStr, -1, flags, &uerr, &status);
	if(U_FAILURE(status)) goto nilout;

	 if(!U_FAILURE(status)) {
		uregex_setText(expression, ustring, -1, &status);
		what =  (SCRegExRegion*)malloc((maxfind)*sizeof(SCRegExRegion));
		for(int i=0; i< maxfind; i++)
		{
			SCRegExRegion range;
			range.matched = false;
			what[i] = range;
		}

		int32_t groups = uregex_groupCount(expression, &status) + 1;
		if(U_FAILURE(status)) goto nilout;
//		post("groups: %i\n", groups);
		while (uregex_findNext(expression, &status) && size<maxfind)
		{
			if(U_FAILURE(status)) return errNone;

			for(int i=0; i< groups; ++i){
				what[size].group = i;
				what[size].start = sc_clip(uregex_start(expression, i, &status), 0, stringsize) ;
				if(U_FAILURE(status)) goto nilout;
				what[size].end = sc_clip(uregex_end(expression, i, &status), 0, stringsize);
				what[size].matched = true;
//				post("index:%i, size:%i, start %i, end %i\n", i, size, what[i].start, what[i].end);
				size = indx++ + 1;
				if(U_FAILURE(status)) goto nilout;
			}
		}

		PyrObject *result_array = newPyrArray(g->gc, size, 0, true);
		result_array->size = 0;

		if (size>0) //(matched)
		{
			for (int i = 0; i < size; i++)
			{
				if (what[0].matched == false)
				{
					result_array->size++;
					SetNil(result_array->slots+i);
				}
				else
				{
					result_array->size++;

					int match_start =  what[i].start;
					int match_length = what[i].end -  what[i].start;
//					post("for i:%i, start %i, end %i\n",  i, what[i].start,  what[i].end);
//					char *match = (char*)malloc(match_length);
					char match[match_length];

					strncpy(match, string + offset + match_start, match_length);
					match[match_length] = 0;
					PyrObject *array = newPyrArray(g->gc, 2, 0, true);
					array->size = 2;
					SetInt(array->slots, match_start + offset);

					PyrObject *matched_string = (PyrObject*)newPyrString(g->gc, match, 0, true);
					SetObject(array->slots+1, matched_string);
					g->gc->GCWrite(matched_string, array->slots + 1);

					SetObject(result_array->slots + i, array);
					g->gc->GCWrite(array, result_array->slots + i);
				}
			}
		}
		else
		{
			SetNil(a);
		}
		 free(what);
		 free(pattern);
		 free(regexStr);
		 free(ustring);
		 free(string);
		SetObject(a, result_array);
		g->gc->GCWrite(result_array,a);
		//uregex_close(expression);
		return errNone;
	}

		nilout:
			free(string);
			free(what);
			free(pattern);
			free(regexStr);
			free(ustring);
			SetNil(a);
			return errNone;
}
コード例 #30
0
ファイル: metatype.cpp プロジェクト: acamari/supercollider
MetaType *MetaType::find( PyrSlot *slot )
{
  switch (GetTag(slot)) {
    case tagNil :
      return 0;
    case tagInt :
      return metaType<int>();
    case tagSym :
      return metaType<QString>();
    case tagChar :
      return metaType<QChar>();
    case tagFalse :
    case tagTrue :
      return metaType<bool>();
    case tagObj :
    {
      PyrObject *obj = slotRawObject(slot);
      PyrClass *klass = obj->classptr;
      unsigned char format = obj->obj_format;

      if( format == obj_double || format == obj_float )
        return metaType< QVector<double> >();

      else if( format == obj_int32 || format == obj_int16 || format == obj_int8 )
        return metaType< QVector<int> >();

      else if( isKindOfSlot( slot, class_string ) ) {
        return metaType<QString>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(Point) ) ) {
        return metaType<QPointF>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(Rect) ) ) {
        return metaType<QRectF>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(Size) ) ) {
        return metaType<QSizeF>();
      }
      else if( klass == SC_CLASS(Color) ||
        klass == SC_CLASS(Gradient) ||
        klass == SC_CLASS(HiliteGradient) )
      {
        return metaType<QColor>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(QFont) ) ) {
        return metaType<QFont>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(QPalette) ) ) {
        return metaType<QPalette>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(QObject) ) ) {
        return metaType<QObjectProxy*>();
      }
      else if( isKindOfSlot( slot, class_array ) || isKindOfSlot( slot, class_symbolarray ) ) {
        return metaType<QVariantList>();
      }
      else if( isKindOfSlot( slot, SC_CLASS(QTreeViewItem) ) ) {
        return metaType<QcTreeWidget::ItemPtr>();
      }
      else {
        QString className = TypeCodec<QString>::read( &slotRawObject(slot)->classptr->name );
        qcWarningMsg(QString("WARNING: Do not know how to use an instance of class '%1'").arg(className));
        return 0;
      }
    }
    default:
      return metaType<double>();
  }
}