void bed_paste (t_bed *x, t_symbol *destname) { if (x->can_undo && x->undo_cut) { if (!bed_attach_buffer(x)) { return; } t_buffer *destbuf = NULL; if (bed_attach_any_buffer(&destbuf, destname)) { if (x->buffer->b_nchans != destbuf->b_nchans) { post("bed • Different number of channels of origin (%d) " "and number of channel of destination (%d)", x->buffer->b_nchans, destbuf->b_nchans); return; } t_atom rv; object_method_long(&destbuf->b_obj, gensym("sizeinsamps"), x->undo_frames, &rv); ATOMIC_INCREMENT(&destbuf->b_inuse); long chunksize = x->undo_frames * destbuf->b_nchans * sizeof(float); sysmem_copyptr(x->undo_samples, destbuf->b_samples, chunksize); ATOMIC_DECREMENT(&destbuf->b_inuse); } else { post("bed • \"%s\" is not a valid buffer", destname->s_name); return; } } else { post("bed • Nothing to paste"); return; } }
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 bed_undo(t_bed *x) { if (!x->can_undo) { post("bed • Nothing to undo"); return; } if (!bed_attach_buffer(x)) { return; } t_buffer *b; b = x->buffer; ATOMIC_INCREMENT(&b->b_inuse); if (!b->b_valid) { ATOMIC_DECREMENT(&b->b_inuse); post("bed • Not a valid buffer!"); return; } if (x->undo_cut) { long bufferframes = b->b_frames; long buffersize = bufferframes * b->b_nchans * sizeof(float); float *local_buffer = (float *)sysmem_newptr(buffersize); if (local_buffer == NULL) { error("bed • Cannot allocate memory for undo"); x->can_undo = 0; ATOMIC_DECREMENT(&b->b_inuse); return; } else { sysmem_copyptr(b->b_samples, local_buffer, buffersize); } ATOMIC_DECREMENT(&b->b_inuse); t_atom rv; object_method_long(&b->b_obj, gensym("sizeinsamps"), (bufferframes + x->undo_frames), &rv); ATOMIC_INCREMENT(&b->b_inuse); long chunksize = x->undo_start * b->b_nchans * sizeof(float); sysmem_copyptr(local_buffer, b->b_samples, chunksize); chunksize = x->undo_frames * b->b_nchans * sizeof(float); sysmem_copyptr(x->undo_samples, b->b_samples + (x->undo_start * b->b_nchans), chunksize); chunksize = (bufferframes - x->undo_start) * b->b_nchans * sizeof(float); sysmem_copyptr(local_buffer + (x->undo_start * b->b_nchans), b->b_samples + (x->undo_start + x->undo_frames) * b->b_nchans, chunksize); sysmem_freeptr(local_buffer); x->undo_cut = 0; object_method(&b->b_obj, gensym("dirty")); ATOMIC_DECREMENT(&b->b_inuse); return; } if (x->undo_resize) { ATOMIC_DECREMENT(&b->b_inuse); t_atom rv; object_method_long(&b->b_obj, gensym("sizeinsamps"), x->undo_frames, &rv); ATOMIC_INCREMENT(&b->b_inuse); } long chunksize = x->undo_frames * b->b_nchans * sizeof(float); sysmem_copyptr(x->undo_samples, b->b_samples + x->undo_start, chunksize); x->can_undo = 0; object_method(&b->b_obj, gensym("dirty")); ATOMIC_DECREMENT(&b->b_inuse); }
void bed_cut(t_bed *x, double start, double end) { if (!bed_attach_buffer(x)) { return; } t_buffer *b; b = x->buffer; ATOMIC_INCREMENT(&b->b_inuse); if (!b->b_valid) { ATOMIC_DECREMENT(&b->b_inuse); post("bed • Not a valid buffer!"); return; } long startframe = start * 0.001 * b->b_sr; long endframe = end * 0.001 * b->b_sr; long cutframes = endframe - startframe; if (startframe < 0 || endframe > b->b_frames || startframe > endframe) { post("bed • %.0fms and %.0fms are not valid cut times", start, end); ATOMIC_DECREMENT(&b->b_inuse); return; } long chunksize = cutframes * b->b_nchans * sizeof(float); if (x->undo_samples == NULL) { x->undo_samples = (float *)sysmem_newptr(chunksize); } else { x->undo_samples = (float *)sysmem_resizeptr(x->undo_samples, chunksize); } if (x->undo_samples == NULL) { error("bed • Cannot allocate memory for undo"); x->can_undo = 0; ATOMIC_DECREMENT(&b->b_inuse); return; } else { x->can_undo = 1; x->undo_start = startframe; x->undo_frames = cutframes; x->undo_resize = 1; x->undo_cut = 1; sysmem_copyptr(b->b_samples + (startframe * b->b_nchans), x->undo_samples, chunksize); } long bufferframes = b->b_frames; long buffersize = bufferframes * b->b_nchans * sizeof(float); float *local_buffer = (float *)sysmem_newptr(buffersize); if (local_buffer == NULL) { error("bed • Cannot allocate memory for undo"); x->can_undo = 0; ATOMIC_DECREMENT(&b->b_inuse); return; } else { sysmem_copyptr(b->b_samples, local_buffer, buffersize); } ATOMIC_DECREMENT(&b->b_inuse); t_atom rv; object_method_long(&b->b_obj, gensym("sizeinsamps"), (b->b_frames - cutframes), &rv); ATOMIC_INCREMENT(&b->b_inuse); chunksize = startframe * b->b_nchans * sizeof(float); sysmem_copyptr(local_buffer, b->b_samples, chunksize); chunksize = (bufferframes - endframe) * b->b_nchans * sizeof(float); sysmem_copyptr(local_buffer + (endframe * b->b_nchans), b->b_samples + (startframe * b->b_nchans), chunksize); sysmem_freeptr(local_buffer); object_method(&b->b_obj, gensym("dirty")); ATOMIC_DECREMENT(&b->b_inuse); }
void jamoma_init(void) { if(!initialized){ t_object* max = gensym("max")->s_thing; t_symbol* meth = gensym("objectfile"); t_atom a[4]; if(maxversion() >= 0x0500) max5 = true; TTBlueInit(); common_symbols_init(); jamomaSymbolsInit(); receivemaster_initclass(); receive_initclass(); object_method(max, meth, gensym("jcom.receive"), gensym("jcom.loader"), gensym("jcom.receive")); object_method_sym(max, gensym("db.object_addinternal"), gensym("jcom.receive"), NULL); send_initclass(); object_method(max, meth, gensym("jcom.send"), gensym("jcom.loader"), gensym("jcom.send")); object_method_sym(max, gensym("db.object_addinternal"), gensym("jcom.send"), NULL); receive_tilde_initclass(); object_method(max, meth, gensym("jcom.receive~"), gensym("jcom.loader"), gensym("jcom.receive~")); object_method_sym(max, gensym("db.object_addinternal"), gensym("jcom.receive~"), NULL); send_tilde_initclass(); object_method(max, meth, gensym("jcom.send~"), gensym("jcom.loader"), gensym("jcom.send~")); object_method_sym(max, gensym("db.object_addinternal"), gensym("jcom.send~"), NULL); // Setup Class Aliases for TTBlue object_method(max, meth, gensym("jcom.limiter~"), gensym("tt.limiter~"), gensym("jcom.limiter~")); object_method(max, meth, gensym("jcom.saturation~"), gensym("tt.overdrive~"), gensym("jcom.saturation~")); // Create Required Global Instances // obj_jamoma_clock = (t_object*)object_new_typed(CLASS_NOBOX, gensym("jamoma.clock"), 0, NULL); // obj_jamoma_scheduler = (t_object*)object_new_typed(CLASS_NOBOX, gensym("jamoma.scheduler"), 0, NULL); hash_modules = (t_hashtab*)hashtab_new(0); // TODO: Use quittask_install() to set up a destructor for this to free it before Max exits // 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(max, 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(max, gensym("setmirrortoconsole"), 1, NULL); // Add Jamoma Key Commands: // J -- Jamoma: a new object box with "jcom." in it atom_setsym(a+0, gensym("J")); atom_setsym(a+1, gensym("patcher")); atom_setsym(a+2, gensym("inserttextobj")); atom_setsym(a+3, gensym("jcom.")); object_method_typed(max, gensym("definecommand"), 4, a, NULL); // M -- Module: a new object box with "jmod." in it atom_setsym(a+0, gensym("M")); atom_setsym(a+1, gensym("patcher")); atom_setsym(a+2, gensym("inserttextobj")); atom_setsym(a+3, gensym("jmod.")); object_method_typed(max, gensym("definecommand"), 4, a, NULL); // I -- Input: a new audio input module object_method_parse(max, gensym("definecommand"), "I patcher insertobj bpatcher @name jmod.input~.maxpat @args /input~", NULL); // O -- Output: a new audio output module object_method_parse(max, gensym("definecommand"), "O patcher insertobj bpatcher @name jmod.output~.maxpat @args /output~", NULL); // B -- BPatcher: a new module in a bpatcher object_method_parse(max, gensym("definecommand"), "B patcher inserttextobj \"bpatcher @name jmod. @args myModule\"", NULL); // D -- Demo: a new module in a bpatcher, but with the args reverse which is handy for super-fast demos when you don't care about the OSC name object_method_parse(max, gensym("definecommand"), "D patcher inserttextobj \"bpatcher @name jmod.\"", NULL); // Here bind the TTBlue environment object to the symbol "TTBlue" { t_symbol* TTBlueMaxSymbol = gensym("TTBlue"); TTBlueMaxSymbol->s_thing = 0; // Before we can do this we have to have a ttblue max class to receive the messages, duh... } // now the jamoma object { t_symbol* jamomaSymbol = gensym("jamoma"); jamoma_object_initclass(); jamomaSymbol->s_thing = jamoma_object_new(); } post("Jamoma %s - www.jamoma.org", JAMOMA_VERSION); initialized = true; } }