void CVstPluginManager::OnIdle() //------------------------------ { for(const_iterator pFactory = begin(); pFactory != end(); pFactory++) { CVstPlugin *p = (**pFactory).pPluginsList; while (p) { //rewbs. VSTCompliance: A specific plug has requested indefinite periodic processing time. if (p->m_bNeedIdle) { if (!(p->Dispatch(effIdle, 0, 0, nullptr, 0.0f))) p->m_bNeedIdle=false; } //We need to update all open editors if ((p->m_pEditor) && (p->m_pEditor->m_hWnd)) { p->m_pEditor->UpdateParamDisplays(); } //end rewbs. VSTCompliance: p = p->m_pNext; } } }
bool VSTPresets::SaveFile(std::ostream &f, CVstPlugin &plugin, bool bank) //----------------------------------------------------------------------- { if(!bank) { SaveProgram(f, plugin); } else { bool writeChunk = plugin.ProgramsAreChunks(); ChunkHeader header; header.chunkMagic = cMagic; header.version = 2; header.fxID = plugin.GetUID(); header.fxVersion = plugin.GetVersion(); // Write unfinished header... We need to update the size once we're done writing. Write(header, f); uint32 numProgs = std::max(plugin.GetNumPrograms(), VstInt32(1)), curProg = plugin.GetCurrentProgram(); WriteBE(numProgs, f); WriteBE(curProg, f); char reserved[124]; MemsetZero(reserved); Write(reserved, f); if(writeChunk) { char *chunk = nullptr; uint32 chunkSize = mpt::saturate_cast<uint32>(plugin.Dispatch(effGetChunk, 0, 0, &chunk, 0)); if(chunkSize && chunk) { WriteBE(chunkSize, f); f.write(chunk, chunkSize); } else { // The plugin returned no chunk! Gracefully go back and save parameters instead... writeChunk = false; } } if(!writeChunk) { for(uint32 p = 0; p < numProgs; p++) { plugin.SetCurrentProgram(p); SaveProgram(f, plugin); } plugin.SetCurrentProgram(curProg); } // Now we know the correct chunk size. std::streamoff end = f.tellp(); header.byteSize = static_cast<VstInt32>(end - 8); header.fxMagic = writeChunk ? chunkBankMagic : bankMagic; header.ConvertEndianness(); f.seekp(0); Write(header, f); } return true; }
// Returns macro description including plugin parameter / MIDI CC information CString MIDIMacroConfig::GetParameteredMacroName(size_t macroIndex, PLUGINDEX plugin, const CSoundFile &sndFile) const //-------------------------------------------------------------------------------------------------------------------- { const parameteredMacroType macroType = GetParameteredMacroType(macroIndex); switch(macroType) { case sfx_plug: { const int param = MacroToPlugParam(macroIndex); CString paramName; #ifndef NO_VST if(plugin < MAX_MIXPLUGINS) { CVstPlugin *pPlug = dynamic_cast<CVstPlugin *>(sndFile.m_MixPlugins[plugin].pMixPlugin); if(pPlug) { paramName = pPlug->GetParamName(param); } if (paramName.IsEmpty()) { return TEXT("N/A"); } CString formattedName; formattedName.Format(TEXT("Param %d (%s)"), param, paramName); return formattedName; } else #endif // NO_VST { return TEXT("N/A - No Plugin"); } } case sfx_cc: { CString formattedCC; formattedCC.Format(TEXT("MIDI CC %d"), MacroToMidiCC(macroIndex)); return formattedCC; } default: return GetParameteredMacroName(macroType); } }
void VSTPresets::SaveProgram(std::ostream &f, CVstPlugin &plugin) //--------------------------------------------------------------- { bool writeChunk = plugin.ProgramsAreChunks(); ChunkHeader header; header.chunkMagic = cMagic; header.version = 1; header.fxID = plugin.GetUID(); header.fxVersion = plugin.GetVersion(); // Write unfinished header... We need to update the size once we're done writing. std::streamoff start = f.tellp(); Write(header, f); const uint32 numParams = plugin.GetNumParameters(); WriteBE(numParams, f); char name[MAX(kVstMaxProgNameLen + 1, 256)]; plugin.Dispatch(effGetProgramName, 0, 0, name, 0); f.write(name, 28); if(writeChunk) { char *chunk = nullptr; uint32 chunkSize = mpt::saturate_cast<uint32>(plugin.Dispatch(effGetChunk, 1, 0, &chunk, 0)); if(chunkSize && chunk) { WriteBE(chunkSize, f); f.write(chunk, chunkSize); } else { // The plugin returned no chunk! Gracefully go back and save parameters instead... writeChunk = false; } } if(!writeChunk) { for(uint32 p = 0; p < numParams; p++) { WriteBE(plugin.GetParameter(p), f); } } // Now we know the correct chunk size. std::streamoff end = f.tellp(); header.byteSize = static_cast<VstInt32>(end - start - 8); header.fxMagic = writeChunk ? chunkPresetMagic : fMagic; header.ConvertEndianness(); f.seekp(start); Write(header, f); f.seekp(end); }
VSTPresets::ErrorCode VSTPresets::LoadFile(FileReader &file, CVstPlugin &plugin) //------------------------------------------------------------------------------ { const bool firstChunk = file.GetPosition() == 0; ChunkHeader header; if(!file.ReadConvertEndianness(header) || header.chunkMagic != cMagic) { return invalidFile; } if(header.fxID != plugin.GetUID()) { return wrongPlugin; } if(header.fxMagic == fMagic || header.fxMagic == chunkPresetMagic) { // Program PlugParamIndex numParams = file.ReadUint32BE(); VstPatchChunkInfo info; info.version = 1; info.pluginUniqueID = header.fxID; info.pluginVersion = header.fxVersion; info.numElements = numParams; MemsetZero(info.future); plugin.Dispatch(effBeginLoadProgram, 0, 0, &info, 0.0f); plugin.Dispatch(effBeginSetProgram, 0, 0, nullptr, 0.0f); char prgName[28]; file.ReadString<mpt::String::maybeNullTerminated>(prgName, 28); plugin.Dispatch(effSetProgramName, 0, 0, prgName, 0.0f); if(header.fxMagic == fMagic) { if(plugin.GetNumParameters() != numParams) { return wrongParameters; } for(PlugParamIndex p = 0; p < numParams; p++) { plugin.SetParameter(p, file.ReadFloatBE()); } } else { FileReader chunk = file.ReadChunk(file.ReadUint32BE()); plugin.Dispatch(effSetChunk, 1, chunk.GetLength(), const_cast<char *>(chunk.GetRawData()), 0); } plugin.Dispatch(effEndSetProgram, 0, 0, nullptr, 0.0f); } else if((header.fxMagic == bankMagic || header.fxMagic == chunkBankMagic) && firstChunk) { // Bank - only read if it's the first chunk in the file, not if it's a sub chunk. uint32 numProgs = file.ReadUint32BE(); uint32 currentProgram = file.ReadUint32BE(); file.Skip(124); VstPatchChunkInfo info; info.version = 1; info.pluginUniqueID = header.fxID; info.pluginVersion = header.fxVersion; info.numElements = numProgs; MemsetZero(info.future); plugin.Dispatch(effBeginLoadBank, 0, 0, &info, 0.0f); if(header.fxMagic == bankMagic) { VstInt32 oldCurrentProgram = plugin.GetCurrentProgram(); for(uint32 p = 0; p < numProgs; p++) { plugin.Dispatch(effBeginSetProgram, 0, 0, nullptr, 0.0f); plugin.Dispatch(effSetProgram, 0, 0, nullptr, 0.0f); ErrorCode retVal = LoadFile(file, plugin); if(retVal != noError) { return retVal; } plugin.Dispatch(effEndSetProgram, 0, 0, nullptr, 0.0f); } plugin.SetCurrentProgram(oldCurrentProgram); } else { FileReader chunk = file.ReadChunk(file.ReadUint32BE()); plugin.Dispatch(effSetChunk, 0, chunk.GetLength(), const_cast<char *>(chunk.GetRawData()), 0); } if(header.version >= 2) { plugin.SetCurrentProgram(currentProgram); } } return noError; }