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 }
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; } }
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 }
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); }
// 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; }
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); }
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 }
// 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; }
// 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); }
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 }