UnpackPtr UnpackNew(SymbolPtr msg, AtomCount argc, AtomPtr argv) { UnpackPtr self; TTValue v; TTErr err; self = UnpackPtr(object_alloc(sUnpackClass)); if (self) { object_obex_store((void*)self, _sym_dumpout, (ObjectPtr)outlet_new(self, NULL)); // dumpout self->graphOutlets[0] = outlet_new(self, NULL); v.setSize(2); v.set(0, TT("graph.output")); v.set(1, TTUInt32(1)); err = TTObjectInstantiate(TT("graph.object"), (TTObjectPtr*)&self->graphObject, v); if (!self->graphObject->mKernel) { object_error(SELF, "cannot load Jamoma object"); return NULL; } err = TTObjectInstantiate(TT("Callback"), (TTObjectPtr*)&self->callback, kTTValNONE); self->callback->setAttributeValue(TT("Function"), TTPtr(&UnpackGraphCallback)); self->callback->setAttributeValue(TT("Baton"), TTPtr(self)); // dynamically add a message to the callback object so that it can handle the 'dictionaryReceived' notification self->callback->registerMessage(TT("dictionaryReceived"), (TTMethod)&TTCallback::notify, kTTMessagePassValue); // tell the graph object that we want to watch it self->graphObject->mKernel->registerObserverForNotifications(*self->callback); attr_args_process(self, argc, argv); } return self; }
JamomaError RampLib::createUnit(const TTSymbol* unitName, RampUnit **unit, RampUnitCallback callback, void* baton) { TTValue v; v.setSize(2); v.set(0, TTPtr(callback)); v.set(1, TTPtr(baton)); // These should be alphabetized if (unitName == TT("async")) TTObjectInstantiate(TT("AsyncRamp"), (TTObjectPtr*)unit, v); //*unit = (RampUnit*) new AsyncRamp(callback, baton); else if (unitName == TT("none")) TTObjectInstantiate(TT("NoneRamp"), (TTObjectPtr*)unit, v); // *unit = (RampUnit*) new NoneRamp(callback, baton); else if (unitName == TT("queue")) TTObjectInstantiate(TT("QueueRamp"), (TTObjectPtr*)unit, v); // *unit = (RampUnit*) new QueueRamp(callback, baton); else if (unitName == TT("scheduler")) TTObjectInstantiate(TT("SchedulerRamp"), (TTObjectPtr*)unit, v); // *unit = (RampUnit*) new SchedulerRamp(callback, baton); else { // Invalid function specified default to linear error("Jamoma RampLib: Invalid RampUnit ( %s ) specified", (char*)unitName); TTObjectInstantiate(TT("NoneRamp"), (TTObjectPtr*)unit, v); // *unit = (RampUnit*) new NoneRamp(callback, baton); } return JAMOMA_ERR_NONE; }
void* balance_new(t_symbol *msg, short argc, t_atom *argv) { t_balance *x; TTValue sr(sys_getsr()); long attrstart = attr_args_offset(argc, argv); // support normal arguments short i; x = (t_balance *)object_alloc(balance_class); if(x){ // Default values x->attrFrequency = 10; x->attrBypass = 0; // An initial argument to this object will set the maximum number of channels to process // Two input channels are required for each processed channel (source and comperator) x->maxNumChannels = 1; if(attrstart && argv) x->maxNumChannels = atom_getlong(argv); ttEnvironment->setAttributeValue(kTTSym_SampleRate, sr); TTObjectInstantiate(TT("balance"), &x->balance, x->maxNumChannels); TTObjectInstantiate(TT("audiosignal"), &x->audioIn, x->maxNumChannels*2); TTObjectInstantiate(TT("audiosignal"), &x->audioOut, x->maxNumChannels); attr_args_process(x,argc,argv); // handle attribute args object_obex_store((void *)x, _sym_dumpout, (object *)outlet_new(x,NULL)); // dumpout dsp_setup((t_pxobject *)x, x->maxNumChannels*2); // inlets for(i=0; i < x->maxNumChannels; i++) outlet_new((t_pxobject *)x, "signal"); // outlets x->obj.z_misc = Z_NO_INPLACE; } return (x); // Return the pointer }
NSPStatus Namespace::namespacePresetsLoadFromXml(std::string filepath) { TTValue args, v, attr; // TTPresetManagerPtr returnedPresetManager = NULL; TTXmlHandlerPtr aXmlHandler = NULL; TTHashPtr toStore = new TTHash(); TTObjectPtr testObjectCallback; // TTValuePtr testObjectBaton; // Instanciate a PresetManager args.append(GalamusApplication); // add application arg testObjectCallback = NULL; // without this, TTObjectInstantiate try to release an oldObject that doesn't exist ... Is it good ? TTObjectInstantiate(TTSymbol("callback"), &testObjectCallback, kTTValNONE); // testObjectBaton = new TTValue(TTPtr(x)); // testObjectCallback->setAttributeValue(kTTSym_baton, TTPtr(testObjectBaton)); // testObjectCallback->setAttributeValue(kTTSym_function, TTPtr(&jamoma_presetManager_test_object_callback)); args.append(testObjectCallback); // add callback method arg (we don't need here) // Here we decide to store only Value and Priority attributes for Data object attr = TTValue(kTTSym_value); attr.append(kTTSym_priority); //toStore->append(TTSymbol("Data"), attr); args.append((TTPtr)toStore); // add storing hash table arg m_presetManager = NULL; TTObjectInstantiate(TTSymbol("PresetManager"), TTObjectHandle(&m_presetManager), args); // Instanciate a XmlHandler args.clear(); TTObjectInstantiate(TTSymbol("XmlHandler"), TTObjectHandle(&aXmlHandler), args); // Set XmlHandler being used by PresetManager v = TTValue(TTPtr(m_presetManager)); aXmlHandler->setAttributeValue(kTTSym_object, v); aXmlHandler->setAttributeValue(TTSymbol("headerNodeName"), TT(XML_PRESET_HEADER_NODE_NAME)); aXmlHandler->setAttributeValue(TTSymbol("version"), TT(XML_PRESET_VERSION)); aXmlHandler->setAttributeValue(TTSymbol("xmlSchemaLocation"), TT(XML_PRESET_SCHEMA_LOCATION)); v.clear(); v.append(TT(filepath)); aXmlHandler->sendMessage(TTSymbol("Read"), v);//TODO : return an error code if fail // TTValue tmp; // m_presetManager->getAttributeValue(TTSymbol("names"), tmp); // // for (int i = 0; i < tmp.getSize(); i++) { // TTString s; // tmp.toString(); // tmp.get(i, s); // // std::cout << s << std::endl; // } return NSP_NO_ERROR; }
NSPStatus Namespace::namespaceParameterCreate(std::string address, int instanceNumber, void* object, void (*returnValueCallback) (TTPtr, TTValue&) , void (*returnAddressCallback)(TTPtr, TTValue&)) { // Create a TTData TTDataPtr data = NULL; TTCallbackPtr p_returnValueCallback, p_returnAddressCallback; TTValuePtr p_returnValueBaton, p_returnAddressBaton; // prepare arguments : see TTData.h to know which args are needed TTValue args; args.clear(); p_returnValueCallback = NULL; TTObjectInstantiate(TTSymbol("callback"), TTObjectHandle(&p_returnValueCallback), kTTValNONE); p_returnValueBaton = new TTValue(TTPtr(object)); p_returnValueCallback->setAttributeValue(kTTSym_baton, TTPtr(p_returnValueBaton)); p_returnValueCallback->setAttributeValue(kTTSym_function, TTPtr(returnValueCallback)); args.append(p_returnValueCallback); p_returnAddressCallback = NULL; TTObjectInstantiate(TTSymbol("callback"), TTObjectHandle(&p_returnAddressCallback), kTTValNONE); p_returnAddressBaton = new TTValue(TTPtr(object)); p_returnAddressCallback->setAttributeValue(kTTSym_baton, TTPtr(p_returnAddressBaton)); p_returnAddressCallback->setAttributeValue(kTTSym_function, TTPtr(p_returnAddressCallback)); args.append(p_returnAddressCallback); // Register a TTObject into the NSPDirectory TTNodePtr returnedNode; TTBoolean newInstanceCreated; for (int i = 0; i < instanceNumber; i++) { data = NULL; returnedNode = NULL; newInstanceCreated = NULL; // create an instance of TTData TTObjectInstantiate(TTSymbol("Data"), TTObjectHandle(&data), args); std::string absAddress = AppName + address; // add instance number if (i != 0) { absAddress += "."; stringstream st; st << i; absAddress += st.str(); } // add the parameter data in the namespace directory NSPDirectory->TTNodeCreate(TT(absAddress), (TTObjectPtr)data, NULL, &returnedNode, &newInstanceCreated); // note : our myRegistrationObserver is informed if declared } return NSP_NO_ERROR; }
NSPStatus Namespace::namespaceMappingLoadFromXml(std::string filepath) { // Parse xml file to instantiate TTData for each input XMLNode xMainNode; XMLError err = XMLNode::openFileHelper(&xMainNode, filepath.c_str(), XML_MAPPING_HEADER_NODE_NAME); if (err == eXMLErrorFileNotFound) return NSP_FILE_NOTFOUND; if (err == eXMLErrorFirstTagNotFound) return NSP_XMLPARSING_ERROR; int nChild = xMainNode.nChildNode(); // For each child of the node create a mapping parameter according to the input attribute for (int i = 0; i < nChild; i++) { XMLNode child = xMainNode.getChildNode(i); namespaceParameterCreate(child.getAttribute("input"), NULL); } // Instanciate a MapperManager TTValue args, v; TTMapperManagerPtr returnedMapperManager = NULL; TTXmlHandlerPtr aXmlHandler = NULL; args.append(GalamusApplication); TTObjectInstantiate(TTSymbol("MapperManager"), TTObjectHandle(&returnedMapperManager), args); // Instanciate a XmlHandler args.clear(); TTObjectInstantiate(TTSymbol("XmlHandler"), TTObjectHandle(&aXmlHandler), args); // Set XmlHandler being used by MapperManager v = TTValue(TTPtr(returnedMapperManager)); aXmlHandler->setAttributeValue(kTTSym_object, v); aXmlHandler->setAttributeValue(TTSymbol("headerNodeName"), TT(XML_MAPPING_HEADER_NODE_NAME)); aXmlHandler->setAttributeValue(TTSymbol("version"), TT(XML_MAPPING_VERSION)); aXmlHandler->setAttributeValue(TTSymbol("xmlSchemaLocation"), TT(XML_MAPPING_SCHEMA_LOCATION)); v.clear(); v.append(TT(filepath)); aXmlHandler->sendMessage(TTSymbol("Read"), v);//TODO : return an error code if fail // v.clear(); // v.append(TTSymbol("writtenMapping.xml")); // aXmlHandler->sendMessage(TTSymbol("Write"), v); return NSP_NO_ERROR; }
// Create void *out_new(t_symbol *s, long argc, t_atom *argv) { long attrstart = attr_args_offset(argc, argv); // support normal arguments t_out *x = (t_out *)object_alloc(out_class); short i; if(x){ x->dumpout = outlet_new(x, NULL); object_obex_store((void *)x, jps_dumpout, (object *)x->dumpout); // setup the dumpout x->numOutputs = 1; x->attr_preview = 0; x->preview_object = NULL; x->attr_bypass = 0; x->attr_mute = 0; x->attr_mix = 100; // Assume 100%, so that processed signal is passed through if @has_mix is false if(attrstart > 0){ int argument = atom_getlong(argv); x->numOutputs = TTClip(argument, 1, MAX_NUM_CHANNELS); } #ifdef JCOM_OUT_TILDE if(x->numOutputs > 0) dsp_setup((t_pxobject *)x, x->numOutputs); // Create Object and Inlets else dsp_setup((t_pxobject *)x, 1); // Create Object and Inlets x->common.ob.z_misc = Z_NO_INPLACE | Z_PUT_LAST; // Z_PUT_LAST so that thispoly~ gets it's message properly? for(i=0; i < (x->numOutputs); i++) outlet_new((t_pxobject *)x, "signal"); // Create a signal Outlet x->clock = clock_new(x, (method)update_meters); x->clock_is_set = 0; TTObjectInstantiate(kTTSym_audiosignal, &x->audioIn, x->numOutputs); TTObjectInstantiate(kTTSym_audiosignal, &x->audioOut, x->numOutputs); TTObjectInstantiate(kTTSym_audiosignal, &x->audioTemp, x->numOutputs); TTObjectInstantiate(kTTSym_audiosignal, &x->zeroSignal, x->numOutputs); TTObjectInstantiate(TT("crossfade"), &x->xfade, x->numOutputs); x->xfade->setAttributeValue(TT("position"), 1.0); TTObjectInstantiate(TT("gain"), &x->gain, x->numOutputs); TTObjectInstantiate(TT("ramp"), &x->ramp_gain, x->numOutputs); TTObjectInstantiate(TT("ramp"), &x->ramp_xfade, x->numOutputs); // out_alloc(x, sys_getblksize()); // allocates the vectors for the audio signals x->gain->setAttributeValue(TT("linearGain"), 1.0); #else for(i=x->numOutputs-1; i >= 1; i--) x->inlet[i] = proxy_new(x, i, 0L); for(i=x->numOutputs-1; i >= 0; i--) x->outlet[i] = outlet_new(x, 0L); #endif jcom_core_subscriber_new_common(&x->common, jps__jcom_out__, jps_subscribe_out); jcom_core_subscriber_setcustomsubscribe_method(&x->common, &out_subscribe); attr_args_process(x, argc, argv); // handle attribute args jcom_core_subscriber_subscribe((t_jcom_core_subscriber_common*)x); } return (x); // Return the pointer }
NSPStatus Namespace::namespaceInit(bool useDeviceManager) { // Initialise TT environments TTModularInit(m_appName, ""); GalamusApplication = (TTApplicationPtr)TTModularGetApplication(TT(m_appName)); if (NSPDirectory == NULL) { return NSP_INIT_ERROR; } if (useDeviceManager) { // Initialise DeviceManager if wanted /*TTDeviceManagerPtr */m_deMan = NULL; TTValue args; // Make a TTDeviceManager object args.append(GalamusApplication); args.append(TT(m_appName)); TTObjectInstantiate(TTSymbol("DeviceManager"), TTObjectHandle(&m_deMan), args); // Load plugins and config with xml TTValue value; value.append(TT(PLUGINS_PATH)); value.append(TT(XML_CONFIG_PATH)); m_deMan->LoadPlugins(value); // Load devices with xml m_deMan->LoadDeviceXmlConfig(TT(XML_CONFIG_PATH)); } return NSP_NO_ERROR; }
NSPStatus Namespace::namespaceValueSend(std::string address, TTSymbolPtr attribute, TTValue value, int instance) { TTSenderPtr sender = NULL; // prepare arguments : see TTSender.h to know which args are needed TTValue args; args.clear(); args.append(GalamusApplication); // add Application name to the address std::string absAddress = AppName + address; // add instance number if (instance != 0) { absAddress += "."; stringstream st; st << instance; absAddress += st.str(); } args.append(TT(absAddress)); args.append(attribute); TTObjectInstantiate(TTSymbol("Sender"), TTObjectHandle(&sender), args); sender->sendMessage(kTTSym_Send, value); // note : the value is returned by the Data and the Receiver //TTObjectRelease(TTObjectHandle(&sender));// throw an exception on windows return NSP_NO_ERROR; }
OpPtr OpNew(SymbolPtr msg, AtomCount argc, AtomPtr argv) { OpPtr self; TTValue v; TTErr err; self = OpPtr(object_alloc(sOpClass)); if (self) { object_obex_store((void*)self, _sym_dumpout, (ObjectPtr)outlet_new(self, NULL)); // dumpout self->outlet = outlet_new(self, "audio.connect"); self->inlet = proxy_new(self, 1, &self->inletnum); v.setSize(2); v.set(0, TT("operator")); v.set(1, TTUInt32(1)); // we set it up with 1 inlet, and later modify to 2 inlets if the connection is made err = TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&self->audioGraphObject, v); if (!self->audioGraphObject->getUnitGenerator()) { object_error(SELF, "cannot load Jamoma DSP object"); return NULL; } attr_args_process(self, argc, argv); } return self; }
PackPtr PackNew(SymbolPtr msg, AtomCount argc, AtomPtr argv) { PackPtr self; TTValue v; TTErr err; self = PackPtr(object_alloc(sPackClass)); if (self) { object_obex_store((void*)self, _sym_dumpout, (ObjectPtr)outlet_new(self, NULL)); self->graphOutlets[0] = outlet_new(self, "graph.connect"); v.setSize(2); v.set(0, TT("graph.input")); v.set(1, TTUInt32(1)); err = TTObjectInstantiate(TT("graph.object"), (TTObjectPtr*)&self->graphObject, v); ((TTGraphInput*)self->graphObject->mKernel)->setOwner(self->graphObject); if (!self->graphObject->mKernel) { object_error(SELF, "cannot load Jamoma object"); return NULL; } self->graphDictionary = new TTDictionary; self->graphDictionary->setSchema(TT("none")); self->graphDictionary->append(TT("outlet"), 0); attr_args_process(self, argc, argv); self->qelem = qelem_new(self, (method)PackQFn); // PackStartTracking(self); defer_low(self, (method)PackStartTracking, NULL, 0, NULL); } return self; }
NSPStatus Namespace::namespaceObserverCreate(std::string address, TTSymbolPtr attribute, void* object, void (*returnValueCallback) (TTPtr, TTValue&) , void (*returnAddressCallback) (TTPtr, TTValue&) , int instance) { TTReceiverPtr myReceiver = NULL; TTCallbackPtr r_returnAddressCallback; TTCallbackPtr r_returnValueCallback; TTValuePtr r_returnAddressBaton, r_returnValueBaton; // prepare arguments : see TTReceiver.h to know which args are needed TTValue args; args.clear(); args.append(GalamusApplication); // add Application name to the address std::string absAddress = AppName + address; // add instance number if (instance != 0) { absAddress += "."; stringstream st; st << instance; absAddress += st.str(); } args.append(TT(absAddress)); args.append(attribute); r_returnAddressCallback = NULL; TTObjectInstantiate(TTSymbol("callback"), TTObjectHandle(&r_returnAddressCallback), kTTValNONE); r_returnAddressBaton = new TTValue(TTPtr(object)); r_returnAddressCallback->setAttributeValue(kTTSym_baton, TTPtr(r_returnAddressBaton)); r_returnAddressCallback->setAttributeValue(kTTSym_function, TTPtr(returnAddressCallback)); args.append(r_returnAddressCallback); r_returnValueCallback = NULL; TTObjectInstantiate(TTSymbol("callback"), TTObjectHandle(&r_returnValueCallback), kTTValNONE); r_returnValueBaton = new TTValue(TTPtr(object)); r_returnValueCallback->setAttributeValue(kTTSym_baton, TTPtr(r_returnValueBaton)); r_returnValueCallback->setAttributeValue(kTTSym_function, TTPtr(returnValueCallback)); args.append(r_returnValueCallback); TTObjectInstantiate(TTSymbol("Receiver"), TTObjectHandle(&myReceiver), args); return NSP_NO_ERROR; }
void *ttclip_new(t_symbol *s, long ac, t_atom *at) { t_ttclip* x = (t_ttclip*)pd_new(ttclip_class); TTUInt16 numChannels = 1; // Just mono now... TTErr err; if(x){ outlet_new(&x->obj, gensym("signal")); // Create new signal outlet x->clipper = NULL; err = TTObjectInstantiate(TT("clipper"), &x->clipper, numChannels); if (err) post("ERROR FROM TTCLIP_NEW: %ld", err); TTObjectInstantiate(kTTSym_audiosignal, &x->audioIn, numChannels); TTObjectInstantiate(kTTSym_audiosignal, &x->audioOut, numChannels); } return(x); }
ObjectPtr wrappedClass_new(SymbolPtr name, AtomCount argc, AtomPtr argv) { WrappedClass* wrappedMaxClass = NULL; WrappedInstancePtr self = NULL; TTValue v; TTErr err = kTTErrNone; TTUInt8 numInputs = 1; TTUInt8 numOutputs = 1; long attrstart = attr_args_offset(argc, argv); // support normal arguments // Find the WrappedClass hashtab_lookup(wrappedMaxClasses, name, (ObjectPtr*)&wrappedMaxClass); // If the WrappedClass has a validity check defined, then call the validity check function. // If it returns an error, then we won't instantiate the object. if (wrappedMaxClass) { if (wrappedMaxClass->validityCheck) err = wrappedMaxClass->validityCheck(wrappedMaxClass->validityCheckArgument); else err = kTTErrNone; } else err = kTTErrGeneric; if (!err) self = (WrappedInstancePtr)object_alloc(wrappedMaxClass->maxClass); if (self){ if (wrappedMaxClass->options && !wrappedMaxClass->options->lookup(TT("argumentDefinesNumInlets"), v)) { long argumentOffsetToDefineTheNumberOfInlets = v; if ((attrstart-argumentOffsetToDefineTheNumberOfInlets > 0) && argv+argumentOffsetToDefineTheNumberOfInlets) numInputs = atom_getlong(argv+argumentOffsetToDefineTheNumberOfInlets); } for (TTUInt16 i=numInputs-1; i>0; i--) self->inlets[i-1] = proxy_new(self, i, NULL); object_obex_store((void*)self, _sym_dumpout, (object*)outlet_new(self, NULL)); // dumpout if (wrappedMaxClass->options && !wrappedMaxClass->options->lookup(TT("argumentDefinesNumOutlets"), v)) { long argumentOffsetToDefineTheNumberOfOutlets = v; if ((attrstart-argumentOffsetToDefineTheNumberOfOutlets > 0) && argv+argumentOffsetToDefineTheNumberOfOutlets) numOutputs = atom_getlong(argv+argumentOffsetToDefineTheNumberOfOutlets); } for (TTInt16 i=numOutputs-1; i>=0; i--) self->audioGraphOutlets[i] = outlet_new(self, "audio.connect"); self->wrappedClassDefinition = wrappedMaxClass; v.setSize(3); v.set(0, wrappedMaxClass->ttClassName); v.set(1, numInputs); v.set(2, numOutputs); err = TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&self->audioGraphObject, v); attr_args_process(self, argc, argv); } return ObjectPtr(self); }
// Create void* gain_new(t_symbol* s, long argc, t_atom* argv) { long attrstart = attr_args_offset(argc, argv); // support normal arguments short i; t_gain* x = (t_gain*)object_alloc(s_gain_class); if(x){ object_obex_store((void*)x, _sym_dumpout, (object*)outlet_new(x, NULL)); // dumpout x->numChannels = 1; if(attrstart && argv){ int argument = atom_getlong(argv); x->numChannels = TTClip(argument, 1, MAX_NUM_CHANNELS); } dsp_setup((t_pxobject*)x, x->numChannels * 2); // Create Object and Inlets x->obj.z_misc = Z_NO_INPLACE; // ESSENTIAL! for(i=0; i < x->numChannels; i++) outlet_new((t_pxobject*)x, "signal"); // Create a signal Outlet //x->xfade = new TTCrossfade(x->numChannels); // Constructors //x->gain = new TTGain(x->numChannels); TTObjectInstantiate(TT("crossfade"), &x->xfade, x->numChannels); TTObjectInstantiate(TT("gain"), &x->gain, x->numChannels); TTObjectInstantiate(kTTSym_audiosignal, &x->signalTemp, x->numChannels); TTObjectInstantiate(kTTSym_audiosignal, &x->signalOut, x->numChannels); TTObjectInstantiate(kTTSym_audiosignal, &x->signalIn, x->numChannels*2); //x->signalTemp = new TTAudioSignal(x->numChannels); //x->signalOut = new TTAudioSignal(x->numChannels); //x->signalIn = new TTAudioSignal(x->numChannels*2); x->xfade->setAttributeValue(TT("Position"), 1.0); // defaults x->gain->setAttributeValue(TT("LinearGain"), 0.0); x->attrBypass = 0; x->attrGain = 0; attr_args_process(x, argc, argv); // handle attribute args } return (x); // Return the pointer }
TTAudioGraphObject :: TTAudioGraphObject (TTValue& arguments) : TTGraphObject(arguments), mAudioFlags(kTTAudioGraphProcessor), mInputSignals(NULL), mOutputSignals(NULL), mVectorSize(0) { TTErr err = kTTErrNone; TTSymbolPtr wrappedObjectName = NULL; //TTUInt16 initialNumChannels = 1; TTUInt16 numInlets = 1; TTUInt16 numOutlets = 1; TT_ASSERT(audiograph_correct_instantiation_arg_count, arguments.getSize() > 0); arguments.get(0, &wrappedObjectName); if (arguments.getSize() > 1) arguments.get(1, numInlets); if (arguments.getSize() > 2) arguments.get(2, numOutlets); // instantiated by the TTGraph super-class //err = TTObjectInstantiate(wrappedObjectName, &mUnitGenerator, initialNumChannels); err = TTObjectInstantiate(kTTSym_audiosignalarray, (TTObjectPtr*)&mInputSignals, numInlets); err = TTObjectInstantiate(kTTSym_audiosignalarray, (TTObjectPtr*)&mOutputSignals, numOutlets); mAudioInlets.resize(numInlets); mInputSignals->setMaxNumAudioSignals(numInlets); mInputSignals->numAudioSignals = numInlets; // TODO: this array num signals access is kind of clumsy and inconsistent [tap] mAudioOutlets.resize(numOutlets); mOutputSignals->setMaxNumAudioSignals(numOutlets); mOutputSignals->numAudioSignals = numOutlets; // if an object supports the 'setOwner' message, then we tell it that we want to become the owner // this is particularly important for the dac object TTValue v = TTPtr(this); mKernel->sendMessage(TT("setOwner"), v); if (!sSharedMutex) sSharedMutex = new TTMutex(false); }
BlueSaturation::BlueSaturation(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, kNumPresets, kNumParameters), mNumChannels(2), mOverdrive(NULL), mInput(NULL), mOutput(NULL) { TTDSPInit(); setNumInputs(2); // stereo in setNumOutputs(2); // stereo out setUniqueID('TTOv'); // identify canProcessReplacing(); // supports replacing output canDoubleReplacing(); // supports double precision processing TTObjectInstantiate(TT("overdrive"), &mOverdrive, mNumChannels); TTObjectInstantiate(kTTSym_audiosignal, &mInput, mNumChannels); TTObjectInstantiate(kTTSym_audiosignal, &mOutput, mNumChannels); mParameterList = new BlueParameter[kNumParameters]; strncpy(mParameterList[kParameterDrive].name, "drive", 256); mParameterList[kParameterDrive].scaling = 9.0; mParameterList[kParameterDrive].offset = 1.0; strncpy(mParameterList[kParameterPreamp].name, "preamp", 256); mParameterList[kParameterPreamp].scaling = 96.0; mParameterList[kParameterPreamp].offset = -78.0; strncpy(mParameterList[kParameterMode].name, "mode", 256); mParameterList[kParameterMode].scaling = 2.0; // just round this one mParameterList[kParameterMode].offset = 0.5; strncpy(mParameterList[kParameterBlockDC].name, "dcblocker", 256); mParameterList[kParameterBlockDC].scaling = 1.0; // just round this one mParameterList[kParameterBlockDC].offset = 0.5; vst_strncpy(programName, "Default", kVstMaxProgNameLen); // default program name }
// Create TTPtr FFTNew(SymbolPtr s, AtomCount argc, AtomPtr argv) { short i; FFTPtr self = (FFTPtr)object_alloc(sFFTClass); if (self) { object_obex_store((TTPtr)self, _sym_dumpout, (object*)outlet_new(self, NULL)); // dumpout self->numChannels = 1; dsp_setup((t_pxobject*)self, self->numChannels); // Create Object and N Inlets (last argument) self->obj.z_misc = Z_NO_INPLACE; // ESSENTIAL! for (i=0; i< (self->numChannels*2); i++) outlet_new((t_pxobject*)self, "signal"); TTObjectInstantiate(TT("fft"), &self->fft, self->numChannels); TTObjectInstantiate(kTTSym_audiosignal, &self->audioIn, self->numChannels); TTObjectInstantiate(kTTSym_audiosignal, &self->audioOut, self->numChannels); attr_args_process(self, argc, argv); } return (self); }
OpPtr OpNew(SymbolPtr msg, AtomCount argc, AtomPtr argv) { OpPtr self; TTValue v; TTErr err; self = OpPtr(pd_new(sOpClass)); if (self) { self->outlet = outlet_new(SELF, gensym("audio.connect")); v.setSize(2); v.set(0, TT("operator")); v.set(1, TTUInt32(1)); err = TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&self->audioGraphObject, v); if (!self->audioGraphObject->getUnitGenerator()) { error("op≈: cannot load Jamoma DSP object"); return NULL; } } return self; }
TTErr setType(const TTValue& newValue) { TTSymbolPtr newType = newValue; TTErr err = kTTErrNone; // if the type didn't change, then don't change the filter if (newType == mType) return kTTErrNone; mType = newType; err = TTObjectInstantiate(mType, &mActualFilterObject, maxNumChannels); if (!err) { // Now that we have our new filter, update it with the current state of the wrapper: mActualFilterObject->setAttributeValue(TT("Frequency"), mFrequency); err = mActualFilterObject->setAttributeValue(TT("Q"), mQ); if (err == kTTErrInvalidAttribute) err = mActualFilterObject->setAttributeValue(TT("Resonance"), mQ); mActualFilterObject->setAttributeValue(TT("Bypass"), this->attrBypass); mActualFilterObject->setAttributeValue(TT("SampleRate"), sr); } return err; }
TTErr TTGain::test(TTValue& returnedTestInfo) { // preliminary setup int errorCount = 0; int testAssertionCount = 0; TTTestLog("Testing Parameter value conversions"); // N test assertions // Test 1: trival value conversion this->setAttributeValue(TT("midiGain"), 100); TTTestAssertion("midi gain of 100 == linear gain of 1.", TTTestFloatEquivalence(this->mGain, 1.0), testAssertionCount, errorCount); // Test 2: trival value conversion this->setAttributeValue(TT("midiGain"), 99); TTTestAssertion("midi gain of 99 != linear gain of 1.", TTTestFloatEquivalence(this->mGain, 1.0, false), testAssertionCount, errorCount); // Test 3: audio test // set the input signals 1 // apply -6 dB gain // check that the signals are properly scaled TTAudioSignalPtr input = NULL; TTAudioSignalPtr output = NULL; // create 1 channel audio signal objects TTObjectInstantiate(kTTSym_audiosignal, &input, 1); TTObjectInstantiate(kTTSym_audiosignal, &output, 1); input->allocWithVectorSize(64); output->allocWithVectorSize(64); for (int i=0; i<64; i++) input->mSampleVectors[0][i] = 1.0; this->setAttributeValue(TT("gain"), -6.0); this->process(input, output); TTSampleValuePtr samples = output->mSampleVectors[0]; int validSampleCount = 0; for (int i=0; i<64; i++) { validSampleCount += TTTestFloatEquivalence(0.5011872336272722, samples[i]); } TTTestAssertion("accumulated audio error at gain = -6 dB", validSampleCount == 64, testAssertionCount, errorCount); TTTestLog("Numbe of bad samples: %i", 64-validSampleCount); TTObjectRelease(&input); TTObjectRelease(&output); // Wrap up the test results to pass back to whoever called this test return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo); }
TTErr TTSmoothPolynomialFunction::test(TTValue& returnedTestInfo) { int errorCount = 0; int testAssertionCount = 0; int badSampleCount = 0; TTAudioSignalPtr input = NULL; TTAudioSignalPtr output = NULL; int N = 128; TTValue v; TTFloat64 inputSignal1[128] = { 0.0000000000000000e+00, 7.8740157480314960e-03, 1.5748031496062992e-02, 2.3622047244094488e-02, 3.1496062992125984e-02, 3.9370078740157480e-02, 4.7244094488188976e-02, 5.5118110236220472e-02, 6.2992125984251968e-02, 7.0866141732283464e-02, 7.8740157480314960e-02, 8.6614173228346455e-02, 9.4488188976377951e-02, 1.0236220472440945e-01, 1.1023622047244094e-01, 1.1811023622047244e-01, 1.2598425196850394e-01, 1.3385826771653545e-01, 1.4173228346456693e-01, 1.4960629921259844e-01, 1.5748031496062992e-01, 1.6535433070866143e-01, 1.7322834645669291e-01, 1.8110236220472442e-01, 1.8897637795275590e-01, 1.9685039370078741e-01, 2.0472440944881889e-01, 2.1259842519685040e-01, 2.2047244094488189e-01, 2.2834645669291340e-01, 2.3622047244094488e-01, 2.4409448818897639e-01, 2.5196850393700787e-01, 2.5984251968503935e-01, 2.6771653543307089e-01, 2.7559055118110237e-01, 2.8346456692913385e-01, 2.9133858267716534e-01, 2.9921259842519687e-01, 3.0708661417322836e-01, 3.1496062992125984e-01, 3.2283464566929132e-01, 3.3070866141732286e-01, 3.3858267716535434e-01, 3.4645669291338582e-01, 3.5433070866141730e-01, 3.6220472440944884e-01, 3.7007874015748032e-01, 3.7795275590551181e-01, 3.8582677165354329e-01, 3.9370078740157483e-01, 4.0157480314960631e-01, 4.0944881889763779e-01, 4.1732283464566927e-01, 4.2519685039370081e-01, 4.3307086614173229e-01, 4.4094488188976377e-01, 4.4881889763779526e-01, 4.5669291338582679e-01, 4.6456692913385828e-01, 4.7244094488188976e-01, 4.8031496062992124e-01, 4.8818897637795278e-01, 4.9606299212598426e-01, 5.0393700787401574e-01, 5.1181102362204722e-01, 5.1968503937007871e-01, 5.2755905511811019e-01, 5.3543307086614178e-01, 5.4330708661417326e-01, 5.5118110236220474e-01, 5.5905511811023623e-01, 5.6692913385826771e-01, 5.7480314960629919e-01, 5.8267716535433067e-01, 5.9055118110236215e-01, 5.9842519685039375e-01, 6.0629921259842523e-01, 6.1417322834645671e-01, 6.2204724409448819e-01, 6.2992125984251968e-01, 6.3779527559055116e-01, 6.4566929133858264e-01, 6.5354330708661412e-01, 6.6141732283464572e-01, 6.6929133858267720e-01, 6.7716535433070868e-01, 6.8503937007874016e-01, 6.9291338582677164e-01, 7.0078740157480313e-01, 7.0866141732283461e-01, 7.1653543307086609e-01, 7.2440944881889768e-01, 7.3228346456692917e-01, 7.4015748031496065e-01, 7.4803149606299213e-01, 7.5590551181102361e-01, 7.6377952755905509e-01, 7.7165354330708658e-01, 7.7952755905511806e-01, 7.8740157480314965e-01, 7.9527559055118113e-01, 8.0314960629921262e-01, 8.1102362204724410e-01, 8.1889763779527558e-01, 8.2677165354330706e-01, 8.3464566929133854e-01, 8.4251968503937003e-01, 8.5039370078740162e-01, 8.5826771653543310e-01, 8.6614173228346458e-01, 8.7401574803149606e-01, 8.8188976377952755e-01, 8.8976377952755903e-01, 8.9763779527559051e-01, 9.0551181102362199e-01, 9.1338582677165359e-01, 9.2125984251968507e-01, 9.2913385826771655e-01, 9.3700787401574803e-01, 9.4488188976377951e-01, 9.5275590551181100e-01, 9.6062992125984248e-01, 9.6850393700787396e-01, 9.7637795275590555e-01, 9.8425196850393704e-01, 9.9212598425196852e-01, 1.0000000000000000e+00 }; TTFloat64 expectedSignal1[128] = { 0.0000000000000000e+00, 4.8244209039635314e-06, 3.8138443955198070e-05, 1.2718493906995618e-04, 2.9786651631526754e-04, 5.7476731875201535e-04, 9.8117481527801352e-04, 1.5391015934710839e-03, 2.2693071524321311e-03, 3.1913196956282223e-03, 4.3234579237356610e-03, 5.6828528274830668e-03, 7.2854694804944482e-03, 9.1461288321322883e-03, 1.1278529500340605e-02, 1.3695269564488044e-02, 1.6407868358210953e-02, 1.9426788262256446e-02, 2.2761456497325496e-02, 2.6420286916916010e-02, 3.0410701800165873e-02, 3.4739153644696097e-02, 3.9411146959453816e-02, 4.4431260057555426e-02, 4.9803166849129596e-02, 5.5529658634160470e-02, 6.1612665895330529e-02, 6.8053280090863921e-02, 7.4851775447369331e-02, 8.2007630752683164e-02, 8.9519551148712656e-02, 9.7385489924278826e-02, 1.0560267030795963e-01, 1.1416760726093299e-01, 1.2307612926982006e-01, 1.3232340013952798e-01, 1.4190394078609317e-01, 1.5181165102952443e-01, 1.6203983138664596e-01, 1.7258120486394016e-01, 1.8342793875039137e-01, 1.9457166641032828e-01, 2.0600350907626741e-01, 2.1771409764175598e-01, 2.2969359445421497e-01, 2.4193171510778244e-01, 2.5441775023615654e-01, 2.6714058730543810e-01, 2.8008873240697457e-01, 2.9325033205020234e-01, 3.0661319495549044e-01, 3.2016481384698270e-01, 3.3389238724544185e-01, 3.4778284126109205e-01, 3.6182285138646236e-01, 3.7599886428922880e-01, 3.9029711960505920e-01, 4.0470367173045396e-01, 4.1920441161559163e-01, 4.3378508855717035e-01, 4.4843133199125074e-01, 4.6312867328610041e-01, 4.7786256753503586e-01, 4.9261841534926576e-01, 5.0738158465073435e-01, 5.2213743246496436e-01, 5.3687132671389948e-01, 5.5156866800874915e-01, 5.6621491144282976e-01, 5.8079558838440848e-01, 5.9529632826954604e-01, 6.0970288039494136e-01, 6.2400113571077132e-01, 6.3817714861353769e-01, 6.5221715873890806e-01, 6.6610761275455821e-01, 6.7983518615301786e-01, 6.9338680504450978e-01, 7.0674966794979754e-01, 7.1991126759302526e-01, 7.3285941269456178e-01, 7.4558224976384357e-01, 7.5806828489221756e-01, 7.7030640554578467e-01, 7.8228590235824358e-01, 7.9399649092373314e-01, 8.0542833358967236e-01, 8.1657206124960879e-01, 8.2741879513605987e-01, 8.3796016861335465e-01, 8.4818834897047601e-01, 8.5809605921390641e-01, 8.6767659986047230e-01, 8.7692387073018008e-01, 8.8583239273906678e-01, 8.9439732969204044e-01, 9.0261451007572102e-01, 9.1048044885128654e-01, 9.1799236924731620e-01, 9.2514822455263168e-01, 9.3194671990913625e-01, 9.3838733410466979e-01, 9.4447034136584040e-01, 9.5019683315087100e-01, 9.5556873994244551e-01, 9.6058885304054709e-01, 9.6526084635530474e-01, 9.6958929819983375e-01, 9.7357971308308588e-01, 9.7723854350267647e-01, 9.8057321173774348e-01, 9.8359213164178971e-01, 9.8630473043551437e-01, 9.8872147049965875e-01, 9.9085387116786894e-01, 9.9271453051950509e-01, 9.9431714717251651e-01, 9.9567654207626521e-01, 9.9680868030437164e-01, 9.9773069284756843e-01, 9.9846089840652841e-01, 9.9901882518472185e-01, 9.9942523268124717e-01, 9.9970213348368553e-01, 9.9987281506093062e-01, 9.9996186155604327e-01, 9.9999517557909634e-01, 1.0000000000000000e+00 }; // setup Function this->setAttributeValue(TT("function"), TT("smoothPolynomial")); // create 1 channel audio signal objects TTObjectInstantiate(kTTSym_audiosignal, &input, 1); TTObjectInstantiate(kTTSym_audiosignal, &output, 1); input->allocWithVectorSize(N); output->allocWithVectorSize(N); // create a signal to be transformed and then process it) input->clear(); for (int i=0; i<N; i++) input->mSampleVectors[0][i] = inputSignal1[i]; this->process(input, output); // now test the output for (int n=0; n<N; n++) { TTBoolean result = !TTTestFloatEquivalence(output->mSampleVectors[0][n], expectedSignal1[n]); badSampleCount += result; if (result) TTTestLog("BAD SAMPLE @ n=%i ( value=%.10f expected=%.10f )", n, output->mSampleVectors[0][n], expectedSignal1[n]); } TTTestAssertion("Produces correct function values", badSampleCount == 0, testAssertionCount, errorCount); if (badSampleCount) TTTestLog("badSampleCount is %i", badSampleCount); TTObjectRelease(&input); TTObjectRelease(&output); // wrap up test results and pass back to whoever called test return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo); }
TTErr FunctionLib::createUnit(const TTSymbolPtr unitName, TTObject **unit) { TTUInt16 numChannels = 1; return TTObjectInstantiate(unitName, unit, numChannels); }
TTErr TTAudioGraphGenerator::test(TTValue& returnedTestInfo) { int errorCount = 0; int testAssertionCount = 0; int badSampleCount = 0; // TTAudioSignalPtr input = NULL; TTAudioSignalPtr output = NULL; TTAudioGraphPreprocessData mInitData; // TTAudioSignalPtr mAudioSignal = NULL; TTAudioGraphObjectPtr obj0 = NULL; TTAudioGraphObjectPtr obj1 = NULL; TTAudioGraphObjectPtr obj2 = NULL; TTAudioGraphObjectPtr obj3 = NULL; TTAudioGraphObjectPtr obj4 = NULL; TTAudioGraphObjectPtr obj5 = NULL; TTAudioGraphObjectPtr obj6 = NULL; TTAudioGraphObjectPtr obj7 = NULL; // TTAudioGraphObjectPtr obj8 = NULL; TTAudioGraphObjectPtr obj9 = NULL; TTAudioGraphObjectPtr obj10 = NULL; // TTAudioGraphObjectPtr obj11 = NULL; TTAudioGraphObjectPtr obj12 = NULL; TTAudioGraphObjectPtr obj13 = NULL; TTValue audioObjectArguments; memset(&mInitData, 0, sizeof(mInitData)); audioObjectArguments.setSize(3); // Create the Graph audioObjectArguments.set(0, TT("thru")); // <<-- THIS IS THE SINK ON WHICH WE WILL PULL audioObjectArguments.set(1, 1); // <<-- NUMBER OF INLETS audioObjectArguments.set(2, 1); TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&obj0, audioObjectArguments); obj0->mKernel->setAttributeValue(TT("maxNumChannels"), 0); obj0->mKernel->setAttributeValue(TT("mute"), 0); obj0->mKernel->setAttributeValue(TT("bypass"), 0); obj0->mKernel->setAttributeValue(TT("sampleRate"), 44100u); audioObjectArguments.set(0, TT("audio.join")); audioObjectArguments.set(1, 2); audioObjectArguments.set(2, 1); TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&obj1, audioObjectArguments); obj1->mKernel->setAttributeValue(TT("maxNumChannels"), 1); obj1->mKernel->setAttributeValue(TT("mute"), 0); obj1->mKernel->setAttributeValue(TT("bypass"), 0); obj1->mKernel->setAttributeValue(TT("sampleRate"), 44100u); audioObjectArguments.set(0, TT("gain")); audioObjectArguments.set(1, 1); audioObjectArguments.set(2, 1); TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&obj2, audioObjectArguments); //obj2->mKernel->setAttributeValue(TT("midiGain"), 86.639865); obj2->mKernel->setAttributeValue(TT("maxNumChannels"), 0); obj2->mKernel->setAttributeValue(TT("interpolated"), 0); obj2->mKernel->setAttributeValue(TT("mute"), 0); obj2->mKernel->setAttributeValue(TT("bypass"), 0); //obj2->mKernel->setAttributeValue(TT("gain"), -6.000000); //obj2->mKernel->setAttributeValue(TT("linearGain"), 0.501187); obj2->mKernel->setAttributeValue(TT("linearGain"), 0.25); obj2->mKernel->setAttributeValue(TT("sampleRate"), 44100u); audioObjectArguments.set(0, TT("audio.split")); audioObjectArguments.set(1, 1); audioObjectArguments.set(2, 2); TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&obj3, audioObjectArguments); obj3->mKernel->setAttributeValue(TT("maxNumChannels"), 1); TTValue v(1,1); obj3->mKernel->setAttributeValue(TT("groups"), v); obj3->mKernel->setAttributeValue(TT("mute"), 0); obj3->mKernel->setAttributeValue(TT("bypass"), 0); obj3->mKernel->setAttributeValue(TT("sampleRate"), 44100u); audioObjectArguments.set(0, TT("audio.generator")); audioObjectArguments.set(1, 0); audioObjectArguments.set(2, 1); TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&obj4, audioObjectArguments); obj4->mKernel->setAttributeValue(TT("maxNumChannels"), 2); obj4->mKernel->setAttributeValue(TT("mute"), 0); obj4->mKernel->setAttributeValue(TT("bypass"), 0); obj4->mKernel->setAttributeValue(TT("vectorSize"), 64); obj4->mKernel->setAttributeValue(TT("sampleRate"), 44100u); obj4->addAudioFlag(kTTAudioGraphGenerator); obj4->setOutputNumChannels(0, 2); obj3->connectAudio(obj4, 0, 0); obj2->connectAudio(obj3, 0, 0); // TTObjectInstantiate(TT("graph.object"), (TTObjectPtr*)&obj8, TTValue(TT("plugtastic.parameter"))); // ((PlugtasticParameter*)obj8->mKernel)->setOwner(obj8); // obj8->mKernel->setAttributeValue(TT("rangeTop"), 24.000000); // obj8->mKernel->setAttributeValue(TT("bypass"), 0); // obj8->mKernel->setAttributeValue(TT("name"), TT("gain")); // obj8->mKernel->setAttributeValue(TT("style"), TT("decibels")); // obj8->mKernel->setAttributeValue(TT("default"), -6.000000); // obj8->mKernel->setAttributeValue(TT("value"), 0.000000); // obj8->mKernel->setAttributeValue(TT("rangeBottom"), -96.000000); // obj2->connect(obj8); obj1->connectAudio(obj2, 0, 0); audioObjectArguments.set(0, TT("gain")); audioObjectArguments.set(1, 1); audioObjectArguments.set(2, 1); TTObjectInstantiate(TT("audio.object"), (TTObjectPtr*)&obj9, audioObjectArguments); // obj9->mKernel->setAttributeValue(TT("midiGain"), 86.639865); obj9->mKernel->setAttributeValue(TT("maxNumChannels"), 0); obj9->mKernel->setAttributeValue(TT("interpolated"), 0); obj9->mKernel->setAttributeValue(TT("mute"), 0); obj9->mKernel->setAttributeValue(TT("bypass"), 0); // obj9->mKernel->setAttributeValue(TT("gain"), -6.000000); // obj9->mKernel->setAttributeValue(TT("linearGain"), 0.501187); obj9->mKernel->setAttributeValue(TT("linearGain"), 0.25); obj9->mKernel->setAttributeValue(TT("sampleRate"), 44100u); obj9->connectAudio(obj3, 1, 0); // TTObjectInstantiate(TT("graph.object"), (TTObjectPtr*)&obj11, TTValue(TT("plugtastic.parameter"))); // ((PlugtasticParameter*)obj11->mKernel)->setOwner(obj11); // obj11->mKernel->setAttributeValue(TT("rangeTop"), 24.000000); // obj11->mKernel->setAttributeValue(TT("bypass"), 0); // obj11->mKernel->setAttributeValue(TT("name"), TT("gain")); // obj11->mKernel->setAttributeValue(TT("style"), TT("decibels")); // obj11->mKernel->setAttributeValue(TT("default"), -6.000000); // obj11->mKernel->setAttributeValue(TT("value"), 0.000000); // obj11->mKernel->setAttributeValue(TT("rangeBottom"), -96.000000); // obj9->connect(obj11); obj1->connectAudio(obj9, 0, 1); obj0->connectAudio(obj1, 0, 0); // SET UP SOME AUDIO AND PULL ON THE GRAPH // obj4 is the source // obj0 is the sink TTSampleValue chan1input[64] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; TTSampleValue chan2input[64] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; TTSampleValue chan1output[64]; TTSampleValue chan2output[64]; mInitData.vectorSize = 64; TTTestLog("Processing First Pull"); TTAudioGraphGeneratorPtr(obj4->getUnitGenerator())->mBuffer->setVector64Copy(0, 64, chan1input); TTAudioGraphGeneratorPtr(obj4->getUnitGenerator())->mBuffer->setVector64Copy(1, 64, chan2input); obj0->lockProcessing(); obj0->preprocess(mInitData); obj0->process(output, 0); obj0->unlockProcessing(); output->getVectorCopy(0, 64, chan1output); output->getVectorCopy(1, 64, chan2output); // CHECK THE RESULTS for (int i=0; i<64; i++) { TTBoolean result = TTTestFloatEquivalence(chan1output[i], chan1input[i] * 0.25); badSampleCount += !result; if (!result) TTTestLog("CHAN1 BAD SAMPLE @ i=%i ( value=%.10f expected=%.10f )", i, chan1output[i], chan1input[i] * 0.25); result = TTTestFloatEquivalence(chan2output[i], chan2input[i] * 0.25); badSampleCount += !result; if (!result) TTTestLog("CHAN2 BAD SAMPLE @ i=%i ( value=%.10f expected=%.10f )", i, chan2output[i], chan2input[i] * 0.25); } TTTestAssertion("Produces correct results for first pull", badSampleCount == 0, testAssertionCount, errorCount); if (badSampleCount) TTTestLog("badSampleCount is %i", badSampleCount); TTTestLog("Processing Second Pull"); TTAudioGraphGeneratorPtr(obj4->getUnitGenerator())->mBuffer->setVector64Copy(0, 64, chan1input); TTAudioGraphGeneratorPtr(obj4->getUnitGenerator())->mBuffer->setVector64Copy(1, 64, chan2input); obj0->lockProcessing(); obj0->preprocess(mInitData); obj0->process(output, 64); obj0->unlockProcessing(); output->getVectorCopy(0, 64, chan1output); output->getVectorCopy(1, 64, chan2output); // CHECK THE RESULTS for (int i=0; i<64; i++) { TTBoolean result = TTTestFloatEquivalence(chan1output[i], chan1input[i] * 0.25); badSampleCount += !result; if (!result) TTTestLog("CHAN1 BAD SAMPLE @ i=%i ( value=%.10f expected=%.10f )", i, chan1output[i], chan1input[i] * 0.25); result = TTTestFloatEquivalence(chan2output[i], chan2input[i] * 0.25); badSampleCount += !result; if (!result) TTTestLog("CHAN2 BAD SAMPLE @ i=%i ( value=%.10f expected=%.10f )", i, chan2output[i], chan2input[i] * 0.25); } TTTestAssertion("Produces correct results for second pull", badSampleCount == 0, testAssertionCount, errorCount); if (badSampleCount) TTTestLog("badSampleCount is %i", badSampleCount); // FREE MEMORY FROM OUR GRAPH TTObjectRelease((TTObjectPtr*)&obj0); TTObjectRelease((TTObjectPtr*)&obj1); TTObjectRelease((TTObjectPtr*)&obj2); TTObjectRelease((TTObjectPtr*)&obj3); TTObjectRelease((TTObjectPtr*)&obj4); TTObjectRelease((TTObjectPtr*)&obj5); TTObjectRelease((TTObjectPtr*)&obj6); TTObjectRelease((TTObjectPtr*)&obj7); // TTObjectRelease((TTObjectPtr*)&obj8); TTObjectRelease((TTObjectPtr*)&obj9); TTObjectRelease((TTObjectPtr*)&obj10); // TTObjectRelease((TTObjectPtr*)&obj11); TTObjectRelease((TTObjectPtr*)&obj12); TTObjectRelease((TTObjectPtr*)&obj13); // Wrap up the test results to pass back to whoever called this test return TTTestFinish(testAssertionCount, errorCount, returnedTestInfo); }
TTErr wrapAsMaxAudioGraph(TTSymbolPtr ttClassName, char* maxClassName, WrappedClassPtr* c, WrappedClassOptionsPtr options) { TTObject* o = NULL; TTValue v; TTUInt16 numChannels = 1; WrappedClass* wrappedMaxClass = NULL; common_symbols_init(); TTAudioGraphInit(); if(!wrappedMaxClasses) wrappedMaxClasses = hashtab_new(0); wrappedMaxClass = new WrappedClass; wrappedMaxClass->maxClassName = gensym(maxClassName); wrappedMaxClass->maxClass = class_new( maxClassName, (method)wrappedClass_new, (method)wrappedClass_free, sizeof(WrappedInstance), (method)0L, A_GIMME, 0); wrappedMaxClass->ttClassName = ttClassName; wrappedMaxClass->validityCheck = NULL; wrappedMaxClass->validityCheckArgument = NULL; wrappedMaxClass->options = options; wrappedMaxClass->maxAttrNamesToTTAttrNames = hashtab_new(0); // Create a temporary instance of the class so that we can query it. TTObjectInstantiate(ttClassName, &o, numChannels); o->getMessageNames(v); for(TTUInt16 i=0; i<v.getSize(); i++){ TTSymbolPtr name = NULL; v.get(i, &name); if(name == TT("updateMaxNumChannels") || name == TT("updateSr")) continue; // don't expose these attributes to Max users class_addmethod(wrappedMaxClass->maxClass, (method)wrappedClass_anything, (char*)name->getCString(), A_GIMME, 0); } o->getAttributeNames(v); for (TTUInt16 i=0; i<v.getSize(); i++) { TTSymbolPtr name = NULL; TTAttributePtr attr = NULL; SymbolPtr maxType = _sym_long; TTCString nameCString = NULL; SymbolPtr nameMaxSymbol = NULL; TTUInt32 nameSize = 0; v.get(i, &name); if(name == TT("maxNumChannels") || name == TT("processInPlace")) continue; // don't expose these attributes to Max users o->findAttribute(name, &attr); if (attr->type == kTypeFloat32) maxType = _sym_float32; else if (attr->type == kTypeFloat64) maxType = _sym_float64; else if (attr->type == kTypeSymbol || attr->type == kTypeString) maxType = _sym_symbol; // convert first letter to lower-case if it isn't already nameSize = name->getString().length(); nameCString = new char[nameSize+1]; strncpy_zero(nameCString, name->getCString(), nameSize+1); if (nameCString[0]>64 && nameCString[0]<91) nameCString[0] += 32; nameMaxSymbol = gensym(nameCString); hashtab_store(wrappedMaxClass->maxAttrNamesToTTAttrNames, nameMaxSymbol, ObjectPtr(name)); class_addattr(wrappedMaxClass->maxClass, attr_offset_new(nameCString, maxType, 0, (method)wrappedClass_attrGet, (method)wrappedClass_attrSet, NULL)); // Add display styles for the Max 5 inspector if (attr->type == kTypeBoolean) CLASS_ATTR_STYLE(wrappedMaxClass->maxClass, (char*)name->getCString(), 0, "onoff"); if (name == TT("fontFace")) CLASS_ATTR_STYLE(wrappedMaxClass->maxClass, "fontFace", 0, "font"); } TTObjectRelease(&o); class_addmethod(wrappedMaxClass->maxClass, (method)MaxAudioGraphReset, "audio.reset", A_CANT, 0); class_addmethod(wrappedMaxClass->maxClass, (method)MaxAudioGraphSetup, "audio.setup", A_CANT, 0); class_addmethod(wrappedMaxClass->maxClass, (method)MaxAudioGraphConnect, "audio.connect", A_OBJ, A_LONG, 0); class_addmethod(wrappedMaxClass->maxClass, (method)object_obex_dumpout, "dumpout", A_CANT, 0); class_addmethod(wrappedMaxClass->maxClass, (method)wrappedClass_assist, "assist", A_CANT, 0L); class_addmethod(wrappedMaxClass->maxClass, (method)stdinletinfo, "inletinfo", A_CANT, 0); class_register(_sym_box, wrappedMaxClass->maxClass); if (c) *c = wrappedMaxClass; hashtab_store(wrappedMaxClasses, wrappedMaxClass->maxClassName, ObjectPtr(wrappedMaxClass)); return kTTErrNone; }