void data_subscribe(TTPtr self, t_symbol *relativeAddress, long argc, t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTAddress returnedAddress; TTNodePtr returnedNode = NULL; TTNodePtr returnedContextNode = NULL; // for relative address if (TTAddress(relativeAddress->s_name).getType() == kAddressRelative) { jamoma_subscriber_create((t_object*)x, x->wrappedObject, TTAddress(jamoma_parse_dieze((t_object*)x, relativeAddress)->s_name), x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode); #ifndef JMOD_MESSAGE #ifndef JMOD_RETURN // if a j.parameter is registered under the root : reset to the default value our self if (returnedContextNode == accessApplicationLocalDirectory->getRoot()) { TTBoolean initialized; x->wrappedObject.get("initialized", initialized); if (!initialized) x->wrappedObject.send(kTTSym_Init); } #endif #endif } else object_error((t_object*)x, "can't register because %s is not a relative address", relativeAddress->s_name); }
TTErr convertUpperCasedNameInAddress(TTSymbol upperCasedName, TTAddress& convertedInAddress) { TTUInt32 upperCasedNameSize = strlen(upperCasedName.c_str()); TTCString upperCasedNameCString = new char[upperCasedNameSize+1]; TTUInt32 nbUpperCase = 0; TTUInt32 i; TTCString convertedNameCString = NULL; TTUInt32 convertedNameSize = 0; strncpy(upperCasedNameCString, upperCasedName.c_str(), upperCasedNameSize+1); // "ExampleName" to "example/name" // "anyOtherExample" to "any/other/example" if ((upperCasedNameCString[0] > 64 && upperCasedNameCString[0] < 91) || (upperCasedNameCString[0] > 96 && upperCasedNameCString[0] < 123)) { // count how many upper-case letter there are in the TTName after the first letter for (i=1; i<upperCasedNameSize; i++) { if (upperCasedNameCString[i] > 64 && upperCasedNameCString[i] < 91) nbUpperCase++; } // prepare the convertedName convertedNameSize = upperCasedNameSize + nbUpperCase; convertedNameCString = new char[convertedNameSize+1]; // convert first letter to lower-case if needed if (upperCasedNameCString[0] > 64 && upperCasedNameCString[0] < 91) convertedNameCString[0] = upperCasedNameCString[0] + 32; else convertedNameCString[0] = upperCasedNameCString[0]; // copy each letter while checking upper-case letter to replace them by a / + lower-case letter nbUpperCase = 0; for (i=1; i<upperCasedNameSize; i++) { if (upperCasedNameCString[i] > 64 && upperCasedNameCString[i] < 91) { convertedNameCString[i + nbUpperCase] = '/'; convertedNameCString[i + nbUpperCase + 1] = upperCasedNameCString[i] + 32; nbUpperCase++; } else convertedNameCString[i + nbUpperCase] = upperCasedNameCString[i]; } // ends the CString with a NULL letter convertedNameCString[convertedNameSize] = 0; convertedInAddress = TTAddress(convertedNameCString); delete convertedNameCString; convertedNameCString = NULL; } else convertedInAddress = TTAddress(upperCasedName); delete upperCasedNameCString; upperCasedNameCString = NULL; return kTTErrNone; }
void out_subscribe(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTAddress signalAddress; TTAddress outputAddress; TTAddress inputAddress; TTValue v, args; TTNodePtr returnedNode = NULL; TTNodePtr returnedContextNode = NULL; TTAddress returnedAddress, parentAddress; TTString formatDescription, sInstance; t_object *modelOrView = NULL; #ifdef J_OUT_TILDE signalAddress = TTAddress("audio"); #endif #ifdef J_OUT_MULTI signalAddress = TTAddress("audio"); #endif #ifndef J_OUT_TILDE #ifndef J_OUT_MULTI signalAddress = TTAddress("data"); #endif #endif // edit "signal/out.instance" address outputAddress = signalAddress.appendAddress(TTAddress("out")).appendInstance(EXTRA->instance); // if the subscription is successful if (!jamoma_subscriber_create((t_eobj*)x, x->wrappedObject, outputAddress, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) { // get patcher x->patcherPtr = ((t_eobj*)x)->o_canvas; // update instance symbol in case of duplicate instance EXTRA->instance = returnedAddress.getInstance(); // observe /parent/in address in order to link/unlink with an Input object below returnedNode->getParent()->getAddress(parentAddress); inputAddress = parentAddress.appendAddress(TTAddress("in")).appendInstance(EXTRA->instance); x->wrappedObject.set("inputAddress", inputAddress); // get model or view object jamoma_patcher_get_model_or_view(x->patcherPtr, &modelOrView); // notify the model there is something new concerning signal processing if (modelOrView) object_method_typed(modelOrView, gensym("output_created"), 0, NULL, NULL); } }
void model_preset_amenities(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTAddress modelAdrs; TTValue v, a, args, none; TTAddress presetAddress; // get model:address EXTRA->modelInfo->get(kTTSym_address, v); modelAdrs = v[0]; // create the preset manager jamoma_presetManager_create((t_object*)x, *EXTRA->presetManager); // suscribe it under a preset node presetAddress = modelAdrs.appendAddress(TTAddress("preset")); args = TTValue(presetAddress, *EXTRA->presetManager, x->patcherPtr); if (!MaxApplication.send("ObjectRegister", args, none)) { EXTRA->presetManager->set(kTTSym_address, modelAdrs); defer_low(x, (method)model_preset_default, 0, 0, 0L); } }
void node_subscribe(TTPtr self, t_symbol* relativeAddress, long argc, t_atom* argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTAddress returnedAddress; TTNodePtr returnedNode = NULL; TTNodePtr returnedContextNode = NULL; // for relative address if (TTAddress(relativeAddress->s_name).getType() == kAddressRelative) { if(!jamoma_subscriber_create((t_eobj*)x, x->wrappedObject, TTAddress(relativeAddress->s_name), x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) pd_error((t_object*)x, "error when registering %s", relativeAddress->s_name); } else pd_error((t_object*)x, "can't register because %s is not a relative address", relativeAddress->s_name); }
// Create void *init_new(t_symbol *s, long argc, t_atom *argv) { long attrstart = attr_args_offset(argc, argv); // support normal arguments t_init *x = (t_init *)object_alloc(g_init_class); t_symbol *relativeAddress = _sym_nothing; // could be used to binds on a sub level j.hub if (attrstart && argv) atom_arg_getsym(&relativeAddress, 0, attrstart, argv); if (x) { x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 2); x->outlets[end_out] = bangout(x); x->outlets[start_out] = bangout(x); x->patcherNode = NULL; x->address = TTAddress(jamoma_parse_dieze((t_object*)x, relativeAddress)->s_name); attr_args_process(x, argc, argv); // handle attribute args // The following must be deferred because we have to interrogate our box, // and our box is not yet valid until we have finished instantiating the object. // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6) defer_low((t_object*)x, (method)init_subscribe, NULL, 0, 0); } return (x); // Return the pointer }
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; }
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; }
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; }
void WrappedMapperClass_new(TTPtr self, long argc, t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; t_symbol *relativeAddress; long attrstart = attr_args_offset(argc, argv); // support normal arguments // possible relativeAddress if (attrstart && argv) relativeAddress = atom_getsym(argv); else relativeAddress = _sym_nothing; if (relativeAddress) x->address = TTAddress(relativeAddress->s_name); jamoma_mapper_create((t_object*)x, x->wrappedObject); // Make two outlets x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr)); x->outlets[data_out] = outlet_new((t_object*)x, NULL); // anything outlet to output data x->dumpOut = outlet_new((t_object*)x, NULL); // handle attribute args attr_args_process(x, argc, argv); // Prepare extra data x->extra = (t_extra*)malloc(sizeof(t_extra)); EXTRA->arguments = new TTValue(); jamoma_ttvalue_from_Atom(*EXTRA->arguments, _sym_nothing, argc, argv); // The following must be deferred because we have to interrogate our box, // and our box is not yet valid until we have finished instantiating the object. // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6) // map_subscribe(x); // defer_low((t_object*)x, (method)map_subscribe, NULL, 0, 0); }
void data_address(TTPtr self, t_symbol *address) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; // Avoid succession of address changes if (!EXTRA->changingAddress) { EXTRA->changingAddress = YES; // filter repetitions if (!(x->arrayAddress == TTAddress(address->s_name))) { if (!x->iterateInternals) { // unregister internals wrappedModularClass_unregister(x); x->arraySize = 0; // rebuild internals defer(self,(method)data_new_address, address, 0, NULL); // for array mode : output the array once afterward if (x->arrayAttrFormat == gensym("array")) { TTValue array; t_symbol *msg; long argc = 0; t_atom *argv = NULL; TTBoolean shifted = NO; data_edit_array(self, array); jamoma_ttvalue_to_typed_Atom(array, &msg, &argc, &argv, shifted); // avoid blank before data if (msg == _sym_nothing) outlet_atoms(x->outlets[data_out], argc, argv); else outlet_anything(x->outlets[data_out], msg, argc, argv); if (shifted) argv--; sysmem_freeptr(argv); } } } EXTRA->changingAddress = NO; return; } object_error((t_object*)x, "can't change to %s address. Please defer low", address->s_name); }
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; }
void data_new_address(TTPtr self, t_symbol *relativeAddress) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; long argc = 0; t_atom *argv = NULL; TTUInt32 number; TTUInt32 i; TTAddress newAddress = relativeAddress->s_name; TTAddress returnedAddress; TTNodePtr returnedNode = NULL; TTNodePtr returnedContextNode = NULL; t_symbol *instanceAddress; TTObject anObject; TTObject aSubscriber; TTValue v; x->useInternals = YES; x->internals->clear(); x->internals->setThreadProtection(YES); x->cursor = kTTSymEmpty; x->arrayAddress = newAddress; if (x->arrayAddress.getType() == kAddressRelative) { number = jamoma_parse_bracket(relativeAddress, x->arrayFormatInteger, x->arrayFormatString); // don't resize to 0 if (number && number <= MAX_ARRAY_SIZE) { // Starts iteration on internals x->iterateInternals = YES; x->arraySize = number; EXTRA->objectsSorted->clear(); for (i = 1; i <= x->arraySize; i++) { jamoma_edit_numeric_instance(x->arrayFormatInteger, &instanceAddress, i); // create a data #ifdef JMOD_MESSAGE data_array_create(self, anObject, kTTSym_message, i); #endif #if JMOD_RETURN data_array_create(self, anObject, kTTSym_return, i); #endif #ifndef JMOD_MESSAGE #ifndef JMOD_RETURN data_array_create(self, anObject, kTTSym_parameter, i); #endif #endif if (!jamoma_subscriber_create((t_object*)x, anObject, TTAddress(instanceAddress->s_name), aSubscriber, returnedAddress, &returnedNode, &returnedContextNode)) { if (aSubscriber.valid()) { // append the data to the internals table v = TTValue(anObject); v.append(TTSymbol(instanceAddress->s_name)); v.append(aSubscriber); x->internals->append(TTSymbol(instanceAddress->s_name), v); // inverse objects order for iteration purpose (see in data_array_return_value : array mode) EXTRA->objectsSorted->insert(0, anObject); } } } // Ends iteration on internals x->iterateInternals = NO; // handle args jamoma_ttvalue_to_Atom(x->arrayArgs, &argc, &argv); if (argc && argv) attr_args_process(x, argc, argv); // select all datas wrappedModularClass_ArraySelect(self, gensym("*"), 0, NULL); #ifndef JMOD_MESSAGE // init all datas created dynamically if (!EXTRA->firstArray) defer((t_object*)x, (method)wrappedModularClass_anything, _sym_init, 0, NULL); #endif } else if (number > MAX_ARRAY_SIZE) object_error((t_object*)x, "the size is greater than the maximum array size (%d)", MAX_ARRAY_SIZE); EXTRA->firstArray = NO; } else object_error((t_object*)x, "can't register because %s is not a relative address", relativeAddress->s_name); }
// Create void* allpassmod_new(t_symbol* s, long argc, t_atom* argv) { t_allpassmod* x = (t_allpassmod*)object_alloc(s_allpassmod_class); long attrstart = attr_args_offset(argc, argv); // support normal arguments TTString name = "/"; TTPtr context = TTPtr(x); TTValue none; object_obex_lookup(x, gensym("#P"), (t_object**)&context); if (attrstart) { if (atom_getsym(argv)->s_name[0] == '/') name += atom_getsym(argv)->s_name + 1; else name += atom_getsym(argv)->s_name; } else name += s->s_name; x->name = TTAddress(name); // need to cache so we can free // 1. Create the DSP objects x->allpass = TTAudioObject("allpass.1", 2); x->signalOut = TTObject(kTTSym_audiosignal, 2); x->signalIn = TTObject(kTTSym_audiosignal, 2); // 2. Create the "model" container { TTValue container_args; // TODO: (optional) pass address callback and value callback (these are both for the activity return mechanism) x->model = TTObject(kTTSym_Container, container_args); x->model.set(kTTSym_tags, kTTSym_model); TTValue registration_args(x->name, x->model, context); MaxApplication.send("ObjectRegister", registration_args, none); x->model.set("address", x->name); } // 3. Create the "clear" message { x->message_clear = TTObject(kTTSym_Data, kTTSym_message); x->message_clear.set(kTTSym_baton, TTPtr(x)); x->message_clear.set(kTTSym_function, TTPtr(allpassmod_parameter_clear_callback)); x->message_clear.set(kTTSym_type, kTTSym_none); x->message_clear.set(kTTSym_description, TTSymbol("Clear the filter history")); TTAddress address = x->name.appendAddress("/clear"); TTValue registration_args(address, x->message_clear, context); MaxApplication.send("ObjectRegister", registration_args, none); } // 4. Create the "gain" parameter (linear) { x->parameter_coefficient = TTObject(kTTSym_Data, kTTSym_parameter); x->parameter_coefficient.set(kTTSym_baton, TTPtr(x)); x->parameter_coefficient.set(kTTSym_function, TTPtr(allpassmod_parameter_coefficient_callback)); x->parameter_coefficient.set(kTTSym_type, kTTSym_decimal); x->parameter_coefficient.set(kTTSym_valueDefault, 0.7); x->parameter_coefficient.set(kTTSym_description, TTSymbol("Gain coefficient")); TTAddress address = x->name.appendAddress("/coefficient"); TTValue registration_args(address, x->parameter_coefficient, context); MaxApplication.send("ObjectRegister", registration_args, none); } // 5. Create the "delay" parameter (milliseconds) { x->parameter_delay = TTObject(kTTSym_Data, kTTSym_parameter); x->parameter_delay.set(kTTSym_baton, TTPtr(x)); x->parameter_delay.set(kTTSym_function, TTPtr(allpassmod_parameter_delay_callback)); x->parameter_delay.set(kTTSym_type, kTTSym_decimal); x->parameter_delay.set(kTTSym_valueDefault, 0.2); x->parameter_delay.set(kTTSym_description, TTSymbol("Delay time")); TTAddress address = x->name.appendAddress("/delay"); TTValue registration_args(address, x->parameter_delay, context); MaxApplication.send("ObjectRegister", registration_args, none); } // 6. Create the Input access points { // left input { x->in_left = TTObject("Input.audio"); TTAddress address = x->name.appendAddress("/in.left"); TTValue registration_args(address, x->in_left, context); MaxApplication.send("ObjectRegister", registration_args, none); } // right input { x->in_right = TTObject("Input.audio"); TTAddress address = x->name.appendAddress("/in.right"); TTValue registration_args(address, x->in_right, context); MaxApplication.send("ObjectRegister", registration_args, none); } } // 7. Create the Output access points { // left output { x->out_left = TTObject("Output.audio"); TTAddress address = x->name.appendAddress("/out.left"); TTValue registration_args(address, x->out_left, context); MaxApplication.send("ObjectRegister", registration_args, none); } // right output { x->out_right = TTObject("Output.audio"); TTAddress address = x->name.appendAddress("/out.right"); TTValue registration_args(address, x->out_right, context); MaxApplication.send("ObjectRegister", registration_args, none); } } // 8. Add the preset functions { x->preset = TTObject(kTTSym_PresetManager); x->preset.set("address", x->name); TTAddress address = x->name.appendAddress("/preset"); TTValue registration_args(address, x->preset, context); MaxApplication.send("ObjectRegister", registration_args, none); // load a preset file and recall the first preset { TTValue out; TTObject xmlHandler("XmlHandler"); // set the object attr of the above object to be the PresetManager xmlHandler.set("object", x->preset); // TODO : get the filepath as an argument TTSymbol path; xmlHandler.send("Read", path, out); // recall the first preset x->preset.send("Recall", 1, none); } } // 9. Initialize the module (set default values, etc) x->model.send("Init"); // 10. Do some final Max-specific stuff dsp_setup((t_pxobject*)x, 2); x->obj.z_misc = Z_NO_INPLACE; for (int i=0; i < 2; i++) outlet_new((t_pxobject*)x, "signal"); attr_args_process(x, argc, argv); return x; }
void in_subscribe(TTPtr self) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; TTAddress inputAddress; TTAddress outputAddress; TTValue v, args; TTNodePtr returnedNode = NULL; TTNodePtr returnedContextNode = NULL; TTAddress returnedAddress, parentAddress; TTDataPtr aData; TTString formatDescription, sInstance; SymbolPtr inDescription; inputAddress = TTAddress("in").appendInstance(EXTRA->instance); // if the subscription is successful if (!jamoma_subscriber_create((ObjectPtr)x, x->wrappedObject, inputAddress, &x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) { // get patcher x->patcherPtr = jamoma_patcher_get((ObjectPtr)x); // update instance symbol in case of duplicate instance EXTRA->instance = returnedAddress.getInstance(); // observe /parent/out address in order to link/unlink with an Input object below returnedNode->getParent()->getAddress(parentAddress); outputAddress = parentAddress.appendAddress(TTAddress("out")).appendInstance(EXTRA->instance); x->wrappedObject->setAttributeValue(TTSymbol("outputAddress"), outputAddress); #ifdef JCOM_IN_TILDE // make internal data to return amplitude v = TTValue(0., 1.); formatDescription = "instant amplitude of %s input"; sInstance = EXTRA->instance.c_str(); jamoma_edit_string_instance(formatDescription, &inDescription, sInstance); makeInternals_data(x, returnedAddress, TTSymbol("amplitude"), NULL, x->patcherPtr, kTTSym_return, (TTObjectBasePtr*)&aData); aData->setAttributeValue(kTTSym_type, kTTSym_decimal); aData->setAttributeValue(kTTSym_tag, kTTSym_generic); aData->setAttributeValue(kTTSym_rangeBounds, v); aData->setAttributeValue(kTTSym_description, TTSymbol(inDescription->s_name)); aData->setAttributeValue(kTTSym_dataspace, TTSymbol("gain")); aData->setAttributeValue(kTTSym_dataspaceUnit, TTSymbol("linear")); // make internal data to parameter in/amplitude/active makeInternals_data(x, returnedAddress, TTSymbol("amplitude/active"), gensym("return_amplitude_active"), x->patcherPtr, kTTSym_parameter, (TTObjectBasePtr*)&aData); aData->setAttributeValue(kTTSym_type, kTTSym_integer); aData->setAttributeValue(kTTSym_tag, kTTSym_generic); v = TTValue((int)EXTRA->pollInterval); aData->setAttributeValue(kTTSym_valueDefault, v); v = TTValue(0, 1000); aData->setAttributeValue(kTTSym_rangeBounds, v); aData->setAttributeValue(kTTSym_rangeClipmode, kTTSym_low); aData->setAttributeValue(kTTSym_description, TTSymbol("set the sample rate of the amplitude follower")); // launch the clock to update amplitude regulary EXTRA->clock = clock_new(x, (method)in_update_amplitude); if (EXTRA->pollInterval) clock_delay(EXTRA->clock, EXTRA->pollInterval); #endif // expose bypass and mute attributes of TTInput as TTData in the tree structure x->subscriberObject->exposeAttribute(x->wrappedObject, kTTSym_bypass, kTTSym_parameter, &aData); aData->setAttributeValue(kTTSym_type, kTTSym_boolean); aData->setAttributeValue(kTTSym_tag, kTTSym_generic); aData->setAttributeValue(kTTSym_description, TTSymbol("When active, this attribute bypasses the model's processing algtorithm, letting incoming signal pass through unaffected")); v = TTValue(0); aData->setAttributeValue(kTTSym_valueDefault, v); x->subscriberObject->exposeAttribute(x->wrappedObject, kTTSym_mute, kTTSym_parameter, &aData); aData->setAttributeValue(kTTSym_type, kTTSym_boolean); aData->setAttributeValue(kTTSym_tag, kTTSym_generic); aData->setAttributeValue(kTTSym_description, TTSymbol("When active, this attribute turns off model's inputs.")); v = TTValue(0); aData->setAttributeValue(kTTSym_valueDefault, v); } }
void TTNodeLibTestMiscellaneous(int& errorCount, int& testAssertionCount) { TTTestLog("\n"); TTTestLog("Miscellaneous Tests"); // test convertUpperCasedName global method TTSymbol testSymbolA = "TestSymbolName"; TTSymbol testSymbolB = "testSymbolName"; TTSymbol testSymbolC = "testsymbolname"; TTAddress result; convertUpperCasedNameInAddress(testSymbolA, result); TTTestAssertion("convertUpperCasedName: Test passes if \"TestSymbolName\" is converted in \"test/symbol/name\"", result == TTAddress("test/symbol/name"), testAssertionCount, errorCount); convertUpperCasedNameInAddress(testSymbolB, result); TTTestAssertion("convertUpperCasedName: Test passes if \"testSymbolName\" is converted in \"test/symbol/name\"", result == TTAddress("test/symbol/name"), testAssertionCount, errorCount); convertUpperCasedNameInAddress(testSymbolC, result); TTTestAssertion("convertUpperCasedName: Test passes if \"testsymbolname\" is not converted", result == testSymbolC, testAssertionCount, errorCount); // test TTSymbol to TTAdress casting TTValue testValue = TTValue(TTSymbol("directory:/gran/parent/name.instance:attribute")); TTAddress testAddress; testAddress = testValue[0]; TTSymbol directory = testAddress.getDirectory(); TTAddress parent = testAddress.getParent(); TTSymbol name = testAddress.getName(); TTSymbol instance = testAddress.getInstance(); TTSymbol attribute = testAddress.getAttribute(); TTAddressType type = testAddress.getType(); TTBoolean t1 = directory == TTSymbol("directory"); TTBoolean t2 = parent == TTAddress("/gran/parent"); TTBoolean t3 = name == TTSymbol("name"); TTBoolean t4 = instance == TTSymbol("instance"); TTBoolean t5 = attribute == TTSymbol("attribute"); TTBoolean t6 = type == kAddressAbsolute; TTTestAssertion("TTValue::get : Test2 fails if a TTSymbol contained into a value is not casted into a TTAddress during a get method", directory == TTSymbol("directory") && parent == TTAddress("/gran/parent") && name == TTSymbol("name") && instance == TTSymbol("instance") && attribute == TTSymbol("attribute") && type == kAddressAbsolute, testAssertionCount, errorCount); // test TTSymbol for TTHash access when a key is stored using a TTAddress TTHash testTable; TTAddress keyAddress = TTAddress("testKeyAddress"); TTValue keyValue; TTErr err; testTable.append(keyAddress, keyValue); // store a value into the table using "testKeyAddress" address testValue = TTValue(TTSymbol("testKeyAddress")); // store a "testKeyAddress" symbol into a value testAddress = testValue[0]; // get it as an address err = testTable.lookup(testAddress, keyValue); // use the address to lookup the table TTTestAssertion("TTHash::lookup : Test fails if a TTSymbol cannot be used as storage key for TTHash table when the lookup key is a TTAddress", err == kTTErrNone, testAssertionCount, errorCount); // The test below fails but it have been added only to check the opposite operation. // For instant we don't need this test to pass so it is commented out until we need this feature. /* test TTAddress for TTHash access when a key is stored using a TTSymbol TTSymbol keySymbol = TTSymbol("testKeySymbol"); TTSymbol testSymbol; testTable.append(keySymbol, keyValue); // store a value into the table using "testKeySymbol" symbol testValue = TTValue(TTAddress("testKeySymbol")); // store a "testKeySymbol" address into a value testSymbol = testValue[0]; // get it as an symbol err = testTable.lookup(testSymbol, keyValue); // use the symbol to lookup the table TTTestAssertion("TTHash::lookup : Test fails if a TTAddress cannot be used as storage key for TTHash table when the lookup key is a TTSymbol", err == kTTErrNone, testAssertionCount, errorCount); */ }
void TTNodeLibTestAddressItem(int& errorCount, int& testAssertionCount) { TTAddressItemPtr aNamespace, aParent, n, f; TTSymbol aSymbol(kTTSymEmpty); TTBoolean aSelection, empty; TTUInt8 size; TTErr err; TTTestLog("\n"); TTTestLog("Testing Address Item management"); // The first test checks item creation and member access aNamespace = new TTAddressItem(kTTSymEmpty); aSymbol = aNamespace->getSymbol(); aParent = aNamespace->getParent(); aSelection = aNamespace->getSelection(); empty = aNamespace->isEmpty(); TTTestAssertion("TTAddressItem: Test fails if the namespace is not empty", empty && aSymbol == NO_NAME && aParent == NULL && aSelection == NO, testAssertionCount, errorCount); // The second set of tests checks item management n = new TTAddressItem(TTSymbol("test")); aNamespace->merge(n); TTTestAssertion("TTAddressItem: Test fails if the namespace size is not equal 1", aNamespace->getSize() == 1, testAssertionCount, errorCount); f = aNamespace->getItem(n->getSymbol()); if (f) { aSymbol = f->getSymbol(); aParent = f->getParent(); aSelection = f->getSelection(); empty = f->isEmpty(); } TTTestAssertion("TTAddressItem: Test fails if the namespace is not named \"test\" or have no parent", empty && aSymbol == TTSymbol("test") && aParent == aNamespace && aSelection == NO, testAssertionCount, errorCount); aNamespace->destroy(n); TTTestAssertion("TTAddressItem: Test fails if the namespace is not empty", aNamespace->isEmpty(), testAssertionCount, errorCount); // The third set of tests checks item management using TTAddress aNamespace->clear(); aNamespace->append(TTAddress("/parent/name"), &f); aNamespace->append(TTAddress("/parent/name.instance"), &f); aSymbol = aNamespace->getSymbol(); size = aNamespace->getSize(); TTTestAssertion("TTAddressItem: Test fails if the namespace is not named \"\" and size is not equal 1", size == 1 && aSymbol == kTTSymEmpty, testAssertionCount, errorCount); f = NULL; err = aNamespace->find(TTAddress("/parent"), &f); if (!err) { aSymbol = f->getSymbol(); aParent = f->getParent(); aSelection = f->getSelection(); empty = f->isEmpty(); } TTTestAssertion("TTAddressItem: Test fails if the namespace is not named \"\" or have no parent or no child", !empty && aSymbol == kTTSymEmpty && aParent == aNamespace->getItem(TTSymbol("parent")) && aSelection == NO, testAssertionCount, errorCount); n = f; f = NULL; err = aNamespace->find(TTAddress("/parent/name"), &f); if (!err) { aSymbol = f->getSymbol(); aParent = f->getParent(); aSelection = f->getSelection(); empty = f->isEmpty(); } TTTestAssertion("TTAddressItem: Test fails if the namespace is not named \"\" or have no parent or is not empty", empty && aSymbol == kTTSymEmpty && aParent == n->getItem(TTSymbol("name")) && aSelection == NO, testAssertionCount, errorCount); n = f; f = NULL; err = aNamespace->find(TTAddress("/parent/name.instance"), &f); if (!err) { aSymbol = f->getSymbol(); aParent = f->getParent(); aSelection = f->getSelection(); empty = f->isEmpty(); } TTTestAssertion("TTAddressItem: Test fails if the namespace is not named \"instance\" or have no parent or is not empty", empty && aSymbol == TTSymbol("instance") && aParent == n->getParent() && aSelection == NO, testAssertionCount, errorCount); f = NULL; aNamespace->append(TTAddress("/parent/name.other"), &f); size = f->getParent()->getSize(); // have to be 3 because there are the empty, "instance" and "other" instances TTTestAssertion("TTAddressItem: Test fails if size is not equal to 3", size == 3, testAssertionCount, errorCount); }
void TTNodeLibTestAddressParsing(int& errorCount, int& testAssertionCount) { TTTestLog("\n"); TTTestLog("Testing Address Parsing"); TTAddress testAddress1("directory1:/gran/parent1/name1.instance1:attribute1"); TTSymbol directory1 = testAddress1.getDirectory(); TTAddress parent1 = testAddress1.getParent(); TTSymbol name1 = testAddress1.getName(); TTSymbol instance1 = testAddress1.getInstance(); TTSymbol attribute1 = testAddress1.getAttribute(); TTAddressType type1 = testAddress1.getType(); TTAddress testAddress2("/gran/parent2/name2.instance2"); TTSymbol directory2 = testAddress2.getDirectory(); TTAddress parent2 = testAddress2.getParent(); TTSymbol name2 = testAddress2.getName(); TTSymbol instance2 = testAddress2.getInstance(); TTSymbol attribute2 = testAddress2.getAttribute(); TTAddressType type2 = testAddress2.getType(); TTAddress testAddress3("parent3/name3.instance3"); TTSymbol directory3 = testAddress3.getDirectory(); TTAddress parent3 = testAddress3.getParent(); TTSymbol name3 = testAddress3.getName(); TTSymbol instance3 = testAddress3.getInstance(); TTSymbol attribute3 = testAddress3.getAttribute(); TTAddressType type3 = testAddress3.getType(); TTAddress testAddress4("/"); TTSymbol directory4 = testAddress4.getDirectory(); TTAddress parent4 = testAddress4.getParent(); TTSymbol name4 = testAddress4.getName(); TTSymbol instance4 = testAddress4.getInstance(); TTSymbol attribute4 = testAddress4.getAttribute(); TTAddressType type4 = testAddress4.getType(); TTAddress testAddress5(":attribute5"); TTSymbol directory5 = testAddress5.getDirectory(); TTAddress parent5 = testAddress5.getParent(); TTSymbol name5 = testAddress5.getName(); TTSymbol instance5 = testAddress5.getInstance(); TTSymbol attribute5 = testAddress5.getAttribute(); TTAddressType type5 = testAddress5.getType(); TTAddress testAddress6("/gran/parent6.0/name6.0:attribute6"); TTSymbol directory6 = testAddress6.getDirectory(); TTAddress parent6 = testAddress6.getParent(); TTSymbol name6 = testAddress6.getName(); TTSymbol instance6 = testAddress6.getInstance(); TTSymbol attribute6 = testAddress6.getAttribute(); TTAddressType type6 = testAddress6.getType(); TTAddress testAddress7("/*.*"); TTSymbol directory7 = testAddress7.getDirectory(); TTAddress parent7 = testAddress7.getParent(); TTSymbol name7 = testAddress7.getName(); TTSymbol instance7 = testAddress7.getInstance(); TTSymbol attribute7 = testAddress7.getAttribute(); TTAddressType type7 = testAddress7.getType(); // The first set of tests checks parsing of addresses TTTestAssertion("TTAddress: Test fails if parsing of testAddress1 is bad", directory1 == TTSymbol("directory1") && parent1 == TTAddress("/gran/parent1") && name1 == TTSymbol("name1") && instance1 == TTSymbol("instance1") && attribute1 == TTSymbol("attribute1") && type1 == kAddressAbsolute, testAssertionCount, errorCount); TTTestAssertion("TTAddress: Test fails if parsing of testAddress2 is bad", directory2 == NO_DIRECTORY && parent2 == TTAddress("/gran/parent2") && name2 == TTSymbol("name2") && instance2 == TTSymbol("instance2") && attribute2 == NO_ATTRIBUTE && type2 == kAddressAbsolute, testAssertionCount, errorCount); TTTestAssertion("TTAddress: Test fails if parsing of testAddress3 is bad", directory3 == NO_DIRECTORY && parent3 == TTAddress("parent3") && name3 == TTSymbol("name3") && instance3 == TTSymbol("instance3") && attribute3 == NO_ATTRIBUTE && type3 == kAddressRelative, testAssertionCount, errorCount); TTTestAssertion("TTAddress: Test fails if parsing of testAddress4 is bad", directory4 == NO_DIRECTORY && parent4 == NO_PARENT && name4 == S_SEPARATOR && instance4 == NO_INSTANCE && attribute4 == NO_ATTRIBUTE && type4 == kAddressAbsolute, testAssertionCount, errorCount); TTTestAssertion("TTAddress: Test fails if parsing of testAddress5 is bad", directory5 == NO_DIRECTORY && parent5 == NO_PARENT && name5 == NO_NAME && instance5 == NO_INSTANCE && attribute5 == TTSymbol("attribute5") && type5 == kAddressRelative, testAssertionCount, errorCount); TTTestAssertion("TTAddress: Test fails if parsing of testAddress6 is bad", directory6 == NO_DIRECTORY && parent6 == TTAddress("/gran/parent6") && name6 == TTSymbol("name6") && instance6 == NO_INSTANCE && attribute6 == TTSymbol("attribute6") && type6 == kAddressAbsolute, testAssertionCount, errorCount); TTTestAssertion("TTAddress: Test fails if parsing of testAddress7 is bad", directory7 == NO_DIRECTORY && parent7 == kTTAdrsRoot && name7 == S_WILDCARD && instance7 == S_WILDCARD && attribute7 == NO_ATTRIBUTE && type7 == kAddressAbsolute, testAssertionCount, errorCount); }
void TTNodeLibTestAddressMethods(int& errorCount, int& testAssertionCount) { TTAddress testAddressA("directory:/gran/parent/name.instance:attribute"); TTAddress testAddressB("/parent/name"); TTAddress testAddressC("name"); TTAddress testAddressD("/gran/parent"); TTAddress testAddressE("directory:/gran/parent"); TTAddress testAddressF("name.instance:attribute"); TTAddress testAddressG("/name.instance:attribute"); TTSymbol testSymbolA(""); TTSymbol resultSymbol; TTAddress resultAddress; TTAddress part1, part2; // the first set of tests checks the getNameInstance method TTTestLog("\n"); TTTestLog("Testing Address getNameInstance Method"); resultSymbol = testAddressA.getNameInstance(); TTTestAssertion("TTAddress: Test passes if the getNameInstance() method returns \"name.instance\"", resultSymbol == TTSymbol("name.instance"), testAssertionCount, errorCount); resultSymbol = testAddressB.getNameInstance(); TTTestAssertion("TTAddress: Test passes if the getNameInstance() method returns \"name\"", resultSymbol == TTSymbol("name"), testAssertionCount, errorCount); resultSymbol = testAddressC.getNameInstance(); TTTestAssertion("TTAddress: Test passes if the getNameInstance() method returns \"name\"", resultSymbol == TTSymbol("name"), testAssertionCount, errorCount); resultSymbol = kTTAdrsEmpty.getNameInstance(); TTTestAssertion("TTAddress: Test passes if the getNameInstance() method returns kTTSymEmpty", resultSymbol == kTTSymEmpty, testAssertionCount, errorCount); // the second set of tests checks the appendAddress method TTTestLog("\n"); TTTestLog("Testing Address appendAddress Method"); resultAddress = testAddressD.appendAddress(kTTAdrsEmpty); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns the same address", resultAddress == testAddressD, testAssertionCount, errorCount); resultAddress = kTTAdrsEmpty.appendAddress(testAddressD); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns the same address", resultAddress == testAddressD, testAssertionCount, errorCount); resultAddress = kTTAdrsRoot.appendAddress(testAddressD); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns the same address", resultAddress == testAddressD, testAssertionCount, errorCount); resultAddress = kTTAdrsEmpty.appendAddress(testAddressE); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns the same address", resultAddress == testAddressE, testAssertionCount, errorCount); resultAddress = kTTAdrsRoot.appendAddress(testAddressE); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns the same address", resultAddress == testAddressE, testAssertionCount, errorCount); resultAddress = testAddressD.appendAddress(testAddressF); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns \"/gran/parent/name.instance:attribute\"", resultAddress == TTAddress("/gran/parent/name.instance:attribute"), testAssertionCount, errorCount); resultAddress = testAddressD.appendAddress(testAddressG); TTTestAssertion("TTAddress: Test passes if the appendAddress() method returns \"/gran/parent/name.instance:attribute\"", resultAddress == TTAddress("/gran/parent/name.instance:attribute"), testAssertionCount, errorCount); // This test checks appendInstance() and appendAttribute() methods resultAddress = kTTAdrsRoot.appendAddress(TTAddress("name")).appendInstance(TTAddress("instance")).appendAttribute(TTAddress("attribute")); TTTestAssertion("TTAddress: Test passes if appendAddress + appendInstance + appendAttribute methods returns \"/name.instance:attribute\"", resultAddress == TTAddress("/name.instance:attribute"), testAssertionCount, errorCount); // the third set of tests checks the splitAt method TTTestLog("\n"); TTTestLog("Testing Address splitAt Method"); testAddressA.splitAt(0, part1, part2); TTTestAssertion("TTAddress: Test passes if splitAt method returns \"directory:/\" and \"gran/parent/name.instance:attribute\"", part1 == TTAddress("directory:/") && part2 == TTAddress("gran/parent/name.instance:attribute"), testAssertionCount, errorCount); testAddressA.splitAt(1, part1, part2); TTTestAssertion("TTAddress: Test passes if splitAt method returns \"directory:/gran\" and \"parent/name.instance:attribute\"", part1 == TTAddress("directory:/gran") && part2 == TTAddress("parent/name.instance:attribute"), testAssertionCount, errorCount); testAddressA.splitAt(2, part1, part2); TTTestAssertion("TTAddress: Test passes if splitAt method returns \"directory:/gran/parent\" and \"name.instance:attribute\"", part1 == TTAddress("directory:/gran/parent") && part2 == TTAddress("name.instance:attribute"), testAssertionCount, errorCount); // the fourth set of tests checks the countSeparator method TTTestLog("\n"); TTTestLog("Testing Address countSeparator Method"); /* // the fift set of tests checks the listNameInstance method TTTestLog("\n"); TTTestLog("Testing Address listNameInstance Method"); */ }