287 lines
12 KiB
C++
287 lines
12 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Project : VST SDK
|
|
//
|
|
// Category : Helpers
|
|
// Filename : public.sdk/source/vst/vstpresetfile.h
|
|
// Created by : Steinberg, 03/2006
|
|
// Description : VST 3 Preset File Format
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// This file is part of a Steinberg SDK. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this distribution
|
|
// and at www.steinberg.net/sdklicenses.
|
|
// No part of the SDK, including this file, may be copied, modified, propagated,
|
|
// or distributed except according to the terms contained in the LICENSE file.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include "pluginterfaces/vst/ivstcomponent.h"
|
|
#include "pluginterfaces/vst/ivsteditcontroller.h"
|
|
#include "pluginterfaces/vst/ivstunits.h"
|
|
|
|
#include "pluginterfaces/base/ibstream.h"
|
|
#include "base/source/fbuffer.h"
|
|
|
|
#include <cstdio>
|
|
#include <vector>
|
|
|
|
//------------------------------------------------------------------------
|
|
/*
|
|
VST 3 Preset File Format Definition
|
|
===================================
|
|
|
|
0 +---------------------------+
|
|
| HEADER |
|
|
| header id ('VST3') | 4 Bytes
|
|
| version | 4 Bytes (int32)
|
|
| ASCII-encoded class id | 32 Bytes
|
|
+--| offset to chunk list | 8 Bytes (int64)
|
|
| +---------------------------+
|
|
| | DATA AREA |<-+
|
|
| | data of chunks 1..n | |
|
|
| ... ... |
|
|
| | | |
|
|
+->+---------------------------+ |
|
|
| CHUNK LIST | |
|
|
| list id ('List') | | 4 Bytes
|
|
| entry count | | 4 Bytes (int32)
|
|
+---------------------------+ |
|
|
| 1..n | |
|
|
| +----------------------+ | |
|
|
| | chunk id | | | 4 Bytes
|
|
| | offset to chunk data |----+ 8 Bytes (int64)
|
|
| | size of chunk data | | 8 Bytes (int64)
|
|
| +----------------------+ |
|
|
EOF +---------------------------+
|
|
*/
|
|
|
|
//------------------------------------------------------------------------
|
|
namespace Steinberg {
|
|
namespace Vst {
|
|
|
|
//------------------------------------------------------------------------
|
|
using ChunkID = char[4];
|
|
|
|
//------------------------------------------------------------------------
|
|
enum ChunkType
|
|
{
|
|
kHeader,
|
|
kComponentState,
|
|
kControllerState,
|
|
kProgramData,
|
|
kMetaInfo,
|
|
kChunkList,
|
|
kNumPresetChunks
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
extern const ChunkID& getChunkID (ChunkType type);
|
|
|
|
//------------------------------------------------------------------------
|
|
inline bool isEqualID (const ChunkID id1, const ChunkID id2)
|
|
{
|
|
return memcmp (id1, id2, sizeof (ChunkID)) == 0;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
/** Handler for a VST 3 Preset File.
|
|
\ingroup vstClasses
|
|
\see \ref presetformat
|
|
*/
|
|
class PresetFile
|
|
{
|
|
public:
|
|
//------------------------------------------------------------------------
|
|
PresetFile (IBStream* stream); ///< Constructor of Preset file based on a stream
|
|
virtual ~PresetFile ();
|
|
|
|
/** Internal structure used for chunk handling */
|
|
struct Entry
|
|
{
|
|
ChunkID id;
|
|
TSize offset;
|
|
TSize size;
|
|
};
|
|
|
|
IBStream* getStream () const { return stream; } ///< Returns the associated stream.
|
|
|
|
const FUID& getClassID () const { return classID; } ///< Returns the associated classID (component ID: Processor part (not the controller!)).
|
|
void setClassID (const FUID& uid) { classID = uid; }///< Sets the associated classID (component ID: Processor part (not the controller!)).
|
|
|
|
const Entry* getEntry (ChunkType which) const; ///< Returns an entry for a given chunk type.
|
|
const Entry* getLastEntry () const; ///< Returns the last available entry.
|
|
int32 getEntryCount () const { return entryCount; } ///< Returns the number of total entries in the current stream.
|
|
const Entry& at (int32 index) const { return entries[index]; } ///< Returns the entry at a given position.
|
|
bool contains (ChunkType which) const { return getEntry (which) != nullptr; } ///< Checks if a given chunk type exist in the stream.
|
|
|
|
bool readChunkList (); ///< Reads and build the chunk list (including the header chunk).
|
|
bool writeHeader (); ///< Writes into the stream the main header.
|
|
bool writeChunkList (); ///< Writes into the stream the chunk list (should be at the end).
|
|
|
|
/** Reads the meta XML info and its size, the size could be retrieved by passing zero as xmlBuffer. */
|
|
bool readMetaInfo (char* xmlBuffer, int32& size);
|
|
|
|
/** Writes the meta XML info, -1 means null-terminated, forceWriting to true will force to rewrite the XML Info when the chunk already exists. */
|
|
bool writeMetaInfo (const char* xmlBuffer, int32 size = -1, bool forceWriting = false);
|
|
bool prepareMetaInfoUpdate (); ///< checks if meta info chunk is the last one and jump to correct position.
|
|
|
|
/** Writes a given data of a given size as "which" chunk type. */
|
|
bool writeChunk (const void* data, int32 size, ChunkType which = kComponentState);
|
|
|
|
//-------------------------------------------------------------
|
|
// for storing and restoring the whole plug-in state (component and controller states)
|
|
bool seekToComponentState (); ///< Seeks to the begin of the Component State.
|
|
bool storeComponentState (IComponent* component); ///< Stores the component state (only one time).
|
|
bool storeComponentState (IBStream* componentStream); ///< Stores the component state from stream (only one time).
|
|
bool restoreComponentState (IComponent* component); ///< Restores the component state.
|
|
|
|
bool seekToControllerState (); ///< Seeks to the begin of the Controller State.
|
|
bool storeControllerState (IEditController* editController);///< Stores the controller state (only one time).
|
|
bool storeControllerState (IBStream* editStream); ///< Stores the controller state from stream (only one time).
|
|
bool restoreControllerState (IEditController* editController);///< Restores the controller state.
|
|
|
|
bool restoreComponentState (IEditController* editController);///< Restores the component state and apply it to the controller.
|
|
|
|
//--- ----------------------------------------------------------
|
|
/** Store program data or unit data from stream (including the header chunk).
|
|
\param inStream
|
|
\param listID could be ProgramListID or UnitID. */
|
|
bool storeProgramData (IBStream* inStream, ProgramListID listID);
|
|
|
|
//---when plug-in uses IProgramListData-----------------------
|
|
/** Stores a IProgramListData with a given identifier and index (including the header chunk). */
|
|
bool storeProgramData (IProgramListData* programListData, ProgramListID programListID,
|
|
int32 programIndex);
|
|
/** Restores a IProgramListData with a given identifier and index. */
|
|
bool restoreProgramData (IProgramListData* programListData, ProgramListID* programListID = nullptr,
|
|
int32 programIndex = 0);
|
|
|
|
//---when plug-in uses IUnitData------------------------------
|
|
/** Stores a IUnitData with a given unitID (including the header chunk). */
|
|
bool storeProgramData (IUnitData* unitData, UnitID unitID);
|
|
/** Restores a IUnitData with a given unitID (optional). */
|
|
bool restoreProgramData (IUnitData* unitData, UnitID* unitID = nullptr);
|
|
|
|
//--- ----------------------------------------------------------
|
|
/** for keeping the controller part in sync concerning preset data stream, unitProgramListID
|
|
* could be ProgramListID or UnitID. */
|
|
bool restoreProgramData (IUnitInfo* unitInfo, int32 unitProgramListID, int32 programIndex = -1);
|
|
|
|
/** Gets the unitProgramListID saved in the kProgramData chunk (if available). */
|
|
bool getUnitProgramListID (int32& unitProgramListID);
|
|
|
|
//--- ---------------------------------------------------------------------
|
|
/** Shortcut helper to create preset from component/controller state. classID is the FUID of the
|
|
* component (processor) part. */
|
|
static bool savePreset (IBStream* stream, const FUID& classID, IComponent* component,
|
|
IEditController* editController = nullptr,
|
|
const char* xmlBuffer = nullptr, int32 xmlSize = -1);
|
|
static bool savePreset (IBStream* stream, const FUID& classID, IBStream* componentStream,
|
|
IBStream* editStream = nullptr, const char* xmlBuffer = nullptr,
|
|
int32 xmlSize = -1);
|
|
|
|
/** Shortcut helper to load preset with component/controller state. classID is the FUID of the
|
|
* component (processor) part. */
|
|
static bool loadPreset (IBStream* stream, const FUID& classID, IComponent* component,
|
|
IEditController* editController = nullptr,
|
|
std::vector<FUID>* otherClassIDArray = nullptr);
|
|
//------------------------------------------------------------------------
|
|
protected:
|
|
bool readID (ChunkID id);
|
|
bool writeID (const ChunkID id);
|
|
bool readEqualID (const ChunkID id);
|
|
bool readSize (TSize& size);
|
|
bool writeSize (TSize size);
|
|
bool readInt32 (int32& value);
|
|
bool writeInt32 (int32 value);
|
|
bool seekTo (TSize offset);
|
|
bool beginChunk (Entry& e, ChunkType which);
|
|
bool endChunk (Entry& e);
|
|
|
|
IBStream* stream;
|
|
FUID classID; ///< classID is the FUID of the component (processor) part
|
|
enum { kMaxEntries = 128 };
|
|
Entry entries[kMaxEntries];
|
|
int32 entryCount {0};
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
/** Stream implementation for a file using stdio.
|
|
*/
|
|
class FileStream: public IBStream
|
|
{
|
|
public:
|
|
//------------------------------------------------------------------------
|
|
static IBStream* open (const char* filename, const char* mode); ///< open a stream using stdio function
|
|
|
|
//---from FUnknown------------------
|
|
DECLARE_FUNKNOWN_METHODS
|
|
|
|
//---from IBStream------------------
|
|
tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;
|
|
|
|
//------------------------------------------------------------------------
|
|
protected:
|
|
FileStream (FILE* file);
|
|
virtual ~FileStream ();
|
|
|
|
FILE* file;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
/** Stream representing a Read-Only subsection of its source stream.
|
|
*/
|
|
class ReadOnlyBStream: public IBStream
|
|
{
|
|
public:
|
|
//------------------------------------------------------------------------
|
|
ReadOnlyBStream (IBStream* sourceStream, TSize sourceOffset, TSize sectionSize);
|
|
virtual ~ReadOnlyBStream ();
|
|
|
|
//---from FUnknown------------------
|
|
DECLARE_FUNKNOWN_METHODS
|
|
|
|
//---from IBStream------------------
|
|
tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;
|
|
|
|
//------------------------------------------------------------------------
|
|
protected:
|
|
IBStream* sourceStream;
|
|
TSize sourceOffset;
|
|
TSize sectionSize;
|
|
TSize seekPosition;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
/** Stream implementation for a memory buffer.
|
|
*/
|
|
class BufferStream : public IBStream
|
|
{
|
|
public:
|
|
BufferStream ();
|
|
virtual ~BufferStream ();
|
|
|
|
//---from FUnknown------------------
|
|
DECLARE_FUNKNOWN_METHODS
|
|
|
|
//---from IBStream------------------
|
|
tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = nullptr) SMTG_OVERRIDE;
|
|
tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;
|
|
|
|
protected:
|
|
Buffer mBuffer;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
} // namespace Vst
|
|
} // namespace Steinberg
|