t_max_err space_notify(t_space *x, t_symbol *s, t_symbol *msg, void *sender, void *data) { t_symbol *name; if (msg == gensym("attr_modified")) { name = (t_symbol *)object_method((t_object *)data, gensym("getname")); if(name == gensym("bgcolor") || name == gensym("borderboxcolor") || name == gensym("cicolor") || name == gensym("cicolorin") ) { jbox_invalidate_layer((t_object *)x, NULL, gensym("background_layer")); } else if(name == gensym("harmocolor")) { jbox_invalidate_layer((t_object *)x, NULL, gensym("harmonics_layer")); } else if(name == gensym("miccolor")) { jbox_invalidate_layer((t_object *)x, NULL, gensym("microphones_points_layer")); } else if(name == gensym("shadow")) { jbox_invalidate_layer((t_object *)x, NULL, gensym("background_layer")); if (x->f_shadow) object_attr_setdisabled((t_object *)x, gensym("cishadcolor"), 0); else object_attr_setdisabled((t_object *)x, gensym("cishadcolor"), 1); } jbox_redraw((t_jbox *)x); } return jbox_notify((t_jbox *)x, s, msg, sender, data); }
t_max_err mode_set(t_hoa_decoder *x, t_object *attr, long argc, t_atom *argv) { if(argc && argv && atom_gettype(argv) == A_SYM) { if(atom_getsym(argv) == gensym("ambisonic") && x->f_decoder->getDecodingMode() != Hoa2D::DecoderMulti::Regular) { object_method(gensym("dsp")->s_thing, gensym("stop")); x->f_decoder->setDecodingMode(Hoa2D::DecoderMulti::Regular); object_attr_setdisabled((t_object *)x, gensym("angles"), 1); object_attr_setdisabled((t_object *)x, gensym("channels"), 0); object_attr_setdisabled((t_object *)x, gensym("offset"), 0); object_attr_setfloat(x, gensym("offset"), (float)x->f_decoder->getChannelsOffset() / HOA_2PI * 360.f); } else if(atom_getsym(argv) == gensym("irregular") && x->f_decoder->getDecodingMode() != Hoa2D::DecoderMulti::Irregular) { object_method(gensym("dsp")->s_thing, gensym("stop")); x->f_decoder->setDecodingMode(Hoa2D::DecoderMulti::Irregular); object_attr_setdisabled((t_object *)x, gensym("angles"), 0); object_attr_setdisabled((t_object *)x, gensym("channels"), 0); object_attr_setdisabled((t_object *)x, gensym("offset"), 1); } else if(atom_getsym(argv) == gensym("binaural") && x->f_decoder->getDecodingMode() != Hoa2D::DecoderMulti::Binaural) { object_method(gensym("dsp")->s_thing, gensym("stop")); x->f_decoder->setDecodingMode(Hoa2D::DecoderMulti::Binaural); object_attr_setdisabled((t_object *)x, gensym("angles"), 1); object_attr_setdisabled((t_object *)x, gensym("channels"), 1); object_attr_setdisabled((t_object *)x, gensym("offset"), 1); } object_attr_setlong(x, gensym("channels"), x->f_decoder->getNumberOfChannels()); } send_configuration(x); return MAX_ERR_NONE; }
void *HoaRecomposer_new(t_symbol *s, long argc, t_atom *argv) { t_HoaRecomposer *x = NULL; t_dictionary *d; int order = 4, inputs = 10; x = (t_HoaRecomposer *)object_alloc((t_class*)HoaRecomposer_class); if (x) { if(atom_gettype(argv) == A_LONG) order = atom_getlong(argv); if(atom_gettype(argv+1) == A_LONG) inputs = atom_getlong(argv+1); /* Base Attributes */ x->f_ambiRecomposer = new AmbisonicRecomposer(order, inputs, Hoa_Fixe, sys_getblksize(), sys_getsr()); x->f_ambiRecomposer->setRampInMs(20.); x->f_ramp_time = x->f_ambiRecomposer->getRampInMs(); x->f_mode = gensym("fixe"); dsp_setup((t_pxobject *)x, x->f_ambiRecomposer->getNumberOfInputs()); for (int i = 0; i < x->f_ambiRecomposer->getNumberOfOutputs(); i++) outlet_new(x, "signal"); x->f_ob.z_misc = Z_NO_INPLACE; attr_args_process(x, argc, argv); d = (t_dictionary *)gensym("#D")->s_thing; if (d) attr_dictionary_process(x, d); object_attr_setdisabled((t_object *)x, gensym("ramp"), (x->f_mode == gensym("fixe")) ? 1 : 0); } return (x); }
void *HoaDelay_new(t_symbol *s, long argc, t_atom *argv) { t_HoaDelay *x = NULL; t_dictionary *d = NULL; int order = 4; bool mode = 1; double maxdelay = 5000.; x = (t_HoaDelay *)object_alloc(HoaDelay_class); if (x) { if(atom_gettype(argv) == A_LONG) order = atom_getlong(argv); if(atom_gettype(argv+1) == A_SYM && atom_getsym(argv+1) == gensym("no")) mode = 0; if(atom_gettype(argv+2) == A_LONG || atom_gettype(argv+2) == A_FLOAT) maxdelay = atom_getfloat(argv+2); x->f_AmbiDelay = new AmbisonicsDelay(order, mode, maxdelay, sys_getblksize(), sys_getsr()); dsp_setup((t_pxobject *)x, x->f_AmbiDelay->getNumberOfInputs()); for (int i = 0; i < x->f_AmbiDelay->getNumberOfOutputs(); i++) outlet_new(x, "signal"); x->f_ramp_time = x->f_AmbiDelay->getRampInMs(); x->f_diffuse_factor = x->f_AmbiDelay->getDiffuseFactor(); x->f_encoding_compensation = x->f_AmbiDelay->getEncodingCompensation(); x->f_delay = x->f_AmbiDelay->getDelayTimeInMs(); if(x->f_AmbiDelay->getMode() == Hoa_No_Encoding) { object_attr_setdisabled((t_object*)x, gensym("diffusion"), 1); object_attr_setdisabled((t_object*)x, gensym("compensation"), 1); } x->f_ob.z_misc = Z_NO_INPLACE; d = (t_dictionary *)gensym("#D")->s_thing; if (d) attr_dictionary_process(x, d); attr_args_process(x, argc, argv); } return (x); }
t_max_err HoaRecomposer_set_attr_mode(t_HoaRecomposer *x, t_object *attr, long argc, t_atom *argv) { long lastNumberOfInputs = x->f_ambiRecomposer->getNumberOfInputs(); if(argc && argv) { int dspState = sys_getdspobjdspstate((t_object*)x); if(dspState) object_method(gensym("dsp")->s_thing, gensym("stop")); if(atom_gettype(argv) == A_SYM) { t_symbol* newModeSym = atom_getsym(argv); int newModeInt = (newModeSym == gensym("free")) ? Hoa_Free : (newModeSym == gensym("fisheye")) ? Hoa_Fisheye : 0; x->f_ambiRecomposer->setMode(newModeInt); } else if(atom_gettype(argv) == A_LONG || atom_gettype(argv) == A_FLOAT) { x->f_ambiRecomposer->setMode(atom_getfloat(argv)); } int newModeInt = x->f_ambiRecomposer->getMode(); x->f_mode = (newModeInt == Hoa_Free) ? gensym("free") : (newModeInt == Hoa_Fisheye) ? gensym("fisheye") : gensym("fixe"); if (lastNumberOfInputs != x->f_ambiRecomposer->getNumberOfInputs()) { t_object *b = NULL; object_obex_lookup(x, gensym("#B"), (t_object **)&b); object_method(b, gensym("dynlet_begin")); dsp_resize((t_pxobject*)x, x->f_ambiRecomposer->getNumberOfInputs()); object_method(b, gensym("dynlet_end")); } if(x->f_ambiRecomposer->getMode() == Hoa_Fixe) object_attr_setdisabled((t_object *)x, gensym("ramp"), 1); else object_attr_setdisabled((t_object *)x, gensym("ramp"), 0); } return MAX_ERR_NONE; }
t_max_err mode_set(t_hoa_3d_decoder *x, t_object *attr, long argc, t_atom *argv) { if(argc && argv && atom_gettype(argv) == A_SYM) { t_symbol* mode = atom_getsym(argv); if(mode == hoa_sym_ambisonic) // retro-compatibility { mode = hoa_sym_regular; } if (mode != x->f_mode) { if(mode == hoa_sym_regular) { object_method(hoa_sym_dsp->s_thing, hoa_sym_stop); ulong order = x->f_decoder->getDecompositionOrder(); x->f_decoder = SharedPtr<Decoder<Hoa3d, float>>(new Decoder<Hoa3d, float>::Regular(order, (order+1)*(order+1))); x->f_mode = mode; object_attr_setdisabled((t_object *)x, hoa_sym_angles, 0); object_attr_setdisabled((t_object *)x, hoa_sym_offset, 0); object_attr_setdisabled((t_object *)x, hoa_sym_channels, 0); object_attr_setdouble_array(x, hoa_sym_offset, 3, x->f_offsets); x->f_number_of_channels = x->f_decoder->getNumberOfPlanewaves(); object_attr_touch((t_object *)x, hoa_sym_channels); object_attr_touch((t_object *)x, hoa_sym_angles); hoa_3d_decoder_resize_outlets(x); } else if(mode == hoa_sym_binaural) { object_method(hoa_sym_dsp->s_thing, hoa_sym_stop); ulong order = x->f_decoder->getDecompositionOrder(); x->f_decoder = SharedPtr<Decoder<Hoa3d, float>>(new Decoder<Hoa3d, float>::Binaural(order)); x->f_mode = mode; object_attr_setdisabled((t_object *)x, hoa_sym_angles, 1); object_attr_setdisabled((t_object *)x, hoa_sym_offset, 1); object_attr_setdisabled((t_object *)x, hoa_sym_channels, 1); x->f_mode = mode; x->f_number_of_channels = 2; object_attr_touch((t_object *)x, hoa_sym_channels); object_attr_touch((t_object *)x, hoa_sym_angles); hoa_3d_decoder_resize_outlets(x); } } } return MAX_ERR_NONE; }
t_max_err channels_set(t_meter *x, t_object *attr, long argc, t_atom *argv) { if(argc && argv && atom_isNumber(argv)) { t_object *b = NULL; int numberOfPlanewaves = atom_getlong(argv); if(numberOfPlanewaves != x->f_meter->getNumberOfPlanewaves() && numberOfPlanewaves > 0 && numberOfPlanewaves <= MAX_UI_CHANNELS) { object_method(hoa_sym_dsp->s_thing, hoa_sym_stop); if (x->f_meter) delete x->f_meter; if (x->f_vector) delete x->f_vector; x->f_meter = new Meter<Hoa2d, t_sample>(numberOfPlanewaves); x->f_vector = new Vector<Hoa2d, t_sample>(numberOfPlanewaves); x->f_meter->computeRendering(); x->f_vector->computeRendering(); object_obex_lookup(x, hoa_sym_pound_B, (t_object **)&b); object_method(b, hoa_sym_dynlet_begin); dsp_resize((t_pxobject*)x, x->f_meter->getNumberOfPlanewaves()); object_method(b, hoa_sym_dynlet_end); if (x->f_meter->getNumberOfPlanewaves() == 1) { object_attr_setdisabled((t_object*)x, hoa_sym_angles, 1); object_attr_setdisabled((t_object*)x, gensym("offset"), 1); object_attr_setdisabled((t_object*)x, gensym("rotation"), 1); } else { object_attr_setdisabled((t_object*)x, hoa_sym_angles, 0); object_attr_setdisabled((t_object*)x, gensym("offset"), 0); object_attr_setdisabled((t_object*)x, gensym("rotation"), 0); } } object_attr_setvalueof(x, hoa_sym_angles, 0, NULL); } return MAX_ERR_NONE; }
t_max_err number_of_channels_set(t_meter *x, t_object *attr, long argc, t_atom *argv) { t_object *b = NULL; int numberOfChannels; if(argc && argv && atom_gettype(argv) == A_LONG) { numberOfChannels = atom_getlong(argv); if(numberOfChannels != x->f_meter->getNumberOfChannels() && numberOfChannels > 0 && numberOfChannels <= MAX_SPEAKER) { int dspState = sys_getdspobjdspstate((t_object*)x); if(dspState) object_method(gensym("dsp")->s_thing, gensym("stop")); delete x->f_meter; delete x->f_vector; x->f_number_of_channels = numberOfChannels; x->f_meter = new Hoa2D::Meter(x->f_number_of_channels); x->f_vector = new Hoa2D::Vector(x->f_number_of_channels); object_obex_lookup(x, gensym("#B"), (t_object **)&b); object_method(b, gensym("dynlet_begin")); dsp_resize((t_pxobject*)x, x->f_number_of_channels); object_method(b, gensym("dynlet_end")); if (x->f_number_of_channels == 1) { object_attr_setdisabled((t_object*)x, gensym("angles"), 1); object_attr_setdisabled((t_object*)x, gensym("offset"), 1); object_attr_setdisabled((t_object*)x, gensym("rotation"), 1); } else { object_attr_setdisabled((t_object*)x, gensym("angles"), 0); object_attr_setdisabled((t_object*)x, gensym("offset"), 0); object_attr_setdisabled((t_object*)x, gensym("rotation"), 0); } object_attr_setvalueof(x, gensym("angles"), 0, NULL); } } return NULL; }
t_max_err configuration_set(t_HoaDecode *x, t_object *attr, long argc, t_atom *argv) { if(atom_gettype(argv) == A_SYM) { int dspState = sys_getdspobjdspstate((t_object*)x); if(dspState) object_method(gensym("dsp")->s_thing, gensym("stop")); long numOutlet = x->f_AmbisonicsDecoder->getNumberOfOutputs(); if(atom_getsym(argv) == gensym("binaural") || atom_getsym(argv) == gensym(" binaural")) { x->f_AmbisonicsDecoder->setMode(Hoa_Dec_Binaural); x->f_mode = gensym("binaural"); object_attr_setdisabled((t_object *)x, gensym("angles"), 1); object_attr_setdisabled((t_object *)x, gensym("pinnaesize"), 0); object_attr_setdisabled((t_object *)x, gensym("loudspeakers"), 1); object_attr_setdisabled((t_object *)x, gensym("restitution"), 1); } else if(atom_getsym(argv) == gensym("irregular") || atom_getsym(argv) == gensym(" irregular")) { x->f_AmbisonicsDecoder->setMode(Hoa_Dec_Irregular); x->f_mode = gensym("irregular"); object_attr_setdisabled((t_object *)x, gensym("angles"), 0); object_attr_setdisabled((t_object *)x, gensym("pinnaesize"), 1); object_attr_setdisabled((t_object *)x, gensym("loudspeakers"), 0); object_attr_setdisabled((t_object *)x, gensym("restitution"), 0); } else { x->f_AmbisonicsDecoder->setMode(Hoa_Dec_Ambisonic); x->f_mode = gensym("ambisonic"); object_attr_setdisabled((t_object *)x, gensym("angles"), 1); object_attr_setdisabled((t_object *)x, gensym("pinnaesize"), 1); object_attr_setdisabled((t_object *)x, gensym("loudspeakers"), 0); object_attr_setdisabled((t_object *)x, gensym("restitution"), 1); } HoaDecode_resize_outlet(x, numOutlet); x->f_number_of_loudspeakers = x->f_AmbisonicsDecoder->getNumberOfOutputs(); for(int i = 0; i < x->f_number_of_loudspeakers; i++) x->f_angles_of_loudspeakers[i] = x->f_AmbisonicsDecoder->getLoudspeakerAngle(i); object_attr_touch((t_object *)x, gensym("loudspeakers")); object_attr_touch((t_object *)x, gensym("angles")); } return NULL; }
void *HoaDecode_new(t_symbol *s, long argc, t_atom *argv) { t_HoaDecode *x = NULL; int order = 4; x = (t_HoaDecode *)object_alloc((t_class*)HoaDecode_class); if(x) { if(atom_gettype(argv) == A_LONG || atom_gettype(argv) == A_FLOAT) order = atom_getfloat(argv); /* Base Attributes */ x->f_mode = gensym("ambisonics"); x->f_number_of_loudspeakers = order * 2 + 2; x->f_pinna_size = gensym("small"); x->f_resitution_mode = gensym("panning"); x->f_send_config =1; #ifdef MAC_VERSION // OSX only : access to the hoa.binaural~ bundle CFBundleRef hoaBinaural_bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.cicm.hoa-decoder-")); CFURLRef hoaBinaural_ref = CFBundleCopyBundleURL(hoaBinaural_bundle); UInt8 bundle_path[512]; Boolean res = CFURLGetFileSystemRepresentation(hoaBinaural_ref, true, bundle_path, 512); assert(res); // Built the complete resource path std::string absoluteHrtfFilePath = std::string((const char*)bundle_path) + std::string("/Contents/Resources/") + std::string("HrtfDatabase/"); #endif #ifdef WIN_VERSION #ifdef WIN64 HMODULE handle = LoadLibrary("hoa.decoder~.mxe64"); char bundle_path[512]; GetModuleFileName(handle, bundle_path, 512); std::string absoluteHrtfFilePath = std::string((const char*)bundle_path); absoluteHrtfFilePath.erase(absoluteHrtfFilePath.size()-18, 18); absoluteHrtfFilePath.append("HrtfDatabase/"); FreeLibrary(handle); #else HMODULE handle = LoadLibrary("hoa.decoder~.mxe"); char bundle_path[512]; GetModuleFileName(handle, bundle_path, 512); std::string absoluteHrtfFilePath = std::string((const char*)bundle_path); absoluteHrtfFilePath.erase(absoluteHrtfFilePath.size()-16, 16); absoluteHrtfFilePath.append("HrtfDatabase/"); FreeLibrary(handle); #endif #endif x->f_AmbisonicsDecoder = new AmbisonicsMultiDecoder(order, x->f_number_of_loudspeakers, Hoa_Dec_Ambisonic, Hoa_Small, absoluteHrtfFilePath, sys_getblksize(), sys_getsr()); for(int i = 0; i < x->f_AmbisonicsDecoder->getNumberOfLoudspeakers(); i++) x->f_angles_of_loudspeakers[i] = x->f_AmbisonicsDecoder->getLoudspeakerAngle(i); object_attr_setdisabled((t_object *)x, gensym("angles"), 1); object_attr_setdisabled((t_object *)x, gensym("pinnaesize"), 1); object_attr_setdisabled((t_object *)x, gensym("loudspeakers"), 0); object_attr_setdisabled((t_object *)x, gensym("restitution"), 1); /* DSP Setup */ dsp_setup((t_pxobject *)x, x->f_AmbisonicsDecoder->getNumberOfInputs()); for (int i = 0; i < x->f_AmbisonicsDecoder->getNumberOfOutputs(); i++) outlet_new(x, "signal"); attr_args_process(x, argc, argv); x->f_ob.z_misc = Z_NO_INPLACE; } return (x); }