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