예제 #1
0
TTErr makeInternals_viewer(TTPtr self, TTAddress address, TTSymbol name, t_symbol *callbackMethod, TTObject& returnedViewer, TTBoolean deferlow)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			v, baton;
	TTAddress       adrs;
    
    // check the internals do not exist yet
    if (!x->internals->lookup(name, v)) {
        returnedViewer = v[0];
        JamomaDebug object_post((t_object*)x, "makeInternals_viewer : \"%s\" internal already exists", name.c_str());
        return kTTErrNone;
    }
	
	returnedViewer = TTObject(kTTSym_Viewer);
    
    baton = TTValue(TTPtr(x), TTPtr(callbackMethod), deferlow);
    returnedViewer.set(kTTSym_baton, baton);
	returnedViewer.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
	
	// edit address
	adrs = address.appendAddress(TTAddress(name));
	
	// default registration case : store object only (see in unregister method)
	x->internals->append(name, returnedViewer);
    
    // set address attribute (after registration as the value can be updated in the same time)
	returnedViewer.set(kTTSym_address, adrs);
    
    JamomaDebug object_post((t_object*)x, "makes internal \"%s\" viewer to bind on : %s", name.c_str(), adrs.c_str());
    
	return kTTErrNone;
}
예제 #2
0
TTErr makeInternals_explorer(TTPtr self, TTSymbol name, t_symbol *callbackMethod, TTObject& returnedExplorer, TTBoolean deferlow)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue		v, args, baton;
	TTObject    returnValueCallback;
    
    // check the internals do not exist yet
    if (!x->internals->lookup(name, v)) {
        returnedExplorer = v[0];
        JamomaDebug object_post((t_object*)x, "makeInternals_explorer : \"%s\" internal already exists", name.c_str());
        return kTTErrNone;
    }
	
	// prepare arguments
	returnValueCallback = TTObject("callback");
    
	baton = TTValue(TTPtr(x), TTPtr(callbackMethod), deferlow);
    
	returnValueCallback.set(kTTSym_baton, baton);
	returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
	args.append(returnValueCallback);
	
	args.append((TTPtr)jamoma_explorer_default_filter_bank());
	
	returnedExplorer = TTObject(kTTSym_Explorer, args);
	
	// default registration case : store object only (see in unregister method)
	x->internals->append(name, returnedExplorer);
    
    JamomaDebug object_post((t_object*)x, "makes internal \"%s\" explorer", name.c_str());
    
	return kTTErrNone;
}
예제 #3
0
TTErr makeInternals_data(TTPtr self, TTAddress address, TTSymbol name, t_symbol *callbackMethod, TTPtr context, TTSymbol service, TTObject& returnedData, TTBoolean deferlow)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			baton, v, out;
	TTAddress       dataAddress, dataRelativeAddress;
    TTNodePtr       dataNode;
    
	returnedData = TTObject(kTTSym_Data, service);
    
    baton = TTValue(TTPtr(x), TTPtr(callbackMethod), deferlow);
	
    returnedData.set(kTTSym_baton, baton);
	returnedData.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
	
	// absolute registration
	dataAddress = address.appendAddress(TTAddress(name));
    v = TTValue(dataAddress, returnedData, context);
	out = MaxApplication.send("ObjectRegister", v);
	
    // retreive relative effective address
	dataAddress = out[0];
    dataNode = TTNodePtr((TTPtr)out[1]);
    dataNode->getAddress(dataRelativeAddress, address);
    
	// absolute registration case : set the address in second position (see in unregister method)
	v = TTValue(returnedData, dataAddress);
	x->internals->append(dataRelativeAddress, v);
	
	JamomaDebug object_post((t_object*)x, "makes internal \"%s\" %s at : %s", dataRelativeAddress.c_str(), service.c_str(), dataAddress.c_str());
	
	return kTTErrNone;
}
예제 #4
0
void
DemoApp::SetupScore()
{
    TTValue     args, out;
    TTObject    xmlHandler("XmlHandler");
    
    TTLogMessage("\n*** Initialisation of Score environnement ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Init the Score library (passing the folder path where all the dylibs are)
    TTScoreInit("/usr/local/jamoma");
    
    
    TTLogMessage("\n*** Reading of an interactive scenario file ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Create an empty Scenario
    mScenario = TTObject("Scenario");
    
    // Read DemoScenario1.score file to fill mScenario
    xmlHandler.set("object", mScenario);
    xmlHandler.send("Read", "../DemoScenario.score", out);
    
    
    TTLogMessage("\n*** Prepare scenario observation ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Create a callback for the "EventStatusChanged" notification sent by each event
    mEventStatusChangedCallback = TTObject("callback");
    mEventStatusChangedCallback.set("baton", TTPtr(this));
    mEventStatusChangedCallback.set("function", TTPtr(&DemoAppEventStatusChangedCallback));
    mEventStatusChangedCallback.set("notification", TTSymbol("EventStatusChanged"));
    
    // Get all events of the scenario and attach a callback to them
    TTValue timeEvents;
    mScenario.get("timeEvents", timeEvents);
    
    for (TTElementIter it = timeEvents.begin() ; it != timeEvents.end() ; it++) {
        TTObject event = TTElement(*it);
        event.registerObserverForNotifications(mEventStatusChangedCallback);
    }
    
    
    TTLogMessage("\n*** Start scenario execution ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Set the execution speed of the scenario
    mScenario.set("speed", 2.);
    
    // Start the scenario
    mScenario.send("Start");
    
    // Poll Scenario information
    mPollingThread = new TTThread(TTThreadCallbackType(DemoAppScenarioPollingThread), this);
}
예제 #5
0
TTErr MinuitSenderManager::send(TTSymbol applicationName, TTSymbol ip, TTUInt16 port, const TTValue& message)
{
    TTValue  last;
    
    // if nothing is being sent to an application
    if (mSending.findEquals(applicationName, last))
    {
        // lock application
        mSending.append(applicationName);
        
        TTObject anOscSender;
        
        TTErr err = mSenders.lookup(applicationName, last);
        
        if (err)
        {
            anOscSender = TTObject("osc.send");
            
            anOscSender.set("address", ip);
            anOscSender.set("port", port);
            
            TTValue cache(anOscSender, ip, port);
            mSenders.append(applicationName, cache);
        }
        else
        {
            anOscSender = last[0];
            TTSymbol lastIp = last[1];
            TTUInt16 lastPort = last[2];
            
            if (lastIp == ip && lastPort == port)
                ;
            
            else
            {
                anOscSender.set("address", ip);
                anOscSender.set("port", port);
                
                TTValue cache(anOscSender, ip, port);
                mSenders.remove(applicationName);
                mSenders.append(applicationName, cache);
            }
        }
        
        err = anOscSender.send("send", message);
        
        // unlock application
        mSending.remove(applicationName);
        
        return kTTErrNone;
    }

    return kTTErrGeneric;
}
예제 #6
0
void data_array_create(TTPtr self, TTObject& returnedData, TTSymbol service, TTUInt32 index)
{
    WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
    t_symbol    *iAdrs;
	TTValue     baton;

	returnedData = TTObject(kTTSym_Data, service);
    
    jamoma_edit_numeric_instance(x->arrayFormatInteger, &iAdrs, index);
    
    baton = TTValue(self, index, TTSymbol(iAdrs->s_name));
	returnedData.set(kTTSym_baton, baton);
	returnedData.set(kTTSym_function, TTPtr(&data_array_return_value));
}
예제 #7
0
void model_preset_dowrite_again(TTPtr self)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTObject        aTextHandler;
	TTValue			o;
	TTErr			tterr;

    // stop filewatcher
	if (EXTRA->filewatcher)
		filewatcher_stop(EXTRA->filewatcher);

	tterr = x->internals->lookup(kTTSym_TextHandler, o);

	if (!tterr) {

		aTextHandler = o[0];

		aTextHandler.set(kTTSym_object, *EXTRA->presetManager);

		critical_enter(0);
		tterr = aTextHandler.send(kTTSym_WriteAgain);
		critical_exit(0);

		if (!tterr)
			object_obex_dumpout(self, _sym_write, 0, NULL);
		else
			object_obex_dumpout(self, _sym_error, 0, NULL);
	}

    // start filewatcher
	if (EXTRA->filewatcher)
		filewatcher_start(EXTRA->filewatcher);
}
예제 #8
0
TTErr makeInternals_sender(TTPtr self, TTAddress address, TTSymbol name, TTObject& returnedSender, TTBoolean appendNameAsAttribute)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
    TTValue     v;
	TTAddress   adrs;
    
    // check the internals do not exist yet
    if (!x->internals->lookup(name, v)) {
        returnedSender = v[0];
        JamomaDebug object_post((t_object*)x, "makeInternals_sender : \"%s\" internal already exists", name.c_str());
        return kTTErrNone;
    }
	
	returnedSender = TTObject(kTTSym_Sender);
	
	// edit address
	if (appendNameAsAttribute)
        adrs = address.appendAttribute(name);
    else
        adrs = address.appendAddress(TTAddress(name.c_str()));
	
	// default registration case : store object only (see in unregister method)
	x->internals->append(name, returnedSender);
    
    // set address attribute
	returnedSender.set(kTTSym_address, adrs);
    
    JamomaDebug object_post((t_object*)x, "makes internal \"%s\" sender to bind on : %s", name.c_str(), adrs.c_str());
    
	return kTTErrNone;
}
예제 #9
0
void model_preset_doread_again(TTPtr self)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTObject        aTextHandler;
	TTValue			o;
	TTErr			tterr;

	tterr = x->internals->lookup(kTTSym_TextHandler, o);

	if (!tterr) {

		aTextHandler = o[0];

		aTextHandler.set(kTTSym_object, *EXTRA->presetManager);

		critical_enter(0);
		tterr = aTextHandler.send(kTTSym_ReadAgain);
		critical_exit(0);

		if (!tterr)
			object_obex_dumpout(self, _sym_read, 0, NULL);
		else
			object_obex_dumpout(self, _sym_error, 0, NULL);
	}
}
예제 #10
0
void cue_dowrite_again(TTPtr self)
{	
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			o, v;
	TTObject        aTextHandler;
	TTErr			tterr;
	
	if (x->wrappedObject.valid()) {
		
		tterr = x->internals->lookup(kTTSym_TextHandler, o);
		
		if (!tterr) {
			
			aTextHandler = o[0];

			aTextHandler.set(kTTSym_object, x->wrappedObject);
			
			critical_enter(0);
			tterr = aTextHandler.send(kTTSym_WriteAgain, v);
			critical_exit(0);
			
			if (!tterr)
				object_obex_dumpout(self, _sym_write, 0, NULL);
			else
				object_obex_dumpout(self, _sym_error, 0, NULL);
		}
	}
}
예제 #11
0
void cue_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	char 			filename[MAX_FILENAME_CHARS];
	TTSymbol		fullpath;
	TTValue			o, v;
	TTObject        aTextHandler;
	TTErr			tterr;
	
	if (x->wrappedObject.valid()) {
		
		// Default TEXT File Name
		snprintf(filename, MAX_FILENAME_CHARS, "untitled.cues.txt");
		
		fullpath = jamoma_file_write((t_object*)x, argc, argv, filename);
		v.append(fullpath);
		
		tterr = x->internals->lookup(kTTSym_TextHandler, o);
		
		if (!tterr) {
			aTextHandler = o[0];

			aTextHandler.set(kTTSym_object, x->wrappedObject);
			
			critical_enter(0);
			tterr = aTextHandler.send(kTTSym_Write, v);
			critical_exit(0);
			
			if (!tterr)
				object_obex_dumpout(self, _sym_write, argc, argv);
			else
				object_obex_dumpout(self, _sym_error, 0, NULL);
		}
	}
}
예제 #12
0
void cue_doread(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
{	
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			o, v;
	TTSymbol		fullpath;
	TTObject		aTextHandler;
	TTErr			tterr;
	
	if (x->wrappedObject.valid()) {
		
		fullpath = jamoma_file_read((t_object*)x, argc, argv, (t_fourcc)'TEXT');
		v.append(fullpath);
		
		tterr = x->internals->lookup(kTTSym_TextHandler, o);
		
		if (!tterr) {
			
			aTextHandler = o[0];

			aTextHandler.set(kTTSym_object, x->wrappedObject);
			
			critical_enter(0);
			tterr = aTextHandler.send(kTTSym_Read, v);
			critical_exit(0);
			
			if (!tterr)
				object_obex_dumpout(self, _sym_read, argc, argv);
			else
				object_obex_dumpout(self, _sym_error, 0, NULL);
		}
	}
}
예제 #13
0
TTErr makeInternals_receiver(TTPtr self, TTAddress address, TTSymbol name, t_symbol *callbackMethod, TTObject& returnedReceiver, TTBoolean deferlow, TTBoolean appendNameAsAttribute)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			v, args, baton;
	TTObject        returnValueCallback, empty;
	TTAddress       adrs;
    
    // check the internals do not exist yet
    if (!x->internals->lookup(name, v)) {
        returnedReceiver = v[0];
        JamomaDebug object_post((t_object*)x, "makeInternals_receiver : \"%s\" internal already exists", name.c_str());
        returnedReceiver.send("Get");
        return kTTErrNone;
    }
	
	// prepare arguments
	
	// we don't want the address back
	args.append(empty);
	
	returnValueCallback = TTObject("callback");
    
	baton = TTValue(TTPtr(x), TTPtr(callbackMethod), deferlow);
    
	returnValueCallback.set(kTTSym_baton, baton);
	returnValueCallback.set(kTTSym_function, TTPtr(&jamoma_callback_return_value));
	args.append(returnValueCallback);
	
	returnedReceiver = TTObject(kTTSym_Receiver, args);
	
	// edit address
	if (appendNameAsAttribute)
        adrs = address.appendAttribute(name);
    else
        adrs = address.appendAddress(TTAddress(name.c_str()));
	
	// default registration case : store object only (see in unregister method)
	x->internals->append(name, returnedReceiver);
    
    // set address attribute (after registration as the value can be updated in the same time)
    returnedReceiver.set(kTTSym_address, adrs);
    
    JamomaDebug object_post((t_object*)x, "makes internal \"%s\" receiver to bind on : %s", name.c_str(), adrs.c_str());
    
	return kTTErrNone;
}
예제 #14
0
void model_preset_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	char 			filename[MAX_FILENAME_CHARS];
	TTSymbol		fullpath;
	TTValue			o, v, none;
	TTObject        aTextHandler;
	TTErr			tterr;

	// stop filewatcher
	if (EXTRA->filewatcher)
		filewatcher_stop(EXTRA->filewatcher);

	if (EXTRA->presetManager->valid()) {

		// Default TEXT File Name
		snprintf(filename, MAX_FILENAME_CHARS, "%s.%s.presets.txt", x->patcherClass.c_str(), x->patcherContext.c_str());
		fullpath = jamoma_file_write((t_object*)x, argc, argv, filename);
		v.append(fullpath);

		tterr = x->internals->lookup(kTTSym_TextHandler, o);

		if (!tterr) {
			aTextHandler = o[0];

			aTextHandler.set(kTTSym_object, *EXTRA->presetManager);

			critical_enter(0);
			tterr = aTextHandler.send(kTTSym_Write, v, none);
			critical_exit(0);

			if (!tterr)
				object_obex_dumpout(self, _sym_write, argc, argv);
			else
				object_obex_dumpout(self, _sym_error, 0, NULL);
		}
	}

	// start filewatcher
	if (EXTRA->filewatcher)
		filewatcher_start(EXTRA->filewatcher);
}
예제 #15
0
void cue_set(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
{
    WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
    TTHashPtr   allCues;
	TTValue     v;
	TTSymbol    name, attribute;
    TTObject	cue;
    
    if (argc >= 2) {
        
        if (atom_gettype(argv) == A_SYM && atom_gettype(argv+1) == A_SYM) {
            
            attribute = TTSymbol((char*)atom_getsym(argv)->s_name);
            name = TTSymbol((char*)atom_getsym(argv+1)->s_name);
            
            // get cue object table
            x->wrappedObject.get("cues", v);
            allCues = TTHashPtr((TTPtr)v[0]);
            
            if (allCues) {
                
                // get cue
                if (!allCues->lookup(name, v)) {
                    
                    cue = v[0];
                    
                    // prepare value to set
                    jamoma_ttvalue_from_Atom(v, _sym_nothing, argc-2, argv+2);
                    
                    if (cue.set(attribute, v))
                        object_error((t_object*)x, "%s attribute doesn't exist", atom_getsym(argv)->s_name);
                }
                else
                    object_error((t_object*)x, "%s cue doesn't exist", atom_getsym(argv+1)->s_name);
            }
        }
    }
}
예제 #16
0
TTErr TTProtocol::ApplicationRegister(const TTValue& inputValue, TTValue& outputValue)
{
    TTObject    application;
	TTSymbol	parameterName;
	TTHashPtr	applicationParameters;
	TTValue		v, parameterNames, out, none;
	TTErr		err;
    
    // update local application name
    mApplicationManager.get("applicationLocalName", v);
    mLocalApplicationName = v[0];
    
    if (inputValue.size() == 1) {
        
        if (inputValue[0].type() == kTypeSymbol) {
            
            mSelectedApplication = inputValue[0];
            
            // Check the application is not already registered
            err = mApplicationParameters.lookup(mSelectedApplication, v);
                
            if (err) {
                
                applicationParameters = new TTHash();
                
                // prepare parameters table
                this->getParameterNames(parameterNames);
                for (TTUInt32 i = 0; i < parameterNames.size(); i++) {
                    parameterName = parameterNames[i];
                    applicationParameters->append(parameterName, none);
                }
                
                // add the parameters table into mApplicationParameters
                v = TTValue((TTPtr)applicationParameters);
                mApplicationParameters.append(mSelectedApplication, v);
                
                // optionnaly format the application type depending on the protocol features
                // (if the application is already registered into the application manager)
                err = mApplicationManager.send("ApplicationFind", mSelectedApplication, out);
                
                if (!err) {
                        
                    application = out[0];
                    
                    // for none local application
                    if (mSelectedApplication != mLocalApplicationName) {
                        
                        // setup the application type depending of the discovering feature of the protocol
                        if (mDiscover || mDiscoverAll)
                            application.set("type", kTTSym_mirror);
                        else
                            application.set("type", kTTSym_proxy);
                    }
                }
                
                return kTTErrNone;
            }
        }
    }
	
	return kTTErrGeneric;
}
예제 #17
0
void
DemoApp::SetupModular()
{
    TTValue     args, v, out, none;
    TTAddress   address;
    TTErr       err;
    
    TTLogMessage("\n*** Initialisation of Modular environnement ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Init the Modular library (passing the folder path where all the dylibs are)
    TTModularInit("/usr/local/jamoma");
    
    // Create an application manager
    mApplicationManager = TTObject("ApplicationManager");
    
    
    TTLogMessage("\n*** Creation of mApplicationDemo application ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Create a local application called "demo" and get it back
    err = mApplicationManager.send("ApplicationInstantiateLocal", "demo", out);
    
    if (err) {
        TTLogError("Error : can't create demo application \n");
        return;
    }
    else
        mApplicationDemo = out[0];
    
    
	TTLogMessage("\n*** Creation of mApplicationDemo datas ***\n");
    /////////////////////////////////////////////////////////////////////
    
    // Create a parameter data and set its callback function and baton and some attributes
    mDataDemoParameter = TTObject("Data", "parameter");
    
    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoParameter);
    mDataDemoParameter.set("baton", args);
    mDataDemoParameter.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoParameter.set("type", "decimal");
    mDataDemoParameter.set("rangeBounds", TTValue(0., 1.));
    mDataDemoParameter.set("rangeClipmode", "low");
    mDataDemoParameter.set("description", "any information relative to the state of the application");
    
    // Register the parameter data into mApplicationDemo at an address
    args = TTValue("/myParameter", mDataDemoParameter);
    mApplicationDemo.send("ObjectRegister", args, out);
    
    
    // Create a message data and set its callback function and baton and some attributes
    mDataDemoMessage = TTObject("Data", "message");
    
    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoMessage);
    mDataDemoMessage.set("baton", args);
    mDataDemoMessage.set("function", TTPtr(&DemoAppDataReturnValueCallback));
    
    // Setup the data attributes depending of its use inside the application
    mDataDemoMessage.set("type", "string");
    mDataDemoMessage.set("description", "any information to provide to the application");
    
    // Register the message data into mApplicationDemo at an address
    args = TTValue("/myMessage", mDataDemoMessage);
    mApplicationDemo.send("ObjectRegister", args, out);
    
    
    // Create a return data and set its callback function and baton and some attributes
    mDataDemoReturn = TTObject("Data", "return");
    
    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoReturn);
    mDataDemoReturn.set("baton", args);
    mDataDemoReturn.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoReturn.set("type", "integer");
    mDataDemoReturn.set("defaultValue", 0);
    mDataDemoReturn.set("description", "any information the application returns back");
    
    // Register the return data into mApplicationDemo at an address
    args = TTValue("/myReturn", mDataDemoReturn);
    mApplicationDemo.send("ObjectRegister", args, out);
    
    // Initialise the application and all datas inside (using defaultValue attribute)
    mApplicationDemo.send("Init");
}
예제 #18
0
void wrappedModularClass_unregister(WrappedModularInstancePtr x)
{
	TTValue		keys, v;
	TTSymbol	name;
	TTAddress	objectAddress;
	TTErr		err;
    
#ifndef ARRAY_EXTERNAL
    
	x->subscriberObject = TTObject();
    
    // check the wrappedObject is still valid because it could have been released in spec->_free method
	if (x->wrappedObject.valid()) {
        
        // don't release the local application
        if (!(x->wrappedObject.instance() == accessApplicationLocal)) {
            
            if (x->wrappedObject.instance()->getReferenceCount() > 1)
                object_error((t_object*)x, "there are still unreleased reference of the wrappedObject (refcount = %d)", x->wrappedObject.instance()->getReferenceCount() - 1);
            
            // this line should release the last instance of the wrapped object
            // otherwise there is something wrong
            x->wrappedObject = TTObject();
        }
    }

#endif
	
    if (!x->internals->isEmpty()) {
        
        err = x->internals->getKeys(keys);
        
        if (!err) {
            
            x->iterateInternals = YES;
            
			for (int i = 0; i < (TTInt32) keys.size(); i++) {
                
                name = keys[i];
                err = x->internals->lookup(name, v);
                
                if (!err) {
                    
                    TTObject o = v[0];
                    
                    if (o.name() == kTTSym_Sender || o.name() == kTTSym_Receiver || o.name() == kTTSym_Viewer)
                        o.set(kTTSym_address, kTTAdrsEmpty);
                    
                    // absolute registration case : remove the address
                    if (v.size() == 2) {
                        objectAddress = v[1];
                        
                        JamomaDebug object_post((t_object*)x, "Remove internal %s object at : %s", name.c_str(), objectAddress.c_str());
                        MaxApplication.send("ObjectUnregister", objectAddress);
                    }
                }
            }
            x->iterateInternals = NO;
        }
        x->internals->clear();
    }
}
TTErr TTSoundfileLoader::test(TTValue& returnedTestInfo)
{
    int errorCount = 0;
    int testAssertionCount = 0;
    
    // assemble the full path of the target sound file
    
    TTString testSoundPath = TTFoundationBinaryPath;
    int pos = testSoundPath.find_last_of('/');
    testSoundPath = testSoundPath.substr(0,pos+1);
    testSoundPath += TESTFILE;
    
    std::cout << "We will be using the following path for testing: " << testSoundPath << "\n";
    
    try {
        
		TTTestLog("\n");
		TTTestLog("Testing TTSoundfileLoader Basics...");
		
        // TEST 0: establish our objects & pointers
        TTObject* testTargetMatrix = new TTObject("samplematrix");
        TTObject* testNonSampleMatrix = new TTObject("delay");
        TTObjectBase* objectBasePtrToSampleMatrix;
        TTObjectBase* ptrToNonSampleMatrix;
        
        // TEST 1: set the filepath
        TTBoolean result1 = { this->setFilePath(TT(testSoundPath)) == kTTErrNone };
        
        TTTestAssertion("setFilePath operates successfully",
                        result1,
                        testAssertionCount,
                        errorCount);
        
        // TEST 2: set up the samplematrix first
        int channelsSend = 1;           // compiler complained about TTInt32 being ambiguous here
        int lengthSend = 22050;         // compiler complained about TTInt32 being ambiguous here
        testTargetMatrix->set("numChannels", channelsSend);
        testTargetMatrix->set("lengthInSamples", lengthSend);
        
        TTInt32 channelsReturn, lengthReturn;
        
        testTargetMatrix->get("numChannels", channelsReturn);
        testTargetMatrix->get("lengthInSamples", lengthReturn);
        
        // now for the actual test
        TTBoolean result2a = { channelsSend == channelsReturn };
        
        TTTestAssertion("numChannels attribute set successfully",
						result2a,
						testAssertionCount,
						errorCount);
        
        TTBoolean result2b = { lengthSend == lengthReturn };
        
        TTTestAssertion("lengthInSamples attribute set successfully",
						result2b,
						testAssertionCount,
						errorCount);
        //
        
        // TEST 3: set the target via an objectBasePtr
        objectBasePtrToSampleMatrix = testTargetMatrix->instance(); // is there a better syntax for this?
        
        TTBoolean result3 = { this->setTargetMatrix(objectBasePtrToSampleMatrix) == kTTErrNone };
        
        TTTestAssertion("setTargetMatrix via ObjectBasePtr operates successfully",
						result3,
						testAssertionCount,
						errorCount);
        
        // TEST 4: set the target to a non-SampleMatrix, should FAIL
        ptrToNonSampleMatrix = testNonSampleMatrix->instance();
        
        TTBoolean result4 = { this->setTargetMatrix(ptrToNonSampleMatrix) == kTTErrInvalidValue };
        
        TTTestAssertion("setTargetMatrix returns error when not a SampleMatrix",
						result4,
						testAssertionCount,
						errorCount);
        
        // TEST 5: copy samplevalues until samplematrix is filled
        
        TTBoolean result5 = { this->copyUntilFilled() == kTTErrNone };
        
        TTTestAssertion("copyUntilFilled operates successfully",
						result5,
						testAssertionCount,
						errorCount);
        
        // releasing objects
        objectBasePtrToSampleMatrix = NULL;
        ptrToNonSampleMatrix = NULL;
        delete testTargetMatrix;
        delete testNonSampleMatrix;
        
        
        // TEST 6: use TTSampleMatrix's load message, then compare 5 random sample values for equivalence
        
        // create a new TTSampleMatrix
        TTObject newTargetMatrix("samplematrix");
        
        // set the length and channel count
        newTargetMatrix.set("numChannels", TESTNUMCHANNELS);
        newTargetMatrix.set("lengthInSamples", TESTDURATIONINSAMPLES);
        
        // prepare necessary TTValues
        TTValue loadInput6 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue
        TTValue aReturnWeDontCareAbout6;
        
        // send message
        TTBoolean result6a = { newTargetMatrix.send("load", loadInput6, aReturnWeDontCareAbout6) == kTTErrNone };
        
        TTTestAssertion("TTSampleMatrix load operates successfully",
                        result6a,
                        testAssertionCount,
                        errorCount);
        
        // now let's test some values!
        int randomIndex6, randomChannel6;
        TTSampleValue testValueSoundFile6;
        TTBoolean result6b = true;
        
        for (int i = 0; i<10; i++)
        {
            randomIndex6 = lengthReturn * TTRandom64();
            randomChannel6 = i % TESTNUMCHANNELS;
            //std::cout << "let's look at index " << randomIndex6 << " & channel " << randomChannel6 << "\n";
            
            TTValue peekInput6(randomIndex6);
            peekInput6.append(randomChannel6);
            TTValue peekOutput6;
            
            this->peek(randomIndex6,randomChannel6,testValueSoundFile6);
            newTargetMatrix.send("peek",peekInput6,peekOutput6);
            //std::cout << "Does " << testValueSoundFile6 << " = " << double(peekOutput6) << " ?\n";
            
            if (result6b) // allows test to keep variable false once it is false
                result6b = TTTestFloatEquivalence(testValueSoundFile6, double(peekOutput6), true, 0.0000001);
        }
        
        
        TTTestAssertion("comparing values @ 10 random indexes for equivalence",
                        result6b,
                        testAssertionCount,
                        errorCount);
        
        
        // TEST 7: now use TTBuffer's load message, and again compare 5 random sample values for equivalence
        
        // create a new TTBuffer with convenience syntax
        TTAudioBuffer aBufferByAnyOtherName(TESTNUMCHANNELS, TESTDURATIONINSAMPLES);
        
        // prepare necessary TTValues
        TTValue loadInput7 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue
        
        // send message
        TTBoolean result7a = { aBufferByAnyOtherName.load(loadInput7) == kTTErrNone };
        
        TTTestAssertion("TTBuffer load operates successfully",
                        result7a,
                        testAssertionCount,
                        errorCount);
        
        // setup pointer to samplematrix
        TTSampleMatrixPtr myMatrix7;
        
        // check out samplematrix
        TTBoolean result7b = { aBufferByAnyOtherName.checkOutMatrix(myMatrix7) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks out SampleMatrix successfully",
                        result7b,
                        testAssertionCount,
                        errorCount);
        
        TTValue testChannel, testSample;
        myMatrix7->getNumChannels(testChannel);
        myMatrix7->getLengthInSamples(testSample);
        
        //std::cout << "Samplematrix has " << int(testChannel) << " channels & " << int(testSample) << " samples\n";
        
        // now let's test some values!
        int randomIndex7, randomChannel7;
        double testValueSoundFile7, testValueSampleMatrix7;
        TTBoolean result7c = true;
        
        for (int i = 0; i<10; i++)
        {
            randomIndex7 = lengthReturn * TTRandom64();
            randomChannel7 = i % TESTNUMCHANNELS;
            //std::cout << "let's look at index " << randomIndex7 << " & channel " << randomChannel7 << "\n";
            
            this->peek(randomIndex7,randomChannel7,testValueSoundFile7);
            myMatrix7->peek(randomIndex7,randomChannel7,testValueSampleMatrix7);
            //std::cout << "Does " << testValueSoundFile7 << " = " << testValueSampleMatrix7 << " ?\n";
            
            if (result7c) // allows test to keep variable false once it is false
                result7c = TTTestFloatEquivalence(testValueSoundFile7, testValueSampleMatrix7, true, 0.0000001);
        }
        
        TTTestAssertion("comparing values @ 10 random indexes for equivalence",
                        result7c,
                        testAssertionCount,
                        errorCount);
        
        // check in samplematrix
        TTBoolean result7d = { aBufferByAnyOtherName.checkInMatrix(myMatrix7) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks in SampleMatrix successfully",
                        result7d,
                        testAssertionCount,
                        errorCount);
        
        
        // TEST 8: use optional load parameters to copy samples 5 to 15 from channel 0
        
        // resize
        aBufferByAnyOtherName.set("numChannels", 1);
        aBufferByAnyOtherName.set("lengthInSamples", 10);
        
        // prepare necessary TTValues
        int copyChannel8 = 0;       // first channel
        int startIndex8 = 5;        // start @ sample 5
        int endIndex8 = 15;         // end @ sample 15
        
        TTValue loadInput8 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue
        loadInput8.append(copyChannel8);
        loadInput8.append(startIndex8);
        loadInput8.append(endIndex8);
        
        // send message
        TTBoolean result8a = { aBufferByAnyOtherName.load(loadInput8) == kTTErrNone };
        
        TTTestAssertion("TTBuffer load operates successfully w optional parameters",
                        result8a,
                        testAssertionCount,
                        errorCount);
        
        // setup pointer to samplematrix
        TTSampleMatrixPtr myMatrix8;
        
        // check out samplematrix
        TTBoolean result8b = { aBufferByAnyOtherName.checkOutMatrix(myMatrix8) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks out SampleMatrix successfully",
                        result8b,
                        testAssertionCount,
                        errorCount);
        
        // now let's test some values!
        double testValueSoundFile8, testValueSampleMatrix8;
        TTBoolean result8c = true;

        for (int i = 0; i<10; i++)
        {
            //std::cout << "let's look at index " << i << "\n";
            
            this->peek(i+startIndex8,copyChannel8,testValueSoundFile8);
            myMatrix8->peek(i,copyChannel8,testValueSampleMatrix8);
            //std::cout << "Does " << testValueSoundFile8 << " = " << testValueSampleMatrix8 << " ?\n";
            
            if (result8c) // allows test to keep variable false once it is false
                result8c = TTTestFloatEquivalence(testValueSoundFile8, testValueSampleMatrix8, true, 0.0000001);
        }
        
        TTTestAssertion("comparing all 10 copied values for equivalence",
                        result8c,
                        testAssertionCount,
                        errorCount);
        
        // check in samplematrix
        TTBoolean result8d = { aBufferByAnyOtherName.checkInMatrix(myMatrix8) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks in SampleMatrix successfully",
                        result8d,
                        testAssertionCount,
                        errorCount);
        
        // TEST 9: load soundfile into buffer/samplematrix with different sample rate
        
        TTValue testChannel9in = 2;
        TTValue testSampleRate9in = 88200;
        TTValue testLengthSec9in = 0.25;
        
        
        aBufferByAnyOtherName.set("numChannels", testChannel9in);
        aBufferByAnyOtherName.set("sampleRate", testSampleRate9in);
        aBufferByAnyOtherName.set("lengthInSeconds", testLengthSec9in);
        
        TTValue loadInput9 = TT(testSoundPath); // we cannot pass the naked TTString, it needs to be part of a TTValue
        
        // send message
        TTBoolean result9a = { aBufferByAnyOtherName.load(loadInput9) == kTTErrNone };
        
        TTTestAssertion("TTBuffer load operates successfully when sample rates differ",
                        result9a,
                        testAssertionCount,
                        errorCount);
        
        // setup pointer to samplematrix
        TTSampleMatrixPtr myMatrix9;
        
        // check out samplematrix
        TTBoolean result9b = { aBufferByAnyOtherName.checkOutMatrix(myMatrix9) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks out SampleMatrix successfully",
                        result9b,
                        testAssertionCount,
                        errorCount);
        
        TTValue testChannel9, testSampleCount9, testSampleRate9;
        myMatrix9->getAttributeValue("numChannels", testChannel9);
        myMatrix9->getAttributeValue("lengthInSamples", testSampleCount9);
        myMatrix9->getAttributeValue("sampleRate", testSampleRate9);
        
        /*std::cout << "Samplematrix has " << TTInt32(testChannel9) << " channels & " << TTInt32(testSampleCount9) << " samples @ " << TTInt32(testSampleRate9) << " Hz\n";*/
        
        // check out samplematrix
        TTBoolean result9c = {  TTInt32(testChannel9) == TTInt32(testChannel9in) &&
                                TTInt32(testSampleRate9) == TTInt32(testSampleRate9in) &&
                                TTInt32(testSampleCount9) == (TTInt32(testSampleRate9in) * TTFloat64(testLengthSec9in)) };
        
        TTTestAssertion("SampleMatrix has same attributes set via TTBuffer",
                        result9c,
                        testAssertionCount,
                        errorCount);
        
        
        // let's test some values
        int randomIndex9, randomChannel9;
        TTSampleValue testSoundFileValue9, testSampleMatrixValue9;
        TTBoolean result9d = true;
        
        for (int i = 0; i<10; i++)
        {
            randomIndex9 = int(testSampleCount9) * TTRandom64();
            randomChannel9 = i % TESTNUMCHANNELS;
            //std::cout << "let's look at index " << randomIndex9 << " & channel " << randomChannel9 << "\n";
            
            this->peeki(float(randomIndex9)/2.0, randomChannel9, testSoundFileValue9);
            myMatrix9->peek(randomIndex9, randomChannel9, testSampleMatrixValue9);
            //std::cout << "Does " << testSoundFileValue9 << " = " << testSampleMatrixValue9 << " ?\n";
            
            if (result9d) // allows test to keep variable false once it is false
                result9d = TTTestFloatEquivalence(testSoundFileValue9, testSampleMatrixValue9, true, 0.0000001);
        }
        
        TTTestAssertion("comparing values @ 10 random indexes for equivalence",
                        result9d,
                        testAssertionCount,
                        errorCount);
        
        // check in samplematrix
        TTBoolean result9e = { aBufferByAnyOtherName.checkInMatrix(myMatrix9) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks in SampleMatrix successfully",
                        result9e,
                        testAssertionCount,
                        errorCount);
        
        // TEST 10: use resizeThenLoad message and test that TTSampleMatrix conforms to sound file loaded
        
        TTAudioBuffer bufferForTest10(1,1); // start by making the buffer really tiny
        
        TTValue loadInput10 = TT(testSoundPath);
        
        // send message
        TTBoolean result10a = { bufferForTest10.resizeThenLoad(loadInput10) == kTTErrNone };
        
        TTTestAssertion("TTBuffer resizeThenLoad operates successfully",
                        result10a,
                        testAssertionCount,
                        errorCount);
        
        // setup pointer to samplematrix
        TTSampleMatrixPtr myMatrix10;
        
        // check out samplematrix
        TTBoolean result10b = { bufferForTest10.checkOutMatrix(myMatrix10) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks out SampleMatrix successfully",
                        result10b,
                        testAssertionCount,
                        errorCount);
        
        // do some more tests here
        TTValue testChannel10, testLengthSec10, testLengthSample10;
        myMatrix10->getAttributeValue("numChannels", testChannel10);
        myMatrix10->getAttributeValue("lengthInSeconds", testLengthSec10);
        myMatrix10->getAttributeValue("lengthInSamples", testLengthSample10);
        
        /*std::cout << "Samplematrix has " << TTInt32(testChannel10) << " channels & " << TTInt32(testLengthSample10) << " samples and is " << TTFloat64(testLengthSec10) << " secs long\n";*/
        
        TTBoolean result10c = { TTInt32(testChannel10) == TESTNUMCHANNELS &&
                                TTInt32(testLengthSample10) == TESTDURATIONINSAMPLES };
        
        TTTestAssertion("TTBuffer.resizeThenLoad results in properly sized TTSampleMatrix",
                        result10c,
                        testAssertionCount,
                        errorCount);
        
        // check in samplematrix
        TTBoolean result10e = { bufferForTest10.checkInMatrix(myMatrix10) == kTTErrNone };
        
        TTTestAssertion("TTBuffer checks in SampleMartix successfully",
                        result10e,
                        testAssertionCount,
                        errorCount);
        
    } catch (...) {
        TTTestAssertion("FAILED to run tests -- likely that necessary objects did not instantiate",
            0,
            testAssertionCount,
            errorCount);
        
    }
    
    return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo);
}
예제 #20
0
void cue_edit(TTPtr self, t_symbol *msg, long argc, const t_atom *argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTString			*buffer;
	char				title[MAX_FILENAME_CHARS];
	TTObject            aTextHandler;
	TTHashPtr			allCues;
	TTValue				v, o;
	TTSymbol			name = kTTSymEmpty;
    t_atom				a;
	TTErr				tterr;
	
	// choose object to edit : default the cuelist
	*EXTRA->toEdit = x->wrappedObject;
	EXTRA->cueName = kTTSymEmpty;
	
	if (argc && argv)
    {
		if (atom_gettype(argv) == A_LONG)
        {
            TTUInt32 index = atom_getlong(argv);
			
			// get cues names
			x->wrappedObject.get("names", v);
			
			if (index > 0 && index <= v.size())
				name = v[index-1];
			else
            {
				object_error((t_object*)x, "%d doesn't exist", atom_getlong(argv));
				return;
			}
		}
		else if (atom_gettype(argv) == A_SYM)
			name = TTSymbol(atom_getsym(argv)->s_name);
		
		if (name != kTTSymEmpty)
        {
			// get cue object table
			x->wrappedObject.get("cues", v);
			allCues = TTHashPtr((TTPtr)v[0]);
			
			if (allCues)
            {
				// get cue to edit
				if (!allCues->lookup(name, v))
                {
					// edit a cue
					*EXTRA->toEdit = v[0];
					EXTRA->cueName = name;
				}
				else
                {
					object_error((t_object*)x, "%s doesn't exist", atom_getsym(argv)->s_name);
					return;
				}
			}
		}
	}
	
	// only one editor can be open in the same time
	if (!EXTRA->textEditor) {
		
		EXTRA->textEditor = (t_object*)object_new(_sym_nobox, _sym_jed, x, 0);
		
		buffer = new TTString();
		
		// get the buffer handler
		tterr = x->internals->lookup(kTTSym_TextHandler, o);
		
		if (!tterr) {
			
			aTextHandler = o[0];
			
			critical_enter(0);
			aTextHandler.set(kTTSym_object, *EXTRA->toEdit);
			tterr = aTextHandler.send(kTTSym_Write, (TTPtr)buffer);
			critical_exit(0);
		}
		
		// pass the buffer to the editor
		object_method(EXTRA->textEditor, _sym_settext, buffer->c_str(), _sym_utf_8);
		object_attr_setchar(EXTRA->textEditor, gensym("scratch"), 1);
		
		snprintf(title, MAX_FILENAME_CHARS, "cuelist editor");
		object_attr_setsym(EXTRA->textEditor, _sym_title, gensym(title));
        
        // output a flag
        atom_setsym(&a, gensym("opened"));
        object_obex_dumpout(self, gensym("editor"), 1, &a);
		
		buffer->clear();
		delete buffer;
		buffer = NULL;
	}
    else
    {
        object_attr_setchar(EXTRA->textEditor, gensym("visible"), 1);
    }
}