int main(void) { common_symbols_init(); PlugtasticInit(); plugtastic_classinit(); sPlugtasticObject = (t_object*)plugtastic_new(); ps_plugtastic = GENSYM("plugtastic"); ps_plugtastic->s_thing = sPlugtasticObject; sMaxObject = _sym_max->s_thing; ps_objectfile = GENSYM("objectfile"); ps_db_object_addinternal = GENSYM("db.object_addinternal"); ps_oblist = GENSYM("oblist"); ps_db_addmetadata = GENSYM("db.addmetadata"); //defer_low(sMaxObject, (method)plug_setup_db, NULL, 0, NULL); plug_setup_db(); post("Plugtastic Version %s | 74Objects.com", PLUGTASTIC_VERSION); // This tells Max 5.0.6 and higher that we want the patcher files to be saved such that they are sorted. // Having the saved this way makes our SVN diffs much more meaningful. object_method_long(sMaxObject, GENSYM("sortpatcherdictonsave"), 1, NULL); // This tells Max 4.5.7 and higher to take any posts to the Max window and also make the // post to the system console, which greatly aids in debugging problems and crashes object_method_long(sMaxObject, GENSYM("setmirrortoconsole"), 1, NULL); // OPEN THE SPLASH if (sPlugtasticSplash) { char name[MAX_FILENAME_CHARS]; short path = 0; long type = 0; long typelist[2] = {'JSON', 'TEXT'}; short err; t_dictionary* d; t_object* p; t_atom a[2]; strncpy_zero(name, "Plugtastic.maxpat", MAX_FILENAME_CHARS); err = locatefile_extended(name, &path, &type, typelist, 2); dictionary_read(name, path, &d); atom_setobj(a, d); p = (t_object*)object_new_typed(_sym_nobox, _sym_jpatcher, 1, a); object_attr_setlong(p, _sym_locked, 1); // start out locked object_attr_setchar(p, _sym_enablehscroll, 0); // turn off scroll bars object_attr_setchar(p, _sym_enablevscroll, 0); object_attr_setchar(p, _sym_toolbarvisible, 0); object_attr_setsym(p, _sym_title, gensym("Welcome to Plugtastic")); object_attr_setparse(p, _sym_rect, "271 170 799 489"); object_attr_setparse(p, _sym_defrect, "271 170 799 489"); object_method(p, _sym_vis); // "vis" happens immediately, "front" is defer_lowed object_method(p, _sym_loadbang); // object_method_parse(p, _sym_window, "constrain 799 489 799 489", NULL); object_method_parse(p, _sym_window, "flags nozoom", NULL); object_method_parse(p, _sym_window, "flags nogrow", NULL); object_method_parse(p, _sym_window, "exec", NULL); } return 0; }
void hoa_optim_dsp64(t_hoa_optim *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp64, gensym("dsp_add64"), x, hoa_optim_perform64, 0, NULL); }
void make_patchline(t_connect *x) { int connexions, valid_objects, i, j; valid_objects = 0; t_object *obj1, *obj2; t_hoa_err err[2]; t_hoa_boxinfos* startobj_infos; t_hoa_boxinfos* endobj_infos; short startobj_type, endobj_type; long outlets, inlets; if (x->f_nbSelected > 1) { for (i = 0; i < x->f_nbSelected; i++) { obj1 = jbox_get_object(x->f_objects[i]); if(object_is_hoa(obj1) || is_obj_hoa_exotic(obj1)) x->f_objects[valid_objects++] = x->f_objects[i]; // ! store BOX objects } if (valid_objects > 1) { startobj_infos = (t_hoa_boxinfos*) malloc( sizeof(t_hoa_boxinfos)); endobj_infos = (t_hoa_boxinfos*) malloc( sizeof(t_hoa_boxinfos)); for(i = 1; i < valid_objects; i++) { obj1 = jbox_get_object(x->f_objects[i-1]); obj2 = jbox_get_object(x->f_objects[ i ]); outlets = inlets = 0; // referenced object or exotic hoa one; startobj_type = object_is_hoa(obj1); endobj_type = object_is_hoa(obj2); hoa_boxinfos_init(startobj_infos); hoa_boxinfos_init(endobj_infos); err[0] = (t_hoa_err) object_method(obj1, hoa_sym_hoa_getinfos, startobj_infos, NULL); err[1] = (t_hoa_err) object_method(obj2, hoa_sym_hoa_getinfos, endobj_infos, NULL); // get number of outlets if (startobj_type == 1 && err[0] == HOA_ERR_NONE) outlets = startobj_infos->autoconnect_outputs; else outlets = outlet_count(obj1); // get number of inlets if (endobj_type == 1 && err[1] == HOA_ERR_NONE) inlets = endobj_infos->autoconnect_inputs; else inlets = inlet_count(obj2); connexions = MIN(outlets, inlets); for(j = 0; j < connexions; j++) connect_connect(x->f_patcher, x->f_objects[i-1], j, x->f_objects[i], j); } free(startobj_infos); free(endobj_infos); } for(i = 0; i < CONNECT_MAX_TAB; i++) x->f_objects[i] = NULL; jpatcher_set_dirty(x->f_patcherview, true); } x->f_nbSelected = 0; }
void decibels_dsp64(t_decibels *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { if (count[0] && count[1]) object_method(dsp64, gensym("dsp_add64"), (t_object*)x, decibels_perform64, 0, NULL); }
// we get the text, convert it to an OSC bundle, and then call the paint // function via qelem_set which converts the OSC bundle back to text. // We do this so that it's formatted nicely with no unnecessary whitespace // and tabbed subbundles, etc. void odisplay_gettext(t_odisplay *x) { long size = 0; char *text = NULL; #ifdef OMAX_PD_VERSION text = x->textbox->text; #else t_object *textfield = jbox_get_textfield((t_object *)x); object_method(textfield, gensym("gettextptr"), &text, &size); #endif odisplay_clearBundles(x); size = strlen(text); // the value returned in text doesn't make sense if(size == 0){ return; } char *buf = text; if(text[size - 1] != '\n'){ buf = alloca(size + 2); memcpy(buf, text, size); buf[size] = '\n'; buf[size + 1] = '\0'; size += 2; } t_osc_bndl_u *bndl_u = NULL; t_osc_err e = osc_parser_parseString(size, buf, &bndl_u); if(e){ #ifdef OMAX_PD_VERSION // x->parse_error = 1; #endif object_error((t_object *)x, "error parsing bundle\n"); return; } t_osc_bndl_s *bs = osc_bundle_u_serialize(bndl_u); t_osc_bndl_s *bndl_s = NULL; osc_bundle_s_deepCopy(&bndl_s, bs); odisplay_newBundle(x, bndl_u, bndl_s); #ifdef OMAX_PD_VERSION x->have_new_data = 1; jbox_redraw((t_jbox *)x); #else x->have_new_data = 1; qelem_set(x->qelem); #endif /* if(size > 2){ int i; char *r = text + 1; char *w = text + 1; char *rm1 = text; for(i = 0; i <= size; i++){ if(*rm1 == ' ' && *r == ' '){ r++; }else{ *w++ = *r++; } rm1++; } } */ }
void randomvals_dsp64(t_randomvals *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp64, gensym("dsp_add64"), x, randomvals_perform64, 0, NULL); }
// DSP Method void OutDsp(OutPtr self, t_signal** sp, short* count) { //TTUInt16 i; TTUInt16 k=0; void **audioVectors = NULL; MaxErr err; long result = 0; self->vectorSize = sp[0]->s_n; #ifdef DEBUG_NOTIFICATIONS object_post(SELF, "dsp method called"); #endif // DEBUG_NOTIFICATIONS /* We need to figure out what objects are connected to what inlets to build the graph: 1. Broadcast 'audio.reset' to every object in the patcher, to remove all existing connections. 2. Broadcast 'audio.setup' to every object in the patcher, to tell objects to then send 'audio.connect' messages to any objects below them. 3. When an object received 'audio.connect', then it makes the connection. At this point, the graph is configured and we just need to execute it. We execute the graph from our perform method, which MSP calls once per signal vector. 5. Crawl the graph from bottom to top, calling the audio graph preprocess method (prepare for process) 6. Crawl the graph from bottom to top, calling the audio graph process method (calculate the samples) 7. (Maybe) crawl the graph from bottom to top, calling a audio graph postprocess method For steps 1 & 2, we have to traverse thge patcher twice, because we have to clear all connections first, then add connections. It won't work to do them both during the same traversal because situations arise Where we setup the chain and then it gets reset again by another object (since the order in which we traverse objects is undefined). */ if (!self->hasReset) { ObjectPtr patcher = NULL; ObjectPtr parent = NULL; ObjectPtr patcherview = NULL; // first find the top-level patcher err = object_obex_lookup(self, gensym("#P"), &patcher); parent = patcher; while (parent) { patcher = parent; parent = object_attr_getobj(patcher, _sym_parentpatcher); } // now iterate recursively from the top-level patcher down through all of the subpatchers object_method(patcher, gensym("iterate"), (method)OutIterateResetCallback, self, PI_DEEP, &result); object_method(patcher, gensym("iterate"), (method)OutIterateSetupCallback, self, PI_DEEP, &result); // now let's attach to the patcherview to get notifications about any further changes to the patch cords // the patcher 'dirty' attribute is not modified for each change, but the patcherview 'dirty' attribute is if (!self->patcherview) { patcherview = jpatcher_get_firstview(patcher); self->patcherview = patcherview; self->patcher = patcher; object_attach_byptr_register(self, patcherview, _sym_nobox); } } // now we want to go a step further and attach to all of the patch cords // this is how we will know if one is deleted OutAttachToPatchlinesForPatcher(self, self->patcher); // Setup the perform method //audioVectors = (void**)sysmem_newptr(sizeof(void*) * (self->maxNumChannels + 1)); audioVectors = (void**)sysmem_newptr(sizeof(void*) * (1)); audioVectors[k] = self; k++; //self->numChannels = 0; /*for (i=1; i <= self->maxNumChannels; i++) { self->numChannels++; audioVectors[k] = sp[i]->s_vec; k++; }*/ self->numChannels = self->maxNumChannels; //[np] self->audioGraphObject->getUnitGenerator()->setAttributeValue(kTTSym_sampleRate, sp[0]->s_sr); self->audioGraphObject->resetSampleStamp(); self->sampleCount = 0; dsp_addv(OutPerform, k, audioVectors); sysmem_freeptr(audioVectors); self->initData.vectorSize = self->vectorSize; }
void prc_chorus_dsp64(t_prc_chorus *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { Stk::setSampleRate(samplerate); object_method(dsp64, gensym("dsp_add64"), x, prc_chorus_perform64, 0, NULL); }
void buffi_autofunc(t_buffi *x, t_floatarg minval, t_floatarg maxval, t_symbol *buffername) { int minpoints, maxpoints, segpoints, i; int pointcount = 0; double target, lastval; double m1, m2; t_buffer_ref *tablebuf_ref; t_buffer_obj *dbuf; long b_nchans; long b_frames; float *b_samples; ///// tablebuf_ref = buffer_ref_new((t_object*)x, buffername); dbuf = buffer_ref_getobject(tablebuf_ref); if(dbuf == NULL){ object_post((t_object*)x,"%s: nonexistent buffer ( %s )", OBJECT_NAME, buffername->s_name); return; } b_nchans = buffer_getchannelcount(dbuf); b_frames = buffer_getframecount(dbuf); if(b_nchans != 1){ post("%s: table must be mono",OBJECT_NAME); return; } x->warpfunc = (float *)sysmem_newptr(b_frames * sizeof(float)); minpoints = 0.05 * (float) b_frames; maxpoints = 0.25 * (float) b_frames; if( minval > 1000.0 || minval < .001 ){ minval = 0.5; } if( maxval < 0.01 || maxval > 1000.0 ){ minval = 2.0; } lastval = buffi_randf(minval, maxval); // post("automate: min %d max %d",minpoints, maxpoints); while( pointcount < b_frames ){ target = buffi_randf(minval, maxval); segpoints = minpoints + (rand() % (maxpoints-minpoints)); if( pointcount + segpoints > b_frames ){ segpoints = b_frames - pointcount; } for( i = 0; i < segpoints; i++ ){ m2 = (float)i / (float) segpoints ; m1 = 1.0 - m2; x->warpfunc[ pointcount + i ] = m1 * lastval + m2 * target; } lastval = target; pointcount += segpoints; } // buffer stuffer b_samples = buffer_locksamples(dbuf); for(i = 0; i < b_frames; i++){ b_samples[i] = x->warpfunc[i]; } buffer_unlocksamples(dbuf); sysmem_freeptr( (void *) x->warpfunc ); object_method(dbuf, gensym("dirty")); }
void scope_dsp64(t_scope *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp64, gensym("dsp_add64"), x, scope_perform64, 0, NULL); x->f_startclock = 1; }
void freeverb_dsp(t_freeverb *x, t_object *dsp, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp, gensym("dsp_add"), x, (method)freeverb_perform, 0, NULL); }
void hoa_converter_tilde_dsp(t_hoa_converter_tilde *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp64, gensym("dsp_add64"), x, (method)hoa_converter_tilde_perform, 0, NULL); }
void hoa_meter_dsp64(t_hoa_meter *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { x->f_meter->setVectorSize(maxvectorsize); object_method(dsp64, gensym("dsp_add64"), x, hoa_meter_perform64, 0, NULL); x->f_startclock = 1; }
void gain_dsp(t_gain *x, t_object *dsp, short *count, double samplerate, long maxvectorsize, long flags) { x->f_sample_rate = pd_clip_min(samplerate, 1); x->f_ramp_sample = pd_clip_min(x->f_ramp * x->f_sample_rate / 1000., 1); object_method(dsp, gensym("dsp_add"), x, (method)gain_perform, 0, NULL); }
void hoa_dac_assist(t_hoa_dac *x, void *b, long m, long a, char *s) { object_method(x->f_dac, gensym("assist"), b, m, a, s); }
void cambio_dsp(t_cambio *x, t_object *dsp, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp, gensym("dsp_add"), x, cambio_perform, 0, NULL); }
void hoa_dac_dblclick(t_hoa_dac *x) { object_method(x->f_dac, gensym("dblclick"), 0, NULL); }
void hoa_dac_dsp64(t_hoa_dac *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { object_method((t_object *)x->f_dac, gensym("dsp64"), dsp64, count, samplerate, maxvectorsize, flags); }
void HoaBinaural_dsp64(t_HoaBinaural *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { x->f_ambiBinaural->setVectorSize(maxvectorsize); x->f_ambiBinaural->setSamplingRate(samplerate); object_method(dsp64, gensym("dsp_add64"), x, HoaBinaural_perform64, 0, NULL); }
void hoa_dac_stop(t_hoa_dac *x) { object_method(x->f_dac, gensym("stop"), NULL, NULL); }
void HoaSevenDotOne_dsp64(t_HoaSevenDotOne *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { x->f_AmbisonicSixDotOne->setVectorSize(maxvectorsize); object_method(dsp64, gensym("dsp_add64"), x, HoaSevenDotOne_perform64, 0, NULL); }
void hoa_dac_startwindow(t_hoa_dac *x) { object_method(x->f_dac, gensym("startwindow"), NULL, NULL); }
t_max_err wrappedModularClass_attrSet(TTPtr self, t_object *attr, long argc, const t_atom *argv) { WrappedModularInstancePtr x = (WrappedModularInstancePtr)self; t_symbol *attrName = (t_symbol*)object_method(attr, _sym_getname); TTValue v; long ac = 0; t_atom *av = NULL; t_max_err m_err; TTErr err; TTPtr ptr; // for an array of wrapped object if (x->useInternals && !x->iterateInternals) { TTValue keys; // temporary set x->iterateInternals to YES x->iterateInternals = YES; // then recall this method for each element of the array if (!x->internals->isEmpty()) { err = x->internals->getKeys(keys); if (!err) { for (TTUInt32 i = 0; i < keys.size(); i++) { x->cursor = keys[i]; wrappedModularClass_attrSet(self, attr, argc, argv); } } } // reset x->iterateInternals to NO x->iterateInternals = NO; return MAX_ERR_NONE; } m_err = hashtab_lookup(x->wrappedClassDefinition->maxNamesToTTNames, attrName, (t_object**)&ptr); if (m_err) return m_err; TTSymbol ttAttrName(ptr); // set attribute's value if (argc && argv) { jamoma_ttvalue_from_Atom(v, _sym_nothing, argc, argv); if (selectedObject) { selectedObject->setAttributeValue(ttAttrName, v); return MAX_ERR_NONE; } else return MAX_ERR_GENERIC; } // or get it and dumpout his value else { if (selectedObject) { // don't consider array case here (they should have all the same attribute value) selectedObject->getAttributeValue(ttAttrName, v); jamoma_ttvalue_to_Atom(v, &ac, &av); object_obex_dumpout(self, attrName, ac, av); sysmem_freeptr(av); return MAX_ERR_NONE; } else return MAX_ERR_GENERIC; } return MAX_ERR_GENERIC; }
void hoa_dac_open(t_hoa_dac *x) { object_method(x->f_dac, gensym("open"), NULL, NULL); }
void jitter_dsp64(t_jitter *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) { object_method(dsp64, gensym("dsp_add64"), x, jitter_perform64, 0, NULL); }
void hoa_dac_wclose(t_hoa_dac *x) { object_method(x->f_dac, gensym("wclose"), NULL, NULL); }
void hoa_projector_dsp(t_hoa_projector *x, t_object *dsp, short *count, double samplerate, long maxvectorsize, long flags) { x->f_ambi_projector->setVectorSize(maxvectorsize); object_method(dsp, gensym("dsp_add"), x, (method)hoa_projector_perform, 0, NULL); }
void hoa_dac_int(t_hoa_dac *x, long l) { object_method(x->f_dac, l == 1 ? gensym("start") : gensym("stop"), NULL, NULL); }
void color_patchline(t_connect *x) { t_object *line, *startobj; t_object *jb, *o; t_hoa_err err; t_jrgba* linecolor = NULL; int inletnum, sign; short startobj_type; t_hoa_boxinfos* startobj_infos = (t_hoa_boxinfos*) malloc( sizeof(t_hoa_boxinfos)); line = jpatcher_get_firstline(x->f_patcher); while (line) { startobj = jbox_get_object(jpatchline_get_box1(line)); if(object_is_hoa(startobj) || is_obj_hoa_exotic(startobj)) { startobj_type = object_is_hoa(startobj); hoa_boxinfos_init(startobj_infos); err = (t_hoa_err) object_method(startobj, hoa_sym_hoa_getinfos, startobj_infos, NULL); if (err == HOA_ERR_NONE) { // ambisonics colors (zero | neg | pos) (ex: hoa.encoder~ => hoa.optim~) if (startobj_infos->autoconnect_outputs_type == HOA_CONNECT_TYPE_AMBISONICS) { inletnum = jpatchline_get_inletnum(line); if (startobj_infos->object_type == HOA_OBJECT_2D) sign = x->f_ambi2D->getHarmonicArgument(inletnum); if (startobj_infos->object_type == HOA_OBJECT_3D) sign = x->f_ambi3D->getHarmonicArgument(inletnum); if (sign > 0) linecolor = &x->f_color_positiv; else if (sign < 0) linecolor = &x->f_color_negativ; else linecolor = &x->f_color_zero; jpatchline_set_color(line, linecolor); } // planewave color (ex: hoa.projector~ => hoa.recomposer~) else if (startobj_infos->autoconnect_outputs_type == HOA_CONNECT_TYPE_PLANEWAVES) { jpatchline_set_color(line, &x->f_color_plane); } } // hoa.plug~ retro compatibility else if (object_classname(startobj) == hoa_sym_jpatcher) { jb = jpatcher_get_firstobject(startobj); while(jb) { o = jbox_get_object(jb); if(object_classname(o) == gensym("hoa.plug_script")) { inletnum = jpatchline_get_inletnum(line); if (inletnum == 0) jpatchline_set_color(line, &x->f_color_zero); else if (inletnum % 2 == 1) jpatchline_set_color(line, &x->f_color_negativ); else jpatchline_set_color(line, &x->f_color_positiv); break; } jb = jbox_get_nextobject(jb); } } } line = jpatchline_get_nextline(line); } free(startobj_infos); }
t_max_err paramui_getRampFunction(t_paramui *x, void *attr, long *argc, t_atom **argv) { t_symbol *attrName = (t_symbol*)object_method(attr, _sym_getname); return object_attr_getvalueof(x->obj_parameter, attrName, argc, argv); }