Sanguine Mutants - Mutable Instruments Alt Firmwares

Hi folks,

For v2.0-dev only: Sanguine Mutants - MetaModule - Google Drive

I am releasing an early first contribution to the MetaModule ecosystem, which is a port of most of the Sanguine Mutants modules with alternate parasites mutable instruments firmware to the MetaModule.

Please forgive me if it is a little bit rough around the edges, I notice that a lot of the graphics can sometimes be missing though the faceplates load, but everything is functional otherwise. I also wasn’t able to get the funes (plaits clone) to compile, but this is already available through the default Mutable Instruments MetaModule plugin anyways.

Known issues, perhaps @danngreen could take a look for some guidance to help me polish this when he has a moment.

I don’t know how to support NanoSVG: NanoSVG support in dev2.0? Porting SanguineMutants

I don’t know why sometimes I can’t get a mapped knob to reach the last value of a discrete states (like button mode toggles): Bug with discrete knobs/controls - I can't reach the highest discrete state with the mapped knob, but I can when manually adjusting the encoder - #2 by etcetc

I don’t know why I have to keep loading in the plugin when restarting the MetaModule, despite having selected autoload.

7 Likes

Thank you for working on these. Sorry to see that the Plaits clone cannot be compiled. Funes is based on the v1.2 Plaits firmware that has six additional models. The default version of Plaits in the MM does not have those models. Those new models include the ability to load 6-op FM (DX7) presets, wavetables, and wave terrain files. Perhaps it is the file loading capability that is causing the problems with compilation?

Yes, I’ll share the issues I’m running into as well as my cmake.

Cmakelists: CMakeLists-Sanguine.txt · GitHub

Demanged missing symbols:

Symbol in plugin not found in api: std::moneypunct<char, false>::~moneypunct()
Symbol in plugin not found in api: std::__throw_ios_failure(char const*)
Symbol in plugin not found in api: std::ctype<wchar_t>::do_widen(char) const
Symbol in plugin not found in api: std::string::append(char const*, unsigned int)
Symbol in plugin not found in api: std::__cxx11::collate<char>::id
Symbol in plugin not found in api: std::numpunct<char>::_M_initialize_numpunct(int*)
Symbol in plugin not found in api: std::__cxx11::time_get<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id
Symbol in plugin not found in api: std::__basic_file<char>::~__basic_file()
Symbol in plugin not found in api: plaits::fm::lut_cube_root
Symbol in plugin not found in api: std::__cxx11::messages<wchar_t>::messages(unsigned int)
Symbol in plugin not found in api: std::__cxx11::moneypunct<wchar_t, false>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: plaits::fm::Algorithms<6>::opcodes_
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_mutate(unsigned int, unsigned int, unsigned int)
Symbol in plugin not found in api: std::collate<wchar_t>::_M_transform(wchar_t*, wchar_t const*, unsigned int) const
Symbol in plugin not found in api: std::basic_istream<wchar_t, std::char_traits<wchar_t> >::ignore(int)
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::append(unsigned int, wchar_t)
Symbol in plugin not found in api: std::moneypunct<wchar_t, false>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: std::string::append(std::string const&)
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_replace_aux(unsigned int, unsigned int, unsigned int, wchar_t)
Symbol in plugin not found in api: std::ios_base::imbue(std::locale const&)
Symbol in plugin not found in api: std::ctype<char>::ctype(char const*, bool, unsigned int)
Symbol in plugin not found in api: std::locale::_Impl::_M_init_extra(std::locale::facet**)
Symbol in plugin not found in api: vtable for std::__cxx11::collate<char>
Symbol in plugin not found in api: std::__basic_file<char>::is_open() const
Symbol in plugin not found in api: std::ctype<wchar_t>::do_scan_not(char, wchar_t const*, wchar_t const*) const
Symbol in plugin not found in api: std::moneypunct<wchar_t, true>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::push_back(wchar_t)
Symbol in plugin not found in api: vtable for std::__cxx11::money_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >
Symbol in plugin not found in api: std::string::find_first_not_of(char, unsigned int) const
Symbol in plugin not found in api: __cxa_bad_cast
Symbol in plugin not found in api: std::moneypunct<wchar_t, false>::~moneypunct()
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::copy(wchar_t*, unsigned int, unsigned int) const
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_M_destroy(std::allocator<wchar_t> const&)
Symbol in plugin not found in api: plaits::fm::lut_pitch_mod_sensitivity
Symbol in plugin not found in api: vtable for std::__cxx11::money_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >
Symbol in plugin not found in api: std::locale::facet::_M_sso_shim(std::locale::id const*) const
Symbol in plugin not found in api: std::numpunct<wchar_t>::_M_initialize_numpunct(int*)
Symbol in plugin not found in api: std::__basic_file<char>::__basic_file(int*)
Symbol in plugin not found in api: std::ctype<wchar_t>::do_tolower(wchar_t) const
Symbol in plugin not found in api: std::__basic_file<char>::open(char const*, std::_Ios_Openmode, int)
Symbol in plugin not found in api: std::locale::facet::_S_create_c_locale(int*&, char const*, int*)
Symbol in plugin not found in api: void std::__convert_to_v<double>(char const*, double&, std::_Ios_Iostate&, int* const&)
Symbol in plugin not found in api: std::string::append(unsigned int, char)
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_leak_hard()
Symbol in plugin not found in api: std::__cxx11::money_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id
Symbol in plugin not found in api: std::__timepunct<char>::_M_put(char*, unsigned int, char const*, tm const*) const
Symbol in plugin not found in api: vtable for std::__cxx11::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >
Symbol in plugin not found in api: std::__cxx11::money_get<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::id
Symbol in plugin not found in api: plaits::fm::Algorithms<6>::renderers_
Symbol in plugin not found in api: std::collate<char>::_M_compare(char const*, char const*) const
Symbol in plugin not found in api: std::__basic_file<char>::xsputn_2(char const*, int, char const*, int)
Symbol in plugin not found in api: std::__cxx11::moneypunct<wchar_t, false>::id
Symbol in plugin not found in api: std::codecvt<wchar_t, char, _mbstate_t>::do_out(_mbstate_t&, wchar_t const*, wchar_t const*, wchar_t const*&, char*, char*, char*&) const
Symbol in plugin not found in api: std::moneypunct<wchar_t, false>::~moneypunct()
Symbol in plugin not found in api: std::ctype<wchar_t>::do_toupper(wchar_t) const
Symbol in plugin not found in api: rack::system::getDirectory(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
Symbol in plugin not found in api: std::__timepunct<wchar_t>::_M_initialize_timepunct(int*)
Symbol in plugin not found in api: std::locale::facet::_S_destroy_c_locale(int*&)
Symbol in plugin not found in api: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)
Symbol in plugin not found in api: std::string::assign(char const*, unsigned int)
Symbol in plugin not found in api: std::ctype<wchar_t>::do_toupper(wchar_t*, wchar_t const*) const
Symbol in plugin not found in api: std::ctype<char>::do_toupper(char) const
Symbol in plugin not found in api: vtable for std::__cxx11::collate<wchar_t>
Symbol in plugin not found in api: std::__cxx11::numpunct<wchar_t>::id
Symbol in plugin not found in api: std::string::_S_construct(unsigned int, char, std::allocator<char> const&)
Symbol in plugin not found in api: void std::__convert_to_v<float>(char const*, float&, std::_Ios_Iostate&, int* const&)
Symbol in plugin not found in api: std::numpunct<wchar_t>::~numpunct()
Symbol in plugin not found in api: std::string::_M_leak_hard()
Symbol in plugin not found in api: std::__throw_ios_failure(char const*, int)
Symbol in plugin not found in api: std::string::push_back(char)
Symbol in plugin not found in api: std::numpunct<wchar_t>::~numpunct()
Symbol in plugin not found in api: rack::system::openBrowser(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
Symbol in plugin not found in api: std::locale::_S_categories
Symbol in plugin not found in api: std::ctype<wchar_t>::do_scan_is(char, wchar_t const*, wchar_t const*) const
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_S_construct(unsigned int, wchar_t, std::allocator<wchar_t> const&)
Symbol in plugin not found in api: plaits::fm::lut_coarse
Symbol in plugin not found in api: std::moneypunct<wchar_t, true>::~moneypunct()
Symbol in plugin not found in api: std::numpunct<char>::~numpunct()
Symbol in plugin not found in api: std::__cxx11::messages<char>::id
Symbol in plugin not found in api: std::ctype<wchar_t>::do_tolower(wchar_t*, wchar_t const*) const
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_S_create(unsigned int, unsigned int, std::allocator<wchar_t> const&)
Symbol in plugin not found in api: std::__cxx11::money_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::id
Symbol in plugin not found in api: std::string::_Rep::_S_empty_rep_storage
Symbol in plugin not found in api: std::__cxx11::moneypunct<char, false>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: std::this_thread::__sleep_for(std::chrono::duration<long long, std::ratio<1ll, 1ll> >, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> >)
Symbol in plugin not found in api: std::moneypunct<char, true>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: vtable for std::__cxx11::numpunct<wchar_t>
Symbol in plugin not found in api: std::locale::facet::_M_cow_shim(std::locale::id const*) const
Symbol in plugin not found in api: std::string::copy(char*, unsigned int, unsigned int) const
Symbol in plugin not found in api: std::moneypunct<wchar_t, false>::~moneypunct()
Symbol in plugin not found in api: std::istream::ignore(int)
Symbol in plugin not found in api: std::__cxx11::collate<wchar_t>::id
Symbol in plugin not found in api: std::string::_Rep::_M_destroy(std::allocator<char> const&)
Symbol in plugin not found in api: std::ctype<char>::do_tolower(char*, char const*) const
Symbol in plugin not found in api: std::collate<char>::_M_transform(char*, char const*, unsigned int) const
Symbol in plugin not found in api: vtable for std::__cxx11::time_get<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >
Symbol in plugin not found in api: std::__basic_file<char>::xsgetn(char*, int)
Symbol in plugin not found in api: std::moneypunct<wchar_t, true>::~moneypunct()
Symbol in plugin not found in api: std::ctype<wchar_t>::do_narrow(wchar_t const*, wchar_t const*, char, char*) const
Symbol in plugin not found in api: std::collate<wchar_t>::_M_compare(wchar_t const*, wchar_t const*) const
Symbol in plugin not found in api: vtable for std::__cxx11::moneypunct<wchar_t, false>
Symbol in plugin not found in api: rack::system::getExtension(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
Symbol in plugin not found in api: std::ctype<char>::do_tolower(char) const
Symbol in plugin not found in api: std::__cxx11::numpunct<char>::id
Symbol in plugin not found in api: std::locale::facet::_S_clone_c_locale(int*&)
Symbol in plugin not found in api: std::ctype<char>::do_toupper(char*, char const*) const
Symbol in plugin not found in api: vtable for std::__cxx11::moneypunct<char, false>
Symbol in plugin not found in api: std::ctype<wchar_t>::do_narrow(wchar_t, char) const
Symbol in plugin not found in api: std::moneypunct<char, true>::~moneypunct()
Symbol in plugin not found in api: std::codecvt<wchar_t, char, _mbstate_t>::do_encoding() const
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::assign(wchar_t const*, unsigned int)
Symbol in plugin not found in api: std::__cxx11::messages<char>::messages(unsigned int)
Symbol in plugin not found in api: std::codecvt<wchar_t, char, _mbstate_t>::do_in(_mbstate_t&, char const*, char const*, char const*&, wchar_t*, wchar_t*, wchar_t*&) const
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::append(wchar_t const*, unsigned int)
Symbol in plugin not found in api: std::codecvt<wchar_t, char, _mbstate_t>::do_length(_mbstate_t&, char const*, char const*, unsigned int) const
Symbol in plugin not found in api: plaits::fm::lut_amp_mod_sensitivity
Symbol in plugin not found in api: std::__basic_file<char>::xsputn(char const*, int)
Symbol in plugin not found in api: std::__cxx11::numpunct<char>::_M_initialize_numpunct(int*)
Symbol in plugin not found in api: std::ctype_byname<char>::ctype_byname(char const*, unsigned int)
Symbol in plugin not found in api: std::ctype<wchar_t>::do_widen(char const*, char const*, wchar_t*) const
Symbol in plugin not found in api: std::__cxx11::money_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::id
Symbol in plugin not found in api: std::moneypunct<char, false>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: std::string::reserve(unsigned int)
Symbol in plugin not found in api: std::moneypunct<char, true>::~moneypunct()
Symbol in plugin not found in api: std::ios_base::_M_init()
Symbol in plugin not found in api: std::__basic_file<char>::close()
Symbol in plugin not found in api: std::__timepunct<wchar_t>::_M_put(wchar_t*, unsigned int, wchar_t const*, tm const*) const
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::reserve(unsigned int)
Symbol in plugin not found in api: std::messages<char>::do_get(int, int, int, std::string const&) const
Symbol in plugin not found in api: std::moneypunct<char, true>::~moneypunct()
Symbol in plugin not found in api: std::__cxx11::moneypunct<char, true>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: std::codecvt<wchar_t, char, _mbstate_t>::do_max_length() const
Symbol in plugin not found in api: std::uncaught_exception()
Symbol in plugin not found in api: std::numpunct<char>::~numpunct()
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::resize(unsigned int, wchar_t)
Symbol in plugin not found in api: std::moneypunct<wchar_t, true>::~moneypunct()
Symbol in plugin not found in api: std::__cxx11::messages<wchar_t>::id
Symbol in plugin not found in api: osdialog_file
Symbol in plugin not found in api: vtable for std::__cxx11::money_get<wchar_t, std::istreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >
Symbol in plugin not found in api: std::__cxx11::moneypunct<wchar_t, true>::_M_initialize_moneypunct(int*, char const*)
Symbol in plugin not found in api: std::numpunct<char>::~numpunct()
Symbol in plugin not found in api: std::__basic_file<char>::seekoff(long long, std::_Ios_Seekdir)
Symbol in plugin not found in api: std::ctype<wchar_t>::do_is(char, wchar_t) const
Symbol in plugin not found in api: std::moneypunct<char, false>::~moneypunct()
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::append(std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&)
Symbol in plugin not found in api: vtable for std::__cxx11::numpunct<char>
Symbol in plugin not found in api: std::string::_M_replace_aux(unsigned int, unsigned int, unsigned int, char)
Symbol in plugin not found in api: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_S_empty_rep_storage
Symbol in plugin not found in api: std::string::swap(std::string&)
Symbol in plugin not found in api: std::__cxx11::moneypunct<char, true>::id
Symbol in plugin not found in api: std::string::_M_mutate(unsigned int, unsigned int, unsigned int)
Symbol in plugin not found in api: vtable for std::__cxx11::moneypunct<wchar_t, true>
Symbol in plugin not found in api: std::moneypunct<char, false>::~moneypunct()
Symbol in plugin not found in api: osdialog_filters_parse
Symbol in plugin not found in api: std::__cxx11::moneypunct<wchar_t, true>::id
Symbol in plugin not found in api: std::numpunct<wchar_t>::~numpunct()
Symbol in plugin not found in api: void std::__convert_to_v<long double>(char const*, long double&, std::_Ios_Iostate&, int* const&)
Symbol in plugin not found in api: vtable for std::__cxx11::money_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >
Symbol in plugin not found in api: std::string::resize(unsigned int, char)
Symbol in plugin not found in api: vtable for std::__cxx11::moneypunct<char, true>
Symbol in plugin not found in api: std::ctype<wchar_t>::do_is(wchar_t const*, wchar_t const*, char*) const
Symbol in plugin not found in api: std::__cxx11::numpunct<wchar_t>::_M_initialize_numpunct(int*)
Symbol in plugin not found in api: std::__cxx11::moneypunct<char, false>::id
Symbol in plugin not found in api: std::ctype<wchar_t>::_M_initialize_ctype()
Symbol in plugin not found in api: std::messages<wchar_t>::do_get(int, int, int, std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > const&) const
Symbol in plugin not found in api: std::__timepunct<char>::_M_initialize_timepunct(int*)
Symbol in plugin not found in api: std::__basic_file<char>::showmanyc()
Symbol in plugin not found in api: std::__cxx11::time_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::id

Cool!

I recognize those symbols… they appear if you have any #include <stringstream> or any *stream including fstream, ostream…
A common reason for using streams I’ve come acress is for converting numbers to strings for displaying on text screens or context menus. In that case, you can use std::to_string or to_chars or a variety of other ways (itoa, etc…)

The v2.0-dev firmware requires the string “v2.0” in the plugin file name. This is to make sure it doesn’t waste time trying to autoload v1 plugins (which makes startup very slow). So just rename your .mmplugin to pluginame-v2.0-dev-12.0.mmplugin and you can use -dev-12.1 etc to indicate future versions.

1 Like

Thanks! Made a bunch of these fixes and got Funes in.

I also fixed most of the discrete knob states, at least the ones that I have found. I’ve updated the Drive folder above with the new firmware.

3 Likes

Very nice! Thanks for doing this.

Please can you put the code for these changes on GitHub (or somewhere at least) and share the link, so others can see what changes you made and compile it themselves. The original is GPL3 licensed (Open Source Software Licenses 101: GPL v3 - FOSSA) so you need to do so to remain compliant with that. Welcome to the confusing world of OSS licensing :wink:

You got it, will do so later today.

1 Like

Out of curiosity, did you cleanup/change the UIs at all? Glad to get access to the alternate firmwares for those, but the panel designs are a little rough to look at. Maybe it’s my aging eyesight. :slight_smile:

I did not, sorry! - I just went for a beeline to get this compiled/useable. I am still quite new to C/C++ development generally and also have zero context on VCV rack plugin development, so trying to pick up a lot of this as I go!

Added Github repo here: GitHub - Ericxgao/metamodule-sanguine-mutants

2 Likes

@danngreen - Would you have any pointers as to how to debug/fix some of the panel overlays not showing, such as the text?

For example, these two are used to render the background as well as some text on the module, but they aren’t loading.


is this related to their make panel code in some way?

void SanguineModuleWidget::makePanel() {
	BackplateColors themeBackplateColor = PLATE_PURPLE;
	FaceplateThemes faceplateTheme = defaultTheme;

	// Programmer responsibility: if the module is not a SanguineModule, Rack will jump off a cliff.
	// Now you know.
	SanguineModule* sanguineModule = dynamic_cast<SanguineModule*>(this->module);

	if (sanguineModule) {
		if (!sanguineModule->bUniqueTheme) {
			sanguineModule->setModuleTheme(faceplateTheme);
		}
		else {
			faceplateTheme = sanguineModule->currentTheme;
		}
	}

	switch (faceplateTheme)
	{
	case THEME_NONE:
	case THEME_VITRIOL:
		themeBackplateColor = backplateColor;
		break;
	case THEME_PLUMBAGO:
		themeBackplateColor = PLATE_BLACK;
		break;
	}

	std::string backplateFileName = "res/backplate_" + panelSizeStrings[panelSize] + backplateColorStrings[themeBackplateColor] + ".svg";

	std::string faceplateFileName = "res/" + moduleName;

	if (bFaceplateSuffix) {
		faceplateFileName += "_faceplate";
	}

	faceplateFileName += faceplateThemeStrings[faceplateTheme] + ".svg";

	SanguinePanel* panel = new SanguinePanel(backplateFileName, faceplateFileName);
	if (bHasCommon) {
		panel->addLayer("res/" + moduleName + "_common.svg");
	}
	setPanel(panel);
}

Updated - the latest firmware fixes all UI issues so the ports are showing.

https://drive.google.com/drive/folders/1u7dxKmk0P2-qj5RKwXSPZDV2NJcFNKaK?usp=drive_link

6 Likes

Woweee! This has been top of my wishlist for a while. I used to have a typhoon and that thing was top notch. This should scratch that itch nicely. Thanks @etcetc for the incredible contribution with these!

1 Like

Updated with a few newer Sanguine Mutants modules.

Cleaned up the repository now so it should be easier to maintain for everyone involved.

https://drive.google.com/drive/folders/1u7dxKmk0P2-qj5RKwXSPZDV2NJcFNKaK?usp=drive_link

3 Likes

Magnificent. TY. I suppose that with Nix and Ansa together with ProteusX and SickoLooperExp that Expanders are indeed possible, it just depends on content of those expanders

Interesting - I never tried the expanders - the MetaModule docs say that expanders won’t work

1 Like