Esempio n. 1
0
mpt::PathString BuildVariants::GetComponentArch()
{
	#if (MPT_ARCH_BITS == 64)
		return MPT_PATHSTRING("x64");
	#elif (MPT_ARCH_BITS == 32)
		return MPT_PATHSTRING("x86");
	#else
		return MPT_PATHSTRING("");
	#endif
}
Esempio n. 2
0
VSTPluginLib *CSelectPluginDlg::ScanPlugins(const mpt::PathString &path, CWnd *parent)
//------------------------------------------------------------------------------------
{
	CVstPluginManager *pManager = theApp.GetPluginManager();
	VSTPluginLib *plugLib = nullptr;
	bool update = false;

	CDialog pluginScanDlg;
	pluginScanDlg.Create(IDD_SCANPLUGINS, parent);
	pluginScanDlg.CenterWindow(parent);
	pluginScanDlg.ModifyStyle(0, WS_SYSMENU, WS_SYSMENU);
	pluginScanDlg.ShowWindow(SW_SHOW);

	FolderScanner scan(path, true);
	mpt::PathString fileName;
	int files = 0;
	while(scan.NextFile(fileName) && pluginScanDlg.IsWindowVisible())
	{
		if(!mpt::PathString::CompareNoCase(fileName.GetFileExt(), MPT_PATHSTRING(".dll")))
		{
			CWnd *text = pluginScanDlg.GetDlgItem(IDC_SCANTEXT);
			std::wstring scanStr = L"Scanning Plugin...\n" + fileName.ToWide();
			::SetWindowTextW(text->m_hWnd, scanStr.c_str());
			MSG msg;
			while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
				::TranslateMessage(&msg);
				::DispatchMessage(&msg);
			}

			VSTPluginLib *lib = pManager->AddPlugin(fileName, mpt::ustring(), false);
			if(lib)
			{
				update = true;
				if(!VerifyPlug(lib, parent))
				{
					pManager->RemovePlugin(lib);
				} else
				{
					plugLib = lib;
					files++;
				}
			}
		}
	}

	if(update)
	{
		// Force selection to last added plug.
		Reporting::Information(mpt::String::Print("Found %1 plugin%2.", files, files == 1 ? "" : "s").c_str(), parent);
		return plugLib;
	} else
	{
		Reporting::Error("Could not find any valid VST plugins.");
		return nullptr;
	}
}
Esempio n. 3
0
static noinline void DoLog(const mpt::log::Context &context, mpt::ustring message)
//--------------------------------------------------------------------------------
{
	// remove eol if already present
	message = mpt::String::RTrim(message, MPT_USTRING("\r\n"));
	#if defined(MODPLUG_TRACKER)
		static uint64_t s_lastlogtime = 0;
		uint64 cur = mpt::Date::ANSI::Now();
		uint64 diff = cur/10000 - s_lastlogtime;
		s_lastlogtime = cur/10000;
		#ifdef LOG_TO_FILE
		{
			static FILE * s_logfile = nullptr;
			if(!s_logfile)
			{
				s_logfile = mpt_fopen(MPT_PATHSTRING("mptrack.log"), "a");
			}
			if(s_logfile)
			{
				fprintf(s_logfile, mpt::ToCharset(mpt::CharsetUTF8, mpt::String::Print(MPT_USTRING("%1+%2 %3(%4): %5 [%6]\n"
					, mpt::Date::ANSI::ToString(cur)
					, mpt::ufmt::dec<6>(diff)
					, mpt::ToUnicode(mpt::CharsetASCII, context.file)
					, context.line
					, message
					, mpt::ToUnicode(mpt::CharsetASCII, context.function)
					))).c_str());
				fflush(s_logfile);
			}
		}
		#endif // LOG_TO_FILE
		{
			OutputDebugStringW(mpt::String::PrintW(L"%1(%2): +%3 %4 [%5]\n"
				, mpt::ToWide(mpt::CharsetASCII, context.file)
				, context.line
				, mpt::wfmt::dec<6>(diff)
				, message
				, mpt::ToWide(mpt::CharsetASCII, context.function)
				).c_str());
		}
	#else // !MODPLUG_TRACKER
		std::clog
			<< "openmpt: "
			<< context.file << "(" << context.line << ")" << ": "
#if defined(MPT_WITH_CHARSET_LOCALE)
			<< mpt::ToLocale(message)
#else
			<< mpt::ToCharset(mpt::CharsetUTF8, message)
#endif
			<< " [" << context.function << "]"
			<< std::endl;
	#endif // MODPLUG_TRACKER
}
Esempio n. 4
0
WAVEncoder::WAVEncoder()
//----------------------
{
	Encoder::Traits traits;
	traits.fileExtension = MPT_PATHSTRING("wav");
	traits.fileShortDescription = MPT_USTRING("Wave");
	traits.fileDescription = MPT_USTRING("Wave");
	traits.encoderSettingsName = MPT_USTRING("Wave");
	traits.encoderName = MPT_USTRING("OpenMPT");
	traits.description = MPT_USTRING("Microsoft RIFF WAVE");
	traits.canTags = true;
	traits.canCues = true;
	traits.maxChannels = 4;
	traits.samplerates = TrackerSettings::Instance().GetSampleRates();
	traits.modes = Encoder::ModeEnumerated;
	for(std::size_t i = 0; i < traits.samplerates.size(); ++i)
	{
		int samplerate = traits.samplerates[i];
		for(int channels = 1; channels <= traits.maxChannels; channels *= 2)
		{
			for(int bytes = 5; bytes >= 1; --bytes)
			{
				Encoder::Format format;
				format.Samplerate = samplerate;
				format.Channels = channels;
				if(bytes == 5)
				{
					format.Sampleformat = SampleFormatFloat32;
					format.Description = MPT_USTRING("Floating Point");
				} else
				{
					format.Sampleformat = (SampleFormat)(bytes * 8);
					format.Description = mpt::String::Print(MPT_USTRING("%1 Bit"), bytes * 8);
				}
				format.Bitrate = 0;
				traits.formats.push_back(format);
			}
		}
	}
	traits.defaultSamplerate = 48000;
	traits.defaultChannels = 2;
	traits.defaultMode = Encoder::ModeEnumerated;
	traits.defaultFormat = 0;
	SetTraits(traits);
}
Esempio n. 5
0
// Convert an absolute path to a path that's relative to "&relativeTo".
PathString PathString::AbsolutePathToRelative(const PathString &relativeTo) const
//-------------------------------------------------------------------------------
{
	mpt::PathString result = path;
	if(path.empty())
	{
		return result;
	}
	if(!_wcsnicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), relativeTo.AsNative().length()))
	{
		// Path is OpenMPT's directory or a sub directory ("C:\OpenMPT\Somepath" => ".\Somepath")
		result = MPT_PATHSTRING(".\\"); // ".\"
		result += mpt::PathString::FromNative(AsNative().substr(relativeTo.AsNative().length()));
	} else if(!_wcsnicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), 2))
	{
		// Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath")
		result = mpt::PathString::FromNative(AsNative().substr(2));
	}
	return result;
}
Esempio n. 6
0
FLACEncoder::FLACEncoder()
//------------------------
{
	Encoder::Traits traits;
	traits.fileExtension = MPT_PATHSTRING("flac");
	traits.fileShortDescription = MPT_USTRING("FLAC");
	traits.fileDescription = MPT_USTRING("FLAC");
	traits.encoderSettingsName = MPT_USTRING("FLAC");
	traits.encoderName = MPT_USTRING("libFLAC");
	traits.description = MPT_USTRING("");
	traits.description += mpt::String::Print(MPT_USTRING("Free Lossless Audio Codec\n"));
	traits.description += mpt::String::Print(MPT_USTRING("Vendor: %1\n"), mpt::ToUnicode(mpt::CharsetASCII, FLAC__VENDOR_STRING));
	traits.description += mpt::String::Print(MPT_USTRING("Version: %1\n"), mpt::ToUnicode(mpt::CharsetASCII, FLAC__VERSION_STRING));
	traits.description += mpt::String::Print(MPT_USTRING("API: %1.%2.%3\n"), FLAC_API_VERSION_CURRENT, FLAC_API_VERSION_REVISION, FLAC_API_VERSION_AGE);
	traits.canTags = true;
	traits.maxChannels = 4;
	traits.samplerates = TrackerSettings::Instance().GetSampleRates();
	traits.modes = Encoder::ModeEnumerated;
	for(std::size_t i = 0; i < traits.samplerates.size(); ++i)
	{
		int samplerate = traits.samplerates[i];
		for(int channels = 1; channels <= traits.maxChannels; channels *= 2)
		{
			for(int bytes = 3; bytes >= 1; --bytes)
			{
				Encoder::Format format;
				format.Samplerate = samplerate;
				format.Channels = channels;
				format.Sampleformat = (SampleFormat)(bytes * 8);
				format.Description = mpt::String::Print(MPT_USTRING("%1 Bit"), bytes * 8);
				format.Bitrate = 0;
				traits.formats.push_back(format);
			}
		}
	}
	traits.defaultSamplerate = 48000;
	traits.defaultChannels = 2;
	traits.defaultMode = Encoder::ModeEnumerated;
	traits.defaultFormat = 0;
	SetTraits(traits);
}
Esempio n. 7
0
static noinline void DoLog(const mpt::log::Context &context, std::wstring message)
//--------------------------------------------------------------------------------
{
	// remove eol if already present
	message = mpt::String::RTrim(message, L"\r\n");
	#if defined(MODPLUG_TRACKER)
		static uint64_t s_lastlogtime = 0;
		uint64 cur = GetTimeMS();
		uint64 diff = cur - s_lastlogtime;
		s_lastlogtime = cur;
		#ifdef LOG_TO_FILE
		{
			static FILE * s_logfile = nullptr;
			if(!s_logfile)
			{
				s_logfile = mpt_fopen(MPT_PATHSTRING("mptrack.log"), "a");
			}
			if(s_logfile)
			{
				fprintf(s_logfile, "%s+%s %s(%i): %s [%s]\n", TimeAsAsString(cur).c_str(), TimeDiffAsString(diff).c_str(), context.file, context.line, mpt::To(mpt::CharsetUTF8, message).c_str(), context.function);
				fflush(s_logfile);
			}
		}
		#endif // LOG_TO_FILE
		{
			OutputDebugStringW(mpt::String::PrintW(L"%1(%2): +%3 %4 [%5]\n", mpt::ToWide(mpt::CharsetASCII, context.file), context.line, TimeDiffAsStringW(diff), message, mpt::ToWide(mpt::CharsetASCII, context.function)).c_str());
		}
	#else // !MODPLUG_TRACKER
		std::clog
			<< "openmpt: "
			<< context.file << "(" << context.line << ")" << ": "
#if defined(MPT_WITH_CHARSET_LOCALE)
			<< mpt::ToLocale(message)
#else
			<< mpt::To(mpt::CharsetUTF8, message)
#endif
			<< " [" << context.function << "]"
			<< std::endl;
	#endif // MODPLUG_TRACKER
}
Esempio n. 8
0
// Create an instance of a plugin.
bool CVstPluginManager::CreateMixPlugin(SNDMIXPLUGIN &mixPlugin, CSoundFile &sndFile)
//-----------------------------------------------------------------------------------
{
	VSTPluginLib *pFound = nullptr;

	// Find plugin in library
	int match = 0;
	for(const_iterator p = begin(); p != end(); p++)
	{
		VSTPluginLib *plug = *p;
		const bool matchID = (plug->pluginId1 == mixPlugin.Info.dwPluginId1)
			&& (plug->pluginId2 == mixPlugin.Info.dwPluginId2);
		const bool matchName = !mpt::PathString::CompareNoCase(plug->libraryName, mpt::PathString::FromUTF8(mixPlugin.GetLibraryName()));

		if(matchID && matchName)
		{
			pFound = plug;
			break;
		} else if(matchID && match < 2)
		{
			match = 2;
			pFound = plug;
		} else if(matchName && match < 1)
		{
			match = 1;
			pFound = plug;
		}
	}

	if(mixPlugin.Info.dwPluginId1 == kDmoMagic)
	{
		if (!pFound) return false;
		AEffect *pEffect = DmoToVst(*pFound);
		if(pEffect && pEffect->magic == kDmoMagic)
		{
			CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(nullptr, *pFound, mixPlugin, *pEffect, sndFile);
			return pVstPlug != nullptr;
		}
	}

	if(!pFound && strcmp(mixPlugin.GetLibraryName(), ""))
	{
		// Try finding the plugin DLL in the plugin directory or plugin cache instead.
		mpt::PathString fullPath = TrackerDirectories::Instance().GetDefaultDirectory(DIR_PLUGINS);
		if(fullPath.empty())
		{
			fullPath = theApp.GetAppDirPath() + MPT_PATHSTRING("Plugins\\");
		}
		fullPath += mpt::PathString::FromUTF8(mixPlugin.GetLibraryName()) + MPT_PATHSTRING(".dll");

		pFound = AddPlugin(fullPath);
		if(!pFound)
		{
			// Try plugin cache (search for library name)
			SettingsContainer &cacheFile = theApp.GetPluginCache();
			std::string IDs = cacheFile.Read<std::string>(cacheSectionW, mpt::ToWide(mpt::CharsetUTF8, mixPlugin.GetLibraryName()), "");
			if(IDs.length() >= 16)
			{
				fullPath = cacheFile.Read<mpt::PathString>(cacheSection, IDs, MPT_PATHSTRING(""));
				if(!fullPath.empty())
				{
					fullPath = theApp.RelativePathToAbsolute(fullPath);
					if(PathFileExistsW(fullPath.AsNative().c_str()))
					{
						pFound = AddPlugin(fullPath);
					}
				}
			}
		}
	}

	if(pFound)
	{
		AEffect *pEffect = nullptr;
		HINSTANCE hLibrary = nullptr;
		bool validPlugin = false;

		try
		{
			pEffect = LoadPlugin(pFound->dllPath, hLibrary);

			if(pEffect != nullptr && pEffect->dispatcher != nullptr && pEffect->magic == kEffectMagic)
			{
				validPlugin = true;

				const bool oldIsInstrument = pFound->isInstrument;
				const VSTPluginLib::PluginCategory oldCategory = pFound->category;

				GetPluginInformation(pEffect, *pFound);

				if(oldIsInstrument != pFound->isInstrument || oldCategory != pFound->category)
				{
					// Update cached information
					WriteToCache(*pFound);
				}

				CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(hLibrary, *pFound, mixPlugin, *pEffect, sndFile);
				if(pVstPlug == nullptr)
				{
					validPlugin = false;
				}
			}

			if(!validPlugin)
			{
				FreeLibrary(hLibrary);
			}
		} catch(...)
		{
			CVstPluginManager::ReportPlugException(mpt::String::PrintW(L"Exception while trying to create plugin \"%1\"!\n", pFound->libraryName));
		}

		return validPlugin;
	} else
	{
		// "plug not found" notification code MOVED to CSoundFile::Create
#ifdef VST_LOG
		Log("Unknown plugin\n");
#endif
	}
	return false;
}
Esempio n. 9
0
// Add a plugin to the list of known plugins.
VSTPluginLib *CVstPluginManager::AddPlugin(const mpt::PathString &dllPath, bool fromCache, const bool checkFileExistence, std::wstring *const errStr)
//---------------------------------------------------------------------------------------------------------------------------------------------------
{
	const mpt::PathString fileName = dllPath.GetFileName();

	if(checkFileExistence && (PathFileExistsW(dllPath.AsNative().c_str()) == FALSE))
	{
		if(errStr)
		{
			*errStr += L"\nUnable to find ";
			*errStr += dllPath.ToWide();
		}
	}

	// Check if this is already a known plugin.
	for(const_iterator dupePlug = begin(); dupePlug != end(); dupePlug++)
	{
		if(!dllPath.CompareNoCase(dllPath, (**dupePlug).dllPath)) return *dupePlug;
	}

	// Look if the plugin info is stored in the PluginCache
	if(fromCache)
	{
		SettingsContainer & cacheFile = theApp.GetPluginCache();
		const std::string IDs = cacheFile.Read<std::string>(cacheSectionW, fileName.ToWide(), "");

		if(IDs.length() >= 16)
		{
			// Get path from cache file
			mpt::PathString realPath = cacheFile.Read<mpt::PathString>(cacheSection, IDs, MPT_PATHSTRING(""));
			realPath = theApp.RelativePathToAbsolute(realPath);

			if(!realPath.empty() && !dllPath.CompareNoCase(realPath, dllPath))
			{
				VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(dllPath, fileName);
				if(plug == nullptr)
				{
					return nullptr;
				}
				pluginList.push_back(plug);

				// Extract plugin IDs
				for (int i = 0; i < 16; i++)
				{
					VstInt32 n = IDs[i] - '0';
					if (n > 9) n = IDs[i] + 10 - 'A';
					n &= 0x0f;
					if (i < 8)
					{
						plug->pluginId1 = (plug->pluginId1 << 4) | n;
					} else
					{
						plug->pluginId2 = (plug->pluginId2 << 4) | n;
					}
				}

				const std::string flagKey = IDs + ".Flags";
				plug->DecodeCacheFlags(cacheFile.Read<int32>(cacheSection, flagKey, 0));

#ifdef VST_LOG
				Log("Plugin \"%s\" found in PluginCache\n", plug->libraryName.ToLocale().c_str());
#endif // VST_LOG
				return plug;
			} else
			{
#ifdef VST_LOG
				Log("Plugin \"%s\" mismatch in PluginCache: \"%s\" [%s]=\"%s\"\n", s, dllPath, (LPCTSTR)IDs, (LPCTSTR)strFullPath);
#endif // VST_LOG
			}
		}
	}

	// If this key contains a file name on program launch, a plugin previously crashed OpenMPT.
	theApp.GetSettings().Write<mpt::PathString>("VST Plugins", "FailedPlugin", dllPath);

	AEffect *pEffect;
	HINSTANCE hLib;
	bool validPlug = false;

	VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(dllPath, fileName);
	if(plug == nullptr)
	{
		return nullptr;
	}

	try
	{
		pEffect = LoadPlugin(dllPath, hLib);

		if(pEffect != nullptr && pEffect->magic == kEffectMagic && pEffect->dispatcher != nullptr)
		{
			pEffect->dispatcher(pEffect, effOpen, 0, 0, 0, 0);

			plug->pluginId1 = pEffect->magic;
			plug->pluginId2 = pEffect->uniqueID;

			GetPluginInformation(pEffect, *plug);

#ifdef VST_LOG
			int nver = pEffect->dispatcher(pEffect, effGetVstVersion, 0,0, nullptr, 0);
			if (!nver) nver = pEffect->version;
			Log("%-20s: v%d.0, %d in, %d out, %2d programs, %2d params, flags=0x%04X realQ=%d offQ=%d\n",
				plug->libraryName.ToLocale().c_str(), nver,
				pEffect->numInputs, pEffect->numOutputs,
				pEffect->numPrograms, pEffect->numParams,
				pEffect->flags, pEffect->realQualities, pEffect->offQualities);
#endif // VST_LOG

			pEffect->dispatcher(pEffect, effClose, 0, 0, 0, 0);

			validPlug = true;
		}

		FreeLibrary(hLib);
	} catch(...)
	{
		CVstPluginManager::ReportPlugException(mpt::String::PrintW(L"Exception while trying to load plugin \"%1\"!\n", plug->libraryName));
	}

	// Now it should be safe to assume that this plugin loaded properly. :)
	theApp.GetSettings().Remove("VST Plugins", "FailedPlugin");

	// If OK, write the information in PluginCache
	if(validPlug)
	{
		pluginList.push_back(plug);
		WriteToCache(*plug);
	} else
	{
		delete plug;
	}

	return (validPlug ? plug : nullptr);
}
Esempio n. 10
0
OPENMPT_NAMESPACE_BEGIN


bool CSoundFile::ReadMO3(FileReader &file, ModLoadingFlags loadFlags)
//-------------------------------------------------------------------
{
	file.Rewind();

	// No valid MO3 file (magic bytes: "MO3")
	if(!file.CanRead(8) || !file.ReadMagic("MO3"))
	{
		return false;
	} else if(loadFlags == onlyVerifyHeader)
	{
		return true;
	}

#ifdef NO_MO3
	// As of November 2013, the format revision is 5; Versions > 31 are unlikely to exist in the next few years,
	// so we will just ignore those if there's no UNMO3 library to tell us if the file is valid or not
	// (avoid log entry with .MOD files that have a song name starting with "MO3".
	if(file.ReadUint8() > 31)
	{
		return false;
	}

	AddToLog(GetStrI18N("The file appears to be a MO3 file, but this OpenMPT build does not support loading MO3 files."));
	return false;

#else

	bool result = false;	// Result of trying to load the module, false == fail.

	// Try to load unmo3 dynamically.
	mpt::Library unmo3 = mpt::Library(mpt::LibraryPath::App(MPT_PATHSTRING("unmo3")));

	if(!unmo3.IsValid())
	{
		// Didn't succeed.
		AddToLog(GetStrI18N("Loading MO3 file failed because unmo3.dll could not be loaded."));
	} else
	{
		// Library loaded successfully.
		#if MPT_OS_WINDOWS
			#define UNMO3_API __stdcall
		#else
			#define UNMO3_API 
		#endif
		typedef uint32 (UNMO3_API * UNMO3_GETVERSION)();
		// Decode a MO3 file (returns the same "exit codes" as UNMO3.EXE, eg. 0=success)
		// IN: data/len = MO3 data/len
		// OUT: data/len = decoded data/len (if successful)
		// flags & 1: Don't load samples
		typedef int32 (UNMO3_API * UNMO3_DECODE_OLD)(const void **data, uint32 *len);
		typedef int32 (UNMO3_API * UNMO3_DECODE)(const void **data, uint32 *len, uint32 flags);
		// Free the data returned by UNMO3_Decode
		typedef void (UNMO3_API * UNMO3_FREE)(const void *data);
		#undef UNMO3_API

		UNMO3_GETVERSION UNMO3_GetVersion = nullptr;
		UNMO3_DECODE_OLD UNMO3_Decode_Old = nullptr;
		UNMO3_DECODE UNMO3_Decode = nullptr;
		UNMO3_FREE UNMO3_Free = nullptr;
		unmo3.Bind(UNMO3_GetVersion, "UNMO3_GetVersion");
		if(UNMO3_GetVersion == nullptr)
		{
			// Old API version: No "flags" parameter.
			unmo3.Bind(UNMO3_Decode_Old, "UNMO3_Decode");
		} else
		{
			unmo3.Bind(UNMO3_Decode, "UNMO3_Decode");
		}
		unmo3.Bind(UNMO3_Free, "UNMO3_Free");
		if((UNMO3_Decode != nullptr || UNMO3_Decode_Old != nullptr) && UNMO3_Free != nullptr)
		{
			file.Rewind();
			const void *stream = file.GetRawData();
			uint32 length = mpt::saturate_cast<uint32>(file.GetLength());

			int32 unmo3result;
			if(UNMO3_Decode != nullptr)
			{
				unmo3result = UNMO3_Decode(&stream, &length, (loadFlags & loadSampleData) ? 0 : 1);
			} else
			{
				// Old API version: No "flags" parameter.
				unmo3result = UNMO3_Decode_Old(&stream, &length);
			}

			if(unmo3result == 0)
			{
				// If decoding was successful, stream and length will keep the new pointers now.
				FileReader unpackedFile(stream, length);

				result = ReadXM(unpackedFile, loadFlags)
					|| ReadIT(unpackedFile, loadFlags)
					|| ReadS3M(unpackedFile, loadFlags)
					|| ReadMTM(unpackedFile, loadFlags)
					|| ReadMod(unpackedFile, loadFlags)
					|| ReadM15(unpackedFile, loadFlags);
				if(result)
				{
					m_ContainerType = MOD_CONTAINERTYPE_MO3;
				}

				UNMO3_Free(stream);
			}
		}
	}
	return result;
#endif // NO_MO3
}