mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
VST3_SDK: Move to juce_audio_processors_headless
This commit is contained in:
parent
bf4486e2aa
commit
db64002610
139 changed files with 24 additions and 29 deletions
|
|
@ -1,5 +0,0 @@
|
|||
This list details modifications made to the VST3 SDK in order to facilitate
|
||||
inclusion in JUCE.
|
||||
|
||||
- The main.cpp of moduleinfotool was updated to include information exported
|
||||
by the plugin's IPluginCompatibility object, if present.
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
This license applies only to files referencing this license,
|
||||
for other files of the Software Development Kit the respective embedded license text
|
||||
is applicable. The license can be found at: www.steinberg.net/sdklicenses_vst3
|
||||
|
||||
This Software Development Kit is licensed under the terms of the Steinberg VST3 License,
|
||||
or alternatively under the terms of the General Public License (GPL) Version 3.
|
||||
You may use the Software Development Kit according to either of these licenses as it is
|
||||
most appropriate for your project on a case-by-case basis (commercial or not).
|
||||
|
||||
a) Proprietary Steinberg VST3 License
|
||||
The Software Development Kit may not be distributed in parts or its entirety
|
||||
without prior written agreement by Steinberg Media Technologies GmbH.
|
||||
The SDK must not be used to re-engineer or manipulate any technology used
|
||||
in any Steinberg or Third-party application or software module,
|
||||
unless permitted by law.
|
||||
Neither the name of the Steinberg Media Technologies GmbH nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
Before publishing a software under the proprietary license, you need to obtain a copy
|
||||
of the License Agreement signed by Steinberg Media Technologies GmbH.
|
||||
The Steinberg VST SDK License Agreement can be found at:
|
||||
www.steinberg.net/en/company/developers.html
|
||||
|
||||
THE SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
b) General Public License (GPL) Version 3
|
||||
Details of these licenses can be found at: www.gnu.org/licenses/gpl-3.0.html
|
||||
Please refer to the Steinberg VST usage guidelines for the use of VST, VST logo and VST
|
||||
compatible logos:
|
||||
https://steinbergmedia.github.io/vst3_dev_portal/pages/VST+3+Licensing/Usage+guidelines.html
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -1,249 +0,0 @@
|
|||
<div style="text-align:center">
|
||||
<img src="https://steinbergmedia.github.io/vst3_doc/gfx/vst3_logo.jpg" alt="VST 3 SDK" /></div>
|
||||
|
||||
# Welcome to VST SDK 3.7.x
|
||||
|
||||
## Table Of Contents
|
||||
|
||||
1. [The VST SDK package](#100)
|
||||
1. [System requirements](#200)
|
||||
1. [About VST plug-ins in general](#300)
|
||||
1. [About VST 3](#400)
|
||||
1. [How to build VST 3](#500)
|
||||
1. [Contributing](#600)
|
||||
1. [License & Usage guidelines](#700)
|
||||
|
||||
<div id='100'/>
|
||||
|
||||
## The VST SDK package contains
|
||||
|
||||
- VST 3 API
|
||||
- VST 3 Implementation Helper Classes
|
||||
- AAX, AUv3 and AU Wrappers
|
||||
- VST 3 plug-ins Examples
|
||||
|
||||
The full **VST 3 SDK** is available [here!](https://www.steinberg.net/en/company/developers.html). It contains:
|
||||
|
||||
- VST 3 plug-in Test Host Application/Validator,
|
||||
- the **Steinberg VST 3 Plug-In SDK Licensing Agreement** that you have to sign if you want to develop or host **VST 3** plug-ins.
|
||||
|
||||
<div id='200'/>
|
||||
|
||||
## System requirements
|
||||
|
||||
Supported Platforms:
|
||||
|
||||
| Operating System |Architecture |Compiler | Notes|
|
||||
| :------------------------------ | :-----------------------: | :---------------------: | :--------------------------: |
|
||||
|Windows 10/11 |x86, x86_64, arm64 |MSVC 2022, MSVC 2019 | |
|
||||
|Windows 8.1 |x86, x86_64 |MSVC 2019, MSVC 2017 | |
|
||||
|macOS 10.13 - 14 |x86, x86_64, Apple Silicon |Xcode 10 - 15 | |
|
||||
|iOS 13 - iOS 17 |arm64 |Xcode 11 - 15 | |
|
||||
|Linux - Raspberry Pi OS (Buster) |arm32 |GCC 8.3 and higher |Visual Studio Code |
|
||||
|Linux - Ubuntu 18.04 LTS |x86, x86_64 |GCC 8.3 and higher |Visual Studio Code, Qt Creator|
|
||||
|Linux - Ubuntu 20.04 LTS |x86, x86_64 |GCC 8.3 and higher |Visual Studio Code, Qt Creator|
|
||||
|
||||
---
|
||||
<div id='300'/>
|
||||
|
||||
## About VST plug-ins in general
|
||||
|
||||
A VST plug-in is an audio processing component that is utilized within a host application. This host application provides the audio or/and event streams that are processed by the plug-in's code. Generally speaking, a VST plug-in can take a stream of audio data, apply a process to the audio, and return the result to the host application. A VST plug-in performs its process normally using the processor of the computer. The audio stream is broken down into a series of blocks. The host supplies the blocks in sequence. The host and its current environment control the block-size. The VST plug-in maintains the status of all its own parameters relating to the running process: The host does not maintain any information about what the plug-in did with the last block of data it processed.
|
||||
|
||||
From the host application's point of view, a VST plug-in is a black box with an arbitrary number of inputs, outputs (Event (MIDI) or Audio), and associated parameters. The host needs no implicit knowledge of the plug-in's process to be able to use it. The plug-in process can use whatever parameters it wishes, internally to the process, but depending on the capabilities of the host, it can allow the changes to user parameters to be automated by the host.
|
||||
|
||||
The source code of a VST plug-in is platform independent, but the delivery system depends on the platform architecture:
|
||||
|
||||
- On **Windows**, a VST plug-in is a multi-threaded DLL (Dynamic Link Library), recently packaged into a folder structure.
|
||||
- On **Mac OS X**, a VST plug-in is a Mach-O Bundle
|
||||
- On **Linux**, a VST plug-in is a package
|
||||
|
||||
To learn more about VST you can:
|
||||
|
||||
- subscribe to the [VST Developer Forum](https://sdk.steinberg.net)
|
||||
- check the 3rd Party Developer Support section at [www.steinberg.net](https://www.steinberg.net/en/company/developers.html)
|
||||
- check the VST 3 SDK online documentation under: [steinbergmedia.github.io/vst3_dev_portal](https://steinbergmedia.github.io/vst3_dev_portal/pages/index.html)
|
||||
- check the online documentation under: [steinbergmedia.github.io/vst3_doc](https://steinbergmedia.github.io/vst3_doc)
|
||||
|
||||
---
|
||||
<div id='400'/>
|
||||
|
||||
## About VST 3
|
||||
|
||||
VST 3 is a general rework of the long-serving VST plug-in interface. It is not compatible with the older VST versions, but it includes some new features and possibilities. We have redesigned the API to make it not only far easier and more reliable for developers to work with, but have also provided completely new possibilities for plug-ins. These include:
|
||||
|
||||
### 1. Improved Performance with the Silence Flag
|
||||
|
||||
Processing can optionally be applied to plug-ins only when audio signals are present on their respective inputs, so VST 3 plug-ins can apply their processing economically and only when it is needed.
|
||||
|
||||
### 2. Multiple Dynamic I/Os
|
||||
|
||||
VST 3 plug-ins are no longer limited to a fixed number of inputs and outputs, and their I/O configuration can dynamically adapt to the channel configuration. Side-chains are also very easily realizable. This includes the possibility to deactivate unused busses after loading and even reactivate those when needed. This cleans up the mixer and further helps to reduce CPU load.
|
||||
|
||||
### 3. Sample-accurate Automation
|
||||
|
||||
VST 3 also features vastly improved parameter automation with sample accuracy and support for ramped automation data, allowing completely accurate and rapid parameter automation changes.
|
||||
|
||||
### 4. Logical Parameter Organization
|
||||
|
||||
The VST 3 plug-in parameters are displayed in a tree structure. Parameters are grouped into sections which represent the structure of the plug-in. Plug-ins can communicate their internal structure for the purpose of overview, but also for some associated functionality (eg. program-lists).
|
||||
|
||||
### 5. Resizeable UI Editor
|
||||
|
||||
VST 3 defines a way to allow resizing of the plug-in editor by a user.
|
||||
|
||||
### 6. Mouse Over Support
|
||||
|
||||
The host could ask the plug-in which parameter is under the mouse.
|
||||
|
||||
### 7. Context Menu Support
|
||||
|
||||
VST 3 defines a way to allow the host to add its own entries in the plug-in context menu of a specific parameter.
|
||||
|
||||
### 8. Channel Context Information
|
||||
|
||||
A VST 3 plug-in could access some channel information where it is instantiated: name, color, ...
|
||||
|
||||
### 9. Note Expression
|
||||
|
||||
VST 3 defines with Note Expression a new way of event controller editing. The plug-in is able to break free from the limitations of MIDI controller events by providing access to new VST 3 controller events that circumvent the laws of MIDI and provide articulation information for each individual note (event) in a polyphonic arrangement according to its noteId.
|
||||
|
||||
### 10. 3D Support
|
||||
|
||||
VST 3 supports new speaker configurations like Ambisonic, Atmos, Auro 3D or 22.2.
|
||||
|
||||
### 11. Factory Concept
|
||||
|
||||
VST 3 plug-in library could export multiple plug-ins and in this way replaces the shell concept of VST 2 (kPlugCategShell).
|
||||
|
||||
### 12. Support Remote control Representation
|
||||
|
||||
VST 3 plug-in can deliver a specific parameter mapping for remote controls like Nuage.
|
||||
|
||||
### 13. Others
|
||||
|
||||
While designing VST 3, we performed a careful analysis of the existing functionality of VST and rewrote the interfaces from scratch. In doing so, we focused a lot on providing clear interfaces and their documentation in order to avoid usage errors from the deepest possible layer.
|
||||
Some more features implemented specifically for developers include:
|
||||
|
||||
- More stable technical host/plug-in environment
|
||||
- Advanced technical definition of the standard
|
||||
- Modular approach
|
||||
- Separation of UI and processing
|
||||
- Advanced Preset System
|
||||
- Multiple plug-ins per Library
|
||||
- Test Host included
|
||||
- Automated Testing Environment
|
||||
- Validator (small command line Test Host) and plug-in examples code included
|
||||
|
||||
---
|
||||
<div id='500'/>
|
||||
|
||||
## How to build VST3
|
||||
|
||||
### Get the source code from GitHub
|
||||
|
||||
```c
|
||||
git clone --recursive https://github.com/steinbergmedia/vst3sdk.git
|
||||
```
|
||||
|
||||
### Build the examples on Windows
|
||||
|
||||
- Create a folder for the build and move to this folder (using cd):
|
||||
|
||||
```c
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
||||
- Generate the Solution/Projects: provide the path of the Project where CMakeLists.txt is located:
|
||||
|
||||
```c
|
||||
// examples:
|
||||
cmake.exe -G "Visual Studio 17 2022" -A x64 ..\vst3sdk
|
||||
// or without symbolic links
|
||||
cmake.exe -G "Visual Studio 17 2022" -A x64 ..\vst3sdk -DSMTG_CREATE_PLUGIN_LINK=0
|
||||
// or by using the local user program folder (FOLDERID_UserProgramFilesCommon) as VST3 folder
|
||||
cmake.exe -G "Visual Studio 17 2022" -A x64 -DSMTG_PLUGIN_TARGET_USER_PROGRAM_FILES_COMMON=1
|
||||
```
|
||||
|
||||
- Now you can build the plug-in (you can use Visual Studio too):
|
||||
|
||||
```c
|
||||
msbuild.exe vstsdk.sln
|
||||
// (or alternatively for example for release)
|
||||
cmake --build . --config Release
|
||||
```
|
||||
Note: If you have any issue with symbolic links, check [Preparation on Windows](https://steinbergmedia.github.io/vst3_dev_portal/pages/Getting+Started/Preparation+on+Windows.html) for potential solutions.
|
||||
|
||||
### Build the examples on macOS
|
||||
|
||||
- Create a folder for the build and move to this folder (using cd):
|
||||
|
||||
```c
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
||||
- Generate the Solution/Projects: provide the path of the Project where CMakeLists.txt is located:
|
||||
|
||||
```c
|
||||
// For XCode:
|
||||
cmake -GXcode ../vst3sdk
|
||||
// Without XCode (here debug variant):
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ../
|
||||
```
|
||||
|
||||
- Now you can build the plug-in (you can use XCode too):
|
||||
|
||||
```c
|
||||
xcodebuild
|
||||
// (or alternatively for example for release)
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### Build the examples on Linux
|
||||
|
||||
- Install the required packages [Package Requirements](https://steinbergmedia.github.io/vst3_dev_portal/pages/Getting+Started/How+to+setup+my+system.html#for-linux)
|
||||
- Create a folder for the build and move to this folder (using cd):
|
||||
|
||||
```c
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
||||
- Generate the Solution/Projects: provide the path of the Project where CMakeLists.txt is located:
|
||||
|
||||
```c
|
||||
cmake ../vst3sdk
|
||||
```
|
||||
|
||||
- Now you can build the plug-in:
|
||||
|
||||
```c
|
||||
make
|
||||
// (or alternatively for example for release)
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### Build using cmake-gui
|
||||
|
||||
- start the cmake-gui Application
|
||||
- **Browse Source...**: select the folder vst3sdk
|
||||
- **Browse Build...**: select a folder where the outputs (projects/...) will be created. Typically, a folder named "build"
|
||||
- you can check the SMTG Options
|
||||
- Press **Configure**
|
||||
- Press **Generate** and the project will be created
|
||||
|
||||
---
|
||||
<div id='600'/>
|
||||
|
||||
## Contributing
|
||||
|
||||
For bug reports and features requests, please visit the [VST Developer Forum](https://sdk.steinberg.net)
|
||||
|
||||
---
|
||||
<div id='700'/>
|
||||
|
||||
## License & Usage guidelines
|
||||
|
||||
More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,27 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
# Welcome to VST SDK 3 base
|
||||
|
||||
Here you can find some helper classes useful for developing **VST 3** plug-ins.
|
||||
|
||||
## License & Usage guidelines
|
||||
|
||||
More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
|
||||
|
||||
----
|
||||
Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk)
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/baseidds.cpp
|
||||
// Created by : Steinberg, 01/2008
|
||||
// Description : Basic Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include "pluginterfaces/base/istringresult.h"
|
||||
#include "pluginterfaces/base/ipersistent.h"
|
||||
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
DEF_CLASS_IID (IString)
|
||||
DEF_CLASS_IID (IStringResult)
|
||||
|
||||
DEF_CLASS_IID (IPersistent)
|
||||
DEF_CLASS_IID (IAttributes)
|
||||
DEF_CLASS_IID (IAttributes2)
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/classfactoryhelpers.h
|
||||
// Created by : Steinberg, 03/2017
|
||||
// Description : Class factory
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helper Macros. Not intended for direct use.
|
||||
// Use:
|
||||
// META_CLASS(className),
|
||||
// META_CLASS_IFACE(className,Interface),
|
||||
// META_CLASS_SINGLE(className,Interface)
|
||||
// instead.
|
||||
//------------------------------------------------------------------------------
|
||||
#define META_CREATE_FUNC(funcName) static FUnknown* funcName ()
|
||||
|
||||
#define CLASS_CREATE_FUNC(className) \
|
||||
namespace Meta { \
|
||||
META_CREATE_FUNC (make##className) { return (NEW className)->unknownCast (); } \
|
||||
}
|
||||
|
||||
#define SINGLE_CREATE_FUNC(className) \
|
||||
namespace Meta { \
|
||||
META_CREATE_FUNC (make##className) { return className::instance ()->unknownCast (); } \
|
||||
}
|
||||
|
||||
#define _META_CLASS(className) \
|
||||
namespace Meta { \
|
||||
static Steinberg::MetaClass meta##className ((#className), Meta::make##className); \
|
||||
}
|
||||
|
||||
#define _META_CLASS_IFACE(className, Interface) \
|
||||
namespace Meta { \
|
||||
static Steinberg::MetaClass meta##Interface##className ((#className), Meta::make##className, \
|
||||
Interface##_iid); \
|
||||
}
|
||||
|
||||
/** TODO
|
||||
*/
|
||||
#define META_CLASS(className) \
|
||||
CLASS_CREATE_FUNC (className) \
|
||||
_META_CLASS (className)
|
||||
|
||||
/** TODO
|
||||
*/
|
||||
#define META_CLASS_IFACE(className, Interface) \
|
||||
CLASS_CREATE_FUNC (className) \
|
||||
_META_CLASS_IFACE (className, Interface)
|
||||
|
||||
/** TODO
|
||||
*/
|
||||
#define META_CLASS_SINGLE(className, Interface) \
|
||||
SINGLE_CREATE_FUNC (className) \
|
||||
_META_CLASS_IFACE (className, Interface)
|
||||
|
|
@ -1,641 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fbuffer.cpp
|
||||
// Created by : Steinberg, 2008
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "base/source/fbuffer.h"
|
||||
#include "base/source/fstring.h"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
Buffer::Buffer ()
|
||||
: buffer (nullptr)
|
||||
, memSize (0)
|
||||
, fillSize (0)
|
||||
, delta (defaultDelta)
|
||||
{}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
Buffer::Buffer (uint32 s, uint8 initVal)
|
||||
: buffer (nullptr)
|
||||
, memSize (s)
|
||||
, fillSize (0)
|
||||
, delta (defaultDelta)
|
||||
{
|
||||
if (memSize == 0)
|
||||
return;
|
||||
buffer = (int8*)::malloc (memSize);
|
||||
if (buffer)
|
||||
memset (buffer, initVal, memSize);
|
||||
else
|
||||
memSize = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
Buffer::Buffer (uint32 s)
|
||||
: buffer (nullptr)
|
||||
, memSize (s)
|
||||
, fillSize (0)
|
||||
, delta (defaultDelta)
|
||||
{
|
||||
if (memSize == 0)
|
||||
return;
|
||||
buffer = (int8*)::malloc (memSize);
|
||||
if (!buffer)
|
||||
memSize = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
Buffer::Buffer (const void* b , uint32 s)
|
||||
: buffer (nullptr)
|
||||
, memSize (s)
|
||||
, fillSize (s)
|
||||
, delta (defaultDelta)
|
||||
{
|
||||
if (memSize == 0)
|
||||
return;
|
||||
buffer = (int8*)::malloc (memSize);
|
||||
if (buffer)
|
||||
memcpy (buffer, b, memSize);
|
||||
else
|
||||
{
|
||||
memSize = 0;
|
||||
fillSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
Buffer::Buffer (const Buffer& bufferR)
|
||||
: buffer (nullptr)
|
||||
, memSize (bufferR.memSize)
|
||||
, fillSize (bufferR.fillSize)
|
||||
, delta (bufferR.delta)
|
||||
{
|
||||
if (memSize == 0)
|
||||
return;
|
||||
|
||||
buffer = (int8*)::malloc (memSize);
|
||||
if (buffer)
|
||||
memcpy (buffer, bufferR.buffer, memSize);
|
||||
else
|
||||
memSize = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
Buffer::~Buffer ()
|
||||
{
|
||||
if (buffer)
|
||||
::free (buffer);
|
||||
buffer = nullptr;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
void Buffer::operator = (const Buffer& b2)
|
||||
{
|
||||
if (&b2 != this)
|
||||
{
|
||||
setSize (b2.memSize);
|
||||
if (b2.memSize > 0 && buffer)
|
||||
memcpy (buffer, b2.buffer, b2.memSize);
|
||||
fillSize = b2.fillSize;
|
||||
delta = b2.delta;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::operator == (const Buffer& b2)const
|
||||
{
|
||||
if (&b2 == this)
|
||||
return true;
|
||||
if (b2.getSize () != getSize ())
|
||||
return false;
|
||||
return memcmp (this->int8Ptr (), b2.int8Ptr (), getSize ()) == 0 ? true : false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
uint32 Buffer::get (void* b, uint32 size)
|
||||
{
|
||||
uint32 maxGet = memSize - fillSize;
|
||||
if (size > maxGet)
|
||||
size = maxGet;
|
||||
if (size > 0)
|
||||
memcpy (b, buffer + fillSize, size);
|
||||
fillSize += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::put (char16 c)
|
||||
{
|
||||
return put ((const void*)&c, sizeof (c));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::put (uint8 byte)
|
||||
{
|
||||
if (grow (fillSize + 1) == false)
|
||||
return false;
|
||||
|
||||
buffer [fillSize++] = byte;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::put (char c)
|
||||
{
|
||||
if (grow (fillSize + 1) == false)
|
||||
return false;
|
||||
|
||||
buffer [fillSize++] = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::put (const void* toPut, uint32 s)
|
||||
{
|
||||
if (!toPut)
|
||||
return false;
|
||||
|
||||
if (grow (fillSize + s) == false)
|
||||
return false;
|
||||
|
||||
memcpy (buffer + fillSize, toPut, s);
|
||||
fillSize += s;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::put (const String& str)
|
||||
{
|
||||
return put ((const void*)str.text () , (str.length () + 1) * sizeof (tchar));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::appendString8 (const char8* s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
uint32 len = (uint32) strlen (s);
|
||||
return put (s, len);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::appendString16 (const char16* s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
ConstString str (s);
|
||||
uint32 len = (uint32) str.length () * sizeof (char16);
|
||||
return put (s, len);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::prependString8 (const char8* s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
uint32 len = (uint32) strlen (s);
|
||||
if (len > 0)
|
||||
{
|
||||
shiftStart (len);
|
||||
memcpy (buffer, s, len);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::prependString16 (const char16* s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
ConstString str (s);
|
||||
uint32 len = (uint32) str.length () * sizeof (char16);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
shiftStart (len);
|
||||
memcpy (buffer, s, len);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::prependString8 (char8 c)
|
||||
{
|
||||
shiftStart (sizeof (char));
|
||||
char* b = (char*)buffer;
|
||||
b [0] = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::prependString16 (char16 c)
|
||||
{
|
||||
shiftStart (sizeof (char16));
|
||||
char16* b = (char16*)buffer;
|
||||
b [0] = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::copy (uint32 from, uint32 to, uint32 bytes)
|
||||
{
|
||||
if (from + bytes > memSize || bytes == 0)
|
||||
return false;
|
||||
|
||||
if (to + bytes > memSize)
|
||||
setSize (to + bytes);
|
||||
|
||||
if (from + bytes > to && from < to)
|
||||
{ // overlap
|
||||
Buffer tmp (buffer + from, bytes);
|
||||
memcpy (buffer + to, tmp, bytes);
|
||||
}
|
||||
else
|
||||
memcpy (buffer + to, buffer + from, bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::makeHexString (String& result)
|
||||
{
|
||||
unsigned char* data = uint8Ptr ();
|
||||
uint32 bytes = getSize ();
|
||||
|
||||
if (data == nullptr || bytes == 0)
|
||||
return false;
|
||||
|
||||
char8* stringBuffer = NEWSTR8 ((bytes * 2) + 1);
|
||||
if (!stringBuffer)
|
||||
return false;
|
||||
|
||||
int32 count = 0;
|
||||
while (bytes > 0)
|
||||
{
|
||||
unsigned char t1 = ((*data) >> 4) & 0x0F;
|
||||
unsigned char t2 = (*data) & 0x0F;
|
||||
if (t1 < 10)
|
||||
t1 += '0';
|
||||
else
|
||||
t1 = t1 - 10 + 'A';
|
||||
if (t2 < 10)
|
||||
t2 += '0';
|
||||
else
|
||||
t2 = t2 - 10 + 'A';
|
||||
|
||||
stringBuffer [count++] = t1;
|
||||
stringBuffer [count++] = t2;
|
||||
data++;
|
||||
bytes--;
|
||||
}
|
||||
stringBuffer [count] = 0;
|
||||
|
||||
result.take ((void*)stringBuffer, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::fromHexString (const char8* string)
|
||||
{
|
||||
flush ();
|
||||
if (string == nullptr)
|
||||
return false;
|
||||
|
||||
int32 len = strlen8 (string);
|
||||
if (len == 0 || ((len & 1) == 1)/*odd number*/ )
|
||||
return false;
|
||||
|
||||
setSize (len / 2);
|
||||
unsigned char* data = uint8Ptr ();
|
||||
|
||||
bool upper = true;
|
||||
int32 count = 0;
|
||||
while (count < len)
|
||||
{
|
||||
char c = string [count];
|
||||
|
||||
unsigned char d = 0;
|
||||
if (c >= '0' && c <= '9') d += c - '0';
|
||||
else if (c >= 'A' && c <= 'F') d += c - 'A' + 10;
|
||||
else if (c >= 'a' && c <= 'f') d += c - 'a' + 10;
|
||||
else return false; // no hex string
|
||||
|
||||
if (upper)
|
||||
data [count >> 1] = static_cast<unsigned char> (d << 4);
|
||||
else
|
||||
data [count >> 1] += d;
|
||||
|
||||
upper = !upper;
|
||||
count++;
|
||||
}
|
||||
setFillSize (len / 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void Buffer::set (uint8 value)
|
||||
{
|
||||
if (buffer)
|
||||
memset (buffer, value, memSize);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::setFillSize (uint32 c)
|
||||
{
|
||||
if (c <= memSize)
|
||||
{
|
||||
fillSize = c;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::truncateToFillSize ()
|
||||
{
|
||||
if (fillSize < memSize)
|
||||
setSize (fillSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::grow (uint32 newSize)
|
||||
{
|
||||
if (newSize > memSize)
|
||||
{
|
||||
if (delta == 0)
|
||||
delta = defaultDelta;
|
||||
uint32 s = ((newSize + delta - 1) / delta) * delta;
|
||||
return setSize (s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void Buffer::shiftAt (uint32 position, int32 amount)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
if (grow (fillSize + amount))
|
||||
{
|
||||
if (position < fillSize)
|
||||
memmove (buffer + amount + position, buffer + position, fillSize - position);
|
||||
|
||||
fillSize += amount;
|
||||
}
|
||||
}
|
||||
else if (amount < 0 && fillSize > 0)
|
||||
{
|
||||
uint32 toRemove = -amount;
|
||||
|
||||
if (toRemove < fillSize)
|
||||
{
|
||||
if (position < fillSize)
|
||||
memmove (buffer + position, buffer + toRemove + position, fillSize - position - toRemove);
|
||||
fillSize -= toRemove;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
void Buffer::move (int32 amount, uint8 initVal)
|
||||
{
|
||||
if (memSize == 0)
|
||||
return;
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
if ((uint32)amount < memSize)
|
||||
{
|
||||
memmove (buffer + amount, buffer, memSize - amount);
|
||||
memset (buffer, initVal, amount);
|
||||
}
|
||||
else
|
||||
memset (buffer, initVal, memSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 toRemove = -amount;
|
||||
if (toRemove < memSize)
|
||||
{
|
||||
memmove (buffer, buffer + toRemove, memSize - toRemove);
|
||||
memset (buffer + memSize - toRemove, initVal, toRemove);
|
||||
}
|
||||
else
|
||||
memset (buffer, initVal, memSize);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::setSize (uint32 newSize)
|
||||
{
|
||||
if (memSize != newSize)
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
if (newSize > 0)
|
||||
{
|
||||
int8* newBuffer = (int8*) ::realloc (buffer, newSize);
|
||||
if (newBuffer == nullptr)
|
||||
{
|
||||
newBuffer = (int8*)::malloc (newSize);
|
||||
if (newBuffer)
|
||||
{
|
||||
uint32 tmp = newSize;
|
||||
if (tmp > memSize)
|
||||
tmp = memSize;
|
||||
memcpy (newBuffer, buffer, tmp);
|
||||
::free (buffer);
|
||||
buffer = newBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
::free (buffer);
|
||||
buffer = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
buffer = newBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
::free (buffer);
|
||||
buffer = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
buffer = (int8*)::malloc (newSize);
|
||||
|
||||
if (newSize > 0 && !buffer)
|
||||
memSize = 0;
|
||||
else
|
||||
memSize = newSize;
|
||||
if (fillSize > memSize)
|
||||
fillSize = memSize;
|
||||
}
|
||||
|
||||
return (newSize > 0) == (buffer != nullptr);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
void Buffer::fillup (uint8 value)
|
||||
{
|
||||
if (getFree () > 0)
|
||||
memset (buffer + fillSize, value, getFree ());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
int8* Buffer::operator + (uint32 i)
|
||||
{
|
||||
if (i < memSize)
|
||||
return buffer + i;
|
||||
|
||||
static int8 eof;
|
||||
eof = 0;
|
||||
return &eof;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::swap (int16 swapSize)
|
||||
{
|
||||
return swap (buffer, memSize, swapSize);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::swap (void* buffer, uint32 bufferSize, int16 swapSize)
|
||||
{
|
||||
if (swapSize != kSwap16 && swapSize != kSwap32 && swapSize != kSwap64)
|
||||
return false;
|
||||
|
||||
if (swapSize == kSwap16)
|
||||
{
|
||||
for (uint32 count = 0 ; count < bufferSize ; count += 2)
|
||||
{
|
||||
SWAP_16 ( * (((int16*)buffer) + count) );
|
||||
}
|
||||
}
|
||||
else if (swapSize == kSwap32)
|
||||
{
|
||||
for (uint32 count = 0 ; count < bufferSize ; count += 4)
|
||||
{
|
||||
SWAP_32 ( * (((int32*)buffer) + count) );
|
||||
}
|
||||
}
|
||||
else if (swapSize == kSwap64)
|
||||
{
|
||||
for (uint32 count = 0 ; count < bufferSize ; count += 8)
|
||||
{
|
||||
SWAP_64 ( * (((int64*)buffer) + count) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
void Buffer::take (Buffer& from)
|
||||
{
|
||||
setSize (0);
|
||||
memSize = from.memSize;
|
||||
fillSize = from.fillSize;
|
||||
buffer = from.buffer;
|
||||
from.buffer = nullptr;
|
||||
from.memSize = 0;
|
||||
from.fillSize = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
int8* Buffer::pass ()
|
||||
{
|
||||
int8* res = buffer;
|
||||
buffer = nullptr;
|
||||
memSize = 0;
|
||||
fillSize = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::toWideString (int32 sourceCodePage)
|
||||
{
|
||||
if (getFillSize () > 0)
|
||||
{
|
||||
if (str8 () [getFillSize () - 1] != 0) // multiByteToWideString only works with 0-terminated strings
|
||||
endString8 ();
|
||||
|
||||
Buffer dest (getFillSize () * sizeof (char16));
|
||||
int32 result = String::multiByteToWideString (dest.str16 (), str8 (), dest.getFree () / sizeof (char16), sourceCodePage);
|
||||
if (result > 0)
|
||||
{
|
||||
dest.setFillSize ((result - 1) * sizeof (char16));
|
||||
take (dest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
bool Buffer::toMultibyteString (int32 destCodePage)
|
||||
{
|
||||
if (getFillSize () > 0)
|
||||
{
|
||||
int32 textLength = getFillSize () / sizeof (char16); // wideStringToMultiByte only works with 0-terminated strings
|
||||
if (str16 () [textLength - 1] != 0)
|
||||
endString16 ();
|
||||
|
||||
Buffer dest (getFillSize ());
|
||||
int32 result = String::wideStringToMultiByte (dest.str8 (), str16 (), dest.getFree (), destCodePage);
|
||||
if (result > 0)
|
||||
{
|
||||
dest.setFillSize (result - 1);
|
||||
take (dest);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,306 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fbuffer.h
|
||||
// Created by : Steinberg, 2008
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/ftypes.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace Steinberg {
|
||||
class String;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Buffer.
|
||||
@ingroup adt
|
||||
|
||||
A Buffer is an object-oriented wrapper for a piece of memory.
|
||||
It adds several utility functions, e.g. for managing the size of the Buffer,
|
||||
appending or prepending values or strings to it.
|
||||
Internally it uses the standard memory functions malloc(), free(), etc. */
|
||||
//------------------------------------------------------------------------
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/** Default constructor, allocates no memory at all.
|
||||
*/
|
||||
Buffer ();
|
||||
|
||||
/** Constructor - creates a new Buffer with a given size and copies contents from optional memory pointer.
|
||||
\param[in] b : optional memory pointer with the size of at least the given size
|
||||
\param[in] size : the size of the new Buffer to be allocated, in bytes.
|
||||
*/
|
||||
Buffer (const void* b, uint32 size);
|
||||
|
||||
/** Constructor - creates a new Buffer with a given size and fills it all with a given value.
|
||||
\param[in] size : the size of the new Buffer to be allocated, in bytes.
|
||||
\param[in] initVal : the initial value the Buffer will be completely filled with
|
||||
*/
|
||||
Buffer (uint32 size, uint8 initVal);
|
||||
|
||||
/** Constructor - creates a new Buffer with a given size.
|
||||
\param[in] size : the size of the new Buffer to be allocated, in bytes.
|
||||
*/
|
||||
Buffer (uint32 size);
|
||||
|
||||
/** Copy constructor - creates a new Buffer from a given Buffer.
|
||||
\param[in] buff : the Buffer from which all memory will be copied to the new one
|
||||
*/
|
||||
Buffer (const Buffer& buff);
|
||||
|
||||
/** Destructor - deallocates the internal memory.
|
||||
*/
|
||||
virtual ~Buffer ();
|
||||
|
||||
/** Assignment operator - copies contents from a given Buffer and increases the size if necessary.
|
||||
\param[in] buff : the Buffer from which all memory will be copied
|
||||
*/
|
||||
void operator = (const Buffer& buff);
|
||||
|
||||
/** Comparison operator - copies contents from a given Buffer and increases the size if necessary.
|
||||
\param[in] buff : the Buffer to be compared to
|
||||
\return true, if the given Buffer's content is equal to this one, else false
|
||||
*/
|
||||
bool operator == (const Buffer& buff)const;
|
||||
|
||||
uint32 getSize () const {return memSize;} ///< \return the actual size of the Buffer's memory, in bytes.
|
||||
|
||||
/** Sets a new size for this Buffer, keeping as much content as possible.
|
||||
\param[in] newSize : the new size for the Buffer, in bytes, newSize maybe zero
|
||||
\return true, if the new size could be adapted, else false
|
||||
*/
|
||||
bool setSize (uint32 newSize);
|
||||
|
||||
/** Increases the Buffer to the next block, block size given by delta.
|
||||
\param[in] memSize : the new minimum size of the Buffer, newSize maybe zero
|
||||
\return true, if the Buffer could be grown successfully, else false
|
||||
*/
|
||||
bool grow (uint32 memSize);
|
||||
bool setMaxSize (uint32 size) {return grow (size);} ///< see \ref grow()
|
||||
|
||||
void fillup (uint8 initVal = 0); ///< set from fillSize to end
|
||||
uint32 getFillSize ()const {return fillSize;} ///< \return the actual fill size
|
||||
bool setFillSize (uint32 c); ///< sets a new fill size, does not change any memory
|
||||
inline void flush () {setFillSize (0);} ///< sets fill size to zero
|
||||
bool truncateToFillSize (); ///< \return always true, truncates the size of the Buffer to the actual fill size
|
||||
|
||||
bool isFull () const { return (fillSize == memSize); } ///< \return true, if all memory is filled up, else false
|
||||
uint32 getFree () const { return (memSize - fillSize); }///< \return remaining memory
|
||||
|
||||
inline void shiftStart (int32 amount) {return shiftAt (0, amount);} ///< moves all memory by given amount, grows the Buffer if necessary
|
||||
void shiftAt (uint32 position, int32 amount); ///< moves memory starting at the given position
|
||||
void move (int32 amount, uint8 initVal = 0); ///< shifts memory at start without growing the buffer, so data is lost and initialized with init val
|
||||
|
||||
bool copy (uint32 from, uint32 to, uint32 bytes); ///< copies a number of bytes from one position to another, the size may be adapted
|
||||
uint32 get (void* b, uint32 size); ///< copy to buffer from fillSize, and shift fillSize
|
||||
|
||||
void setDelta (uint32 d) {delta = d;} ///< define the block size by which the Buffer grows, see \ref grow()
|
||||
|
||||
bool put (uint8); ///< append value at end, grows Buffer if necessary
|
||||
bool put (char16 c); ///< append value at end, grows Buffer if necessary
|
||||
bool put (char c); ///< append value at end, grows Buffer if necessary
|
||||
bool put (const void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
|
||||
bool put (void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
|
||||
bool put (uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
|
||||
bool put (char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
|
||||
bool put (const uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
|
||||
bool put (const char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
|
||||
bool put (const String&); ///< append String at end, grows Buffer if necessary
|
||||
|
||||
void set (uint8 value); ///< fills complete Buffer with given value
|
||||
|
||||
// strings ----------------
|
||||
bool appendString (const tchar* s);
|
||||
bool appendString (tchar* s);
|
||||
bool appendString (tchar c) { return put (c); }
|
||||
|
||||
bool appendString8 (const char8* s);
|
||||
bool appendString16 (const char16* s);
|
||||
|
||||
bool appendString8 (char8* s) { return appendString8 ((const char8*)s); }
|
||||
bool appendString8 (unsigned char* s) { return appendString8 ((const char8*)s); }
|
||||
bool appendString8 (const unsigned char* s) { return appendString8 ((const char8*)s); }
|
||||
|
||||
bool appendString8 (char8 c) { return put ((uint8)c); }
|
||||
bool appendString8 (unsigned char c) { return put (c); }
|
||||
bool appendString16 (char16 c) { return put (c); }
|
||||
bool appendString16 (char16* s) { return appendString16 ((const char16*)s); }
|
||||
|
||||
bool prependString (const tchar* s);
|
||||
bool prependString (tchar* s);
|
||||
bool prependString (tchar c);
|
||||
|
||||
bool prependString8 (const char8* s);
|
||||
bool prependString16 (const char16* s);
|
||||
|
||||
bool prependString8 (char8 c);
|
||||
bool prependString8 (unsigned char c) { return prependString8 ((char8)c); }
|
||||
bool prependString8 (char8* s) { return prependString8 ((const char8*)s); }
|
||||
bool prependString8 (unsigned char* s) { return prependString8((const char8*)s); }
|
||||
bool prependString8 (const unsigned char* s) { return prependString8 ((const char8*)s); }
|
||||
bool prependString16 (char16 c);
|
||||
bool prependString16 (char16* s) { return prependString16 ((const char16*)s); }
|
||||
|
||||
bool operator+= (const char* s) { return appendString8 (s); }
|
||||
bool operator+= (char c) { return appendString8 (c); }
|
||||
bool operator+= (const char16* s) { return appendString16 (s); }
|
||||
bool operator+= (char16 c) { return appendString16 (c); }
|
||||
|
||||
bool operator= (const char* s) { flush (); return appendString8 (s); }
|
||||
bool operator= (const char16* s) { flush (); return appendString16 (s); }
|
||||
bool operator= (char8 c) { flush (); return appendString8 (c); }
|
||||
bool operator= (char16 c) { flush (); return appendString16 (c); }
|
||||
|
||||
void endString () {put (tchar (0));}
|
||||
void endString8 () {put (char8 (0));}
|
||||
void endString16 () {put (char16 (0));}
|
||||
|
||||
bool makeHexString (String& result);
|
||||
bool fromHexString (const char8* string);
|
||||
|
||||
// conversion
|
||||
operator void* () const { return (void*)buffer; } ///< conversion
|
||||
inline tchar* str () const {return (tchar*)buffer;} ///< conversion
|
||||
inline char8* str8 () const {return (char8*)buffer;} ///< conversion
|
||||
inline char16* str16 () const {return (char16*)buffer;} ///< conversion
|
||||
inline int8* int8Ptr () const {return (int8*)buffer;} ///< conversion
|
||||
inline uint8* uint8Ptr () const {return (uint8*)buffer; } ///< conversion
|
||||
inline int16* int16Ptr () const {return (int16*)buffer; } ///< conversion
|
||||
inline uint16* uint16Ptr () const {return (uint16*)buffer; } ///< conversion
|
||||
inline int32* int32Ptr () const {return (int32*)buffer; } ///< conversion
|
||||
inline uint32* uint32Ptr () const {return (uint32*)buffer; } ///< conversion
|
||||
inline float* floatPtr () const {return (float*)buffer; } ///< conversion
|
||||
inline double* doublePtr () const {return (double*)buffer; } ///< conversion
|
||||
inline char16* wcharPtr () const {return (char16*)buffer;} ///< conversion
|
||||
|
||||
int8* operator + (uint32 i); ///< \return the internal Buffer's address plus the given offset i, zero if offset is out of range
|
||||
|
||||
int32 operator ! () { return buffer == nullptr; }
|
||||
|
||||
enum swapSize
|
||||
{
|
||||
kSwap16 = 2,
|
||||
kSwap32 = 4,
|
||||
kSwap64 = 8
|
||||
};
|
||||
bool swap (int16 swapSize); ///< swap all bytes of this Buffer by the given swapSize
|
||||
static bool swap (void* buffer, uint32 bufferSize, int16 swapSize); ///< utility, swap given number of bytes in given buffer by the given swapSize
|
||||
|
||||
void take (Buffer& from); ///< takes another Buffer's memory, frees the current Buffer's memory
|
||||
int8* pass (); ///< pass the current Buffer's memory
|
||||
|
||||
/** Converts a Buffer's content to UTF-16 from a given multi-byte code page, Buffer must contain char8 of given encoding.
|
||||
\param[in] sourceCodePage : the actual code page of the Buffer's content
|
||||
\return true, if the conversion was successful, else false
|
||||
*/
|
||||
virtual bool toWideString (int32 sourceCodePage); // Buffer contains char8 of given encoding -> utf16
|
||||
|
||||
/** Converts a Buffer's content from UTF-16 to a given multi-byte code page, Buffer must contain UTF-16 encoded characters.
|
||||
\param[in] destCodePage : the desired code page to convert the Buffer's content to
|
||||
\return true, if the conversion was successful, else false
|
||||
*/
|
||||
virtual bool toMultibyteString (int32 destCodePage); // Buffer contains utf16 -> char8 of given encoding
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
static const uint32 defaultDelta = 0x1000; // 0x1000
|
||||
|
||||
int8* buffer;
|
||||
uint32 memSize;
|
||||
uint32 fillSize;
|
||||
uint32 delta;
|
||||
};
|
||||
|
||||
inline bool Buffer::put (void* p, uint32 count) { return put ((const void*)p , count ); }
|
||||
inline bool Buffer::put (uint8 * p, uint32 count) { return put ((const void*)p , count ); }
|
||||
inline bool Buffer::put (char8* p, uint32 count) { return put ((const void*)p , count ); }
|
||||
inline bool Buffer::put (const uint8* p, uint32 count) { return put ((const void*)p , count ); }
|
||||
inline bool Buffer::put (const char8* p, uint32 count) { return put ((const void*)p , count ); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool Buffer::appendString (const tchar* s)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return appendString16 (s);
|
||||
#else
|
||||
return appendString8 (s);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool Buffer::appendString (tchar* s)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return appendString16 (s);
|
||||
#else
|
||||
return appendString8 (s);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool Buffer::prependString (const tchar* s)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return prependString16 (s);
|
||||
#else
|
||||
return prependString8 (s);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool Buffer::prependString (tchar* s)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return prependString16 (s);
|
||||
#else
|
||||
return prependString8 (s);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool Buffer::prependString (tchar c)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return prependString16 (c);
|
||||
#else
|
||||
return prependString8 (c);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,392 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fcommandline.h
|
||||
// Created by : Steinberg, 2007
|
||||
// Description : Very simple command-line parser.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @file base/source/fcommandline.h
|
||||
Very simple command-line parser.
|
||||
@see Steinberg::CommandLine */
|
||||
//------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace Steinberg {
|
||||
//------------------------------------------------------------------------
|
||||
/** Very simple command-line parser.
|
||||
|
||||
Parses the command-line into a CommandLine::VariablesMap.\n
|
||||
The command-line parser uses CommandLine::Descriptions to define the available options.
|
||||
|
||||
@b Example:
|
||||
\code
|
||||
#include "base/source/fcommandline.h"
|
||||
#include <iostream>
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
CommandLine::Descriptions desc;
|
||||
CommandLine::VariablesMap valueMap;
|
||||
|
||||
desc.addOptions ("myTool")
|
||||
("help", "produce help message")
|
||||
("opt1", string(), "option 1")
|
||||
("opt2", string(), "option 2")
|
||||
;
|
||||
CommandLine::parse (argc, argv, desc, valueMap);
|
||||
|
||||
if (valueMap.hasError () || valueMap.count ("help"))
|
||||
{
|
||||
cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
if (valueMap.count ("opt1"))
|
||||
{
|
||||
cout << "Value of option 1 " << valueMap["opt1"] << "\n";
|
||||
}
|
||||
if (valueMap.count ("opt2"))
|
||||
{
|
||||
cout << "Value of option 2 " << valueMap["opt2"] << "\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
@note
|
||||
This is a "header only" implementation.\n
|
||||
If you need the declarations in more than one cpp file, you have to define
|
||||
@c SMTG_NO_IMPLEMENTATION in all but one file.
|
||||
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
namespace CommandLine {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Command-line parsing result.
|
||||
This is the result of the parser.\n
|
||||
- Use hasError() to check for errors.\n
|
||||
- To test if a option was specified on the command-line use: count()\n
|
||||
- To retrieve the value of an options, use operator [](const VariablesMapContainer::key_type
|
||||
k)\n
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class VariablesMap
|
||||
{
|
||||
bool mParaError;
|
||||
using VariablesMapContainer = std::map<std::string, std::string>;
|
||||
VariablesMapContainer mVariablesMapContainer;
|
||||
|
||||
public:
|
||||
VariablesMap () : mParaError (false) {} ///< Constructor. Creates a empty VariablesMap.
|
||||
bool hasError () const { return mParaError; } ///< Returns @c true when an error has occurred.
|
||||
void setError () { mParaError = true; } ///< Sets the error state to @c true.
|
||||
|
||||
/** Retrieve the value of option @c k.*/
|
||||
std::string& operator[] (const VariablesMapContainer::key_type k);
|
||||
|
||||
/** Retrieve the value of option @c k. */
|
||||
const std::string& operator[] (const VariablesMapContainer::key_type k) const;
|
||||
|
||||
/** Returns @c != @c 0 if command-line contains option @c k. */
|
||||
VariablesMapContainer::size_type count (const VariablesMapContainer::key_type k) const;
|
||||
};
|
||||
|
||||
//! type of the list of elements on the command line that are not handled by options parsing
|
||||
using FilesVector = std::vector<std::string>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** The description of one single command-line option.
|
||||
Normally you rarely use a Description directly.\n
|
||||
In most cases you will use the Descriptions::addOptions (const std::string&) method to create
|
||||
and add descriptions.
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class Description : public std::string
|
||||
{
|
||||
public:
|
||||
/** Construct a Description */
|
||||
Description (const std::string& name, const std::string& help,
|
||||
const std::string& valueType);
|
||||
std::string mHelp; ///< The help string for this option.
|
||||
std::string mType; ///< The type of this option (kBool, kString).
|
||||
static const std::string kBool;
|
||||
static const std::string kString;
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
/** List of command-line option descriptions.
|
||||
|
||||
Use addOptions (const std::string&) to add Descriptions.
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class Descriptions
|
||||
{
|
||||
using DescriptionsList = std::deque<Description>;
|
||||
DescriptionsList mDescriptions;
|
||||
std::string mCaption;
|
||||
|
||||
public:
|
||||
/** Sets the command-line tool caption and starts adding Descriptions. */
|
||||
Descriptions& addOptions (const std::string& caption = "",
|
||||
std::initializer_list<Description>&& options = {});
|
||||
|
||||
/** Parse the command-line. */
|
||||
bool parse (int ac, char* av[], VariablesMap& result, FilesVector* files = nullptr) const;
|
||||
|
||||
/** Print a brief description for the command-line tool into the stream @c os. */
|
||||
void print (std::ostream& os) const;
|
||||
|
||||
/** Add a new switch. Only */
|
||||
Descriptions& operator () (const std::string& name, const std::string& help);
|
||||
|
||||
/** Add a new option of type @c inType. Currently only std::string is supported. */
|
||||
template <typename Type>
|
||||
Descriptions& operator () (const std::string& name, const Type& inType, std::string help);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// If you need the declarations in more than one cpp file you have to define
|
||||
// SMTG_NO_IMPLEMENTATION in all but one file.
|
||||
//------------------------------------------------------------------------
|
||||
#ifndef SMTG_NO_IMPLEMENTATION
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! If command-line contains option @c k more than once, only the last value will survive. */
|
||||
//------------------------------------------------------------------------
|
||||
std::string& VariablesMap::operator[] (const VariablesMapContainer::key_type k)
|
||||
{
|
||||
return mVariablesMapContainer[k];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! If command-line contains option @c k more than once, only the last value will survive. */
|
||||
//------------------------------------------------------------------------
|
||||
const std::string& VariablesMap::operator[] (const VariablesMapContainer::key_type k) const
|
||||
{
|
||||
return (*const_cast<VariablesMap*> (this))[k];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
VariablesMap::VariablesMapContainer::size_type VariablesMap::count (
|
||||
const VariablesMapContainer::key_type k) const
|
||||
{
|
||||
return mVariablesMapContainer.count (k);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Add a new option with a string as parameter. */
|
||||
//------------------------------------------------------------------------
|
||||
template <>
|
||||
Descriptions& Descriptions::operator () (const std::string& name, const std::string& inType,
|
||||
std::string help)
|
||||
{
|
||||
mDescriptions.emplace_back (name, help, inType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Parse the command - line. */
|
||||
bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result,
|
||||
FilesVector* files = nullptr);
|
||||
|
||||
/** Make Descriptions stream able. */
|
||||
std::ostream& operator<< (std::ostream& os, const Descriptions& desc);
|
||||
|
||||
const std::string Description::kBool = "bool";
|
||||
const std::string Description::kString = "string";
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! In most cases you will use the Descriptions::addOptions (const std::string&) method to create
|
||||
and add descriptions.
|
||||
|
||||
@param[in] name of the option.
|
||||
@param[in] help a help description for this option.
|
||||
@param[out] valueType Description::kBool or Description::kString.
|
||||
*/
|
||||
Description::Description (const std::string& name, const std::string& help,
|
||||
const std::string& valueType)
|
||||
: std::string (name), mHelp (help), mType (valueType)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! Returning a reference to *this, enables chaining of calls to operator()(const std::string&,
|
||||
const std::string&).
|
||||
|
||||
@param[in] name of the added option.
|
||||
@param[in] help a help description for this option.
|
||||
@return a reference to *this.
|
||||
*/
|
||||
Descriptions& Descriptions::operator () (const std::string& name, const std::string& help)
|
||||
{
|
||||
mDescriptions.emplace_back (name, help, Description::kBool);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! <b>Usage example:</b>
|
||||
@code
|
||||
CommandLine::Descriptions desc;
|
||||
desc.addOptions ("myTool") // Set caption to "myTool"
|
||||
("help", "produce help message") // add switch -help
|
||||
("opt1", string(), "option 1") // add string option -opt1
|
||||
("opt2", string(), "option 2") // add string option -opt2
|
||||
;
|
||||
@endcode
|
||||
@note
|
||||
The operator() is used for every additional option.
|
||||
|
||||
Or with initializer list :
|
||||
@code
|
||||
CommandLine::Descriptions desc;
|
||||
desc.addOptions ("myTool", // Set caption to "myTool"
|
||||
{{"help", "produce help message", Description::kBool}, // add switch -help
|
||||
{"opt1", "option 1", Description::kString}, // add string option -opt1
|
||||
{"opt2", "option 2", Description::kString}} // add string option -opt2
|
||||
);
|
||||
@endcode
|
||||
@param[in] caption the caption of the command-line tool.
|
||||
@param[in] options initializer list with options
|
||||
@return a reverense to *this.
|
||||
*/
|
||||
Descriptions& Descriptions::addOptions (const std::string& caption,
|
||||
std::initializer_list<Description>&& options)
|
||||
{
|
||||
mCaption = caption;
|
||||
std::move (options.begin (), options.end (), std::back_inserter (mDescriptions));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! @param[in] ac count of command-line parameters
|
||||
@param[in] av command-line as array of strings
|
||||
@param[out] result the parsing result
|
||||
@param[out] files optional list of elements on the command line that are not handled by options
|
||||
parsing
|
||||
*/
|
||||
bool Descriptions::parse (int ac, char* av[], VariablesMap& result, FilesVector* files) const
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
for (int i = 1; i < ac; i++)
|
||||
{
|
||||
string current = av[i];
|
||||
if (current[0] == '-')
|
||||
{
|
||||
int pos = current[1] == '-' ? 2 : 1;
|
||||
current = current.substr (pos, string::npos);
|
||||
|
||||
DescriptionsList::const_iterator found =
|
||||
find (mDescriptions.begin (), mDescriptions.end (), current);
|
||||
if (found != mDescriptions.end ())
|
||||
{
|
||||
result[*found] = "true";
|
||||
if (found->mType != Description::kBool)
|
||||
{
|
||||
if (((i + 1) < ac) && *av[i + 1] != '-')
|
||||
{
|
||||
result[*found] = av[++i];
|
||||
}
|
||||
else
|
||||
{
|
||||
result[*found] = "error!";
|
||||
result.setError ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.setError ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (files)
|
||||
files->push_back (av[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! The description includes the help strings for all options. */
|
||||
//------------------------------------------------------------------------
|
||||
void Descriptions::print (std::ostream& os) const
|
||||
{
|
||||
if (!mCaption.empty ())
|
||||
os << mCaption << ":\n";
|
||||
|
||||
size_t maxLength = 0u;
|
||||
std::for_each (mDescriptions.begin (), mDescriptions.end (),
|
||||
[&] (const Description& d) { maxLength = std::max (maxLength, d.size ()); });
|
||||
|
||||
for (const Description& opt : mDescriptions)
|
||||
{
|
||||
os << "-" << opt;
|
||||
for (auto s = opt.size (); s < maxLength; ++s)
|
||||
os << " ";
|
||||
os << " | " << opt.mHelp << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::ostream& operator<< (std::ostream& os, const Descriptions& desc)
|
||||
{
|
||||
desc.print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! @param[in] ac count of command-line parameters
|
||||
@param[in] av command-line as array of strings
|
||||
@param[in] desc Descriptions including all allowed options
|
||||
@param[out] result the parsing result
|
||||
@param[out] files optional list of elements on the command line that are not handled by options
|
||||
parsing
|
||||
*/
|
||||
bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, FilesVector* files)
|
||||
{
|
||||
return desc.parse (ac, av, result, files);
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace CommandLine
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fdebug.cpp
|
||||
// Created by : Steinberg, 1995
|
||||
// Description : There are 2 levels of debugging messages:
|
||||
// DEVELOPMENT During development
|
||||
// RELEASE Program is shipping.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "base/source/fdebug.h"
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#include <windows.h>
|
||||
|
||||
bool AmIBeingDebugged ()
|
||||
{
|
||||
return IsDebuggerPresent ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_LINUX
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
//--------------------------------------------------------------------------
|
||||
bool AmIBeingDebugged ()
|
||||
{
|
||||
// TODO: check if GDB or LLDB is attached
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// from Technical Q&A QA1361 (http://developer.apple.com/qa/qa2004/qa1361.html)
|
||||
//------------------------------------------------------------------------
|
||||
bool AmIBeingDebugged ()
|
||||
// Returns true if the current process is being debugged (either
|
||||
// running under the debugger or has a debugger attached post facto).
|
||||
{
|
||||
int mib[4];
|
||||
struct kinfo_proc info;
|
||||
size_t size;
|
||||
|
||||
// Initialize the flags so that, if sysctl fails for some bizarre
|
||||
// reason, we get a predictable result.
|
||||
|
||||
info.kp_proc.p_flag = 0;
|
||||
|
||||
// Initialize mib, which tells sysctl the info we want, in this case
|
||||
// we're looking for information about a specific process ID.
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = getpid ();
|
||||
|
||||
// Call sysctl.
|
||||
|
||||
size = sizeof (info);
|
||||
sysctl (mib, sizeof (mib) / sizeof (*mib), &info, &size, NULL, 0);
|
||||
|
||||
// We're being debugged if the P_TRACED flag is set.
|
||||
return ((info.kp_proc.p_flag & P_TRACED) != 0);
|
||||
}
|
||||
|
||||
#endif // SMTG_OS_MACOS
|
||||
|
||||
#if DEVELOPMENT
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#if _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#define vsnprintf _vsnprintf
|
||||
#define snprintf _snprintf
|
||||
|
||||
#elif SMTG_OS_MACOS
|
||||
#include <errno.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <new>
|
||||
#include <signal.h>
|
||||
|
||||
#define THREAD_ALLOC_WATCH 0 // check allocations on specific threads
|
||||
|
||||
#if THREAD_ALLOC_WATCH
|
||||
mach_port_t watchThreadID = 0;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
AssertionHandler gAssertionHandler = nullptr;
|
||||
AssertionHandler gPreAssertionHook = nullptr;
|
||||
DebugPrintLogger gDebugPrintLogger = nullptr;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static const int kDebugPrintfBufferSize = 10000;
|
||||
static bool neverDebugger = false; // so I can switch it off in the debugger...
|
||||
|
||||
static std::once_flag neverDebuggerEnvCheckFlag {};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void initNeverDebugger ()
|
||||
{
|
||||
std::call_once (neverDebuggerEnvCheckFlag, [] () {
|
||||
// add this environment variable to not stop in the debugger on ASSERT
|
||||
if (std::getenv ("SMTG_DEBUG_IGNORE_ASSERT"))
|
||||
{
|
||||
neverDebugger = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static void printDebugString (const char* string)
|
||||
{
|
||||
if (!string)
|
||||
return;
|
||||
|
||||
if (gDebugPrintLogger)
|
||||
{
|
||||
gDebugPrintLogger (string);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if SMTG_OS_MACOS || defined(__MINGW32__)
|
||||
fprintf (stderr, "%s", string);
|
||||
#elif SMTG_OS_WINDOWS
|
||||
OutputDebugStringA (string);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// printf style debugging output
|
||||
//--------------------------------------------------------------------------
|
||||
void FDebugPrint (const char* format, ...)
|
||||
{
|
||||
char string[kDebugPrintfBufferSize];
|
||||
va_list marker;
|
||||
va_start (marker, format);
|
||||
vsnprintf (string, kDebugPrintfBufferSize, format, marker);
|
||||
|
||||
printDebugString (string);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// printf style debugging output
|
||||
//--------------------------------------------------------------------------
|
||||
void FDebugBreak (const char* format, ...)
|
||||
{
|
||||
char string[kDebugPrintfBufferSize];
|
||||
va_list marker;
|
||||
va_start (marker, format);
|
||||
vsnprintf (string, kDebugPrintfBufferSize, format, marker);
|
||||
|
||||
printDebugString (string);
|
||||
|
||||
// The Pre-assertion hook is always called, even if we're not running in the debugger,
|
||||
// so that we can log asserts without displaying them
|
||||
if (gPreAssertionHook)
|
||||
{
|
||||
gPreAssertionHook (string);
|
||||
}
|
||||
|
||||
initNeverDebugger ();
|
||||
if (neverDebugger)
|
||||
return;
|
||||
if (AmIBeingDebugged ())
|
||||
{
|
||||
// do not crash if no debugger present
|
||||
// If there is an assertion handler defined then let this override the UI
|
||||
// and tell us whether we want to break into the debugger
|
||||
bool breakIntoDebugger = true;
|
||||
if (gAssertionHandler && gAssertionHandler (string) == false)
|
||||
{
|
||||
breakIntoDebugger = false;
|
||||
}
|
||||
|
||||
if (breakIntoDebugger)
|
||||
{
|
||||
#if SMTG_OS_WINDOWS && _MSC_VER
|
||||
__debugbreak (); // intrinsic version of DebugBreak()
|
||||
#elif SMTG_OS_MACOS && __arm64__
|
||||
raise (SIGSTOP);
|
||||
|
||||
#elif __ppc64__ || __ppc__ || __arm__
|
||||
kill (getpid (), SIGINT);
|
||||
#elif __i386__ || __x86_64__
|
||||
{
|
||||
__asm__ volatile ("int3");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void FPrintLastError (const char* file, int line)
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
LPVOID lpMessageBuffer = nullptr;
|
||||
FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
|
||||
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMessageBuffer, 0, nullptr);
|
||||
FDebugPrint ("%s(%d) : %s\n", file, line, lpMessageBuffer);
|
||||
LocalFree (lpMessageBuffer);
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
#if !__MACH__
|
||||
extern int errno;
|
||||
#endif
|
||||
FDebugPrint ("%s(%d) : Errno %d\n", file, line, errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void* operator new (size_t size, int, const char* file, int line)
|
||||
{
|
||||
#if THREAD_ALLOC_WATCH
|
||||
mach_port_t threadID = mach_thread_self ();
|
||||
if (watchThreadID == threadID)
|
||||
{
|
||||
FDebugPrint ("Watched Thread Allocation : %s (Line:%d)\n", file ? file : "Unknown", line);
|
||||
}
|
||||
#endif
|
||||
try
|
||||
{
|
||||
return ::operator new (size);
|
||||
}
|
||||
catch (std::bad_alloc exception)
|
||||
{
|
||||
FDebugPrint ("bad_alloc exception : %s (Line:%d)", file ? file : "Unknown", line);
|
||||
}
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void* operator new[] (size_t size, int, const char* file, int line)
|
||||
{
|
||||
#if THREAD_ALLOC_WATCH
|
||||
mach_port_t threadID = mach_thread_self ();
|
||||
if (watchThreadID == threadID)
|
||||
{
|
||||
FDebugPrint ("Watched Thread Allocation : %s (Line:%d)\n", file ? file : "Unknown", line);
|
||||
}
|
||||
#endif
|
||||
try
|
||||
{
|
||||
return ::operator new[] (size);
|
||||
}
|
||||
catch (std::bad_alloc exception)
|
||||
{
|
||||
FDebugPrint ("bad_alloc exception : %s (Line:%d)", file ? file : "Unknown", line);
|
||||
}
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void operator delete (void* p, int, const char* file, int line)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
::operator delete (p);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void operator delete[] (void* p, int, const char* file, int line)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
::operator delete[] (p);
|
||||
}
|
||||
|
||||
#endif // SMTG_OS_MACOS
|
||||
|
||||
#endif // DEVELOPMENT
|
||||
|
||||
static bool smtg_unit_testing_active = false; // ugly hack to unit testing ...
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool isSmtgUnitTesting ()
|
||||
{
|
||||
return smtg_unit_testing_active;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void setSmtgUnitTesting ()
|
||||
{
|
||||
smtg_unit_testing_active = true;
|
||||
}
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fdebug.h
|
||||
// Created by : Steinberg, 1995
|
||||
// Description : There are 2 levels of debugging messages:
|
||||
// DEVELOPMENT During development
|
||||
// RELEASE Program is shipping.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** @file base/source/fdebug.h
|
||||
Debugging tools.
|
||||
|
||||
There are 2 levels of debugging messages:
|
||||
- DEVELOPMENT
|
||||
- During development
|
||||
- RELEASE
|
||||
- Program is shipping.
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/ftypes.h"
|
||||
#include <cstring>
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
/** Returns true if a debugger is attached. */
|
||||
bool AmIBeingDebugged ();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// development / release
|
||||
//-----------------------------------------------------------------------------
|
||||
#if !defined (DEVELOPMENT) && !defined (RELEASE)
|
||||
#ifdef _DEBUG
|
||||
#define DEVELOPMENT 1
|
||||
#elif defined (NDEBUG)
|
||||
#define RELEASE 1
|
||||
#else
|
||||
#error DEVELOPMENT, RELEASE, _DEBUG, or NDEBUG must be defined!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if SMTG_OS_WINDOWS
|
||||
|
||||
/** Disable compiler warning:
|
||||
* C4291: "No matching operator delete found; memory will not be freed if initialization throws an
|
||||
* exception. A placement new is used for which there is no placement delete." */
|
||||
#if DEVELOPMENT && defined(_MSC_VER)
|
||||
#pragma warning(disable : 4291)
|
||||
#pragma warning(disable : 4985)
|
||||
#endif
|
||||
|
||||
#endif // SMTG_OS_WINDOWS
|
||||
|
||||
#if DEVELOPMENT
|
||||
//-----------------------------------------------------------------------------
|
||||
/** If "f" is not true and a debugger is present, send an error string to the debugger for display
|
||||
and cause a breakpoint exception to occur in the current process. SMTG_ASSERT is removed
|
||||
completely in RELEASE configuration. So do not pass methods calls to this macro that are expected
|
||||
to exist in the RELEASE build (for method calls that need to be present in a RELEASE build, use
|
||||
the VERIFY macros instead)*/
|
||||
#define SMTG_ASSERT(f) \
|
||||
if (!(f)) \
|
||||
FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f);
|
||||
|
||||
#define SMTG_ASSERT_MSG(f, msg) \
|
||||
if (!(f)) \
|
||||
FDebugBreak ("%s(%d) : Assert failed: [%s] [%s]\n", __FILE__, __LINE__, #f, msg);
|
||||
|
||||
/** Send "comment" string to the debugger for display. */
|
||||
#define SMTG_WARNING(comment) FDebugPrint ("%s(%d) : %s\n", __FILE__, __LINE__, comment);
|
||||
|
||||
/** Send the last error string to the debugger for display. */
|
||||
#define SMTG_PRINTSYSERROR FPrintLastError (__FILE__, __LINE__);
|
||||
|
||||
/** If a debugger is present, send string "s" to the debugger for display and
|
||||
cause a breakpoint exception to occur in the current process. */
|
||||
#define SMTG_DEBUGSTR(s) FDebugBreak (s);
|
||||
|
||||
/** Use VERIFY for calling methods "f" having a bool result (expecting them to return 'true')
|
||||
The call of "f" is not removed in RELEASE builds, only the result verification. eg: SMTG_VERIFY
|
||||
(isValid ()) */
|
||||
#define SMTG_VERIFY(f) SMTG_ASSERT (f)
|
||||
|
||||
/** Use VERIFY_IS for calling methods "f" and expect a certain result "r".
|
||||
The call of "f" is not removed in RELEASE builds, only the result verification. eg:
|
||||
SMTG_VERIFY_IS (callMethod (), kResultOK) */
|
||||
#define SMTG_VERIFY_IS(f, r) \
|
||||
if ((f) != (r)) \
|
||||
FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f);
|
||||
|
||||
/** Use VERIFY_NOT for calling methods "f" and expect the result to be anything else but "r".
|
||||
The call of "f" is not removed in RELEASE builds, only the result verification. eg:
|
||||
SMTG_VERIFY_NOT (callMethod (), kResultError) */
|
||||
#define SMTG_VERIFY_NOT(f, r) \
|
||||
if ((f) == (r)) \
|
||||
FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f);
|
||||
|
||||
/** @name Shortcut macros for sending strings to the debugger for display.
|
||||
First parameter is always the format string (printf like).
|
||||
*/
|
||||
|
||||
///@{
|
||||
#define SMTG_DBPRT0(a) FDebugPrint (a);
|
||||
#define SMTG_DBPRT1(a, b) FDebugPrint (a, b);
|
||||
#define SMTG_DBPRT2(a, b, c) FDebugPrint (a, b, c);
|
||||
#define SMTG_DBPRT3(a, b, c, d) FDebugPrint (a, b, c, d);
|
||||
#define SMTG_DBPRT4(a, b, c, d, e) FDebugPrint (a, b, c, d, e);
|
||||
#define SMTG_DBPRT5(a, b, c, d, e, f) FDebugPrint (a, b, c, d, e, f);
|
||||
///@}
|
||||
|
||||
/** @name Helper functions for the above defined macros.
|
||||
|
||||
You shouldn't use them directly (if you do so, don't forget "#if DEVELOPMENT")!
|
||||
It is recommended to use the macros instead.
|
||||
*/
|
||||
///@{
|
||||
void FDebugPrint (const char* format, ...);
|
||||
void FDebugBreak (const char* format, ...);
|
||||
void FPrintLastError (const char* file, int line);
|
||||
///@}
|
||||
|
||||
/** @name Provide a custom assertion handler and debug print handler, eg
|
||||
so that we can provide an assert with a custom dialog, or redirect
|
||||
the debug output to a file or stream.
|
||||
*/
|
||||
///@{
|
||||
using AssertionHandler = bool (*) (const char* message);
|
||||
extern AssertionHandler gAssertionHandler;
|
||||
extern AssertionHandler gPreAssertionHook;
|
||||
using DebugPrintLogger = void (*) (const char* message);
|
||||
extern DebugPrintLogger gDebugPrintLogger;
|
||||
///@}
|
||||
|
||||
/** Definition of memory allocation macros:
|
||||
Use "NEW" to allocate storage for individual objects.
|
||||
Use "NEWVEC" to allocate storage for an array of objects. */
|
||||
#if SMTG_OS_MACOS
|
||||
void* operator new (size_t, int, const char*, int);
|
||||
void* operator new[] (size_t, int, const char*, int);
|
||||
void operator delete (void* p, int, const char* file, int line);
|
||||
void operator delete[] (void* p, int, const char* file, int line);
|
||||
#ifndef NEW
|
||||
#define NEW new (1, __FILE__, __LINE__)
|
||||
#define NEWVEC new (1, __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#define DEBUG_NEW DEBUG_NEW_LEAKS
|
||||
|
||||
#elif SMTG_OS_WINDOWS && defined(_MSC_VER)
|
||||
#ifndef NEW
|
||||
void* operator new (size_t, int, const char*, int);
|
||||
#define NEW new (1, __FILE__, __LINE__)
|
||||
#define NEWVEC new (1, __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef NEW
|
||||
#define NEW new
|
||||
#define NEWVEC new
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
/** if DEVELOPMENT is not set, these macros will do nothing. */
|
||||
#define SMTG_ASSERT(f)
|
||||
#define SMTG_ASSERT_MSG(f, msg)
|
||||
#define SMTG_WARNING(s)
|
||||
#define SMTG_PRINTSYSERROR
|
||||
#define SMTG_DEBUGSTR(s)
|
||||
#define SMTG_VERIFY(f) f;
|
||||
#define SMTG_VERIFY_IS(f, r) f;
|
||||
#define SMTG_VERIFY_NOT(f, r) f;
|
||||
|
||||
#define SMTG_DBPRT0(a)
|
||||
#define SMTG_DBPRT1(a, b)
|
||||
#define SMTG_DBPRT2(a, b, c)
|
||||
#define SMTG_DBPRT3(a, b, c, d)
|
||||
#define SMTG_DBPRT4(a, b, c, d, e)
|
||||
#define SMTG_DBPRT5(a, b, c, d, e, f)
|
||||
|
||||
#ifndef NEW
|
||||
#define NEW new
|
||||
#define NEWVEC new
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// replace #if SMTG_CPPUNIT_TESTING
|
||||
bool isSmtgUnitTesting ();
|
||||
void setSmtgUnitTesting ();
|
||||
|
||||
#if !SMTG_RENAME_ASSERT
|
||||
#if SMTG_OS_WINDOWS
|
||||
#undef ASSERT
|
||||
#endif
|
||||
|
||||
#define ASSERT SMTG_ASSERT
|
||||
#define WARNING SMTG_WARNING
|
||||
#define DEBUGSTR SMTG_DEBUGSTR
|
||||
#define VERIFY SMTG_VERIFY
|
||||
#define VERIFY_IS SMTG_VERIFY_IS
|
||||
#define VERIFY_NOT SMTG_VERIFY_NOT
|
||||
#define PRINTSYSERROR SMTG_PRINTSYSERROR
|
||||
|
||||
#define DBPRT0 SMTG_DBPRT0
|
||||
#define DBPRT1 SMTG_DBPRT1
|
||||
#define DBPRT2 SMTG_DBPRT2
|
||||
#define DBPRT3 SMTG_DBPRT3
|
||||
#define DBPRT4 SMTG_DBPRT4
|
||||
#define DBPRT5 SMTG_DBPRT5
|
||||
#endif
|
||||
|
|
@ -1,293 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fobject.cpp
|
||||
// Created by : Steinberg, 2008
|
||||
// Description : Basic Object implementing FUnknown
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "base/source/fobject.h"
|
||||
#include "base/thread/include/flock.h"
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#define SMTG_VALIDATE_DEPENDENCY_COUNT DEVELOPMENT // validating dependencyCount
|
||||
|
||||
#if SMTG_DEPENDENCY_COUNT
|
||||
#include "base/source/updatehandler.h"
|
||||
#define SMTG_DEPENDENCY_CHECK_LEVEL 1 // 1 => minimal assert, 2 => full assert
|
||||
#endif // SMTG_DEPENDENCY_COUNT
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
// Entry point for addRef/release tracking. See fobjecttracker.h
|
||||
//------------------------------------------------------------------------
|
||||
#if DEVELOPMENT
|
||||
using FObjectTrackerFn = std::function<void (FObject*, bool)>;
|
||||
FObjectTrackerFn gFObjectTracker = nullptr;
|
||||
#endif
|
||||
|
||||
IUpdateHandler* FObject::gUpdateHandler = nullptr;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const FUID FObject::iid;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct FObjectIIDInitializer
|
||||
{
|
||||
// the object iid is always generated so that different components
|
||||
// only can cast to their own objects
|
||||
// this initializer must be after the definition of FObject::iid, otherwise
|
||||
// the default constructor of FUID will clear the generated iid
|
||||
FObjectIIDInitializer () { const_cast<FUID&> (FObject::iid).generate (); }
|
||||
} gFObjectIidInitializer;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FObject::~FObject ()
|
||||
{
|
||||
#if SMTG_DEPENDENCY_COUNT && DEVELOPMENT
|
||||
static bool localNeverDebugger = false;
|
||||
#endif
|
||||
|
||||
#if DEVELOPMENT
|
||||
if (refCount > 1)
|
||||
FDebugPrint ("Refcount is %d when trying to delete %s\n", refCount, isA ());
|
||||
#endif
|
||||
|
||||
#if SMTG_DEPENDENCY_COUNT
|
||||
#if SMTG_DEPENDENCY_CHECK_LEVEL >= 1
|
||||
if (gUpdateHandler)
|
||||
{
|
||||
#if DEVELOPMENT
|
||||
SMTG_ASSERT (dependencyCount == 0 || localNeverDebugger);
|
||||
#endif // DEVELOPMENT
|
||||
}
|
||||
#endif
|
||||
#endif // SMTG_DEPENDENCY_COUNT
|
||||
|
||||
#if SMTG_VALIDATE_DEPENDENCY_COUNT
|
||||
if (!gUpdateHandler || gUpdateHandler != UpdateHandler::instance (false))
|
||||
return;
|
||||
|
||||
auto updateHandler = UpdateHandler::instance ();
|
||||
if (!updateHandler || updateHandler == this)
|
||||
return;
|
||||
|
||||
SMTG_ASSERT ((updateHandler->checkDeferred (this) == false || localNeverDebugger) &&
|
||||
"'this' has scheduled a deferUpdate that was not yet delivered");
|
||||
|
||||
if (updateHandler->hasDependencies (this))
|
||||
{
|
||||
SMTG_ASSERT (
|
||||
(false || localNeverDebugger) &&
|
||||
"Another object is still dependent on 'this'. This leads to zombie entries in the dependency map that can later crash.");
|
||||
FDebugPrint ("Object still has dependencies %x %s\n", this, this->isA ());
|
||||
updateHandler->printForObject (this);
|
||||
}
|
||||
#endif // SMTG_VALIDATE_DEPENDENCY_COUNT
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32 PLUGIN_API FObject::addRef ()
|
||||
{
|
||||
#if DEVELOPMENT
|
||||
if (gFObjectTracker)
|
||||
{
|
||||
gFObjectTracker (this, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return FUnknownPrivate::atomicAdd (refCount, 1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32 PLUGIN_API FObject::release ()
|
||||
{
|
||||
#if DEVELOPMENT
|
||||
if (gFObjectTracker)
|
||||
{
|
||||
gFObjectTracker (this, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (FUnknownPrivate::atomicAdd (refCount, -1) == 0)
|
||||
{
|
||||
refCount = -1000;
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API FObject::queryInterface (const TUID _iid, void** obj)
|
||||
{
|
||||
QUERY_INTERFACE (_iid, obj, FUnknown::iid, FUnknown)
|
||||
QUERY_INTERFACE (_iid, obj, IDependent::iid, IDependent)
|
||||
QUERY_INTERFACE (_iid, obj, FObject::iid, FObject)
|
||||
*obj = nullptr;
|
||||
return kNoInterface;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FObject::addDependent (IDependent* dep)
|
||||
{
|
||||
if (!gUpdateHandler)
|
||||
return;
|
||||
|
||||
gUpdateHandler->addDependent (unknownCast (), dep);
|
||||
#if SMTG_DEPENDENCY_COUNT
|
||||
dependencyCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FObject::removeDependent (IDependent* dep)
|
||||
{
|
||||
#if SMTG_DEPENDENCY_COUNT && DEVELOPMENT
|
||||
static bool localNeverDebugger = false;
|
||||
#endif
|
||||
|
||||
if (!gUpdateHandler)
|
||||
return;
|
||||
|
||||
#if SMTG_DEPENDENCY_COUNT
|
||||
if (gUpdateHandler != UpdateHandler::instance (false))
|
||||
{
|
||||
gUpdateHandler->removeDependent (unknownCast (), dep);
|
||||
dependencyCount--;
|
||||
return;
|
||||
}
|
||||
#if SMTG_DEPENDENCY_CHECK_LEVEL > 1
|
||||
SMTG_ASSERT ((dependencyCount > 0 || localNeverDebugger) &&
|
||||
"All dependencies have already been removed - mmichaelis 7/2021");
|
||||
#endif
|
||||
size_t removeCount;
|
||||
UpdateHandler::instance ()->removeDependent (unknownCast (), dep, removeCount);
|
||||
if (removeCount == 0)
|
||||
{
|
||||
#if SMTG_DEPENDENCY_CHECK_LEVEL > 1
|
||||
SMTG_ASSERT (localNeverDebugger && "No dependency to remove - ygrabit 8/2021");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SMTG_ASSERT ((removeCount == 1 || localNeverDebugger) &&
|
||||
"Duplicated dependencies established - mmichaelis 7/2021");
|
||||
}
|
||||
dependencyCount -= (int16)removeCount;
|
||||
#else
|
||||
gUpdateHandler->removeDependent (unknownCast (), dep);
|
||||
#endif // SMTG_DEPENDENCY_COUNT
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FObject::changed (int32 msg)
|
||||
{
|
||||
if (gUpdateHandler)
|
||||
gUpdateHandler->triggerUpdates (unknownCast (), msg);
|
||||
else
|
||||
updateDone (msg);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FObject::deferUpdate (int32 msg)
|
||||
{
|
||||
if (gUpdateHandler)
|
||||
gUpdateHandler->deferUpdates (unknownCast (), msg);
|
||||
else
|
||||
updateDone (msg);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Automatic creation and destruction of singleton instances. */
|
||||
//------------------------------------------------------------------------
|
||||
namespace Singleton {
|
||||
using ObjectVector = std::vector<FObject**>;
|
||||
ObjectVector* singletonInstances = nullptr;
|
||||
bool singletonsTerminated = false;
|
||||
Steinberg::Base::Thread::FLock* singletonsLock;
|
||||
|
||||
bool isTerminated ()
|
||||
{
|
||||
return singletonsTerminated;
|
||||
}
|
||||
|
||||
void lockRegister ()
|
||||
{
|
||||
if (!singletonsLock) // assume first call not from multiple threads
|
||||
singletonsLock = NEW Steinberg::Base::Thread::FLock;
|
||||
singletonsLock->lock ();
|
||||
}
|
||||
|
||||
void unlockRegister ()
|
||||
{
|
||||
singletonsLock->unlock ();
|
||||
}
|
||||
|
||||
void registerInstance (FObject** o)
|
||||
{
|
||||
SMTG_ASSERT (singletonsTerminated == false)
|
||||
if (singletonsTerminated == false)
|
||||
{
|
||||
if (singletonInstances == nullptr)
|
||||
singletonInstances = NEW std::vector<FObject**>;
|
||||
singletonInstances->push_back (o);
|
||||
}
|
||||
}
|
||||
|
||||
struct Deleter
|
||||
{
|
||||
~Deleter ()
|
||||
{
|
||||
singletonsTerminated = true;
|
||||
if (singletonInstances)
|
||||
{
|
||||
for (Steinberg::FObject** obj : *singletonInstances)
|
||||
{
|
||||
(*obj)->release ();
|
||||
*obj = nullptr;
|
||||
obj = nullptr;
|
||||
}
|
||||
|
||||
delete singletonInstances;
|
||||
singletonInstances = nullptr;
|
||||
}
|
||||
delete singletonsLock;
|
||||
singletonsLock = nullptr;
|
||||
}
|
||||
} deleter;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,577 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fobject.h
|
||||
// Created by : Steinberg, 2008
|
||||
// Description : Basic Object implementing FUnknown
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @file base/source/fobject.h
|
||||
Basic Object implementing FUnknown. */
|
||||
//------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include "pluginterfaces/base/iupdatehandler.h"
|
||||
#include "base/source/fdebug.h" // use of NEW
|
||||
|
||||
#define SMTG_DEPENDENCY_COUNT DEVELOPMENT
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//----------------------------------
|
||||
|
||||
using FClassID = FIDString;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Basic FObject - implements FUnknown + IDependent
|
||||
//------------------------------------------------------------------------
|
||||
/** Implements FUnknown and IDependent.
|
||||
|
||||
FObject is a polymorphic class that implements IDependent (of SKI module) and therefore derived from
|
||||
FUnknown, which is the most abstract base class of all.
|
||||
|
||||
All COM-like virtual methods of FUnknown such as queryInterface(), addRef(), release() are
|
||||
implemented here. On top of that, dependency-related methods are implemented too.
|
||||
|
||||
Pointer casting is done via the template methods FCast, either FObject to FObject or FUnknown to
|
||||
FObject.
|
||||
|
||||
FObject supports a new singleton concept, therefore these objects are deleted automatically upon
|
||||
program termination.
|
||||
|
||||
- Runtime type information: An object can be queried at runtime, of what class it is. To do this
|
||||
correctly, every class must override some methods. This is simplified by using the OBJ_METHODS
|
||||
macros
|
||||
|
||||
@see
|
||||
- FUnknown
|
||||
- IDependent
|
||||
- IUpdateHandler
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class FObject : public IDependent
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
FObject () = default; ///< default constructor...
|
||||
FObject (const FObject&) ///< overloaded constructor...
|
||||
: refCount (1)
|
||||
#if SMTG_DEPENDENCY_COUNT
|
||||
, dependencyCount (0)
|
||||
#endif
|
||||
{}
|
||||
FObject& operator= (const FObject&) { return *this; } ///< overloads operator "=" as the reference assignment
|
||||
virtual ~FObject (); ///< destructor...
|
||||
|
||||
// OBJECT_METHODS
|
||||
static inline FClassID getFClassID () {return "FObject";} ///< return Class ID as an ASCII string (statically)
|
||||
virtual FClassID isA () const {return FObject::getFClassID ();} ///< a local alternative to getFClassID ()
|
||||
virtual bool isA (FClassID s) const {return isTypeOf (s, false);} ///< evaluates if the passed ID is of the FObject type
|
||||
virtual bool isTypeOf (FClassID s, bool /*askBaseClass*/ = true) const {return classIDsEqual (s, FObject::getFClassID ());}
|
||||
///< evaluates if the passed ID is of the FObject type
|
||||
int32 getRefCount () {return refCount;} ///< returns the current interface reference count
|
||||
FUnknown* unknownCast () {return this;} ///< get FUnknown interface from object
|
||||
|
||||
// FUnknown
|
||||
tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE; ///< please refer to FUnknown::queryInterface ()
|
||||
uint32 PLUGIN_API addRef () SMTG_OVERRIDE; ///< please refer to FUnknown::addref ()
|
||||
uint32 PLUGIN_API release () SMTG_OVERRIDE; ///< please refer to FUnknown::release ()
|
||||
|
||||
// IDependent
|
||||
void PLUGIN_API update (FUnknown* /*changedUnknown*/, int32 /*message*/) SMTG_OVERRIDE {}
|
||||
///< empty virtual method that should be overridden by derived classes for data updates upon changes
|
||||
// IDependency
|
||||
virtual void addDependent (IDependent* dep); ///< adds dependency to the object
|
||||
virtual void removeDependent (IDependent* dep); ///< removes dependency from the object
|
||||
virtual void changed (int32 msg = kChanged); ///< Inform all dependents, that the object has changed.
|
||||
virtual void deferUpdate (int32 msg = kChanged); ///< Similar to triggerUpdates, except only delivered in idle (usefull in collecting updates).
|
||||
virtual void updateDone (int32 /* msg */) {} ///< empty virtual method that should be overridden by derived classes
|
||||
virtual bool isEqualInstance (FUnknown* d) {return this == d;}
|
||||
|
||||
static void setUpdateHandler (IUpdateHandler* handler) {gUpdateHandler = handler;} ///< set method for the local attribute
|
||||
static IUpdateHandler* getUpdateHandler () {return gUpdateHandler;} ///< get method for the local attribute
|
||||
|
||||
// static helper functions
|
||||
static inline bool classIDsEqual (FClassID ci1, FClassID ci2); ///< compares (evaluates) 2 class IDs
|
||||
static inline FObject* unknownToObject (FUnknown* unknown); ///< pointer conversion from FUnknown to FObject
|
||||
/** convert from FUnknown to FObject */
|
||||
template <class Class>
|
||||
static inline IPtr<Class> fromUnknown (FUnknown* unknown);
|
||||
|
||||
/** Special UID that is used to cast an FUnknown pointer to a FObject */
|
||||
static const FUID iid;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
int32 refCount = 1; ///< COM-model local reference count
|
||||
#if SMTG_DEPENDENCY_COUNT
|
||||
int16 dependencyCount = 0;
|
||||
#endif
|
||||
static IUpdateHandler* gUpdateHandler;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// conversion from FUnknown to FObject subclass
|
||||
//------------------------------------------------------------------------
|
||||
template <class C>
|
||||
inline IPtr<C> FObject::fromUnknown (FUnknown* unknown)
|
||||
{
|
||||
if (unknown)
|
||||
{
|
||||
FObject* object = nullptr;
|
||||
if (unknown->queryInterface (FObject::iid, (void**)&object) == kResultTrue && object)
|
||||
{
|
||||
if (object->isTypeOf (C::getFClassID (), true))
|
||||
return IPtr<C> (static_cast<C*> (object), false);
|
||||
object->release ();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline FObject* FObject::unknownToObject (FUnknown* unknown)
|
||||
{
|
||||
FObject* object = nullptr;
|
||||
if (unknown)
|
||||
{
|
||||
unknown->queryInterface (FObject::iid, (void**)&object);
|
||||
if (object)
|
||||
{
|
||||
if (object->release () == 0)
|
||||
object = nullptr;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool FObject::classIDsEqual (FClassID ci1, FClassID ci2)
|
||||
{
|
||||
return (ci1 && ci2) ? (strcmp (ci1, ci2) == 0) : false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** FCast overload 1 - FObject to FObject */
|
||||
//-----------------------------------------------------------------------
|
||||
template <class C>
|
||||
inline C* FCast (const FObject* object)
|
||||
{
|
||||
if (object && object->isTypeOf (C::getFClassID (), true))
|
||||
return (C*) object;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** FCast overload 2 - FUnknown to FObject */
|
||||
//-----------------------------------------------------------------------
|
||||
template <class C>
|
||||
inline C* FCast (FUnknown* unknown)
|
||||
{
|
||||
FObject* object = FObject::unknownToObject (unknown);
|
||||
return FCast<C> (object);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** ICast - casting from FObject to FUnknown Interface */
|
||||
//-----------------------------------------------------------------------
|
||||
template<class I>
|
||||
inline IPtr<I> ICast (FObject* object)
|
||||
{
|
||||
return FUnknownPtr<I> (object ? object->unknownCast () : nullptr);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** ICast - casting from FUnknown to another FUnknown Interface */
|
||||
//-----------------------------------------------------------------------
|
||||
template<class I>
|
||||
inline IPtr<I> ICast (FUnknown* object)
|
||||
{
|
||||
return FUnknownPtr<I> (object);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class C>
|
||||
inline C* FCastIsA (const FObject* object)
|
||||
{
|
||||
if (object && object->isA (C::getFClassID ()))
|
||||
return (C*)object;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef SMTG_HIDE_DEPRECATED_INLINE_FUNCTIONS
|
||||
//-----------------------------------------------------------------------
|
||||
/** \deprecated FUCast - casting from FUnknown to Interface */
|
||||
//-----------------------------------------------------------------------
|
||||
template <class C>
|
||||
SMTG_DEPRECATED_MSG("use ICast<>") inline C* FUCast (FObject* object)
|
||||
{
|
||||
return FUnknownPtr<C> (object ? object->unknownCast () : nullptr);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
SMTG_DEPRECATED_MSG("use ICast<>") inline C* FUCast (FUnknown* object)
|
||||
{
|
||||
return FUnknownPtr<C> (object);
|
||||
}
|
||||
#endif // SMTG_HIDE_DEPRECATED_FUNCTIONS
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @name Convenience methods that call release or delete respectively
|
||||
on a pointer if it is non-zero, and then set the pointer to zero.
|
||||
Note: you should prefer using IPtr or OPtr instead of these methods
|
||||
whenever possible.
|
||||
<b>Examples:</b>
|
||||
@code
|
||||
~Foo ()
|
||||
{
|
||||
// instead of ...
|
||||
if (somePointer)
|
||||
{
|
||||
somePointer->release ();
|
||||
somePointer = 0;
|
||||
}
|
||||
// ... just being lazy I write
|
||||
SafeRelease (somePointer)
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
///@{
|
||||
//-----------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline void SafeRelease (I *& ptr)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
ptr->release ();
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline void SafeRelease (IPtr<I> & ptr)
|
||||
{
|
||||
ptr = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void SafeDelete (T *& ptr)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
///@}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void AssignShared (T*& dest, T* newPtr)
|
||||
{
|
||||
if (dest == newPtr)
|
||||
return;
|
||||
|
||||
if (dest)
|
||||
dest->release ();
|
||||
dest = newPtr;
|
||||
if (dest)
|
||||
dest->addRef ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void AssignSharedDependent (IDependent* _this, T*& dest, T* newPtr)
|
||||
{
|
||||
if (dest == newPtr)
|
||||
return;
|
||||
|
||||
if (dest)
|
||||
dest->removeDependent (_this);
|
||||
AssignShared (dest, newPtr);
|
||||
if (dest)
|
||||
dest->addDependent (_this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void AssignSharedDependent (IDependent* _this, IPtr<T>& dest, T* newPtr)
|
||||
{
|
||||
if (dest == newPtr)
|
||||
return;
|
||||
|
||||
if (dest)
|
||||
dest->removeDependent (_this);
|
||||
dest = newPtr;
|
||||
if (dest)
|
||||
dest->addDependent (_this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void SafeReleaseDependent (IDependent* _this, T*& dest)
|
||||
{
|
||||
if (dest)
|
||||
dest->removeDependent (_this);
|
||||
SafeRelease (dest);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline void SafeReleaseDependent (IDependent* _this, IPtr<T>& dest)
|
||||
{
|
||||
if (dest)
|
||||
dest->removeDependent (_this);
|
||||
SafeRelease (dest);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Automatic creation and destruction of singleton instances. */
|
||||
namespace Singleton {
|
||||
/** registers an instance (type FObject) */
|
||||
void registerInstance (FObject** o);
|
||||
|
||||
/** Returns true when singleton instances were already released. */
|
||||
bool isTerminated ();
|
||||
|
||||
/** lock and unlock the singleton registration for multi-threading safety */
|
||||
void lockRegister ();
|
||||
void unlockRegister ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
#define SINGLETON(ClassName) \
|
||||
static ClassName* instance (bool create = true) \
|
||||
{ \
|
||||
static Steinberg::FObject* inst = nullptr; \
|
||||
if (inst == nullptr && create && Steinberg::Singleton::isTerminated () == false) \
|
||||
{ \
|
||||
Steinberg::Singleton::lockRegister (); \
|
||||
if (inst == nullptr) \
|
||||
{ \
|
||||
inst = NEW ClassName; \
|
||||
Steinberg::Singleton::registerInstance (&inst); \
|
||||
} \
|
||||
Steinberg::Singleton::unlockRegister (); \
|
||||
} \
|
||||
return (ClassName*)inst; \
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
#define OBJ_METHODS(className, baseClass) \
|
||||
static inline Steinberg::FClassID getFClassID () {return (#className);} \
|
||||
virtual Steinberg::FClassID isA () const SMTG_OVERRIDE {return className::getFClassID ();} \
|
||||
virtual bool isA (Steinberg::FClassID s) const SMTG_OVERRIDE {return isTypeOf (s, false);} \
|
||||
virtual bool isTypeOf (Steinberg::FClassID s, bool askBaseClass = true) const SMTG_OVERRIDE \
|
||||
{ return (FObject::classIDsEqual (s, #className) ? true : (askBaseClass ? baseClass::isTypeOf (s, true) : false)); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Delegate refcount functions to BaseClass.
|
||||
BaseClase must implement ref counting.
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
#define REFCOUNT_METHODS(BaseClass) \
|
||||
virtual Steinberg::uint32 PLUGIN_API addRef ()SMTG_OVERRIDE{ return BaseClass::addRef (); } \
|
||||
virtual Steinberg::uint32 PLUGIN_API release ()SMTG_OVERRIDE{ return BaseClass::release (); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @name Macros to implement FUnknown::queryInterface ().
|
||||
|
||||
<b>Examples:</b>
|
||||
@code
|
||||
class Foo : public FObject, public IFoo2, public IFoo3
|
||||
{
|
||||
...
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (IFoo2)
|
||||
DEF_INTERFACE (IFoo3)
|
||||
END_DEFINE_INTERFACES (FObject)
|
||||
REFCOUNT_METHODS(FObject)
|
||||
// Implement IFoo2 interface ...
|
||||
// Implement IFoo3 interface ...
|
||||
...
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
///@{
|
||||
//------------------------------------------------------------------------
|
||||
/** Start defining interfaces. */
|
||||
//------------------------------------------------------------------------
|
||||
#define DEFINE_INTERFACES \
|
||||
Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) SMTG_OVERRIDE \
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Add a interfaces. */
|
||||
//------------------------------------------------------------------------
|
||||
#define DEF_INTERFACE(InterfaceName) \
|
||||
QUERY_INTERFACE (iid, obj, InterfaceName::iid, InterfaceName)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** End defining interfaces. */
|
||||
//------------------------------------------------------------------------
|
||||
#define END_DEFINE_INTERFACES(BaseClass) \
|
||||
return BaseClass::queryInterface (iid, obj); \
|
||||
}
|
||||
///@}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @name Convenient macros to implement Steinberg::FUnknown::queryInterface ().
|
||||
<b>Examples:</b>
|
||||
@code
|
||||
class Foo : public FObject, public IFoo2, public IFoo3
|
||||
{
|
||||
...
|
||||
DEF_INTERFACES_2(IFoo2,IFoo3,FObject)
|
||||
REFCOUNT_METHODS(FObject)
|
||||
...
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
///@{
|
||||
//------------------------------------------------------------------------
|
||||
#define DEF_INTERFACES_1(InterfaceName,BaseClass) \
|
||||
DEFINE_INTERFACES \
|
||||
DEF_INTERFACE (InterfaceName) \
|
||||
END_DEFINE_INTERFACES (BaseClass)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
|
||||
DEFINE_INTERFACES \
|
||||
DEF_INTERFACE (InterfaceName1) \
|
||||
DEF_INTERFACE (InterfaceName2) \
|
||||
END_DEFINE_INTERFACES (BaseClass)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
|
||||
DEFINE_INTERFACES \
|
||||
DEF_INTERFACE (InterfaceName1) \
|
||||
DEF_INTERFACE (InterfaceName2) \
|
||||
DEF_INTERFACE (InterfaceName3) \
|
||||
END_DEFINE_INTERFACES (BaseClass)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
|
||||
DEFINE_INTERFACES \
|
||||
DEF_INTERFACE (InterfaceName1) \
|
||||
DEF_INTERFACE (InterfaceName2) \
|
||||
DEF_INTERFACE (InterfaceName3) \
|
||||
DEF_INTERFACE (InterfaceName4) \
|
||||
END_DEFINE_INTERFACES (BaseClass)
|
||||
///@}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @name Convenient macros to implement Steinberg::FUnknown methods.
|
||||
<b>Examples:</b>
|
||||
@code
|
||||
class Foo : public FObject, public IFoo2, public IFoo3
|
||||
{
|
||||
...
|
||||
FUNKNOWN_METHODS2(IFoo2,IFoo3,FObject)
|
||||
...
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
///@{
|
||||
#define FUNKNOWN_METHODS(InterfaceName,BaseClass) \
|
||||
DEF_INTERFACES_1(InterfaceName,BaseClass) \
|
||||
REFCOUNT_METHODS(BaseClass)
|
||||
|
||||
#define FUNKNOWN_METHODS2(InterfaceName1,InterfaceName2,BaseClass) \
|
||||
DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
|
||||
REFCOUNT_METHODS(BaseClass)
|
||||
|
||||
#define FUNKNOWN_METHODS3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
|
||||
DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
|
||||
REFCOUNT_METHODS(BaseClass)
|
||||
|
||||
#define FUNKNOWN_METHODS4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
|
||||
DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
|
||||
REFCOUNT_METHODS(BaseClass)
|
||||
///@}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
#if COM_COMPATIBLE
|
||||
//------------------------------------------------------------------------
|
||||
/** @name Macros to implement IUnknown interfaces with FObject.
|
||||
<b>Examples:</b>
|
||||
@code
|
||||
class MyEnumFormat : public FObject, IEnumFORMATETC
|
||||
{
|
||||
...
|
||||
COM_UNKNOWN_METHODS (IEnumFORMATETC, IUnknown)
|
||||
...
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
///@{
|
||||
//------------------------------------------------------------------------
|
||||
#define IUNKNOWN_REFCOUNT_METHODS(BaseClass) \
|
||||
STDMETHOD_ (ULONG, AddRef) (void) {return BaseClass::addRef ();} \
|
||||
STDMETHOD_ (ULONG, Release) (void) {return BaseClass::release ();}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define COM_QUERY_INTERFACE(iid, obj, InterfaceName) \
|
||||
if (riid == __uuidof(InterfaceName)) \
|
||||
{ \
|
||||
addRef (); \
|
||||
*obj = (InterfaceName*)this; \
|
||||
return kResultOk; \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
|
||||
STDMETHOD (QueryInterface) (REFIID riid, void** object) \
|
||||
{ \
|
||||
COM_QUERY_INTERFACE (riid, object, InterfaceName) \
|
||||
return BaseClass::queryInterface ((FIDString)&riid, object); \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define COM_UNKNOWN_METHODS(InterfaceName,BaseClass) \
|
||||
COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
|
||||
IUNKNOWN_REFCOUNT_METHODS(BaseClass)
|
||||
///@}
|
||||
|
||||
#endif // COM_COMPATIBLE
|
||||
|
|
@ -1,756 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fstreamer.cpp
|
||||
// Created by : Steinberg, 15.12.2005
|
||||
// Description : Extract of typed stream i/o methods from FStream
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "fstreamer.h"
|
||||
|
||||
#include "base/source/fstring.h"
|
||||
#include "base/source/fbuffer.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
|
||||
#ifndef UNICODE
|
||||
#include "pluginterfaces/base/futils.h"
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IBStreamer
|
||||
//------------------------------------------------------------------------
|
||||
IBStreamer::IBStreamer (IBStream* stream, int16 _byteOrder)
|
||||
: FStreamer (_byteOrder)
|
||||
, stream (stream)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TSize IBStreamer::readRaw (void* buffer, TSize size)
|
||||
{
|
||||
int32 numBytesRead = 0;
|
||||
stream->read (buffer, (int32)size, &numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TSize IBStreamer::writeRaw (const void* buffer, TSize size)
|
||||
{
|
||||
int32 numBytesWritten = 0;
|
||||
stream->write ((void*)buffer, (int32)size, &numBytesWritten);
|
||||
return numBytesWritten;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int64 IBStreamer::seek (int64 pos, FSeekMode mode)
|
||||
{
|
||||
int64 result = -1;
|
||||
stream->seek (pos, mode, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int64 IBStreamer::tell ()
|
||||
{
|
||||
int64 pos = 0;
|
||||
stream->tell (&pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FStreamSizeHolder Implementation
|
||||
//------------------------------------------------------------------------
|
||||
FStreamSizeHolder::FStreamSizeHolder (FStreamer &s)
|
||||
: stream (s), sizePos (-1)
|
||||
{}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FStreamSizeHolder::beginWrite ()
|
||||
{
|
||||
sizePos = stream.tell ();
|
||||
stream.writeInt32 (0L);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32 FStreamSizeHolder::endWrite ()
|
||||
{
|
||||
if (sizePos < 0)
|
||||
return 0;
|
||||
|
||||
int64 currentPos = stream.tell ();
|
||||
|
||||
stream.seek (sizePos, kSeekSet);
|
||||
int32 size = int32 (currentPos - sizePos - sizeof (int32));
|
||||
stream.writeInt32 (size);
|
||||
|
||||
stream.seek (currentPos, kSeekSet);
|
||||
return size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32 FStreamSizeHolder::beginRead ()
|
||||
{
|
||||
sizePos = stream.tell ();
|
||||
int32 size = 0;
|
||||
stream.readInt32 (size);
|
||||
sizePos += size + sizeof (int32);
|
||||
return size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FStreamSizeHolder::endRead ()
|
||||
{
|
||||
if (sizePos >= 0)
|
||||
stream.seek (sizePos, kSeekSet);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FStreamer
|
||||
//------------------------------------------------------------------------
|
||||
FStreamer::FStreamer (int16 _byteOrder)
|
||||
: byteOrder (_byteOrder)
|
||||
{}
|
||||
|
||||
// int8 / char -----------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeChar8 (char8 c)
|
||||
{
|
||||
return writeRaw ((void*)&c, sizeof (char8)) == sizeof (char8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readChar8 (char8& c)
|
||||
{
|
||||
return readRaw ((void*)&c, sizeof (char8)) == sizeof (char8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeUChar8 (unsigned char c)
|
||||
{
|
||||
return writeRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readUChar8 (unsigned char& c)
|
||||
{
|
||||
return readRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeChar16 (char16 c)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_16 (c);
|
||||
return writeRaw ((void*)&c, sizeof (char16)) == sizeof (char16);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readChar16 (char16& c)
|
||||
{
|
||||
if (readRaw ((void*)&c, sizeof (char16)) == sizeof (char16))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_16 (c);
|
||||
return true;
|
||||
}
|
||||
c = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt8 (int8 c)
|
||||
{
|
||||
return writeRaw ((void*)&c, sizeof (int8)) == sizeof (int8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt8 (int8& c)
|
||||
{
|
||||
return readRaw ((void*)&c, sizeof (int8)) == sizeof (int8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt8u (uint8 c)
|
||||
{
|
||||
return writeRaw ((void*)&c, sizeof (uint8)) == sizeof (uint8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt8u (uint8& c)
|
||||
{
|
||||
return readRaw ((void*)&c, sizeof (uint8)) == sizeof (uint8);
|
||||
}
|
||||
|
||||
// int16 -----------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt16 (int16 i)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_16 (i);
|
||||
return writeRaw ((void*)&i, sizeof (int16)) == sizeof (int16);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt16 (int16& i)
|
||||
{
|
||||
if (readRaw ((void*)&i, sizeof (int16)) == sizeof (int16))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_16 (i);
|
||||
return true;
|
||||
}
|
||||
i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt16Array (const int16* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeInt16 (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt16Array (int16* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readInt16 (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt16u (uint16 i)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_16 (i);
|
||||
return writeRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt16u (uint16& i)
|
||||
{
|
||||
if (readRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_16 (i);
|
||||
return true;
|
||||
}
|
||||
i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt16uArray (const uint16* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeInt16u (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt16uArray (uint16* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readInt16u (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// int32 -----------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt32 (int32 i)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_32 (i);
|
||||
return writeRaw ((void*)&i, sizeof (int32)) == sizeof (int32);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt32 (int32& i)
|
||||
{
|
||||
if (readRaw ((void*)&i, sizeof (int32)) == sizeof (int32))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_32 (i);
|
||||
return true;
|
||||
}
|
||||
i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt32Array (const int32* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeInt32 (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt32Array (int32* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readInt32 (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt32u (uint32 i)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_32 (i);
|
||||
return writeRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt32u (uint32& i)
|
||||
{
|
||||
if (readRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_32 (i);
|
||||
return true;
|
||||
}
|
||||
i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt32uArray (const uint32* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeInt32u (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt32uArray (uint32* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readInt32u (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// int64 -----------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt64 (int64 i)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_64 (i);
|
||||
return writeRaw ((void*)&i, sizeof (int64)) == sizeof (int64);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt64 (int64& i)
|
||||
{
|
||||
if (readRaw ((void*)&i, sizeof (int64)) == sizeof (int64))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_64 (i);
|
||||
return true;
|
||||
}
|
||||
i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt64Array (const int64* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeInt64 (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt64Array (int64* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readInt64 (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt64u (uint64 i)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_64 (i);
|
||||
return writeRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt64u (uint64& i)
|
||||
{
|
||||
if (readRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_64 (i);
|
||||
return true;
|
||||
}
|
||||
i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeInt64uArray (const uint64* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeInt64u (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readInt64uArray (uint64* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readInt64u (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// float / double --------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeFloat (float f)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_32 (f);
|
||||
return writeRaw ((void*)&f, sizeof (float)) == sizeof (float);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readFloat (float& f)
|
||||
{
|
||||
if (readRaw ((void*)&f, sizeof (float)) == sizeof (float))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_32 (f);
|
||||
return true;
|
||||
}
|
||||
f = 0.f;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeFloatArray (const float* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeFloat (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readFloatArray (float* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readFloat (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeDouble (double d)
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_64 (d);
|
||||
return writeRaw ((void*)&d, sizeof (double)) == sizeof (double);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readDouble (double& d)
|
||||
{
|
||||
if (readRaw ((void*)&d, sizeof (double)) == sizeof (double))
|
||||
{
|
||||
if (BYTEORDER != byteOrder)
|
||||
SWAP_64 (d);
|
||||
return true;
|
||||
}
|
||||
d = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeDoubleArray (const double* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!writeDouble (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readDoubleArray (double* array, int32 count)
|
||||
{
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
if (!readDouble (array[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::readBool (bool& b)
|
||||
{
|
||||
int16 v = 0;
|
||||
bool res = readInt16 (v);
|
||||
b = (v != 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeBool (bool b)
|
||||
{
|
||||
return writeInt16 ((int16)b);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TSize FStreamer::writeString8 (const char8* ptr, bool terminate)
|
||||
{
|
||||
TSize size = strlen (ptr);
|
||||
if (terminate) // write \0
|
||||
size++;
|
||||
|
||||
return writeRaw ((void*)ptr, size);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TSize FStreamer::readString8 (char8* ptr, TSize size)
|
||||
{
|
||||
if (size < 1 || ptr == nullptr)
|
||||
return 0;
|
||||
|
||||
TSize i = 0;
|
||||
char8 c = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (readRaw ((void*)&c, sizeof (char)) != sizeof (char))
|
||||
break;
|
||||
ptr[i] = c;
|
||||
if (c == '\n' || c == '\0')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
// remove at end \n (LF) or \r\n (CR+LF)
|
||||
if (c == '\n')
|
||||
{
|
||||
if (i > 0 && ptr[i - 1] == '\r')
|
||||
i--;
|
||||
}
|
||||
if (i >= size)
|
||||
i = size - 1;
|
||||
ptr[i] = 0;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeStringUtf8 (const tchar* ptr)
|
||||
{
|
||||
bool isUtf8 = false;
|
||||
|
||||
String str (ptr);
|
||||
if (str.isAsciiString () == false)
|
||||
{
|
||||
str.toMultiByte (kCP_Utf8);
|
||||
isUtf8 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
str.toMultiByte ();
|
||||
}
|
||||
|
||||
if (isUtf8)
|
||||
if (writeRaw (kBomUtf8, kBomUtf8Length) != kBomUtf8Length)
|
||||
return false;
|
||||
|
||||
TSize size = str.length () + 1;
|
||||
if (writeRaw (str.text8 (), size) != size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32 FStreamer::readStringUtf8 (tchar* ptr, int32 nChars)
|
||||
{
|
||||
char8 c = 0;
|
||||
|
||||
ptr [0] = 0;
|
||||
|
||||
Buffer tmp;
|
||||
tmp.setDelta (1024);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (readRaw ((void*)&c, sizeof (char)) != sizeof (char))
|
||||
break;
|
||||
tmp.put (c);
|
||||
if (c == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
char8* source = tmp.str8 ();
|
||||
uint32 codePage = kCP_Default; // for legacy take default page if no utf8 bom is present...
|
||||
if (tmp.getFillSize () > 2)
|
||||
{
|
||||
if (memcmp (source, kBomUtf8, kBomUtf8Length) == 0)
|
||||
{
|
||||
codePage = kCP_Utf8;
|
||||
source += 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp.getFillSize () > 1)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
ConstString::multiByteToWideString (ptr, source, nChars, codePage);
|
||||
#else
|
||||
if (codePage == kCP_Utf8)
|
||||
{
|
||||
Buffer wideBuffer (tmp.getFillSize () * 3);
|
||||
ConstString::multiByteToWideString (wideBuffer.wcharPtr (), source, wideBuffer.getSize () / 2, kCP_Utf8);
|
||||
ConstString::wideStringToMultiByte (ptr, wideBuffer.wcharPtr (), nChars);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (ptr, source, Min<TSize> (nChars, tmp.getFillSize ()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ptr[nChars - 1] = 0;
|
||||
return ConstString (ptr).length ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::writeStr8 (const char8* s)
|
||||
{
|
||||
int32 length = (s) ? (int32) strlen (s) + 1 : 0;
|
||||
if (!writeInt32 (length))
|
||||
return false;
|
||||
|
||||
if (length > 0)
|
||||
return writeRaw (s, sizeof (char8) * length) == static_cast<TSize>(sizeof (char8) * length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32 FStreamer::getStr8Size (const char8* s)
|
||||
{
|
||||
return sizeof (int32) + (int32)strlen (s) + 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
char8* FStreamer::readStr8 ()
|
||||
{
|
||||
int32 length;
|
||||
if (!readInt32 (length))
|
||||
return nullptr;
|
||||
|
||||
// check corruption
|
||||
if (length > 262144)
|
||||
return nullptr;
|
||||
|
||||
char8* s = (length > 0) ? NEWSTR8 (length) : nullptr;
|
||||
if (s)
|
||||
readRaw (s, length * sizeof (char8));
|
||||
return s;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::skip (uint32 bytes)
|
||||
{
|
||||
int8 tmp;
|
||||
while (bytes-- > 0)
|
||||
{
|
||||
if (readInt8 (tmp) == false)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FStreamer::pad (uint32 bytes)
|
||||
{
|
||||
while (bytes-- > 0)
|
||||
{
|
||||
if (writeInt8 (0) == false)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,242 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fstreamer.h
|
||||
// Created by : Steinberg, 12/2005
|
||||
// Description : Extract of typed stream i/o methods from FStream
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
enum FSeekMode
|
||||
{
|
||||
kSeekSet,
|
||||
kSeekCurrent,
|
||||
kSeekEnd
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FStreamer
|
||||
//------------------------------------------------------------------------
|
||||
/** Byteorder-aware base class for typed stream i/o. */
|
||||
//------------------------------------------------------------------------
|
||||
class FStreamer
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
FStreamer (int16 byteOrder = BYTEORDER);
|
||||
virtual ~FStreamer () {}
|
||||
|
||||
/** @name Implementing class must override. */
|
||||
///@{
|
||||
virtual TSize readRaw (void*, TSize) = 0; ///< Read one buffer of size.
|
||||
virtual TSize writeRaw (const void*, TSize) = 0; ///< Write one buffer of size.
|
||||
virtual int64 seek (int64, FSeekMode) = 0; ///< Set file position for stream.
|
||||
virtual int64 tell () = 0; ///< Return current file position.
|
||||
///@}
|
||||
|
||||
/** @name Streams are byteOrder aware. */
|
||||
///@{
|
||||
inline void setByteOrder (int32 e) { byteOrder = (int16)e; }
|
||||
inline int32 getByteOrder () const { return byteOrder; }
|
||||
///@}
|
||||
|
||||
/** @name read and write int8 and char. */
|
||||
///@{
|
||||
bool writeChar8 (char8);
|
||||
bool readChar8 (char8&);
|
||||
bool writeUChar8 (unsigned char);
|
||||
bool readUChar8 (unsigned char&);
|
||||
bool writeChar16 (char16 c);
|
||||
bool readChar16 (char16& c);
|
||||
|
||||
bool writeInt8 (int8 c);
|
||||
bool readInt8 (int8& c);
|
||||
bool writeInt8u (uint8 c);
|
||||
bool readInt8u (uint8& c);
|
||||
///@}
|
||||
|
||||
/** @name read and write int16. */
|
||||
///@{
|
||||
bool writeInt16 (int16);
|
||||
bool readInt16 (int16&);
|
||||
bool writeInt16Array (const int16* array, int32 count);
|
||||
bool readInt16Array (int16* array, int32 count);
|
||||
bool writeInt16u (uint16);
|
||||
bool readInt16u (uint16&);
|
||||
bool writeInt16uArray (const uint16* array, int32 count);
|
||||
bool readInt16uArray (uint16* array, int32 count);
|
||||
///@}
|
||||
|
||||
/** @name read and write int32. */
|
||||
///@{
|
||||
bool writeInt32 (int32);
|
||||
bool readInt32 (int32&);
|
||||
bool writeInt32Array (const int32* array, int32 count);
|
||||
bool readInt32Array (int32* array, int32 count);
|
||||
bool writeInt32u (uint32);
|
||||
bool readInt32u (uint32&);
|
||||
bool writeInt32uArray (const uint32* array, int32 count);
|
||||
bool readInt32uArray (uint32* array, int32 count);
|
||||
///@}
|
||||
|
||||
/** @name read and write int64. */
|
||||
///@{
|
||||
bool writeInt64 (int64);
|
||||
bool readInt64 (int64&);
|
||||
bool writeInt64Array (const int64* array, int32 count);
|
||||
bool readInt64Array (int64* array, int32 count);
|
||||
bool writeInt64u (uint64);
|
||||
bool readInt64u (uint64&);
|
||||
bool writeInt64uArray (const uint64* array, int32 count);
|
||||
bool readInt64uArray (uint64* array, int32 count);
|
||||
///@}
|
||||
|
||||
/** @name read and write float and float array. */
|
||||
///@{
|
||||
bool writeFloat (float);
|
||||
bool readFloat (float&);
|
||||
bool writeFloatArray (const float* array, int32 count);
|
||||
bool readFloatArray (float* array, int32 count);
|
||||
///@}
|
||||
|
||||
/** @name read and write double and double array. */
|
||||
///@{
|
||||
bool writeDouble (double);
|
||||
bool readDouble (double&);
|
||||
bool writeDoubleArray (const double* array, int32 count);
|
||||
bool readDoubleArray (double* array, int32 count);
|
||||
///@}
|
||||
|
||||
/** @name read and write Boolean. */
|
||||
///@{
|
||||
bool writeBool (bool); ///< Write one boolean
|
||||
bool readBool (bool&); ///< Read one bool.
|
||||
///@}
|
||||
|
||||
/** @name read and write Strings. */
|
||||
///@{
|
||||
TSize writeString8 (const char8* ptr, bool terminate = false); ///< a direct output function writing only one string (ascii 8bit)
|
||||
TSize readString8 (char8* ptr, TSize size); ///< a direct input function reading only one string (ascii) (ended by a \n or \0 or eof)
|
||||
|
||||
bool writeStr8 (const char8* ptr); ///< write a string length (strlen) and string itself
|
||||
char8* readStr8 (); ///< read a string length and string text (The return string must be deleted when use is finished)
|
||||
|
||||
static int32 getStr8Size (const char8* ptr); ///< returns the size of a saved string
|
||||
|
||||
bool writeStringUtf8 (const tchar* ptr); ///< always terminated, converts to utf8 if non ascii characters are in string
|
||||
int32 readStringUtf8 (tchar* ptr, int32 maxSize); ///< read a UTF8 string
|
||||
///@}
|
||||
|
||||
bool skip (uint32 bytes);
|
||||
bool pad (uint32 bytes);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
int16 byteOrder;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** FStreamSizeHolder Declaration
|
||||
remembers size of stream chunk for backward compatibility.
|
||||
|
||||
<b>Example:</b>
|
||||
@code
|
||||
externalize (a)
|
||||
{
|
||||
FStreamSizeHolder sizeHolder;
|
||||
sizeHolder.beginWrite (); // sets start mark, writes dummy size
|
||||
a << ....
|
||||
sizeHolder.endWrite (); // jumps to start mark, updates size, jumps back here
|
||||
}
|
||||
|
||||
internalize (a)
|
||||
{
|
||||
FStreamSizeHolder sizeHolder;
|
||||
sizeHolder.beginRead (); // reads size, mark
|
||||
a >> ....
|
||||
sizeHolder.endRead (); // jumps forward if new version has larger size
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class FStreamSizeHolder
|
||||
{
|
||||
public:
|
||||
FStreamSizeHolder (FStreamer &s);
|
||||
|
||||
void beginWrite (); ///< remembers position and writes 0
|
||||
int32 endWrite (); ///< writes and returns size (since the start marker)
|
||||
int32 beginRead (); ///< returns size
|
||||
void endRead (); ///< jump to end of chunk
|
||||
|
||||
protected:
|
||||
FStreamer &stream;
|
||||
int64 sizePos;
|
||||
};
|
||||
|
||||
class IBStream;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IBStreamer
|
||||
//------------------------------------------------------------------------
|
||||
/** Wrapper class for typed reading/writing from or to IBStream.
|
||||
Can be used framework-independent in plug-ins. */
|
||||
//------------------------------------------------------------------------
|
||||
class IBStreamer: public FStreamer
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Constructor for a given IBSTream and a byteOrder. */
|
||||
IBStreamer (IBStream* stream, int16 byteOrder = BYTEORDER);
|
||||
|
||||
IBStream* getStream () { return stream; } ///< Returns the associated IBStream.
|
||||
|
||||
// FStreamer overrides:
|
||||
TSize readRaw (void*, TSize) SMTG_OVERRIDE; ///< Read one buffer of size.
|
||||
TSize writeRaw (const void*, TSize) SMTG_OVERRIDE; ///< Write one buffer of size.
|
||||
int64 seek (int64, FSeekMode) SMTG_OVERRIDE; ///< Set file position for stream.
|
||||
int64 tell () SMTG_OVERRIDE; ///< Return current file position.
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
IBStream* stream;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,778 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/fstring.h
|
||||
// Created by : Steinberg, 2008
|
||||
// Description : String class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/ftypes.h"
|
||||
#include "pluginterfaces/base/fstrdefs.h"
|
||||
#include "pluginterfaces/base/istringresult.h"
|
||||
#include "pluginterfaces/base/ipersistent.h"
|
||||
|
||||
#include "base/source/fobject.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
class FVariant;
|
||||
class String;
|
||||
|
||||
#ifdef UNICODE
|
||||
static const bool kWideStringDefault = true;
|
||||
#else
|
||||
static const bool kWideStringDefault = false;
|
||||
#endif
|
||||
|
||||
static const uint16 kBomUtf16 = 0xFEFF; ///< UTF16 Byte Order Mark
|
||||
static const char8* const kBomUtf8 = "\xEF\xBB\xBF"; ///< UTF8 Byte Order Mark
|
||||
static const int32 kBomUtf8Length = 3;
|
||||
|
||||
|
||||
enum MBCodePage
|
||||
{
|
||||
kCP_ANSI = 0, ///< Default ANSI codepage.
|
||||
kCP_MAC_ROMAN = 2, ///< Default Mac codepage.
|
||||
|
||||
kCP_ANSI_WEL = 1252, ///< West European Latin Encoding.
|
||||
kCP_MAC_CEE = 10029, ///< Mac Central European Encoding.
|
||||
kCP_Utf8 = 65001, ///< UTF8 Encoding.
|
||||
kCP_ShiftJIS = 932, ///< Shifted Japan Industrial Standard Encoding.
|
||||
kCP_US_ASCII = 20127, ///< US-ASCII (7-bit).
|
||||
|
||||
kCP_Default = kCP_ANSI ///< Default ANSI codepage.
|
||||
};
|
||||
|
||||
enum UnicodeNormalization
|
||||
{
|
||||
kUnicodeNormC, ///< Unicode normalization Form C, canonical composition.
|
||||
kUnicodeNormD, ///< Unicode normalization Form D, canonical decomposition.
|
||||
kUnicodeNormKC, ///< Unicode normalization form KC, compatibility composition.
|
||||
kUnicodeNormKD ///< Unicode normalization form KD, compatibility decomposition.
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Helper functions to create hash codes from string data.
|
||||
//------------------------------------------------------------------------
|
||||
extern uint32 hashString8 (const char8* s, uint32 m);
|
||||
extern uint32 hashString16 (const char16* s, uint32 m);
|
||||
inline uint32 hashString (const tchar* s, uint32 m)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return hashString16 (s, m);
|
||||
#else
|
||||
return hashString8 (s, m);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Invariant String.
|
||||
@ingroup adt
|
||||
|
||||
A base class which provides methods to work with its
|
||||
member string. Neither of the operations allows modifying the member string and
|
||||
that is why all operation are declared as const.
|
||||
|
||||
There are operations for access, comparison, find, numbers and conversion.
|
||||
|
||||
Almost all operations exist in three versions for char8, char16 and the
|
||||
polymorphic type tchar. The type tchar can either be char8 or char16 depending
|
||||
on whether UNICODE is activated or not.*/
|
||||
//-----------------------------------------------------------------------------
|
||||
class ConstString
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------------
|
||||
ConstString (const char8* str, int32 length = -1); ///< Assign from string of type char8 (length=-1: all)
|
||||
ConstString (const char16* str, int32 length = -1); ///< Assign from string of type char16 (length=-1: all)
|
||||
ConstString (const ConstString& str, int32 offset = 0, int32 length = -1); ///< Copy constructor (length=-1: all).
|
||||
ConstString (const FVariant& var); ///< Assign a string from FVariant
|
||||
ConstString ();
|
||||
virtual ~ConstString () {} ///< Destructor.
|
||||
|
||||
// access -----------------------------------------------------------------
|
||||
virtual int32 length () const {return static_cast<int32> (len);} ///< Return length of string
|
||||
inline bool isEmpty () const {return buffer == nullptr || len == 0;} ///< Return true if string is empty
|
||||
|
||||
operator const char8* () const {return text8 ();} ///< Returns pointer to string of type char8 (no modification allowed)
|
||||
operator const char16* () const {return text16 ();} ///< Returns pointer to string of type char16(no modification allowed)
|
||||
inline tchar operator[] (short idx) const {return getChar (static_cast<uint32> (idx));} ///< Returns character at 'idx'
|
||||
inline tchar operator[] (long idx) const {return getChar (static_cast<uint32> (idx));}
|
||||
inline tchar operator[] (int idx) const {return getChar (static_cast<uint32> (idx));}
|
||||
inline tchar operator[] (unsigned short idx) const {return getChar (idx);}
|
||||
inline tchar operator[] (unsigned long idx) const {return getChar (static_cast<uint32> (idx));}
|
||||
inline tchar operator[] (unsigned int idx) const {return getChar (idx);}
|
||||
|
||||
inline virtual const char8* text8 () const; ///< Returns pointer to string of type char8
|
||||
inline virtual const char16* text16 () const; ///< Returns pointer to string of type char16
|
||||
inline virtual const tchar* text () const; ///< Returns pointer to string of type tchar
|
||||
inline virtual const void* ptr () const {return buffer;} ///< Returns pointer to string of type void
|
||||
|
||||
inline virtual char8 getChar8 (uint32 index) const; ///< Returns character of type char16 at 'index'
|
||||
inline virtual char16 getChar16 (uint32 index) const; ///< Returns character of type char8 at 'index'
|
||||
inline tchar getChar (uint32 index) const; ///< Returns character of type tchar at 'index'
|
||||
inline tchar getCharAt (uint32 index) const; ///< Returns character of type tchar at 'index', no conversion!
|
||||
|
||||
bool testChar8 (uint32 index, char8 c) const; ///< Returns true if character is equal at position 'index'
|
||||
bool testChar16 (uint32 index, char16 c) const;
|
||||
inline bool testChar (uint32 index, char8 c) const {return testChar8 (index, c);}
|
||||
inline bool testChar (uint32 index, char16 c) const {return testChar16 (index, c);}
|
||||
|
||||
bool extract (String& result, uint32 idx, int32 n = -1) const; ///< Get n characters long substring starting at index (n=-1: until end)
|
||||
int32 copyTo8 (char8* str, uint32 idx = 0, int32 n = -1) const;
|
||||
int32 copyTo16 (char16* str, uint32 idx = 0, int32 n = -1) const;
|
||||
int32 copyTo (tchar* str, uint32 idx = 0, int32 n = -1) const;
|
||||
void copyTo (IStringResult* result) const; ///< Copies whole member string
|
||||
void copyTo (IString& string) const; ///< Copies whole member string
|
||||
|
||||
inline uint32 hash (uint32 tsize) const
|
||||
{
|
||||
return isWide ? hashString16 (buffer16, tsize) : hashString8 (buffer8, tsize) ;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// compare ----------------------------------------------------------------
|
||||
enum CompareMode
|
||||
{
|
||||
kCaseSensitive, ///< Comparison is done with regard to character's case
|
||||
kCaseInsensitive ///< Comparison is done without regard to character's case
|
||||
};
|
||||
|
||||
int32 compareAt (uint32 index, const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive) const; ///< Compare n characters of str with n characters of this starting at index (return: see above)
|
||||
int32 compare (const ConstString& str, int32 n, CompareMode m = kCaseSensitive) const; ///< Compare n characters of str with n characters of this (return: see above)
|
||||
int32 compare (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Compare all characters of str with this (return: see above)
|
||||
|
||||
int32 naturalCompare (const ConstString& str, CompareMode mode = kCaseSensitive) const;
|
||||
|
||||
bool startsWith (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this starts with str
|
||||
bool endsWith (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this ends with str
|
||||
bool contains (const ConstString& str, CompareMode m = kCaseSensitive) const; ///< Check if this contains str
|
||||
|
||||
// static methods
|
||||
static bool isCharSpace (char8 character); ///< Returns true if character is a space
|
||||
static bool isCharSpace (char16 character); ///< @copydoc isCharSpace(const char8)
|
||||
static bool isCharAlpha (char8 character); ///< Returns true if character is an alphabetic character
|
||||
static bool isCharAlpha (char16 character); ///< @copydoc isCharAlpha(const char8)
|
||||
static bool isCharAlphaNum (char8 character); ///< Returns true if character is an alphanumeric character
|
||||
static bool isCharAlphaNum (char16 character); ///< @copydoc isCharAlphaNum(const char8)
|
||||
static bool isCharDigit (char8 character); ///< Returns true if character is a number
|
||||
static bool isCharDigit (char16 character); ///< @copydoc isCharDigit(const char8)
|
||||
static bool isCharAscii (char8 character); ///< Returns true if character is in ASCII range
|
||||
static bool isCharAscii (char16 character); ///< Returns true if character is in ASCII range
|
||||
static bool isCharUpper (char8 character);
|
||||
static bool isCharUpper (char16 character);
|
||||
static bool isCharLower (char8 character);
|
||||
static bool isCharLower (char16 character);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/** @name Find first occurrence of n characters of str in this (n=-1: all) ending at endIndex (endIndex = -1: all)*/
|
||||
///@{
|
||||
inline int32 findFirst (const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, str, n, m, endIndex);}
|
||||
inline int32 findFirst (char8 c, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, c, m, endIndex);}
|
||||
inline int32 findFirst (char16 c, CompareMode m = kCaseSensitive, int32 endIndex = -1) const {return findNext (0, c, m, endIndex);}
|
||||
///@}
|
||||
/** @name Find next occurrence of n characters of str starting at startIndex in this (n=-1: all) ending at endIndex (endIndex = -1: all)*/
|
||||
///@{
|
||||
int32 findNext (int32 startIndex, const ConstString& str, int32 n = -1, CompareMode = kCaseSensitive, int32 endIndex = -1) const;
|
||||
int32 findNext (int32 startIndex, char8 c, CompareMode = kCaseSensitive, int32 endIndex = -1) const;
|
||||
int32 findNext (int32 startIndex, char16 c, CompareMode = kCaseSensitive, int32 endIndex = -1) const;
|
||||
///@}
|
||||
/** @name Find previous occurrence of n characters of str starting at startIndex in this (n=-1: all) */
|
||||
///@{
|
||||
int32 findPrev (int32 startIndex, const ConstString& str, int32 n = -1, CompareMode = kCaseSensitive) const;
|
||||
int32 findPrev (int32 startIndex, char8 c, CompareMode = kCaseSensitive) const;
|
||||
int32 findPrev (int32 startIndex, char16 c, CompareMode = kCaseSensitive) const;
|
||||
///@}
|
||||
|
||||
inline int32 findLast (const ConstString& str, int32 n = -1, CompareMode m = kCaseSensitive) const {return findPrev (-1, str, n, m);} ///< Find last occurrence of n characters of str in this (n=-1: all)
|
||||
inline int32 findLast (char8 c, CompareMode m = kCaseSensitive) const {return findPrev (-1, c, m);}
|
||||
inline int32 findLast (char16 c, CompareMode m = kCaseSensitive) const {return findPrev (-1, c, m);}
|
||||
|
||||
int32 countOccurences (char8 c, uint32 startIndex, CompareMode = kCaseSensitive) const; ///< Counts occurences of c within this starting at index
|
||||
int32 countOccurences (char16 c, uint32 startIndex, CompareMode = kCaseSensitive) const;
|
||||
int32 getFirstDifferent (const ConstString& str, CompareMode = kCaseSensitive) const; ///< Returns position of first different character
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// numbers ----------------------------------------------------------------
|
||||
bool isDigit (uint32 index) const; ///< Returns true if character at position is a digit
|
||||
bool scanFloat (double& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to double value starting at offset
|
||||
bool scanInt64 (int64& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to int64 value starting at offset
|
||||
bool scanUInt64 (uint64& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to uint64 value starting at offset
|
||||
bool scanInt32 (int32& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to int32 value starting at offset
|
||||
bool scanUInt32 (uint32& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to uint32 value starting at offset
|
||||
bool scanHex (uint8& value, uint32 offset = 0, bool scanToEnd = true) const; ///< Converts string to hex/uint8 value starting at offset
|
||||
|
||||
int32 getTrailingNumberIndex (uint32 width = 0) const; ///< Returns start index of trailing number
|
||||
int64 getTrailingNumber (int64 fallback = 0) const; ///< Returns result of scanInt64 or the fallback
|
||||
int64 getNumber () const; ///< Returns result of scanInt64
|
||||
|
||||
// static methods
|
||||
static bool scanInt64_8 (const char8* text, int64& value, bool scanToEnd = true); ///< Converts string of type char8 to int64 value
|
||||
static bool scanInt64_16 (const char16* text, int64& value, bool scanToEnd = true); ///< Converts string of type char16 to int64 value
|
||||
static bool scanInt64 (const tchar* text, int64& value, bool scanToEnd = true); ///< Converts string of type tchar to int64 value
|
||||
|
||||
static bool scanUInt64_8 (const char8* text, uint64& value, bool scanToEnd = true); ///< Converts string of type char8 to uint64 value
|
||||
static bool scanUInt64_16 (const char16* text, uint64& value, bool scanToEnd = true); ///< Converts string of type char16 to uint64 value
|
||||
static bool scanUInt64 (const tchar* text, uint64& value, bool scanToEnd = true); ///< Converts string of type tchar to uint64 value
|
||||
|
||||
static bool scanInt32_8 (const char8* text, int32& value, bool scanToEnd = true); ///< Converts string of type char8 to int32 value
|
||||
static bool scanInt32_16 (const char16* text, int32& value, bool scanToEnd = true); ///< Converts string of type char16 to int32 value
|
||||
static bool scanInt32 (const tchar* text, int32& value, bool scanToEnd = true); ///< Converts string of type tchar to int32 value
|
||||
|
||||
static bool scanUInt32_8 (const char8* text, uint32& value, bool scanToEnd = true); ///< Converts string of type char8 to int32 value
|
||||
static bool scanUInt32_16 (const char16* text, uint32& value, bool scanToEnd = true); ///< Converts string of type char16 to int32 value
|
||||
static bool scanUInt32 (const tchar* text, uint32& value, bool scanToEnd = true); ///< Converts string of type tchar to int32 value
|
||||
|
||||
static bool scanHex_8 (const char8* text, uint8& value, bool scanToEnd = true); ///< Converts string of type char8 to hex/unit8 value
|
||||
static bool scanHex_16 (const char16* text, uint8& value, bool scanToEnd = true); ///< Converts string of type char16 to hex/unit8 value
|
||||
static bool scanHex (const tchar* text, uint8& value, bool scanToEnd = true); ///< Converts string of type tchar to hex/unit8 value
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// conversion -------------------------------------------------------------
|
||||
void toVariant (FVariant& var) const;
|
||||
|
||||
static char8 toLower (char8 c); ///< Converts to lower case
|
||||
static char8 toUpper (char8 c); ///< Converts to upper case
|
||||
static char16 toLower (char16 c);
|
||||
static char16 toUpper (char16 c);
|
||||
|
||||
static int32 multiByteToWideString (char16* dest, const char8* source, int32 wcharCount, uint32 sourceCodePage = kCP_Default); ///< If dest is zero, this returns the maximum number of bytes needed to convert source
|
||||
static int32 wideStringToMultiByte (char8* dest, const char16* source, int32 char8Count, uint32 destCodePage = kCP_Default); ///< If dest is zero, this returns the maximum number of bytes needed to convert source
|
||||
|
||||
bool isWideString () const {return isWide != 0;} ///< Returns true if string is wide
|
||||
bool isAsciiString () const; ///< Checks if all characters in string are in ascii range
|
||||
|
||||
bool isNormalized (UnicodeNormalization = kUnicodeNormC); ///< On PC only kUnicodeNormC is working
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
ConstString (const wchar_t* str, int32 length = -1) : ConstString (wscast (str), length) {}
|
||||
operator const wchar_t* () const { return wscast (text16 ());}
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
virtual void* toCFStringRef (uint32 encoding = 0xFFFF, bool mutableCFString = false) const; ///< CFString conversion
|
||||
#endif
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
protected:
|
||||
|
||||
union
|
||||
{
|
||||
void* buffer;
|
||||
char8* buffer8;
|
||||
char16* buffer16;
|
||||
};
|
||||
uint32 len : 30;
|
||||
uint32 isWide : 1;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** String.
|
||||
@ingroup adt
|
||||
|
||||
Extends class ConstString by operations which allow modifications.
|
||||
|
||||
If allocated externally and passed in via take() or extracted via pass(), memory
|
||||
is expected to be allocated with C's malloc() (rather than new) and deallocated with free().
|
||||
Use the NEWSTR8/16 and DELETESTR8/16 macros below.
|
||||
|
||||
\see ConstString */
|
||||
//-----------------------------------------------------------------------------
|
||||
class String : public ConstString
|
||||
{
|
||||
public:
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
String ();
|
||||
String (const char8* str, MBCodePage codepage, int32 n = -1, bool isTerminated = true); ///< assign n characters of str and convert to wide string by using the specified codepage
|
||||
String (const char8* str, int32 n = -1, bool isTerminated = true); ///< assign n characters of str (-1: all)
|
||||
String (const char16* str, int32 n = -1, bool isTerminated = true); ///< assign n characters of str (-1: all)
|
||||
String (const String& str, int32 n = -1); ///< assign n characters of str (-1: all)
|
||||
String (const ConstString& str, int32 n = -1); ///< assign n characters of str (-1: all)
|
||||
String (const FVariant& var); ///< assign from FVariant
|
||||
String (IString* str); ///< assign from IString
|
||||
~String () SMTG_OVERRIDE;
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
String (String&& str);
|
||||
String& operator= (String&& str);
|
||||
#endif
|
||||
|
||||
// access------------------------------------------------------------------
|
||||
void updateLength (); ///< Call this when the string is truncated outside (not recommended though)
|
||||
const char8* text8 () const SMTG_OVERRIDE;
|
||||
const char16* text16 () const SMTG_OVERRIDE;
|
||||
char8 getChar8 (uint32 index) const SMTG_OVERRIDE;
|
||||
char16 getChar16 (uint32 index) const SMTG_OVERRIDE;
|
||||
|
||||
bool setChar8 (uint32 index, char8 c);
|
||||
bool setChar16 (uint32 index, char16 c);
|
||||
inline bool setChar (uint32 index, char8 c) {return setChar8 (index, c);}
|
||||
inline bool setChar (uint32 index, char16 c) {return setChar16 (index, c);}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// assignment--------------------------------------------------------------
|
||||
String& operator= (const char8* str) {return assign (str);} ///< Assign from a string of type char8
|
||||
String& operator= (const char16* str) {return assign (str);}
|
||||
String& operator= (const ConstString& str) {return assign (str);}
|
||||
String& operator= (const String& str) {return assign (str);}
|
||||
String& operator= (char8 c) {return assign (c);}
|
||||
String& operator= (char16 c) {return assign (c);}
|
||||
|
||||
String& assign (const ConstString& str, int32 n = -1); ///< Assign n characters of str (-1: all)
|
||||
String& assign (const char8* str, int32 n = -1, bool isTerminated = true); ///< Assign n characters of str (-1: all)
|
||||
String& assign (const char16* str, int32 n = -1, bool isTerminated = true); ///< Assign n characters of str (-1: all)
|
||||
String& assign (char8 c, int32 n = 1);
|
||||
String& assign (char16 c, int32 n = 1);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// concat------------------------------------------------------------------
|
||||
String& append (const ConstString& str, int32 n = -1); ///< Append n characters of str to this (n=-1: all)
|
||||
String& append (const char8* str, int32 n = -1); ///< Append n characters of str to this (n=-1: all)
|
||||
String& append (const char16* str, int32 n = -1); ///< Append n characters of str to this (n=-1: all)
|
||||
String& append (const char8 c, int32 n = 1); ///< Append char c n times
|
||||
String& append (const char16 c, int32 n = 1); ///< Append char c n times
|
||||
|
||||
String& insertAt (uint32 idx, const ConstString& str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all)
|
||||
String& insertAt (uint32 idx, const char8* str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all)
|
||||
String& insertAt (uint32 idx, const char16* str, int32 n = -1); ///< Insert n characters of str at position idx (n=-1: all)
|
||||
String& insertAt (uint32 idx, char8 c) {char8 str[] = {c, 0}; return insertAt (idx, str, 1);}
|
||||
String& insertAt (uint32 idx, char16 c) {char16 str[] = {c, 0}; return insertAt (idx, str, 1);}
|
||||
|
||||
String& operator+= (const String& str) {return append (str);}
|
||||
String& operator+= (const ConstString& str) {return append (str);}
|
||||
String& operator+= (const char8* str) {return append (str);}
|
||||
String& operator+= (const char16* str) {return append (str);}
|
||||
String& operator+= (const char8 c) {return append (c);}
|
||||
String& operator+= (const char16 c) {return append (c);}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// replace-----------------------------------------------------------------
|
||||
String& replace (uint32 idx, int32 n1, const ConstString& str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end)
|
||||
String& replace (uint32 idx, int32 n1, const char8* str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end)
|
||||
String& replace (uint32 idx, int32 n1, const char16* str, int32 n2 = -1); ///< Replace n1 characters of this (starting at idx) with n2 characters of str (n1,n2=-1: until end)
|
||||
|
||||
int32 replace (const char8* toReplace, const char8* toReplaceWith, bool all = false, CompareMode m = kCaseSensitive); ///< Replace find string with replace string - returns number of replacements
|
||||
int32 replace (const char16* toReplace, const char16* toReplaceWith, bool all = false, CompareMode m = kCaseSensitive); ///< Replace find string with replace string - returns number of replacements
|
||||
|
||||
bool replaceChars8 (const char8* toReplace, char8 toReplaceBy); ///< Returns true when any replacement was done
|
||||
bool replaceChars16 (const char16* toReplace, char16 toReplaceBy);
|
||||
inline bool replaceChars8 (char8 toReplace, char8 toReplaceBy) {char8 str[] = {toReplace, 0}; return replaceChars8 (str, toReplaceBy);}
|
||||
inline bool replaceChars16 (char16 toReplace, char16 toReplaceBy) {char16 str[] = {toReplace, 0}; return replaceChars16 (str, toReplaceBy);}
|
||||
inline bool replaceChars (char8 toReplace, char8 toReplaceBy) {return replaceChars8 (toReplace, toReplaceBy);}
|
||||
inline bool replaceChars (char16 toReplace, char16 toReplaceBy) {return replaceChars16 (toReplace, toReplaceBy);}
|
||||
inline bool replaceChars (const char8* toReplace, char8 toReplaceBy) {return replaceChars8 (toReplace, toReplaceBy);}
|
||||
inline bool replaceChars (const char16* toReplace, char16 toReplaceBy) {return replaceChars16 (toReplace, toReplaceBy);}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// remove------------------------------------------------------------------
|
||||
String& remove (uint32 index = 0, int32 n = -1); ///< Remove n characters from string starting at index (n=-1: until end)
|
||||
enum CharGroup {kSpace, kNotAlphaNum, kNotAlpha};
|
||||
bool trim (CharGroup mode = kSpace); ///< Trim lead/trail.
|
||||
void removeChars (CharGroup mode = kSpace); ///< Removes all of group.
|
||||
bool removeChars8 (const char8* which); ///< Remove all occurrences of each char in 'which'
|
||||
bool removeChars16 (const char16* which); ///< Remove all occurrences of each char in 'which'
|
||||
inline bool removeChars8 (const char8 which) {char8 str[] = {which, 0}; return removeChars8 (str); }
|
||||
inline bool removeChars16 (const char16 which) {char16 str[] = {which, 0}; return removeChars16 (str); }
|
||||
inline bool removeChars (const char8* which) {return removeChars8 (which);}
|
||||
inline bool removeChars (const char16* which) {return removeChars16 (which);}
|
||||
inline bool removeChars (const char8 which) {return removeChars8 (which);}
|
||||
inline bool removeChars (const char16 which) {return removeChars16 (which);}
|
||||
bool removeSubString (const ConstString& subString, bool allOccurences = true);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// print-------------------------------------------------------------------
|
||||
String& printf (const char8* format, ...); ///< Print formatted data into string
|
||||
String& printf (const char16* format, ...); ///< Print formatted data into string
|
||||
String& vprintf (const char8* format, va_list args);
|
||||
String& vprintf (const char16* format, va_list args);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// numbers-----------------------------------------------------------------
|
||||
String& printInt64 (int64 value);
|
||||
|
||||
/**
|
||||
* @brief print a float into a string, trailing zeros will be trimmed
|
||||
* @param value the floating value to be printed
|
||||
* @param maxPrecision (optional) the max precision allowed for this, num of significant digits after the comma
|
||||
* For instance printFloat (1.234, 2) => 1.23
|
||||
* @return the resulting string.
|
||||
*/
|
||||
String& printFloat (double value, uint32 maxPrecision = 6);
|
||||
/** Increment the trailing number if present else start with minNumber, width specifies the string width format (width 2 for number 3 is 03),
|
||||
applyOnlyFormat set to true will only format the string to the given width without incrementing the founded trailing number */
|
||||
bool incrementTrailingNumber (uint32 width = 2, tchar separator = STR (' '), uint32 minNumber = 1, bool applyOnlyFormat = false);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// conversion--------------------------------------------------------------
|
||||
bool fromVariant (const FVariant& var); ///< Assigns string from FVariant
|
||||
void toVariant (FVariant& var) const;
|
||||
bool fromAttributes (IAttributes* a, IAttrID attrID); ///< Assigns string from FAttributes
|
||||
bool toAttributes (IAttributes* a, IAttrID attrID);
|
||||
|
||||
void swapContent (String& s); ///< Swaps ownership of the strings pointed to
|
||||
void take (String& str); ///< Take ownership of the string of 'str'
|
||||
void take (void* _buffer, bool wide); ///< Take ownership of buffer
|
||||
void* pass ();
|
||||
void passToVariant (FVariant& var); ///< Pass ownership of buffer to Variant - sets Variant ownership
|
||||
|
||||
void toLower (uint32 index); ///< Lower case the character.
|
||||
void toLower (); ///< Lower case the string.
|
||||
void toUpper (uint32 index); ///< Upper case the character.
|
||||
void toUpper (); ///< Upper case the string.
|
||||
|
||||
unsigned char* toPascalString (unsigned char* buf); ///< Pascal string conversion
|
||||
const String& fromPascalString (const unsigned char* buf); ///< Pascal string conversion
|
||||
|
||||
bool toWideString (uint32 sourceCodePage = kCP_Default); ///< Converts to wide string according to sourceCodePage
|
||||
bool toMultiByte (uint32 destCodePage = kCP_Default);
|
||||
|
||||
void fromUTF8 (const char8* utf8String); ///< Assigns from UTF8 string
|
||||
bool normalize (UnicodeNormalization = kUnicodeNormC); ///< On PC only kUnicodeNormC is working
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
String (const wchar_t* str, int32 length = -1, bool isTerminated = true) : String (wscast (str), length, isTerminated) {}
|
||||
String& operator= (const wchar_t* str) {return String::operator= (wscast (str)); }
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
virtual bool fromCFStringRef (const void*, uint32 encoding = 0xFFFF); ///< CFString conversion
|
||||
#endif
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
protected:
|
||||
bool resize (uint32 newSize, bool wide, bool fill = false);
|
||||
|
||||
private:
|
||||
bool _toWideString (const char8* src, int32 length, uint32 sourceCodePage = kCP_Default);
|
||||
void tryFreeBuffer ();
|
||||
bool checkToMultiByte (uint32 destCodePage = kCP_Default) const; // to remove debug code from inline - const_cast inside!!!
|
||||
};
|
||||
|
||||
// String memory allocation macros
|
||||
#define NEWSTR8(len) ((char8*)::malloc(len)) // len includes trailing zero
|
||||
#define NEWSTR16(len) ((char16*)::malloc(2*(len)))
|
||||
#define DELETESTR8(p) (::free((char*)(p))) // cast to strip const
|
||||
#define DELETESTR16(p) (::free((char16*)(p)))
|
||||
|
||||
// String concatenation functions.
|
||||
inline String operator+ (const ConstString& s1, const ConstString& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const ConstString& s1, const char8* s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const ConstString& s1, const char16* s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const char8* s1, const ConstString& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const char16* s1, const ConstString& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const ConstString& s1, const String& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const String& s1, const ConstString& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const String& s1, const String& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const String& s1, const char8* s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const String& s1, const char16* s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const char8* s1, const String& s2) {return String (s1).append (s2);}
|
||||
inline String operator+ (const char16* s1, const String& s2) {return String (s1).append (s2);}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ConstString
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const tchar* ConstString::text () const
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return text16 ();
|
||||
#else
|
||||
return text8 ();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char8* ConstString::text8 () const
|
||||
{
|
||||
return (!isWide && buffer8) ? buffer8: kEmptyString8;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char16* ConstString::text16 () const
|
||||
{
|
||||
return (isWide && buffer16) ? buffer16 : kEmptyString16;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline char8 ConstString::getChar8 (uint32 index) const
|
||||
{
|
||||
if (index < len && buffer8 && !isWide)
|
||||
return buffer8[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline char16 ConstString::getChar16 (uint32 index) const
|
||||
{
|
||||
if (index < len && buffer16 && isWide)
|
||||
return buffer16[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline tchar ConstString::getChar (uint32 index) const
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return getChar16 (index);
|
||||
#else
|
||||
return getChar8 (index);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline tchar ConstString::getCharAt (uint32 index) const
|
||||
{
|
||||
#ifdef UNICODE
|
||||
if (isWide)
|
||||
return getChar16 (index);
|
||||
#endif
|
||||
|
||||
return static_cast<tchar> (getChar8 (index));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int64 ConstString::getNumber () const
|
||||
{
|
||||
int64 tmp = 0;
|
||||
scanInt64 (tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool ConstString::scanInt32_8 (const char8* text, int32& value, bool scanToEnd)
|
||||
{
|
||||
int64 tmp;
|
||||
if (scanInt64_8 (text, tmp, scanToEnd))
|
||||
{
|
||||
value = (int32)tmp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool ConstString::scanInt32_16 (const char16* text, int32& value, bool scanToEnd)
|
||||
{
|
||||
int64 tmp;
|
||||
if (scanInt64_16 (text, tmp, scanToEnd))
|
||||
{
|
||||
value = (int32)tmp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool ConstString::scanInt32 (const tchar* text, int32& value, bool scanToEnd)
|
||||
{
|
||||
int64 tmp;
|
||||
if (scanInt64 (text, tmp, scanToEnd))
|
||||
{
|
||||
value = (int32)tmp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool ConstString::scanUInt32_8 (const char8* text, uint32& value, bool scanToEnd)
|
||||
{
|
||||
uint64 tmp;
|
||||
if (scanUInt64_8 (text, tmp, scanToEnd))
|
||||
{
|
||||
value = (uint32)tmp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool ConstString::scanUInt32_16 (const char16* text, uint32& value, bool scanToEnd)
|
||||
{
|
||||
uint64 tmp;
|
||||
if (scanUInt64_16 (text, tmp, scanToEnd))
|
||||
{
|
||||
value = (uint32)tmp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool ConstString::scanUInt32 (const tchar* text, uint32& value, bool scanToEnd)
|
||||
{
|
||||
uint64 tmp;
|
||||
if (scanUInt64 (text, tmp, scanToEnd))
|
||||
{
|
||||
value = (uint32)tmp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char8* String::text8 () const
|
||||
{
|
||||
if (isWide && !isEmpty ())
|
||||
checkToMultiByte (); // this should be avoided, since it can lead to information loss
|
||||
|
||||
return ConstString::text8 ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char16* String::text16 () const
|
||||
{
|
||||
if (!isWide && !isEmpty ())
|
||||
{
|
||||
const_cast<String&> (*this).toWideString ();
|
||||
}
|
||||
return ConstString::text16 ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline char8 String::getChar8 (uint32 index) const
|
||||
{
|
||||
if (isWide && !isEmpty ())
|
||||
checkToMultiByte (); // this should be avoided, since it can lead to information loss
|
||||
|
||||
return ConstString::getChar8 (index);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline char16 String::getChar16 (uint32 index) const
|
||||
{
|
||||
if (!isWide && !isEmpty ())
|
||||
{
|
||||
const_cast<String&> (*this).toWideString ();
|
||||
}
|
||||
return ConstString::getChar16 (index);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
inline bool operator< (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) < 0) ? true : false;}
|
||||
inline bool operator<= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) <= 0) ? true : false;}
|
||||
inline bool operator> (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) > 0) ? true : false;}
|
||||
inline bool operator>= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) >= 0) ? true : false;}
|
||||
inline bool operator== (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) == 0) ? true : false;}
|
||||
inline bool operator!= (const ConstString& s1, const ConstString& s2) {return (s1.compare (s2) != 0) ? true : false;}
|
||||
|
||||
inline bool operator< (const ConstString& s1, const char8* s2) {return (s1.compare (s2) < 0) ? true : false;}
|
||||
inline bool operator<= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) <= 0) ? true : false;}
|
||||
inline bool operator> (const ConstString& s1, const char8* s2) {return (s1.compare (s2) > 0) ? true : false;}
|
||||
inline bool operator>= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) >= 0) ? true : false;}
|
||||
inline bool operator== (const ConstString& s1, const char8* s2) {return (s1.compare (s2) == 0) ? true : false;}
|
||||
inline bool operator!= (const ConstString& s1, const char8* s2) {return (s1.compare (s2) != 0) ? true : false;}
|
||||
inline bool operator< (const char8* s1, const ConstString& s2) {return (s2.compare (s1) > 0) ? true : false;}
|
||||
inline bool operator<= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) >= 0) ? true : false;}
|
||||
inline bool operator> (const char8* s1, const ConstString& s2) {return (s2.compare (s1) < 0) ? true : false;}
|
||||
inline bool operator>= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) <= 0) ? true : false;}
|
||||
inline bool operator== (const char8* s1, const ConstString& s2) {return (s2.compare (s1) == 0) ? true : false;}
|
||||
inline bool operator!= (const char8* s1, const ConstString& s2) {return (s2.compare (s1) != 0) ? true : false;}
|
||||
|
||||
inline bool operator< (const ConstString& s1, const char16* s2) {return (s1.compare (s2) < 0) ? true : false;}
|
||||
inline bool operator<= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) <= 0) ? true : false;}
|
||||
inline bool operator> (const ConstString& s1, const char16* s2) {return (s1.compare (s2) > 0) ? true : false;}
|
||||
inline bool operator>= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) >= 0) ? true : false;}
|
||||
inline bool operator== (const ConstString& s1, const char16* s2) {return (s1.compare (s2) == 0) ? true : false;}
|
||||
inline bool operator!= (const ConstString& s1, const char16* s2) {return (s1.compare (s2) != 0) ? true : false;}
|
||||
inline bool operator< (const char16* s1, const ConstString& s2) {return (s2.compare (s1) > 0) ? true : false;}
|
||||
inline bool operator<= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) >= 0) ? true : false;}
|
||||
inline bool operator> (const char16* s1, const ConstString& s2) {return (s2.compare (s1) < 0) ? true : false;}
|
||||
inline bool operator>= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) <= 0) ? true : false;}
|
||||
inline bool operator== (const char16* s1, const ConstString& s2) {return (s2.compare (s1) == 0) ? true : false;}
|
||||
inline bool operator!= (const char16* s1, const ConstString& s2) {return (s2.compare (s1) != 0) ? true : false;}
|
||||
|
||||
// The following functions will only work with European Numbers!
|
||||
// (e.g. Arabic, Tibetan, and Khmer digits are not supported)
|
||||
extern int32 strnatcmp8 (const char8* s1, const char8* s2, bool caseSensitive = true);
|
||||
extern int32 strnatcmp16 (const char16* s1, const char16* s2, bool caseSensitive = true);
|
||||
inline int32 strnatcmp (const tchar* s1, const tchar* s2, bool caseSensitive = true)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
return strnatcmp16 (s1, s2, caseSensitive);
|
||||
#else
|
||||
return strnatcmp8 (s1, s2, caseSensitive);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** StringObject implements IStringResult and IString methods.
|
||||
It can therefore be exchanged with other Steinberg objects using one or both of these
|
||||
interfaces.
|
||||
|
||||
\see String, ConstString
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
class StringObject : public FObject, public String, public IStringResult, public IString
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------------
|
||||
StringObject () {}
|
||||
StringObject (const char16* str, int32 n = -1, bool isTerminated = true) : String (str, n, isTerminated) {}
|
||||
StringObject (const char8* str, int32 n = -1, bool isTerminated = true) : String (str, n, isTerminated) {}
|
||||
StringObject (const StringObject& str, int32 n = -1) : String (str, n) {}
|
||||
StringObject (const String& str, int32 n = -1) : String (str, n) {}
|
||||
StringObject (const FVariant& var) : String (var) {}
|
||||
|
||||
using String::operator=;
|
||||
|
||||
// IStringResult ----------------------------------------------------------
|
||||
void PLUGIN_API setText (const char8* text) SMTG_OVERRIDE;
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// IString-----------------------------------------------------------------
|
||||
void PLUGIN_API setText8 (const char8* text) SMTG_OVERRIDE;
|
||||
void PLUGIN_API setText16 (const char16* text) SMTG_OVERRIDE;
|
||||
|
||||
const char8* PLUGIN_API getText8 () SMTG_OVERRIDE;
|
||||
const char16* PLUGIN_API getText16 () SMTG_OVERRIDE;
|
||||
|
||||
void PLUGIN_API take (void* s, bool _isWide) SMTG_OVERRIDE;
|
||||
bool PLUGIN_API isWideString () const SMTG_OVERRIDE;
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
OBJ_METHODS (StringObject, FObject)
|
||||
FUNKNOWN_METHODS2 (IStringResult, IString, FObject)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,740 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/updatehandler.cpp
|
||||
// Created by : Steinberg, 2008
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "base/source/updatehandler.h"
|
||||
#include "base/source/classfactoryhelpers.h"
|
||||
#include "base/source/fstring.h"
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
#include <unordered_map>
|
||||
#else
|
||||
#include <map>
|
||||
#endif
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#define NON_EXISTING_DEPENDENCY_CHECK 0 // not yet
|
||||
#define CLASS_NAME_TRACKED DEVELOPMENT
|
||||
|
||||
using Steinberg::Base::Thread::FGuard;
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
DEF_CLASS_IID (IUpdateManager)
|
||||
|
||||
namespace Update {
|
||||
const uint32 kHashSize = (1 << 8); // must be power of 2 (16 bytes * 256 == 4096)
|
||||
const uint32 kMapSize = 1024 * 10;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline uint32 hashPointer (void* p)
|
||||
{
|
||||
return (uint32)((uint64 (p) >> 12) & (kHashSize - 1));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline IPtr<FUnknown> getUnknownBase (FUnknown* unknown)
|
||||
{
|
||||
FUnknown* result = nullptr;
|
||||
if (unknown)
|
||||
{
|
||||
if (unknown->queryInterface (FObject::iid, (void**)&result) != kResultTrue)
|
||||
unknown->queryInterface (FUnknown::iid, (void**)&result);
|
||||
}
|
||||
|
||||
return owned (result);
|
||||
}
|
||||
|
||||
#if CLASS_NAME_TRACKED
|
||||
//------------------------------------------------------------------------
|
||||
struct Dependency
|
||||
{
|
||||
Dependency (FUnknown* o, IDependent* d)
|
||||
: obj (o), dep (d), objClass (nullptr), depClass (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool operator== (const Dependency& d) const { return obj == d.obj; }
|
||||
inline bool operator!= (const Dependency& d) const { return obj != d.obj; }
|
||||
inline bool operator< (const Dependency& d) const { return obj < d.obj; }
|
||||
inline bool operator> (const Dependency& d) const { return obj > d.obj; }
|
||||
FUnknown* obj;
|
||||
IDependent* dep;
|
||||
|
||||
FClassID objClass;
|
||||
FClassID depClass;
|
||||
};
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct DeferedChange
|
||||
{
|
||||
DeferedChange (FUnknown* o, int32 m = 0) : obj (o), msg (m) {}
|
||||
~DeferedChange () {}
|
||||
DeferedChange (const DeferedChange& r) : obj (r.obj), msg (r.msg) {}
|
||||
inline bool operator== (const DeferedChange& d) const { return obj == d.obj; }
|
||||
inline bool operator!= (const DeferedChange& d) const { return obj != d.obj; }
|
||||
FUnknown* obj;
|
||||
int32 msg;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct UpdateData
|
||||
{
|
||||
UpdateData (FUnknown* o, IDependent** d, uint32 c)
|
||||
: obj (o), dependents (d), count (c)
|
||||
{
|
||||
}
|
||||
FUnknown* obj;
|
||||
IDependent** dependents;
|
||||
uint32 count;
|
||||
bool operator== (const UpdateData& d) const
|
||||
{
|
||||
return d.obj == obj && d.dependents == dependents;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
using DeferedChangeList = std::deque<DeferedChange>;
|
||||
using DeferedChangeListIterConst = DeferedChangeList::const_iterator;
|
||||
using DeferedChangeListIter = DeferedChangeList::iterator;
|
||||
|
||||
using UpdateDataList = std::deque<UpdateData>;
|
||||
using UpdateDataListIterConst = UpdateDataList::const_iterator;
|
||||
|
||||
#if CLASS_NAME_TRACKED
|
||||
using DependentList = std::vector<Dependency>;
|
||||
#else
|
||||
typedef std::vector<IDependent*> DependentList;
|
||||
#endif
|
||||
using DependentListIter = DependentList::iterator;
|
||||
using DependentListIterConst = DependentList::const_iterator;
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
using DependentMap = std::unordered_map<const FUnknown*, DependentList>;
|
||||
#else
|
||||
typedef std::map<const FUnknown*, DependentList> DependentMap;
|
||||
#endif
|
||||
using DependentMapIter = DependentMap::iterator;
|
||||
using DependentMapIterConst = DependentMap::const_iterator;
|
||||
|
||||
struct Table
|
||||
{
|
||||
DependentMap depMap[kHashSize];
|
||||
DeferedChangeList defered;
|
||||
UpdateDataList updateData;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void updateDone (FUnknown* unknown, int32 message)
|
||||
{
|
||||
if (message != IDependent::kDestroyed)
|
||||
{
|
||||
FObject* obj = FObject::unknownToObject (unknown);
|
||||
if (obj)
|
||||
obj->updateDone (message);
|
||||
}
|
||||
}
|
||||
} // namespace Update
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static int32 countEntries (Update::DependentMap& map)
|
||||
{
|
||||
int32 total = 0;
|
||||
Update::DependentMapIterConst iterMap = map.begin ();
|
||||
while (iterMap != map.end ())
|
||||
{
|
||||
const Update::DependentList& list = iterMap->second;
|
||||
Update::DependentListIterConst iterList = list.begin ();
|
||||
while (iterList != list.end ())
|
||||
{
|
||||
total++;
|
||||
++iterList;
|
||||
}
|
||||
++iterMap;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
UpdateHandler::UpdateHandler ()
|
||||
{
|
||||
table = NEW Update::Table;
|
||||
if (FObject::getUpdateHandler () == nullptr)
|
||||
FObject::setUpdateHandler (this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
UpdateHandler::~UpdateHandler ()
|
||||
{
|
||||
if (FObject::getUpdateHandler () == this)
|
||||
FObject::setUpdateHandler (nullptr);
|
||||
delete table;
|
||||
table = nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::addDependent (FUnknown* u, IDependent* _dependent)
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
|
||||
if (!unknown || !_dependent)
|
||||
return kResultFalse;
|
||||
|
||||
FGuard guard (lock);
|
||||
|
||||
#if CLASS_NAME_TRACKED
|
||||
Update::Dependency dependent (unknown, _dependent);
|
||||
|
||||
FObject* obj = FObject::unknownToObject (unknown);
|
||||
if (obj)
|
||||
dependent.objClass = obj->isA ();
|
||||
obj = FObject::unknownToObject (_dependent);
|
||||
if (obj)
|
||||
dependent.depClass = obj->isA ();
|
||||
#else
|
||||
IDependent* dependent = _dependent;
|
||||
#endif
|
||||
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIter it = map.find (unknown);
|
||||
if (it == map.end ())
|
||||
{
|
||||
Update::DependentList list;
|
||||
list.push_back (dependent);
|
||||
map[unknown] = list;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*it).second.push_back (dependent);
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* dependent)
|
||||
{
|
||||
size_t eraseCount;
|
||||
return removeDependent (u, dependent, eraseCount);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* dependent, size_t& eraseCount)
|
||||
{
|
||||
eraseCount = 0;
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
|
||||
if (unknown == nullptr && dependent == nullptr)
|
||||
return kResultFalse;
|
||||
|
||||
FGuard guard (lock);
|
||||
|
||||
Update::UpdateDataListIterConst iter = table->updateData.begin ();
|
||||
while (iter != table->updateData.end ())
|
||||
{
|
||||
if ((*iter).obj == unknown || unknown == nullptr)
|
||||
{
|
||||
for (uint32 count = 0; count < (*iter).count; count++)
|
||||
{
|
||||
if ((*iter).dependents[count] == dependent)
|
||||
(*iter).dependents[count] = nullptr;
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
// Remove all objects for the given dependent
|
||||
if (unknown == nullptr)
|
||||
{
|
||||
for (uint32 j = 0; j < Update::kHashSize; j++)
|
||||
{
|
||||
Update::DependentMap& map = table->depMap[j];
|
||||
Update::DependentMapIter iterMap = map.begin ();
|
||||
while (iterMap != map.end ())
|
||||
{
|
||||
Update::DependentList& list = (*iterMap).second;
|
||||
Update::DependentListIter iterList = list.begin ();
|
||||
bool listIsEmpty = false;
|
||||
|
||||
while (iterList != list.end ())
|
||||
{
|
||||
#if CLASS_NAME_TRACKED
|
||||
if ((*iterList).dep == dependent)
|
||||
#else
|
||||
if ((*iterList) == dependent)
|
||||
#endif
|
||||
{
|
||||
eraseCount = list.size ();
|
||||
if (list.size () == 1u)
|
||||
{
|
||||
listIsEmpty = true;
|
||||
break;
|
||||
}
|
||||
iterList = list.erase (iterList);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iterList;
|
||||
}
|
||||
}
|
||||
|
||||
if (listIsEmpty)
|
||||
iterMap = map.erase (iterMap);
|
||||
else
|
||||
++iterMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool mustFlush = true;
|
||||
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIter iterList = map.find (unknown);
|
||||
|
||||
#if NON_EXISTING_DEPENDENCY_CHECK
|
||||
SMTG_ASSERT (iterList != map.end () && "ERROR: Trying to remove a non existing dependency!")
|
||||
#endif
|
||||
if (iterList != map.end ())
|
||||
{
|
||||
if (dependent == nullptr) // Remove all dependents of object
|
||||
{
|
||||
eraseCount = iterList->second.size ();
|
||||
map.erase (iterList);
|
||||
}
|
||||
else // Remove one dependent
|
||||
{
|
||||
Update::DependentList& dependentlist = (*iterList).second;
|
||||
Update::DependentListIter iterDependentlist = dependentlist.begin ();
|
||||
while (iterDependentlist != dependentlist.end ())
|
||||
{
|
||||
#if CLASS_NAME_TRACKED
|
||||
if ((*iterDependentlist).dep == dependent)
|
||||
#else
|
||||
if ((*iterDependentlist) == dependent)
|
||||
#endif
|
||||
{
|
||||
iterDependentlist = dependentlist.erase (iterDependentlist);
|
||||
eraseCount++;
|
||||
if (dependentlist.empty ())
|
||||
{
|
||||
map.erase (iterList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++iterDependentlist;
|
||||
mustFlush = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustFlush)
|
||||
cancelUpdates (unknown);
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult UpdateHandler::doTriggerUpdates (FUnknown* u, int32 message, bool suppressUpdateDone)
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
|
||||
if (!unknown)
|
||||
return kResultFalse;
|
||||
|
||||
// to avoid crashes due to stack overflow, we reduce the amount of memory reserved for the
|
||||
// dependents
|
||||
IDependent* smallDependents[Update::kMapSize / 10]; // 8kB for x64
|
||||
IDependent** dependents = smallDependents;
|
||||
int32 maxDependents = Update::kMapSize / 10;
|
||||
int32 count = 0;
|
||||
|
||||
{
|
||||
FGuard guard (lock); // scope for lock
|
||||
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIterConst iterList = map.find (unknown);
|
||||
if (iterList != map.end ())
|
||||
{
|
||||
const Update::DependentList& dependentlist = (*iterList).second;
|
||||
Update::DependentListIterConst iterDependentlist = dependentlist.begin ();
|
||||
while (iterDependentlist != dependentlist.end ())
|
||||
{
|
||||
#if CLASS_NAME_TRACKED
|
||||
dependents[count] = (*iterDependentlist).dep;
|
||||
#else
|
||||
dependents[count] = *iterDependentlist;
|
||||
#endif
|
||||
count++;
|
||||
|
||||
if (count >= maxDependents)
|
||||
{
|
||||
if (dependents == smallDependents)
|
||||
{
|
||||
dependents = NEW IDependent*[Update::kMapSize];
|
||||
memcpy (dependents, smallDependents, count * sizeof (dependents[0]));
|
||||
maxDependents = Update::kMapSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
SMTG_WARNING ("Dependency overflow")
|
||||
break;
|
||||
}
|
||||
}
|
||||
++iterDependentlist;
|
||||
}
|
||||
}
|
||||
|
||||
// push update data on the stack
|
||||
if (count > 0)
|
||||
{
|
||||
Update::UpdateData data (unknown, dependents, count);
|
||||
table->updateData.push_back (data);
|
||||
}
|
||||
} // end scope
|
||||
|
||||
int32 i = 0;
|
||||
while (i < count)
|
||||
{
|
||||
if (dependents[i])
|
||||
dependents[i]->update (unknown, message);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (dependents != smallDependents)
|
||||
delete[] dependents;
|
||||
|
||||
// remove update data from the stack
|
||||
if (count > 0)
|
||||
{
|
||||
FGuard guard (lock);
|
||||
|
||||
table->updateData.pop_back ();
|
||||
}
|
||||
|
||||
// send update done message
|
||||
if (suppressUpdateDone == false)
|
||||
Update::updateDone (unknown, message);
|
||||
|
||||
return count > 0 ? kResultTrue : kResultFalse; // Object was found and has been updated
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::triggerUpdates (FUnknown* u, int32 message)
|
||||
{
|
||||
return doTriggerUpdates (u, message, false);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::deferUpdates (FUnknown* u, int32 message)
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
|
||||
if (!unknown)
|
||||
return kResultFalse;
|
||||
|
||||
FGuard guard (lock);
|
||||
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIterConst iterList = map.find (unknown);
|
||||
|
||||
bool hasDependency = (iterList != map.end ());
|
||||
if (hasDependency == false)
|
||||
{
|
||||
Update::updateDone (unknown, message);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
Update::DeferedChangeListIterConst iter = table->defered.begin ();
|
||||
while (iter != table->defered.end ())
|
||||
{
|
||||
if ((*iter).obj == unknown && (*iter).msg == message)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
Update::DeferedChange change (unknown, message);
|
||||
table->defered.push_back (change);
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::triggerDeferedUpdates (FUnknown* unknown)
|
||||
{
|
||||
Update::DeferedChangeList deferedAgain;
|
||||
if (!unknown)
|
||||
{
|
||||
while (table->defered.empty () == false)
|
||||
{
|
||||
// Remove first from queue
|
||||
lock.lock ();
|
||||
|
||||
FUnknown* obj = table->defered.front ().obj;
|
||||
int32 msg = table->defered.front ().msg;
|
||||
table->defered.pop_front ();
|
||||
|
||||
// check if this object is currently being updated. in this case, defer update again...
|
||||
bool canSignal = true;
|
||||
Update::UpdateDataListIterConst iter = table->updateData.begin ();
|
||||
while (iter != table->updateData.end ())
|
||||
{
|
||||
if ((*iter).obj == obj)
|
||||
{
|
||||
canSignal = false;
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
lock.unlock ();
|
||||
|
||||
if (canSignal)
|
||||
{
|
||||
triggerUpdates (obj, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
Update::DeferedChange change (obj, msg);
|
||||
deferedAgain.push_back (change);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPtr<FUnknown> object = Update::getUnknownBase (unknown);
|
||||
Update::DeferedChange tmp (object);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock.lock ();
|
||||
Update::DeferedChangeListIter it =
|
||||
std::find (table->defered.begin (), table->defered.end (), tmp);
|
||||
if (it == table->defered.end ())
|
||||
{
|
||||
lock.unlock ();
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
if ((*it).obj != nullptr)
|
||||
{
|
||||
int32 msg = (*it).msg;
|
||||
table->defered.erase (it);
|
||||
|
||||
// check if this object is currently being updated. in this case, defer update
|
||||
// again...
|
||||
bool canSignal = true;
|
||||
Update::UpdateDataListIterConst iter = table->updateData.begin ();
|
||||
while (iter != table->updateData.end ())
|
||||
{
|
||||
if ((*iter).obj == object)
|
||||
{
|
||||
canSignal = false;
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
lock.unlock ();
|
||||
|
||||
if (canSignal)
|
||||
{
|
||||
triggerUpdates (object, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
Update::DeferedChange change (object, msg);
|
||||
deferedAgain.push_back (change);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deferedAgain.empty () == false)
|
||||
{
|
||||
FGuard guard (lock);
|
||||
|
||||
Update::DeferedChangeListIterConst iter = deferedAgain.begin ();
|
||||
while (iter != deferedAgain.end ())
|
||||
{
|
||||
table->defered.push_back (*iter);
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API UpdateHandler::cancelUpdates (FUnknown* u)
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
|
||||
if (!unknown)
|
||||
return kResultFalse;
|
||||
|
||||
FGuard guard (lock);
|
||||
|
||||
Update::DeferedChange change (unknown, 0);
|
||||
while (true)
|
||||
{
|
||||
auto iter = std::find (table->defered.begin (), table->defered.end (), change);
|
||||
if (iter != table->defered.end ())
|
||||
table->defered.erase (iter);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
size_t UpdateHandler::countDependencies (FUnknown* object)
|
||||
{
|
||||
FGuard guard (lock);
|
||||
uint32 res = 0;
|
||||
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (object);
|
||||
if (unknown)
|
||||
{
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIter iterList = map.find (unknown);
|
||||
if (iterList != map.end ())
|
||||
return iterList->second.size ();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32 j = 0; j < Update::kHashSize; j++)
|
||||
{
|
||||
Update::DependentMap& map = table->depMap[j];
|
||||
res += countEntries (map);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#if DEVELOPMENT
|
||||
//------------------------------------------------------------------------
|
||||
bool UpdateHandler::checkDeferred (FUnknown* object)
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (object);
|
||||
|
||||
FGuard guard (lock);
|
||||
|
||||
Update::DeferedChange tmp (unknown);
|
||||
Update::DeferedChangeListIterConst it =
|
||||
std::find (table->defered.begin (), table->defered.end (), tmp);
|
||||
if (it != table->defered.end ())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UpdateHandler::hasDependencies (FUnknown* u)
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u);
|
||||
if (!unknown)
|
||||
return false;
|
||||
|
||||
FGuard guard (lock);
|
||||
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIterConst iterList = map.find (unknown);
|
||||
bool hasDependency = (iterList != map.end ());
|
||||
|
||||
return hasDependency;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void UpdateHandler::printForObject (FObject* obj) const
|
||||
{
|
||||
IPtr<FUnknown> unknown = Update::getUnknownBase (obj);
|
||||
if (!unknown)
|
||||
return;
|
||||
|
||||
FUnknownPtr<IDependent> dep (obj);
|
||||
|
||||
bool header = false;
|
||||
|
||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
|
||||
Update::DependentMapIterConst iterList = map.begin ();
|
||||
while (iterList != map.end ())
|
||||
{
|
||||
const Update::DependentList& dependentlist = (*iterList).second;
|
||||
Update::DependentListIterConst iterDependentlist = dependentlist.begin ();
|
||||
while (iterDependentlist != dependentlist.end ())
|
||||
{
|
||||
#if CLASS_NAME_TRACKED
|
||||
if ((*iterList).first == unknown || (*iterDependentlist).dep == dep.getInterface ())
|
||||
{
|
||||
if (!header)
|
||||
{
|
||||
FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj,
|
||||
obj->isA ());
|
||||
header = true;
|
||||
}
|
||||
FDebugPrint ("%s %8" FORMAT_INT64A "\n <- %s %8" FORMAT_INT64A "\n",
|
||||
(*iterDependentlist).depClass, (uint64) (*iterDependentlist).dep,
|
||||
(*iterDependentlist).objClass, (uint64) ((*iterList).first));
|
||||
}
|
||||
#else
|
||||
if ((*iterList).first == unknown || (*iterDependentlist) == dep.getInterface ())
|
||||
{
|
||||
if (!header)
|
||||
{
|
||||
FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj,
|
||||
obj->isA ());
|
||||
header = true;
|
||||
}
|
||||
FDebugPrint ("%8" FORMAT_INT64A "\n <- %8" FORMAT_INT64A "\n",
|
||||
(uint64) (*iterDependentlist), (uint64) ((*iterList).first));
|
||||
}
|
||||
#endif
|
||||
++iterDependentlist;
|
||||
}
|
||||
|
||||
++iterList;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/source/updatehandler.h
|
||||
// Created by : Steinberg, 2008
|
||||
// Description :
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/source/fobject.h"
|
||||
#include "base/thread/include/flock.h"
|
||||
#include "pluginterfaces/base/iupdatehandler.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
/// @cond ignore
|
||||
namespace Update { struct Table; }
|
||||
/// @endcond
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Handle Send and Cancel pending message for a given object*/
|
||||
//------------------------------------------------------------------------
|
||||
class IUpdateManager : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** cancel pending messages send by \param object or by any if object is 0 */
|
||||
virtual tresult PLUGIN_API cancelUpdates (FUnknown* object) = 0;
|
||||
/** send pending messages send by \param object or by any if object is 0 */
|
||||
virtual tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = nullptr) = 0;
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IUpdateManager, 0x030B780C, 0xD6E6418D, 0x8CE00BC2, 0x09C834D4)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
UpdateHandler implements IUpdateManager and IUpdateHandler to handle dependencies
|
||||
between objects to store and forward messages to dependent objects.
|
||||
|
||||
This implementation is thread save, so objects can send message, add or remove
|
||||
dependents from different threads.
|
||||
Do do so it uses mutex, so be aware of locking.
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
class UpdateHandler : public FObject, public IUpdateHandler, public IUpdateManager
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
UpdateHandler ();
|
||||
~UpdateHandler () SMTG_OVERRIDE;
|
||||
|
||||
using FObject::addDependent;
|
||||
using FObject::removeDependent;
|
||||
using FObject::deferUpdate;
|
||||
|
||||
// IUpdateHandler
|
||||
//private:
|
||||
friend class FObject;
|
||||
/** register \param dependent to get messages from \param object */
|
||||
tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) SMTG_OVERRIDE;
|
||||
/** unregister \param dependent to get no messages from \param object */
|
||||
tresult PLUGIN_API removeDependent (FUnknown* object, IDependent* dependent, size_t& earseCount);
|
||||
tresult PLUGIN_API removeDependent (FUnknown* object,
|
||||
IDependent* dependent) SMTG_OVERRIDE;
|
||||
public:
|
||||
/** send \param message to all dependents of \param object immediately */
|
||||
tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE;
|
||||
/** send \param message to all dependents of \param object when idle */
|
||||
tresult PLUGIN_API deferUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE;
|
||||
|
||||
// IUpdateManager
|
||||
/** cancel pending messages send by \param object or by any if object is 0 */
|
||||
tresult PLUGIN_API cancelUpdates (FUnknown* object) SMTG_OVERRIDE;
|
||||
/** send pending messages send by \param object or by any if object is 0 */
|
||||
tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = nullptr) SMTG_OVERRIDE;
|
||||
|
||||
/// @cond ignore
|
||||
// obsolete functions kept for compatibility
|
||||
void checkUpdates (FObject* object = nullptr)
|
||||
{
|
||||
triggerDeferedUpdates (object ? object->unknownCast () : nullptr);
|
||||
}
|
||||
void flushUpdates (FObject* object)
|
||||
{
|
||||
if (object)
|
||||
cancelUpdates (object->unknownCast ());
|
||||
}
|
||||
void deferUpdate (FObject* object, int32 message)
|
||||
{
|
||||
if (object)
|
||||
deferUpdates (object->unknownCast (), message);
|
||||
}
|
||||
void signalChange (FObject* object, int32 message, bool suppressUpdateDone = false)
|
||||
{
|
||||
if (object)
|
||||
doTriggerUpdates (object->unknownCast (), message, suppressUpdateDone);
|
||||
}
|
||||
#if DEVELOPMENT
|
||||
bool checkDeferred (FUnknown* object);
|
||||
bool hasDependencies (FUnknown* object);
|
||||
void printForObject (FObject* object) const;
|
||||
#endif
|
||||
/// @endcond
|
||||
size_t countDependencies (FUnknown* object = nullptr);
|
||||
|
||||
OBJ_METHODS (UpdateHandler, FObject)
|
||||
FUNKNOWN_METHODS2 (IUpdateHandler, IUpdateManager, FObject)
|
||||
SINGLETON (UpdateHandler)
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
tresult doTriggerUpdates (FUnknown* object, int32 message, bool suppressUpdateDone);
|
||||
|
||||
Steinberg::Base::Thread::FLock lock;
|
||||
Update::Table* table = nullptr;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/thread/include/flock.h
|
||||
// Created by : Steinberg, 1995
|
||||
// Description : locks
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
/** @file base/thread/include/flock.h
|
||||
Locks. */
|
||||
/** @defgroup baseLocks Locks */
|
||||
//----------------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "base/source/fobject.h"
|
||||
#include "pluginterfaces/base/ftypes.h"
|
||||
|
||||
#if SMTG_PTHREADS
|
||||
#include <pthread.h>
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
struct CRITSECT // CRITICAL_SECTION
|
||||
{
|
||||
void* DebugInfo; // PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
|
||||
Steinberg::int32 LockCount; // LONG LockCount;
|
||||
Steinberg::int32 RecursionCount; // LONG RecursionCount;
|
||||
void* OwningThread; // HANDLE OwningThread
|
||||
void* LockSemaphore; // HANDLE LockSemaphore
|
||||
Steinberg::int32 SpinCount; // ULONG_PTR SpinCount
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Base {
|
||||
namespace Thread {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Lock interface declaration.
|
||||
@ingroup baseLocks */
|
||||
//------------------------------------------------------------------------
|
||||
struct ILock
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
virtual ~ILock () {}
|
||||
|
||||
/** Enables lock. */
|
||||
virtual void lock () = 0;
|
||||
|
||||
/** Disables lock. */
|
||||
virtual void unlock () = 0;
|
||||
|
||||
/** Tries to disable lock. */
|
||||
virtual bool trylock () = 0;
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** FLock declaration.
|
||||
@ingroup baseLocks */
|
||||
//------------------------------------------------------------------------
|
||||
class FLock : public ILock
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/** Lock constructor.
|
||||
* @param name lock name
|
||||
*/
|
||||
FLock (const char8* name = "FLock");
|
||||
|
||||
/** Lock destructor. */
|
||||
~FLock () SMTG_OVERRIDE;
|
||||
|
||||
//-- ILock -----------------------------------------------------------
|
||||
void lock () SMTG_OVERRIDE;
|
||||
void unlock () SMTG_OVERRIDE;
|
||||
bool trylock () SMTG_OVERRIDE;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
#if SMTG_PTHREADS
|
||||
pthread_mutex_t mutex; ///< Mutex object
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
CRITSECT section; ///< Critical section object
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** FLockObj declaration. Reference counted lock
|
||||
@ingroup baseLocks */
|
||||
//------------------------------------------------------------------------
|
||||
class FLockObject : public FObject, public FLock
|
||||
{
|
||||
public:
|
||||
OBJ_METHODS (FLockObject, FObject)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** FGuard - automatic object for locks.
|
||||
@ingroup baseLocks */
|
||||
//------------------------------------------------------------------------
|
||||
class FGuard
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/** FGuard constructor.
|
||||
* @param _lock guard this lock
|
||||
*/
|
||||
FGuard (ILock& _lock) : lock (_lock) { lock.lock (); }
|
||||
|
||||
/** FGuard destructor. */
|
||||
~FGuard () { lock.unlock (); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
ILock& lock; ///< guarded lock
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Conditional Guard - Locks only if valid lock is passed.
|
||||
@ingroup baseLocks */
|
||||
//------------------------------------------------------------------------
|
||||
class FConditionalGuard
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/** FConditionGuard constructor.
|
||||
* @param _lock guard this lock
|
||||
*/
|
||||
FConditionalGuard (FLock* _lock) : lock (_lock)
|
||||
{
|
||||
if (lock)
|
||||
lock->lock ();
|
||||
}
|
||||
|
||||
/** FConditionGuard destructor. */
|
||||
~FConditionalGuard ()
|
||||
{
|
||||
if (lock)
|
||||
lock->unlock ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
FLock* lock; ///< guarded lock
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Thread
|
||||
} // namespace Base
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : SDK Base
|
||||
// Version : 1.0
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : base/thread/source/flock.cpp
|
||||
// Created by : Steinberg, 1995
|
||||
// Description : Locks
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define DEBUG_LOCK 0
|
||||
|
||||
#include "base/thread/include/flock.h"
|
||||
#include "base/source/fdebug.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if SMTG_OS_WINDOWS
|
||||
//------------------------------------------------------------------------
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0500
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT WINVER
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#define INIT_CS(cs) \
|
||||
InitializeCriticalSection ((LPCRITICAL_SECTION)&cs);
|
||||
|
||||
#endif // SMTG_OS_WINDOWS
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Base {
|
||||
namespace Thread {
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FLock implementation
|
||||
//------------------------------------------------------------------------
|
||||
FLock::FLock (const char8* /*name*/)
|
||||
{
|
||||
#if SMTG_PTHREADS
|
||||
pthread_mutexattr_t mutexAttr;
|
||||
pthread_mutexattr_init (&mutexAttr);
|
||||
pthread_mutexattr_settype (&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||
if (pthread_mutex_init (&mutex, &mutexAttr) != 0)
|
||||
{SMTG_WARNING("mutex_init failed")}
|
||||
pthread_mutexattr_destroy (&mutexAttr);
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
INIT_CS (section)
|
||||
#else
|
||||
#warning implement FLock!
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FLock::~FLock ()
|
||||
{
|
||||
#if SMTG_PTHREADS
|
||||
pthread_mutex_destroy (&mutex);
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
DeleteCriticalSection ((LPCRITICAL_SECTION)§ion);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FLock::lock ()
|
||||
{
|
||||
#if DEBUG_LOCK
|
||||
FDebugPrint ("FLock::lock () %x\n", this);
|
||||
#endif
|
||||
|
||||
#if SMTG_PTHREADS
|
||||
pthread_mutex_lock (&mutex);
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
EnterCriticalSection ((LPCRITICAL_SECTION)§ion);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FLock::unlock ()
|
||||
{
|
||||
#if DEBUG_LOCK
|
||||
FDebugPrint ("FLock::unlock () %x\n", this);
|
||||
#endif
|
||||
|
||||
#if SMTG_PTHREADS
|
||||
pthread_mutex_unlock (&mutex);
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
LeaveCriticalSection ((LPCRITICAL_SECTION)§ion);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FLock::trylock ()
|
||||
{
|
||||
#if SMTG_PTHREADS
|
||||
return pthread_mutex_trylock (&mutex) == 0;
|
||||
|
||||
#elif SMTG_OS_WINDOWS
|
||||
return TryEnterCriticalSection ((LPCRITICAL_SECTION)§ion) != 0 ? true : false;
|
||||
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Thread
|
||||
} // namespace Base
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
This license applies only to files referencing this license,
|
||||
for other files of the Software Development Kit the respective embedded license text
|
||||
is applicable. The license can be found at: www.steinberg.net/sdklicenses_vst3
|
||||
|
||||
This Software Development Kit is licensed under the terms of the Steinberg VST3 License,
|
||||
or alternatively under the terms of the General Public License (GPL) Version 3.
|
||||
You may use the Software Development Kit according to either of these licenses as it is
|
||||
most appropriate for your project on a case-by-case basis (commercial or not).
|
||||
|
||||
a) Proprietary Steinberg VST3 License
|
||||
The Software Development Kit may not be distributed in parts or its entirety
|
||||
without prior written agreement by Steinberg Media Technologies GmbH.
|
||||
The SDK must not be used to re-engineer or manipulate any technology used
|
||||
in any Steinberg or Third-party application or software module,
|
||||
unless permitted by law.
|
||||
Neither the name of the Steinberg Media Technologies GmbH nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
Before publishing a software under the proprietary license, you need to obtain a copy
|
||||
of the License Agreement signed by Steinberg Media Technologies GmbH.
|
||||
The Steinberg VST SDK License Agreement can be found at:
|
||||
www.steinberg.net/en/company/developers.html
|
||||
|
||||
THE SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
b) General Public License (GPL) Version 3
|
||||
Details of these licenses can be found at: www.gnu.org/licenses/gpl-3.0.html
|
||||
Please refer to the Steinberg VST usage guidelines for the use of VST, VST logo and VST
|
||||
compatible logos:
|
||||
https://steinbergmedia.github.io/vst3_dev_portal/pages/VST+3+Licensing/Usage+guidelines.html
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
# Welcome to VST 3 SDK Interfaces
|
||||
|
||||
Here are located all **VST 3** interfaces definitions (including VST Component/Controller, UI, Test).
|
||||
|
||||
## License & Usage guidelines
|
||||
|
||||
More details are found at [www.steinberg.net/sdklicenses_vst3](http://www.steinberg.net/sdklicenses_vst3)
|
||||
|
||||
----
|
||||
Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk)
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/conststringtable.cpp
|
||||
// Created by : Steinberg, 09/2007
|
||||
// Description : constant unicode string table
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "conststringtable.h"
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
static std::map<const char8*, char16*>* stringMap;
|
||||
static std::map<const char8, char16>* charMap;
|
||||
|
||||
static char16* generateUTF16 (const char8* str);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ConstStringTable* ConstStringTable::instance ()
|
||||
{
|
||||
static ConstStringTable stringTable;
|
||||
return &stringTable;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char16* ConstStringTable::getString (const char8* str) const
|
||||
{
|
||||
std::map<const char8*, char16*>::iterator iter = stringMap->find (str);
|
||||
if (iter != stringMap->end ())
|
||||
return iter->second;
|
||||
char16* uStr = generateUTF16 (str);
|
||||
stringMap->insert (std::make_pair (str, uStr));
|
||||
return uStr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
char16 ConstStringTable::getString (const char8 str) const
|
||||
{
|
||||
std::map<const char8, char16>::iterator iter = charMap->find (str);
|
||||
if (iter != charMap->end ())
|
||||
return iter->second;
|
||||
char16 uStr = 0;
|
||||
#if BYTEORDER == kBigEndian
|
||||
char8* puStr = (char8*)&uStr;
|
||||
puStr[1] = str;
|
||||
#else
|
||||
uStr = str;
|
||||
#endif
|
||||
charMap->insert (std::make_pair (str, uStr));
|
||||
return uStr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ConstStringTable::ConstStringTable ()
|
||||
{
|
||||
stringMap = new std::map<const char8*, char16*>;
|
||||
charMap = new std::map<const char8, char16>;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ConstStringTable::~ConstStringTable ()
|
||||
{
|
||||
// free out allocated strings
|
||||
{
|
||||
std::map<const char8*, char16*>::iterator iter = stringMap->begin ();
|
||||
while (iter != stringMap->end ())
|
||||
{
|
||||
delete[] iter->second;
|
||||
iter++;
|
||||
}
|
||||
} // delete iterator on map before deleting the map
|
||||
|
||||
delete stringMap;
|
||||
delete charMap;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
char16* generateUTF16 (const char8* str)
|
||||
{
|
||||
int32 len = (int32)strlen (str);
|
||||
char16* result = new char16[len + 1];
|
||||
for (int32 i = 0; i < len; i++)
|
||||
{
|
||||
#if BYTEORDER == kBigEndian
|
||||
char8* pChr = (char8*)&result[i];
|
||||
pChr[0] = 0;
|
||||
pChr[1] = str[i];
|
||||
#else
|
||||
result[i] = str[i];
|
||||
#endif
|
||||
}
|
||||
result[len] = 0;
|
||||
return result;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/conststringtable.h
|
||||
// Created by : Steinberg, 09/2007
|
||||
// Description : constant unicode string table
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "ftypes.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Constant unicode string table.
|
||||
Used for conversion from ASCII string literals to char16.
|
||||
*/
|
||||
class ConstStringTable
|
||||
{
|
||||
public:
|
||||
static ConstStringTable* instance ();
|
||||
|
||||
/** Returns a char16 string of a ASCII string literal*/
|
||||
const char16* getString (const char8* str) const;
|
||||
/** Returns a char16 character of a ASCII character */
|
||||
char16 getString (const char8 str) const;
|
||||
|
||||
protected:
|
||||
ConstStringTable ();
|
||||
~ConstStringTable ();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interface IID definitions
|
||||
// Filename : pluginterfaces/base/coreiids.cpp
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic Interface
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
// 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.
|
||||
// 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.
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
#include "pluginterfaces/base/icloneable.h"
|
||||
#include "pluginterfaces/base/ipluginbase.h"
|
||||
#include "pluginterfaces/base/iupdatehandler.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
DEF_CLASS_IID (IPluginBase)
|
||||
DEF_CLASS_IID (IPluginFactory)
|
||||
DEF_CLASS_IID (IPluginFactory2)
|
||||
DEF_CLASS_IID (IPluginFactory3)
|
||||
|
||||
DEF_CLASS_IID (FUnknown)
|
||||
|
||||
DEF_CLASS_IID (ICloneable)
|
||||
|
||||
DEF_CLASS_IID (IDependent)
|
||||
DEF_CLASS_IID (IUpdateHandler)
|
||||
|
||||
DEF_CLASS_IID (IBStream)
|
||||
DEF_CLASS_IID (ISizeableStream)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/falignpop.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Restore alignment settings
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
#if SMTG_OS_MACOS
|
||||
#pragma pack(pop)
|
||||
#elif defined __BORLANDC__
|
||||
#pragma -a-
|
||||
#elif SMTG_OS_WINDOWS
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/falignpush.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Set alignment settings
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
#if SMTG_OS_MACOS
|
||||
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
|
||||
#pragma GCC diagnostic ignored "-Wpragma-pack"
|
||||
#if SMTG_PLATFORM_64
|
||||
#pragma pack(push, 16)
|
||||
#else
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
#elif defined __BORLANDC__
|
||||
#pragma -a8
|
||||
#elif SMTG_OS_WINDOWS
|
||||
//! @brief warning C4103: alignment changed after including header, may be due to missing #pragma pack(pop)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4103)
|
||||
#endif
|
||||
#pragma pack(push)
|
||||
#if SMTG_PLATFORM_64
|
||||
#pragma pack(16)
|
||||
#else
|
||||
#pragma pack(8)
|
||||
#endif
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
|
@ -1,328 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/fplatform.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Detect platform and set define
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
// values for BYTEORDER according to the used platform
|
||||
#define kLittleEndian 0
|
||||
#define kBigEndian 1
|
||||
|
||||
#undef PLUGIN_API
|
||||
|
||||
#if !defined (__INTEL_CXX11_MODE__)
|
||||
#define SMTG_INTEL_CXX11_MODE 0
|
||||
#else
|
||||
#define SMTG_INTEL_CXX11_MODE __INTEL_CXX11_MODE__
|
||||
#endif
|
||||
|
||||
#if !defined (__INTEL_COMPILER)
|
||||
#define SMTG_INTEL_COMPILER 0
|
||||
#else
|
||||
#define SMTG_INTEL_COMPILER __INTEL_COMPILER
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// WIN32 AND WIN64 (WINDOWS)
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined (_WIN32)
|
||||
//-----------------------------------------------------------------------------
|
||||
#define SMTG_OS_LINUX 0
|
||||
#define SMTG_OS_MACOS 0
|
||||
#define SMTG_OS_WINDOWS 1
|
||||
#define SMTG_OS_IOS 0
|
||||
#define SMTG_OS_OSX 0
|
||||
|
||||
#if defined(_M_IX86)
|
||||
#define SMTG_CPU_X86 1
|
||||
#else
|
||||
#define SMTG_CPU_X86 0
|
||||
#endif
|
||||
#if defined(_M_AMD64)
|
||||
#define SMTG_CPU_X86_64 1
|
||||
#else
|
||||
#define SMTG_CPU_X86_64 0
|
||||
#endif
|
||||
#if defined(_M_ARM)
|
||||
#define SMTG_CPU_ARM 1
|
||||
#else
|
||||
#define SMTG_CPU_ARM 0
|
||||
#endif
|
||||
#if defined(_M_ARM64)
|
||||
#define SMTG_CPU_ARM_64 1
|
||||
#else
|
||||
#define SMTG_CPU_ARM_64 0
|
||||
#endif
|
||||
#if defined(_M_ARM64EC)
|
||||
#define SMTG_CPU_ARM_64EC 1
|
||||
#else
|
||||
#define SMTG_CPU_ARM_64EC 0
|
||||
#endif
|
||||
|
||||
#define SMTG_OS_WINDOWS_ARM (SMTG_CPU_ARM_64EC || SMTG_CPU_ARM_64 || SMTG_CPU_ARM)
|
||||
|
||||
#define BYTEORDER kLittleEndian
|
||||
|
||||
#define COM_COMPATIBLE 1
|
||||
#define PLUGIN_API __stdcall
|
||||
#define SMTG_PTHREADS 0
|
||||
|
||||
#define SMTG_EXPORT_SYMBOL __declspec (dllexport)
|
||||
#define SMTG_HIDDEN_SYMBOL
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4244) //! @brief warning C4244: Conversion from 'type1' to 'type2', possible loss of data.
|
||||
#pragma warning (disable : 4250) //! @brief warning C4250: Inheritance via dominance is allowed
|
||||
|
||||
#pragma warning (3 : 4189) //! @brief warning C4189: local variable is initialized but not referenced
|
||||
#pragma warning (3 : 4238) //! @brief warning C4238: nonstandard extension used : class rvalue used as lvalue
|
||||
#endif
|
||||
|
||||
#if defined (_WIN64) || defined (_M_ARM64)
|
||||
#define SMTG_PLATFORM_64 1
|
||||
#else
|
||||
#define SMTG_PLATFORM_64 0
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#define WIN32 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define SMTG_CPP11 (__cplusplus >= 201103L || _MSC_VER > 1600 || SMTG_INTEL_CXX11_MODE)
|
||||
#define SMTG_CPP11_STDLIBSUPPORT SMTG_CPP11
|
||||
#define SMTG_CPP14 (__cplusplus >= 201402L || ((_MSC_FULL_VER >= 190024210L) && (_MSVC_LANG >= 201402L)))
|
||||
#define SMTG_CPP17 (__cplusplus >= 201703L || ((_MSC_FULL_VER >= 190024210L) && (_MSVC_LANG >= 201703L)))
|
||||
#define SMTG_CPP20 (__cplusplus >= 202002L)
|
||||
#define SMTG_HAS_NOEXCEPT ((_MSC_FULL_VER >= 190023026L) || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER >= 1300))
|
||||
#if ((_MSC_FULL_VER >= 190024210L) || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER >= 1500) || (defined(__MINGW32__) && SMTG_CPP11))
|
||||
#define SMTG_HAS_CPP11_CONSTEXPR 1
|
||||
#else
|
||||
#define SMTG_HAS_CPP11_CONSTEXPR 0
|
||||
#endif
|
||||
#if (((_MSC_VER >= 1915L) && (_MSVC_LANG >= 201402L)) || (SMTG_INTEL_CXX11_MODE && SMTG_INTEL_COMPILER > 1700) || (defined(__MINGW32__) && SMTG_CPP14))
|
||||
#define SMTG_HAS_CPP14_CONSTEXPR 1
|
||||
#else
|
||||
#define SMTG_HAS_CPP14_CONSTEXPR 0
|
||||
#endif
|
||||
#endif //__cplusplus
|
||||
|
||||
#define SMTG_DEPRECATED_ATTRIBUTE(message) __declspec (deprecated ("Is Deprecated: " message))
|
||||
//-----------------------------------------------------------------------------
|
||||
// LINUX
|
||||
//-----------------------------------------------------------------------------
|
||||
#elif __gnu_linux__ || __linux__
|
||||
#define SMTG_OS_LINUX 1
|
||||
#define SMTG_OS_MACOS 0
|
||||
#define SMTG_OS_WINDOWS 0
|
||||
#define SMTG_OS_WINDOWS_ARM 0
|
||||
#define SMTG_OS_IOS 0
|
||||
#define SMTG_OS_OSX 0
|
||||
|
||||
#define SMTG_CPU_X86 __i386__
|
||||
#define SMTG_CPU_X86_64 __x86_64__
|
||||
#if defined(__arm__)
|
||||
#define SMTG_CPU_ARM __arm__
|
||||
#else
|
||||
#define SMTG_CPU_ARM 0
|
||||
#endif
|
||||
#if defined(__aarch64__)
|
||||
#define SMTG_CPU_ARM_64 __aarch64__
|
||||
#else
|
||||
#define SMTG_CPU_ARM_64 0
|
||||
#endif
|
||||
#define SMTG_CPU_ARM_64EC 0
|
||||
|
||||
#include <endian.h>
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define BYTEORDER kLittleEndian
|
||||
#else
|
||||
#define BYTEORDER kBigEndian
|
||||
#endif
|
||||
|
||||
#define COM_COMPATIBLE 0
|
||||
#define PLUGIN_API
|
||||
#define SMTG_PTHREADS 1
|
||||
|
||||
#define SMTG_EXPORT_SYMBOL __attribute__ ((visibility ("default")))
|
||||
#define SMTG_HIDDEN_SYMBOL __attribute__ ((visibility ("hidden")))
|
||||
|
||||
#if __LP64__
|
||||
#define SMTG_PLATFORM_64 1
|
||||
#else
|
||||
#define SMTG_PLATFORM_64 0
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#define SMTG_CPP11 (__cplusplus >= 201103L)
|
||||
#ifndef SMTG_CPP11
|
||||
#error unsupported compiler
|
||||
#endif
|
||||
#define SMTG_CPP14 (__cplusplus >= 201402L)
|
||||
#define SMTG_CPP17 (__cplusplus >= 201703L)
|
||||
#define SMTG_CPP20 (__cplusplus >= 202002L)
|
||||
#if defined(__GNUG__) && __GNUG__ < 8
|
||||
#define SMTG_CPP11_STDLIBSUPPORT 0
|
||||
#else
|
||||
#define SMTG_CPP11_STDLIBSUPPORT 1
|
||||
#endif
|
||||
#define SMTG_HAS_NOEXCEPT 1
|
||||
#define SMTG_HAS_CPP11_CONSTEXPR SMTG_CPP11
|
||||
#define SMTG_HAS_CPP14_CONSTEXPR SMTG_CPP14
|
||||
#endif // __cplusplus
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mac and iOS
|
||||
//-----------------------------------------------------------------------------
|
||||
#elif __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#define SMTG_OS_LINUX 0
|
||||
#define SMTG_OS_MACOS 1
|
||||
#define SMTG_OS_WINDOWS 0
|
||||
#define SMTG_OS_WINDOWS_ARM 0
|
||||
#define SMTG_OS_IOS TARGET_OS_IPHONE
|
||||
#define SMTG_OS_OSX TARGET_OS_MAC && !TARGET_OS_IPHONE
|
||||
|
||||
#define SMTG_CPU_X86 TARGET_CPU_X86
|
||||
#define SMTG_CPU_X86_64 TARGET_CPU_X86_64
|
||||
#define SMTG_CPU_ARM TARGET_CPU_ARM
|
||||
#define SMTG_CPU_ARM_64 TARGET_CPU_ARM64
|
||||
#define SMTG_CPU_ARM_64EC 0
|
||||
|
||||
#if !SMTG_OS_IOS
|
||||
#ifndef __CF_USE_FRAMEWORK_INCLUDES__
|
||||
#define __CF_USE_FRAMEWORK_INCLUDES__
|
||||
#endif
|
||||
#ifndef TARGET_API_MAC_CARBON
|
||||
#define TARGET_API_MAC_CARBON 1
|
||||
#endif
|
||||
#endif
|
||||
#if __LP64__
|
||||
#define SMTG_PLATFORM_64 1
|
||||
#else
|
||||
#define SMTG_PLATFORM_64 0
|
||||
#endif
|
||||
#if defined (__BIG_ENDIAN__)
|
||||
#define BYTEORDER kBigEndian
|
||||
#else
|
||||
#define BYTEORDER kLittleEndian
|
||||
#endif
|
||||
|
||||
#define COM_COMPATIBLE 0
|
||||
#define PLUGIN_API
|
||||
#define SMTG_PTHREADS 1
|
||||
|
||||
#define SMTG_EXPORT_SYMBOL __attribute__ ((visibility ("default")))
|
||||
#define SMTG_HIDDEN_SYMBOL __attribute__ ((visibility ("hidden")))
|
||||
|
||||
#if !defined(__PLIST__) && !defined(SMTG_DISABLE_DEFAULT_DIAGNOSTICS)
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wswitch-enum"
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#if __clang_major__ >= 3
|
||||
#pragma GCC diagnostic ignored "-Wtautological-compare"
|
||||
#pragma GCC diagnostic ignored "-Wunused-value"
|
||||
#if __clang_major__ >= 4 || __clang_minor__ >= 1
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wcomment"
|
||||
#endif
|
||||
#if __clang_major__ >= 5
|
||||
#pragma GCC diagnostic ignored "-Wunsequenced"
|
||||
#if __clang_minor__ >= 1
|
||||
#pragma GCC diagnostic ignored "-Wunused-const-variable"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#define SMTG_CPP11 (__cplusplus >= 201103L || SMTG_INTEL_CXX11_MODE)
|
||||
#define SMTG_CPP14 (__cplusplus >= 201402L)
|
||||
#define SMTG_CPP17 (__cplusplus >= 201703L)
|
||||
#define SMTG_CPP20 (__cplusplus >= 202002L)
|
||||
#if defined (_LIBCPP_VERSION) && SMTG_CPP11
|
||||
#define SMTG_CPP11_STDLIBSUPPORT 1
|
||||
#define SMTG_HAS_NOEXCEPT 1
|
||||
#else
|
||||
#define SMTG_CPP11_STDLIBSUPPORT 0
|
||||
#define SMTG_HAS_NOEXCEPT 0
|
||||
#endif
|
||||
#define SMTG_HAS_CPP11_CONSTEXPR SMTG_CPP11
|
||||
#define SMTG_HAS_CPP14_CONSTEXPR SMTG_CPP14
|
||||
#endif // __cplusplus
|
||||
//-----------------------------------------------------------------------------
|
||||
// Unknown Platform
|
||||
//-----------------------------------------------------------------------------
|
||||
#else
|
||||
#pragma error unknown platform
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if !SMTG_RENAME_ASSERT
|
||||
#undef WINDOWS
|
||||
#undef MAC
|
||||
#undef PTHREADS
|
||||
#undef PLATFORM_64
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#define WINDOWS SMTG_OS_WINDOWS
|
||||
#endif
|
||||
#if SMTG_OS_MACOS
|
||||
#define MAC SMTG_OS_MACOS
|
||||
#endif
|
||||
#define PLATFORM_64 SMTG_PLATFORM_64
|
||||
#define PTHREADS SMTG_PTHREADS
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if SMTG_CPP11
|
||||
#define SMTG_OVERRIDE override
|
||||
#else
|
||||
#define SMTG_OVERRIDE
|
||||
#endif
|
||||
|
||||
#if SMTG_HAS_CPP11_CONSTEXPR
|
||||
#define SMTG_CONSTEXPR constexpr
|
||||
#else
|
||||
#define SMTG_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#if SMTG_HAS_CPP14_CONSTEXPR
|
||||
#define SMTG_CONSTEXPR14 constexpr
|
||||
#else
|
||||
#define SMTG_CONSTEXPR14
|
||||
#endif
|
||||
|
||||
#if SMTG_HAS_NOEXCEPT
|
||||
#define SMTG_NOEXCEPT noexcept
|
||||
#else
|
||||
#define SMTG_NOEXCEPT
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deprecation setting
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef SMTG_DEPRECATED_ATTRIBUTE
|
||||
#if SMTG_CPP17
|
||||
#define SMTG_DEPRECATED_ATTRIBUTE(msg) [[deprecated(msg)]]
|
||||
#else
|
||||
#define SMTG_DEPRECATED_ATTRIBUTE(msg)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SMTG_DEPRECATED_MSG(msg) SMTG_DEPRECATED_ATTRIBUTE(msg)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1,293 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/fstrdefs.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Definitions for handling strings (Unicode / ASCII / Platforms)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "ftypes.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** string methods defines unicode / ASCII */
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// 16 bit string operations
|
||||
#if SMTG_CPP11 // if c++11 unicode string literals
|
||||
#define SMTG_CPP11_CAT_PRIVATE_DONT_USE(a,b) a ## b
|
||||
#define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(u,x)
|
||||
#else
|
||||
#include "conststringtable.h"
|
||||
#define STR16(x) Steinberg::ConstStringTable::instance ()->getString (x)
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
#define STR(x) STR16(x)
|
||||
#define tStrBufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::tchar))
|
||||
|
||||
#else
|
||||
#define STR(x) x
|
||||
#define tStrBufferSize(buffer) (sizeof(buffer))
|
||||
#endif
|
||||
|
||||
#define str8BufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::char8))
|
||||
#define str16BufferSize(buffer) (sizeof(buffer)/sizeof(Steinberg::char16))
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#define FORMAT_INT64A "I64d"
|
||||
#define FORMAT_UINT64A "I64u"
|
||||
|
||||
#elif SMTG_OS_MACOS || SMTG_OS_LINUX
|
||||
#define FORMAT_INT64A "lld"
|
||||
#define FORMAT_UINT64A "llu"
|
||||
#define stricmp strcasecmp
|
||||
#define strnicmp strncasecmp
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
#define FORMAT_INT64W STR(FORMAT_INT64A)
|
||||
#define FORMAT_UINT64W STR(FORMAT_UINT64A)
|
||||
|
||||
#define FORMAT_INT64 FORMAT_INT64W
|
||||
#define FORMAT_UINT64 FORMAT_UINT64W
|
||||
#else
|
||||
#define FORMAT_INT64 FORMAT_INT64A
|
||||
#define FORMAT_UINT64 FORMAT_UINT64A
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// newline
|
||||
//----------------------------------------------------------------------------
|
||||
#if SMTG_OS_WINDOWS
|
||||
#define ENDLINE_A "\r\n"
|
||||
#define ENDLINE_W STR ("\r\n")
|
||||
#elif SMTG_OS_MACOS
|
||||
#define ENDLINE_A "\r"
|
||||
#define ENDLINE_W STR ("\r")
|
||||
#elif SMTG_OS_LINUX
|
||||
#define ENDLINE_A "\n"
|
||||
#define ENDLINE_W STR ("\n")
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
#define ENDLINE ENDLINE_W
|
||||
#else
|
||||
#define ENDLINE ENDLINE_A
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_WINDOWS && !defined(__GNUC__) && defined(_MSC_VER)
|
||||
#define stricmp _stricmp
|
||||
#define strnicmp _strnicmp
|
||||
#if (_MSC_VER < 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static SMTG_CONSTEXPR const tchar kEmptyString[] = { 0 };
|
||||
static SMTG_CONSTEXPR const char8 kEmptyString8[] = { 0 };
|
||||
static SMTG_CONSTEXPR const char16 kEmptyString16[] = { 0 };
|
||||
|
||||
#ifdef UNICODE
|
||||
static SMTG_CONSTEXPR const tchar kInfiniteSymbol[] = { 0x221E, 0 };
|
||||
#else
|
||||
static SMTG_CONSTEXPR const tchar* const kInfiniteSymbol = STR ("oo");
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline SMTG_CONSTEXPR14 int32 _tstrlen (const T* wcs)
|
||||
{
|
||||
const T* eos = wcs;
|
||||
|
||||
while (*eos++)
|
||||
;
|
||||
|
||||
return (int32) (eos - wcs - 1);
|
||||
}
|
||||
|
||||
inline SMTG_CONSTEXPR14 int32 tstrlen (const tchar* str) {return _tstrlen (str);}
|
||||
inline SMTG_CONSTEXPR14 int32 strlen8 (const char8* str) {return _tstrlen (str);}
|
||||
inline SMTG_CONSTEXPR14 int32 strlen16 (const char16* str) {return _tstrlen (str);}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline SMTG_CONSTEXPR14 int32 _tstrcmp (const T* src, const T* dst)
|
||||
{
|
||||
while (*src == *dst && *dst)
|
||||
{
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
|
||||
if (*src == 0 && *dst == 0)
|
||||
return 0;
|
||||
if (*src == 0)
|
||||
return -1;
|
||||
if (*dst == 0)
|
||||
return 1;
|
||||
return (int32) (*src - *dst);
|
||||
}
|
||||
|
||||
inline SMTG_CONSTEXPR14 int32 tstrcmp (const tchar* src, const tchar* dst) {return _tstrcmp (src, dst);}
|
||||
inline SMTG_CONSTEXPR14 int32 strcmp8 (const char8* src, const char8* dst) {return _tstrcmp (src, dst);}
|
||||
inline SMTG_CONSTEXPR14 int32 strcmp16 (const char16* src, const char16* dst) {return _tstrcmp (src, dst);}
|
||||
|
||||
template <typename T>
|
||||
inline SMTG_CONSTEXPR14 int32 strcmpT (const T* first, const T* last);
|
||||
|
||||
template <>
|
||||
inline SMTG_CONSTEXPR14 int32 strcmpT<char8> (const char8* first, const char8* last) { return _tstrcmp (first, last); }
|
||||
|
||||
template <>
|
||||
inline SMTG_CONSTEXPR14 int32 strcmpT<char16> (const char16* first, const char16* last) { return _tstrcmp (first, last); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline SMTG_CONSTEXPR14 int32 _tstrncmp (const T* first, const T* last, uint32 count)
|
||||
{
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
while (--count && *first && *first == *last)
|
||||
{
|
||||
first++;
|
||||
last++;
|
||||
}
|
||||
|
||||
if (*first == 0 && *last == 0)
|
||||
return 0;
|
||||
if (*first == 0)
|
||||
return -1;
|
||||
if (*last == 0)
|
||||
return 1;
|
||||
return (int32) (*first - *last);
|
||||
}
|
||||
|
||||
inline SMTG_CONSTEXPR14 int32 tstrncmp (const tchar* first, const tchar* last, uint32 count) {return _tstrncmp (first, last, count);}
|
||||
inline SMTG_CONSTEXPR14 int32 strncmp8 (const char8* first, const char8* last, uint32 count) {return _tstrncmp (first, last, count);}
|
||||
inline SMTG_CONSTEXPR14 int32 strncmp16 (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count);}
|
||||
|
||||
template <typename T>
|
||||
inline SMTG_CONSTEXPR14 int32 strncmpT (const T* first, const T* last, uint32 count);
|
||||
|
||||
template <>
|
||||
inline SMTG_CONSTEXPR14 int32 strncmpT<char8> (const char8* first, const char8* last, uint32 count) { return _tstrncmp (first, last, count); }
|
||||
|
||||
template <>
|
||||
inline SMTG_CONSTEXPR14 int32 strncmpT<char16> (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline SMTG_CONSTEXPR14 T* _tstrcpy (T* dst, const T* src)
|
||||
{
|
||||
T* cp = dst;
|
||||
while ((*cp++ = *src++) != 0) // copy string
|
||||
;
|
||||
return dst;
|
||||
}
|
||||
inline SMTG_CONSTEXPR14 tchar* tstrcpy (tchar* dst, const tchar* src) {return _tstrcpy (dst, src);}
|
||||
inline SMTG_CONSTEXPR14 char8* strcpy8 (char8* dst, const char8* src) {return _tstrcpy (dst, src);}
|
||||
inline SMTG_CONSTEXPR14 char16* strcpy16 (char16* dst, const char16* src) {return _tstrcpy (dst, src);}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline SMTG_CONSTEXPR14 T* _tstrncpy (T* dest, const T* source, uint32 count)
|
||||
{
|
||||
T* start = dest;
|
||||
while (count && (*dest++ = *source++) != 0) // copy string
|
||||
count--;
|
||||
|
||||
if (count) // pad out with zeros
|
||||
{
|
||||
while (--count)
|
||||
*dest++ = 0;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
inline SMTG_CONSTEXPR14 tchar* tstrncpy (tchar* dest, const tchar* source, uint32 count) {return _tstrncpy (dest, source, count);}
|
||||
inline SMTG_CONSTEXPR14 char8* strncpy8 (char8* dest, const char8* source, uint32 count) {return _tstrncpy (dest, source, count);}
|
||||
inline SMTG_CONSTEXPR14 char16* strncpy16 (char16* dest, const char16* source, uint32 count) {return _tstrncpy (dest, source, count);}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline SMTG_CONSTEXPR14 T* _tstrcat (T* dst, const T* src)
|
||||
{
|
||||
T* cp = dst;
|
||||
|
||||
while (*cp)
|
||||
cp++; // find end of dst
|
||||
|
||||
while ((*cp++ = *src++) != 0) // Copy src to end of dst
|
||||
;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
inline SMTG_CONSTEXPR14 tchar* tstrcat (tchar* dst, const tchar* src) {return _tstrcat (dst, src); }
|
||||
inline SMTG_CONSTEXPR14 char8* strcat8 (char8* dst, const char8* src) {return _tstrcat (dst, src); }
|
||||
inline SMTG_CONSTEXPR14 char16* strcat16 (char16* dst, const char16* src) {return _tstrcat (dst, src); }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline SMTG_CONSTEXPR14 void str8ToStr16 (char16* dst, const char8* src, int32 n = -1)
|
||||
{
|
||||
int32 i = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (i == (n - 1))
|
||||
{
|
||||
dst[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#if BYTEORDER == kBigEndian
|
||||
char8* pChr = (char8*)&dst[i];
|
||||
pChr[0] = 0;
|
||||
pChr[1] = src[i];
|
||||
#else
|
||||
dst[i] = static_cast<char16> (src[i]);
|
||||
#endif
|
||||
if (src[i] == 0)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
while (n > i)
|
||||
{
|
||||
dst[i] = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline SMTG_CONSTEXPR14 bool FIDStringsEqual (FIDString id1, FIDString id2)
|
||||
{
|
||||
return (id1 && id2) ? (strcmp8 (id1, id2) == 0) : false;
|
||||
}
|
||||
|
||||
static SMTG_CONSTEXPR const uint32 kPrintfBufferSize = 4096;
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
/* cast between wchar_t and char16 */
|
||||
inline wchar_t* wscast (char16* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<wchar_t*> (s); }
|
||||
inline char16* wscast (wchar_t* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<char16*> (s);}
|
||||
inline const wchar_t* wscast (const char16* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<const wchar_t*> (s); }
|
||||
inline const char16* wscast (const wchar_t* s) { static_assert (sizeof (wchar_t) == sizeof (char16), ""); return reinterpret_cast<const char16*> (s); }
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/ftypes.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic data types
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "fplatform.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
//#define UNICODE_OFF // disable / enable unicode
|
||||
|
||||
#ifdef UNICODE_OFF
|
||||
#ifdef UNICODE
|
||||
#undef UNICODE
|
||||
#endif
|
||||
#else
|
||||
#define UNICODE 1
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
#define _UNICODE 1
|
||||
#endif
|
||||
|
||||
namespace Steinberg
|
||||
{
|
||||
//-----------------------------------------------------------------
|
||||
// Integral Types
|
||||
typedef char int8;
|
||||
typedef uint8_t uint8;
|
||||
typedef unsigned char uchar;
|
||||
|
||||
typedef int16_t int16;
|
||||
typedef uint16_t uint16;
|
||||
|
||||
typedef int32_t int32;
|
||||
typedef uint32_t uint32;
|
||||
|
||||
static const int32 kMaxInt32 = INT32_MAX;
|
||||
static const int32 kMinInt32 = INT32_MIN;
|
||||
static const int32 kMaxLong = kMaxInt32;
|
||||
static const int32 kMinLong = kMinInt32;
|
||||
static const uint32 kMaxInt32u = UINT32_MAX;
|
||||
|
||||
typedef int64_t int64;
|
||||
typedef uint64_t uint64;
|
||||
static const int64 kMaxInt64 = INT64_MAX;
|
||||
static const int64 kMinInt64 = INT64_MIN;
|
||||
static const uint64 kMaxInt64u = UINT64_MAX;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// other Semantic Types
|
||||
typedef int64 TSize; // byte (or other) sizes
|
||||
typedef int32 tresult; // result code
|
||||
//-----------------------------------------------------------------
|
||||
static const float kMaxFloat = 3.40282346638528860E38;
|
||||
static const double kMaxDouble = 1.7976931348623158E308;
|
||||
|
||||
#if SMTG_PLATFORM_64
|
||||
typedef uint64 TPtrInt;
|
||||
#else
|
||||
typedef uint32 TPtrInt;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Boolean
|
||||
typedef uint8 TBool;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Char / Strings
|
||||
typedef char char8;
|
||||
typedef char16_t char16;
|
||||
|
||||
#ifdef UNICODE
|
||||
typedef char16 tchar;
|
||||
#else
|
||||
typedef char8 tchar;
|
||||
#endif
|
||||
|
||||
typedef const char8* CStringA;
|
||||
typedef const char16* CStringW;
|
||||
typedef const tchar* CString;
|
||||
inline bool strEmpty (const tchar* str) { return (!str || *str == 0); }
|
||||
inline bool str8Empty (const char8* str) { return (!str || *str == 0); }
|
||||
inline bool str16Empty (const char16* str) { return (!str || *str == 0); }
|
||||
|
||||
typedef const char8* FIDString; // identifier as string (used for attributes, messages)
|
||||
|
||||
const FIDString kPlatformStringWin = "WIN";
|
||||
const FIDString kPlatformStringMac = "MAC";
|
||||
const FIDString kPlatformStringIOS = "IOS";
|
||||
const FIDString kPlatformStringLinux = "Linux";
|
||||
#if SMTG_OS_WINDOWS
|
||||
const FIDString kPlatformString = kPlatformStringWin;
|
||||
#elif SMTG_OS_IOS
|
||||
const FIDString kPlatformString = kPlatformStringIOS;
|
||||
#elif SMTG_OS_MACOS
|
||||
const FIDString kPlatformString = kPlatformStringMac;
|
||||
#elif SMTG_OS_LINUX
|
||||
const FIDString kPlatformString = kPlatformStringLinux;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Coordinates */
|
||||
typedef int32 UCoord;
|
||||
static const UCoord kMaxCoord = ((UCoord)0x7FFFFFFF);
|
||||
static const UCoord kMinCoord = ((UCoord)-0x7FFFFFFF);
|
||||
} // namespace Steinberg
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Byte-order Conversion Macros
|
||||
*/
|
||||
#define SWAP_32(l) { \
|
||||
unsigned char* p = (unsigned char*)& (l); \
|
||||
unsigned char t; \
|
||||
t = p[0]; p[0] = p[3]; p[3] = t; t = p[1]; p[1] = p[2]; p[2] = t; }
|
||||
|
||||
#define SWAP_16(w) { \
|
||||
unsigned char* p = (unsigned char*)& (w); \
|
||||
unsigned char t; \
|
||||
t = p[0]; p[0] = p[1]; p[1] = t; }
|
||||
|
||||
#define SWAP_64(i) { \
|
||||
unsigned char* p = (unsigned char*)& (i); \
|
||||
unsigned char t; \
|
||||
t = p[0]; p[0] = p[7]; p[7] = t; t = p[1]; p[1] = p[6]; p[6] = t; \
|
||||
t = p[2]; p[2] = p[5]; p[5] = t; t = p[3]; p[3] = p[4]; p[4] = t;}
|
||||
|
||||
namespace Steinberg
|
||||
{
|
||||
static inline void FSwap (int8&) {}
|
||||
static inline void FSwap (uint8&) {}
|
||||
static inline void FSwap (int16& i16) { SWAP_16 (i16) }
|
||||
static inline void FSwap (uint16& i16) { SWAP_16 (i16) }
|
||||
static inline void FSwap (int32& i32) { SWAP_32 (i32) }
|
||||
static inline void FSwap (uint32& i32) { SWAP_32 (i32) }
|
||||
static inline void FSwap (int64& i64) { SWAP_64 (i64) }
|
||||
static inline void FSwap (uint64& i64) { SWAP_64 (i64) }
|
||||
}
|
||||
|
||||
// always inline macros (only when RELEASE is 1)
|
||||
//----------------------------------------------------------------------------
|
||||
#if RELEASE
|
||||
#if SMTG_OS_MACOS || SMTG_OS_LINUX || defined(__MINGW32__)
|
||||
#define SMTG_ALWAYS_INLINE __inline__ __attribute__((__always_inline__))
|
||||
#define SMTG_NEVER_INLINE __attribute__((noinline))
|
||||
#elif SMTG_OS_WINDOWS
|
||||
#define SMTG_ALWAYS_INLINE __forceinline
|
||||
#define SMTG_NEVER_INLINE __declspec(noinline)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SMTG_ALWAYS_INLINE
|
||||
#define SMTG_ALWAYS_INLINE inline
|
||||
#endif
|
||||
#ifndef SMTG_NEVER_INLINE
|
||||
#define SMTG_NEVER_INLINE
|
||||
#endif
|
||||
|
||||
#ifndef SMTG_CPP11_STDLIBSUPPORT
|
||||
// Enable this for old compilers
|
||||
// #define nullptr NULL
|
||||
#endif
|
||||
|
|
@ -1,500 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/funknown.cpp
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "funknown.h"
|
||||
|
||||
#include "fstrdefs.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#include <objbase.h>
|
||||
#endif
|
||||
|
||||
#if SMTG_OS_MACOS
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#if !defined (SMTG_USE_STDATOMIC_H)
|
||||
#if defined(MAC_OS_X_VERSION_10_11) && defined(MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
#define SMTG_USE_STDATOMIC_H (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_11)
|
||||
#else
|
||||
#define SMTG_USE_STDATOMIC_H 0
|
||||
#endif
|
||||
#endif // !defined (SMTG_USE_STDATOMIC_H)
|
||||
|
||||
#if !SMTG_USE_STDATOMIC_H
|
||||
#include <libkern/OSAtomic.h>
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !__LP64__
|
||||
// on 32 bit Mac OS X we can safely ignore the format warnings as sizeof(int) == sizeof(long)
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
#endif
|
||||
#endif // !SMTG_USE_STDATOMIC_H
|
||||
#endif // SMTG_OS_MACOS
|
||||
|
||||
#if SMTG_OS_LINUX
|
||||
#if !defined (SMTG_USE_STDATOMIC_H)
|
||||
#if defined (__ANDROID__) || defined(_LIBCPP_VERSION)
|
||||
#define SMTG_USE_STDATOMIC_H 1
|
||||
#else
|
||||
#include <ext/atomicity.h>
|
||||
#endif
|
||||
#endif // !defined (SMTG_USE_STDATOMIC_H)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined (SMTG_USE_STDATOMIC_H) && SMTG_USE_STDATOMIC_H
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if COM_COMPATIBLE
|
||||
#if SMTG_OS_WINDOWS
|
||||
#define GuidStruct GUID
|
||||
#else
|
||||
struct GuidStruct
|
||||
{
|
||||
uint32 Data1;
|
||||
uint16 Data2;
|
||||
uint16 Data3;
|
||||
uint8 Data4[8];
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void toString8 (char8* string, const char* data, int32 i1, int32 i2);
|
||||
static void fromString8 (const char8* string, char* data, int32 i1, int32 i2);
|
||||
static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FUnknownPrivate
|
||||
//------------------------------------------------------------------------
|
||||
namespace FUnknownPrivate {
|
||||
//------------------------------------------------------------------------
|
||||
int32 PLUGIN_API atomicAdd (int32& var, int32 d)
|
||||
{
|
||||
#if SMTG_USE_STDATOMIC_H
|
||||
return atomic_fetch_add (reinterpret_cast<atomic_int_least32_t*> (&var), d) + d;
|
||||
#else
|
||||
#if SMTG_OS_WINDOWS
|
||||
#ifdef __MINGW32__
|
||||
return InterlockedExchangeAdd (reinterpret_cast<long volatile*>(&var), d) + d;
|
||||
#else
|
||||
return InterlockedExchangeAdd ((LONG*)&var, d) + d;
|
||||
#endif
|
||||
#elif SMTG_OS_MACOS
|
||||
return OSAtomicAdd32Barrier (d, (int32_t*)&var);
|
||||
#elif defined(__ANDROID__)
|
||||
return atomic_fetch_add ((atomic_int*)&var, d) + d;
|
||||
#elif SMTG_OS_LINUX
|
||||
__gnu_cxx::__atomic_add (&var, d);
|
||||
return var;
|
||||
#else
|
||||
#warning implement me!
|
||||
var += d;
|
||||
return var;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
} // FUnknownPrivate
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FUID implementation
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
FUID::FUID ()
|
||||
{
|
||||
memset (data, 0, sizeof (TUID));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUID::FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4)
|
||||
{
|
||||
from4Int (l1, l2, l3, l4);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUID::FUID (const FUID& f)
|
||||
{
|
||||
memcpy (data, f.data, sizeof (TUID));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
FUID::FUID (FUID&& other)
|
||||
{
|
||||
memcpy (data, other.data, sizeof (TUID));
|
||||
}
|
||||
|
||||
FUID& FUID::operator= (FUID&& other)
|
||||
{
|
||||
memcpy (data, other.data, sizeof (TUID));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FUID::generate ()
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
#if defined(_M_ARM64) || defined(_M_ARM)
|
||||
//#warning implement me!
|
||||
return false;
|
||||
#else
|
||||
GUID guid;
|
||||
HRESULT hr = CoCreateGuid (&guid);
|
||||
switch (hr)
|
||||
{
|
||||
case RPC_S_OK: memcpy (data, (char*)&guid, sizeof (TUID)); return true;
|
||||
|
||||
case (HRESULT)RPC_S_UUID_LOCAL_ONLY:
|
||||
default: return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif SMTG_OS_MACOS
|
||||
CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault);
|
||||
if (uuid)
|
||||
{
|
||||
CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid);
|
||||
memcpy (data, (char*)&bytes, sizeof (TUID));
|
||||
CFRelease (uuid);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
#elif SMTG_OS_LINUX
|
||||
srand ((size_t)this);
|
||||
for (int32 i = 0; i < 16; i++)
|
||||
data[i] = static_cast<unsigned char>(rand ());
|
||||
return true;
|
||||
#else
|
||||
#warning implement me!
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FUID::isValid () const
|
||||
{
|
||||
TUID nulluid = {0};
|
||||
|
||||
return memcmp (data, nulluid, sizeof (TUID)) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FUID& FUID::operator= (const FUID& f)
|
||||
{
|
||||
memcpy (data, f.data, sizeof (TUID));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FUID::from4Int (uint32 l1, uint32 l2, uint32 l3, uint32 l4)
|
||||
{
|
||||
#if COM_COMPATIBLE
|
||||
data [0] = (char)((l1 & 0x000000FF) );
|
||||
data [1] = (char)((l1 & 0x0000FF00) >> 8);
|
||||
data [2] = (char)((l1 & 0x00FF0000) >> 16);
|
||||
data [3] = (char)((l1 & 0xFF000000) >> 24);
|
||||
data [4] = (char)((l2 & 0x00FF0000) >> 16);
|
||||
data [5] = (char)((l2 & 0xFF000000) >> 24);
|
||||
data [6] = (char)((l2 & 0x000000FF) );
|
||||
data [7] = (char)((l2 & 0x0000FF00) >> 8);
|
||||
data [8] = (char)((l3 & 0xFF000000) >> 24);
|
||||
data [9] = (char)((l3 & 0x00FF0000) >> 16);
|
||||
data [10] = (char)((l3 & 0x0000FF00) >> 8);
|
||||
data [11] = (char)((l3 & 0x000000FF) );
|
||||
data [12] = (char)((l4 & 0xFF000000) >> 24);
|
||||
data [13] = (char)((l4 & 0x00FF0000) >> 16);
|
||||
data [14] = (char)((l4 & 0x0000FF00) >> 8);
|
||||
data [15] = (char)((l4 & 0x000000FF) );
|
||||
#else
|
||||
data [0] = (char)((l1 & 0xFF000000) >> 24);
|
||||
data [1] = (char)((l1 & 0x00FF0000) >> 16);
|
||||
data [2] = (char)((l1 & 0x0000FF00) >> 8);
|
||||
data [3] = (char)((l1 & 0x000000FF) );
|
||||
data [4] = (char)((l2 & 0xFF000000) >> 24);
|
||||
data [5] = (char)((l2 & 0x00FF0000) >> 16);
|
||||
data [6] = (char)((l2 & 0x0000FF00) >> 8);
|
||||
data [7] = (char)((l2 & 0x000000FF) );
|
||||
data [8] = (char)((l3 & 0xFF000000) >> 24);
|
||||
data [9] = (char)((l3 & 0x00FF0000) >> 16);
|
||||
data [10] = (char)((l3 & 0x0000FF00) >> 8);
|
||||
data [11] = (char)((l3 & 0x000000FF) );
|
||||
data [12] = (char)((l4 & 0xFF000000) >> 24);
|
||||
data [13] = (char)((l4 & 0x00FF0000) >> 16);
|
||||
data [14] = (char)((l4 & 0x0000FF00) >> 8);
|
||||
data [15] = (char)((l4 & 0x000000FF) );
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FUID::to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const
|
||||
{
|
||||
d1 = getLong1 ();
|
||||
d2 = getLong2 ();
|
||||
d3 = getLong3 ();
|
||||
d4 = getLong4 ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32 FUID::getLong1 () const
|
||||
{
|
||||
#if COM_COMPATIBLE
|
||||
return makeLong (data[3], data[2], data[1], data[0]);
|
||||
#else
|
||||
return makeLong (data[0], data[1], data[2], data[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32 FUID::getLong2 () const
|
||||
{
|
||||
#if COM_COMPATIBLE
|
||||
return makeLong (data[5], data[4], data[7], data[6]);
|
||||
#else
|
||||
return makeLong (data[4], data[5], data[6], data[7]);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32 FUID::getLong3 () const
|
||||
{
|
||||
#if COM_COMPATIBLE
|
||||
return makeLong (data[8], data[9], data[10], data[11]);
|
||||
#else
|
||||
return makeLong (data[8], data[9], data[10], data[11]);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32 FUID::getLong4 () const
|
||||
{
|
||||
#if COM_COMPATIBLE
|
||||
return makeLong (data[12], data[13], data[14], data[15]);
|
||||
#else
|
||||
return makeLong (data[12], data[13], data[14], data[15]);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FUID::toString (char8* string) const
|
||||
{
|
||||
if (!string)
|
||||
return;
|
||||
|
||||
#if COM_COMPATIBLE
|
||||
auto* g = (GuidStruct*)data;
|
||||
|
||||
char8 s[17];
|
||||
Steinberg::toString8 (s, data, 8, 16);
|
||||
|
||||
sprintf (string, "%08X%04X%04X%s", g->Data1, g->Data2, g->Data3, s);
|
||||
#else
|
||||
Steinberg::toString8 (string, data, 0, 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FUID::fromString (const char8* string)
|
||||
{
|
||||
if (!string || !*string)
|
||||
return false;
|
||||
if (strlen (string) != 32)
|
||||
return false;
|
||||
|
||||
#if COM_COMPATIBLE
|
||||
GuidStruct g;
|
||||
char s[33];
|
||||
|
||||
strcpy (s, string);
|
||||
s[8] = 0;
|
||||
sscanf (s, "%x", &g.Data1);
|
||||
strcpy (s, string + 8);
|
||||
s[4] = 0;
|
||||
sscanf (s, "%hx", &g.Data2);
|
||||
strcpy (s, string + 12);
|
||||
s[4] = 0;
|
||||
sscanf (s, "%hx", &g.Data3);
|
||||
|
||||
memcpy (data, &g, 8);
|
||||
Steinberg::fromString8 (string + 16, data, 8, 16);
|
||||
#else
|
||||
Steinberg::fromString8 (string, data, 0, 16);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FUID::fromRegistryString (const char8* string)
|
||||
{
|
||||
if (!string || !*string)
|
||||
return false;
|
||||
if (strlen (string) != 38)
|
||||
return false;
|
||||
|
||||
// e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef}
|
||||
|
||||
#if COM_COMPATIBLE
|
||||
GuidStruct g;
|
||||
char8 s[10];
|
||||
|
||||
strncpy (s, string + 1, 8);
|
||||
s[8] = 0;
|
||||
sscanf (s, "%x", &g.Data1);
|
||||
strncpy (s, string + 10, 4);
|
||||
s[4] = 0;
|
||||
sscanf (s, "%hx", &g.Data2);
|
||||
strncpy (s, string + 15, 4);
|
||||
s[4] = 0;
|
||||
sscanf (s, "%hx", &g.Data3);
|
||||
memcpy (data, &g, 8);
|
||||
|
||||
Steinberg::fromString8 (string + 20, data, 8, 10);
|
||||
Steinberg::fromString8 (string + 25, data, 10, 16);
|
||||
#else
|
||||
Steinberg::fromString8 (string + 1, data, 0, 4);
|
||||
Steinberg::fromString8 (string + 10, data, 4, 6);
|
||||
Steinberg::fromString8 (string + 15, data, 6, 8);
|
||||
Steinberg::fromString8 (string + 20, data, 8, 10);
|
||||
Steinberg::fromString8 (string + 25, data, 10, 16);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FUID::toRegistryString (char8* string) const
|
||||
{
|
||||
// e.g. {c200e360-38c5-11ce-ae62-08002b2b79ef}
|
||||
|
||||
#if COM_COMPATIBLE
|
||||
auto* g = (GuidStruct*)data;
|
||||
|
||||
char8 s1[5];
|
||||
Steinberg::toString8 (s1, data, 8, 10);
|
||||
|
||||
char8 s2[13];
|
||||
Steinberg::toString8 (s2, data, 10, 16);
|
||||
|
||||
sprintf (string, "{%08X-%04X-%04X-%s-%s}", g->Data1, g->Data2, g->Data3, s1, s2);
|
||||
#else
|
||||
char8 s1[9];
|
||||
Steinberg::toString8 (s1, data, 0, 4);
|
||||
char8 s2[5];
|
||||
Steinberg::toString8 (s2, data, 4, 6);
|
||||
char8 s3[5];
|
||||
Steinberg::toString8 (s3, data, 6, 8);
|
||||
char8 s4[5];
|
||||
Steinberg::toString8 (s4, data, 8, 10);
|
||||
char8 s5[13];
|
||||
Steinberg::toString8 (s5, data, 10, 16);
|
||||
|
||||
snprintf (string, 40, "{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void FUID::print (int32 style, char8* string, size_t stringBufferSize) const
|
||||
{
|
||||
if (!string || stringBufferSize == 0) // no string: debug output
|
||||
{
|
||||
char8 str[128];
|
||||
print (style, str, 128);
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
OutputDebugStringA (str);
|
||||
OutputDebugStringA ("\n");
|
||||
#else
|
||||
fprintf (stdout, "%s\n", str);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 l1, l2, l3, l4;
|
||||
to4Int (l1, l2, l3, l4);
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case kINLINE_UID:
|
||||
// length is 60 (with null-terminate)
|
||||
snprintf (string, stringBufferSize, "INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1,
|
||||
l2, l3, l4);
|
||||
break;
|
||||
|
||||
case kDECLARE_UID:
|
||||
// length is 61 (with null-terminate)
|
||||
snprintf (string, stringBufferSize, "DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1,
|
||||
l2, l3, l4);
|
||||
break;
|
||||
|
||||
case kFUID:
|
||||
// length is 54 (with null-terminate)
|
||||
snprintf (string, stringBufferSize, "FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3,
|
||||
l4);
|
||||
break;
|
||||
|
||||
case kCLASS_UID:
|
||||
default:
|
||||
// length is 78 (with null-terminate)
|
||||
snprintf (string, stringBufferSize,
|
||||
"DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3,
|
||||
l4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// helpers
|
||||
//------------------------------------------------------------------------
|
||||
static uint32 makeLong (uint8 b1, uint8 b2, uint8 b3, uint8 b4)
|
||||
{
|
||||
return (uint32 (b1) << 24) | (uint32 (b2) << 16) | (uint32 (b3) << 8) | uint32 (b4);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static void toString8 (char8* string, const char* data, int32 i1, int32 i2)
|
||||
{
|
||||
*string = 0;
|
||||
for (int32 i = i1; i < i2; i++)
|
||||
{
|
||||
char8 s[3];
|
||||
snprintf (s, 3, "%02X", (uint8)data[i]);
|
||||
strcat (string, s);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static void fromString8 (const char8* string, char* data, int32 i1, int32 i2)
|
||||
{
|
||||
for (int32 i = i1; i < i2; i++)
|
||||
{
|
||||
char8 s[3];
|
||||
s[0] = *string++;
|
||||
s[1] = *string++;
|
||||
s[2] = 0;
|
||||
|
||||
int32 d = 0;
|
||||
sscanf (s, "%2x", &d);
|
||||
data[i] = (char)d;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,559 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/funknown.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/fplatform.h"
|
||||
#include "pluginterfaces/base/ftypes.h"
|
||||
#include "pluginterfaces/base/smartpointer.h"
|
||||
#include <cstring>
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! \defgroup pluginBase Basic Interfaces
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Unique Identifier macros
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#if COM_COMPATIBLE
|
||||
#define INLINE_UID(l1, l2, l3, l4) \
|
||||
{ \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \
|
||||
}
|
||||
#else
|
||||
#define INLINE_UID(l1, l2, l3, l4) \
|
||||
{ \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \
|
||||
(::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define DECLARE_UID(name, l1, l2, l3, l4) SMTG_CONSTEXPR14 ::Steinberg::TUID name = INLINE_UID (l1, l2, l3, l4);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define EXTERN_UID(name) extern const ::Steinberg::TUID name;
|
||||
|
||||
#ifdef INIT_CLASS_IID
|
||||
#define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \
|
||||
static SMTG_CONSTEXPR14 const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4); \
|
||||
const ::Steinberg::FUID ClassName::iid (ClassName##_iid);
|
||||
#else
|
||||
#define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \
|
||||
static SMTG_CONSTEXPR14 const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4);
|
||||
#endif
|
||||
|
||||
#define DEF_CLASS_IID(ClassName) const ::Steinberg::FUID ClassName::iid (ClassName##_iid);
|
||||
|
||||
#define INLINE_UID_OF(ClassName) ClassName##_iid
|
||||
|
||||
#define INLINE_UID_FROM_FUID(x) \
|
||||
INLINE_UID (x.getLong1 (), x.getLong2 (), x.getLong3 (), x.getLong4 ())
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FUnknown implementation macros
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#define DECLARE_FUNKNOWN_METHODS \
|
||||
public: \
|
||||
virtual ::Steinberg::tresult PLUGIN_API queryInterface (const ::Steinberg::TUID _iid, void** obj) SMTG_OVERRIDE; \
|
||||
virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE; \
|
||||
virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE; \
|
||||
protected : \
|
||||
::Steinberg::int32 __funknownRefCount; \
|
||||
public:
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#define DELEGATE_REFCOUNT(ClassName) \
|
||||
public: \
|
||||
virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return ClassName::addRef (); } \
|
||||
virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE { return ClassName::release (); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define IMPLEMENT_REFCOUNT(ClassName) \
|
||||
::Steinberg::uint32 PLUGIN_API ClassName::addRef () \
|
||||
{ \
|
||||
return ::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, 1); \
|
||||
} \
|
||||
::Steinberg::uint32 PLUGIN_API ClassName::release () \
|
||||
{ \
|
||||
if (::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, -1) == 0) \
|
||||
{ \
|
||||
delete this; \
|
||||
return 0; \
|
||||
} \
|
||||
return __funknownRefCount; \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define FUNKNOWN_CTOR { __funknownRefCount = 1; }
|
||||
#if SMTG_FUNKNOWN_DTOR_ASSERT
|
||||
#include <cassert>
|
||||
#define FUNKNOWN_DTOR { assert (__funknownRefCount == 0); }
|
||||
#else
|
||||
#define FUNKNOWN_DTOR
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define QUERY_INTERFACE(iid, obj, InterfaceIID, InterfaceName) \
|
||||
if (::Steinberg::FUnknownPrivate::iidEqual (iid, InterfaceIID)) \
|
||||
{ \
|
||||
addRef (); \
|
||||
*obj = static_cast< InterfaceName* >(this); \
|
||||
return ::Steinberg::kResultOk; \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define IMPLEMENT_QUERYINTERFACE(ClassName, InterfaceName, ClassIID) \
|
||||
::Steinberg::tresult PLUGIN_API ClassName::queryInterface (const ::Steinberg::TUID _iid, void** obj)\
|
||||
{ \
|
||||
QUERY_INTERFACE (_iid, obj, ::Steinberg::FUnknown::iid, InterfaceName) \
|
||||
QUERY_INTERFACE (_iid, obj, ClassIID, InterfaceName) \
|
||||
*obj = nullptr; \
|
||||
return ::Steinberg::kNoInterface; \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define IMPLEMENT_FUNKNOWN_METHODS(ClassName,InterfaceName,ClassIID) \
|
||||
IMPLEMENT_REFCOUNT (ClassName) \
|
||||
IMPLEMENT_QUERYINTERFACE (ClassName, InterfaceName, ClassIID)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Result Codes
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if COM_COMPATIBLE
|
||||
#if SMTG_OS_WINDOWS
|
||||
enum
|
||||
{
|
||||
kNoInterface = static_cast<tresult>(0x80004002L), // E_NOINTERFACE
|
||||
kResultOk = static_cast<tresult>(0x00000000L), // S_OK
|
||||
kResultTrue = kResultOk,
|
||||
kResultFalse = static_cast<tresult>(0x00000001L), // S_FALSE
|
||||
kInvalidArgument = static_cast<tresult>(0x80070057L), // E_INVALIDARG
|
||||
kNotImplemented = static_cast<tresult>(0x80004001L), // E_NOTIMPL
|
||||
kInternalError = static_cast<tresult>(0x80004005L), // E_FAIL
|
||||
kNotInitialized = static_cast<tresult>(0x8000FFFFL), // E_UNEXPECTED
|
||||
kOutOfMemory = static_cast<tresult>(0x8007000EL) // E_OUTOFMEMORY
|
||||
};
|
||||
#else
|
||||
enum
|
||||
{
|
||||
kNoInterface = static_cast<tresult>(0x80000004L), // E_NOINTERFACE
|
||||
kResultOk = static_cast<tresult>(0x00000000L), // S_OK
|
||||
kResultTrue = kResultOk,
|
||||
kResultFalse = static_cast<tresult>(0x00000001L), // S_FALSE
|
||||
kInvalidArgument = static_cast<tresult>(0x80000003L), // E_INVALIDARG
|
||||
kNotImplemented = static_cast<tresult>(0x80000001L), // E_NOTIMPL
|
||||
kInternalError = static_cast<tresult>(0x80000008L), // E_FAIL
|
||||
kNotInitialized = static_cast<tresult>(0x8000FFFFL), // E_UNEXPECTED
|
||||
kOutOfMemory = static_cast<tresult>(0x80000002L) // E_OUTOFMEMORY
|
||||
};
|
||||
#endif
|
||||
#else
|
||||
enum
|
||||
{
|
||||
kNoInterface = -1,
|
||||
kResultOk,
|
||||
kResultTrue = kResultOk,
|
||||
kResultFalse,
|
||||
kInvalidArgument,
|
||||
kNotImplemented,
|
||||
kInternalError,
|
||||
kNotInitialized,
|
||||
kOutOfMemory
|
||||
};
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
typedef int64 LARGE_INT; // obsolete
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FUID class declaration
|
||||
//------------------------------------------------------------------------
|
||||
typedef char TUID[16]; ///< plain UID type
|
||||
|
||||
#if SMTG_CPP14
|
||||
//------------------------------------------------------------------------
|
||||
inline SMTG_CONSTEXPR14 void copyTUID (char* dst, const char* src)
|
||||
{
|
||||
for (auto i = 0; i < 16; ++i)
|
||||
dst[i] = src[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/* FUnknown private */
|
||||
namespace FUnknownPrivate {
|
||||
SMTG_ALWAYS_INLINE bool iidEqual (const void* iid1, const void* iid2)
|
||||
{
|
||||
const uint64* p1 = reinterpret_cast<const uint64*> (iid1);
|
||||
const uint64* p2 = reinterpret_cast<const uint64*> (iid2);
|
||||
return p1[0] == p2[0] && p1[1] == p2[1];
|
||||
}
|
||||
|
||||
int32 PLUGIN_API atomicAdd (int32& value, int32 amount);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Handling 16 Byte Globally Unique Identifiers.
|
||||
\ingroup pluginBase
|
||||
|
||||
Each interface declares its identifier as static member inside the interface
|
||||
namespace (e.g. FUnknown::iid).
|
||||
*/
|
||||
class FUID
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
FUID ();
|
||||
FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4);
|
||||
FUID (const FUID&);
|
||||
virtual ~FUID () {}
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
FUID (FUID&& other);
|
||||
FUID& operator= (FUID&& other);
|
||||
#endif
|
||||
|
||||
/** Generates a new Unique Identifier (UID).
|
||||
Will return true for success. If the return value is false, either no
|
||||
UID is generated or the UID is not guaranteed to be unique worldwide. */
|
||||
bool generate ();
|
||||
|
||||
/** Checks if the UID data is valid.
|
||||
The default constructor initializes the memory with zeros. */
|
||||
bool isValid () const;
|
||||
|
||||
FUID& operator = (const FUID& f);
|
||||
bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
|
||||
bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; }
|
||||
bool operator != (const FUID& f) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
|
||||
|
||||
uint32 getLong1 () const;
|
||||
uint32 getLong2 () const;
|
||||
uint32 getLong3 () const;
|
||||
uint32 getLong4 () const;
|
||||
|
||||
void from4Int (uint32 d1, uint32 d2, uint32 d3, uint32 d4);
|
||||
void to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const;
|
||||
|
||||
typedef char8 String[33];
|
||||
|
||||
/** Converts UID to a string.
|
||||
The string will be 32 characters long, representing the hexadecimal values
|
||||
of each data byte (e.g. "9127BE30160E4BB69966670AA6087880").
|
||||
|
||||
Typical use-case is:
|
||||
\code{.cpp}
|
||||
char8[33] strUID = {0};
|
||||
FUID uid;
|
||||
if (uid.generate ())
|
||||
uid.toString (strUID);
|
||||
\endcode
|
||||
*/
|
||||
void toString (char8* string) const;
|
||||
|
||||
/** Sets the UID data from a string.
|
||||
The string has to be 32 characters long, where each character-pair is
|
||||
the ASCII-encoded hexadecimal value of the corresponding data byte. */
|
||||
bool fromString (const char8* string);
|
||||
|
||||
/** Converts UID to a string in Microsoft(R) OLE format.
|
||||
(e.g. "{c200e360-38c5-11ce-ae62-08002b2b79ef}") */
|
||||
void toRegistryString (char8* string) const;
|
||||
|
||||
/** Sets the UID data from a string in Microsoft(R) OLE format. */
|
||||
bool fromRegistryString (const char8* string);
|
||||
|
||||
enum UIDPrintStyle
|
||||
{
|
||||
kINLINE_UID, ///< "INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
|
||||
kDECLARE_UID, ///< "DECLARE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
|
||||
kFUID, ///< "FUID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
|
||||
kCLASS_UID ///< "DECLARE_CLASS_IID (Interface, 0x00000000, 0x00000000, 0x00000000, 0x00000000)"
|
||||
};
|
||||
/** Prints the UID to a string (or debug output if string is NULL).
|
||||
\param style can be chosen from the FUID::UIDPrintStyle enumeration.
|
||||
\param string is the output string if not NULL.
|
||||
\param stringBufferSize is the size of the output string */
|
||||
void print (int32 style, char8* string = nullptr, size_t stringBufferSize = 0) const;
|
||||
|
||||
template <size_t N>
|
||||
inline explicit FUID (const char (&uid)[N])
|
||||
{
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
static_assert (N == sizeof (TUID), "only TUID allowed");
|
||||
#endif
|
||||
memcpy (data, uid, sizeof (TUID));
|
||||
}
|
||||
inline void toTUID (TUID result) const { memcpy (result, data, sizeof (TUID)); }
|
||||
inline operator const TUID& () const { return data; }
|
||||
inline const TUID& toTUID () const { return data; }
|
||||
|
||||
static FUID fromTUID (const TUID uid)
|
||||
{
|
||||
FUID res;
|
||||
if (uid)
|
||||
memcpy (res.data, uid, sizeof (TUID));
|
||||
return res;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
TUID data;
|
||||
};
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
template <typename T>
|
||||
inline bool operator== (const FUID& f1, T f2)
|
||||
{
|
||||
static_assert (
|
||||
std::is_same<typename std::remove_cv<T>::type, FUID>::value,
|
||||
"Do not compare a FUID with a TUID directly. Either convert the TUID to a FUID and compare them or use FUnknownPrivate::iidEqual");
|
||||
return f1.operator== (f2);
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FUnknown
|
||||
//------------------------------------------------------------------------
|
||||
/** The basic interface of all interfaces.
|
||||
\ingroup pluginBase
|
||||
|
||||
- The FUnknown::queryInterface method is used to retrieve pointers to other
|
||||
interfaces of the object.
|
||||
- FUnknown::addRef and FUnknown::release manage the lifetime of the object.
|
||||
If no more references exist, the object is destroyed in memory.
|
||||
|
||||
Interfaces are identified by 16 byte Globally Unique Identifiers.
|
||||
The SDK provides a class called FUID for this purpose.
|
||||
|
||||
\ref howtoClass
|
||||
*/
|
||||
class FUnknown
|
||||
{
|
||||
public:
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Query for a pointer to the specified interface.
|
||||
Returns kResultOk on success or kNoInterface if the object does not implement the interface.
|
||||
The object has to call addRef when returning an interface.
|
||||
\param _iid : (in) 16 Byte interface identifier (-> FUID)
|
||||
\param obj : (out) On return, *obj points to the requested interface */
|
||||
virtual tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) = 0;
|
||||
|
||||
/** Adds a reference and returns the new reference count.
|
||||
\par Remarks:
|
||||
The initial reference count after creating an object is 1. */
|
||||
virtual uint32 PLUGIN_API addRef () = 0;
|
||||
|
||||
/** Releases a reference and returns the new reference count.
|
||||
If the reference count reaches zero, the object will be destroyed in memory. */
|
||||
virtual uint32 PLUGIN_API release () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
|
||||
DECLARE_CLASS_IID (FUnknown, 0x00000000, 0x00000000, 0xC0000000, 0x00000046)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FUnknownPtr
|
||||
//------------------------------------------------------------------------
|
||||
/** FUnknownPtr - automatic interface conversion and smart pointer in one.
|
||||
This template class can be used for interface conversion like this:
|
||||
\code{.cpp}
|
||||
IPtr<IPath> path = owned (FHostCreate (IPath, hostClasses));
|
||||
FUnknownPtr<IPath2> path2 (path); // does a query interface for IPath2
|
||||
if (path2)
|
||||
...
|
||||
\endcode
|
||||
*/
|
||||
template <class I>
|
||||
class FUnknownPtr : public IPtr<I>
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
inline FUnknownPtr (FUnknown* unknown); // query interface
|
||||
inline FUnknownPtr (const FUnknownPtr& p) : IPtr<I> (p) {}
|
||||
inline FUnknownPtr () {}
|
||||
|
||||
inline FUnknownPtr& operator= (const FUnknownPtr& p)
|
||||
{
|
||||
IPtr<I>::operator= (p);
|
||||
return *this;
|
||||
}
|
||||
inline I* operator= (FUnknown* unknown);
|
||||
inline I* getInterface () { return this->ptr; }
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
inline FUnknownPtr (FUnknownPtr&& p) SMTG_NOEXCEPT : IPtr<I> (std::move (p)) {}
|
||||
inline FUnknownPtr& operator= (FUnknownPtr&& p) SMTG_NOEXCEPT
|
||||
{
|
||||
IPtr<I>::operator= (std::move (p));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace FUnknownPrivate {
|
||||
|
||||
template <typename T>
|
||||
struct Void : std::false_type
|
||||
{
|
||||
using Type = void;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using VoidT = typename Void<T>::Type;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* This type trait detects if a class has an @c iid member variable. It is used to detect if
|
||||
* the FUID and DECLARE_CLASS_IID method or the U::UID method is used.
|
||||
*/
|
||||
template <typename T, typename U = void>
|
||||
struct HasIIDType : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct HasIIDType<T, FUnknownPrivate::VoidT<typename T::IID>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // FUnknownPrivate
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @return the TUID for an interface which uses the U::UID method. */
|
||||
template <typename T,
|
||||
typename std::enable_if<FUnknownPrivate::HasIIDType<T>::value>::type* = nullptr>
|
||||
const TUID& getTUID ()
|
||||
{
|
||||
return T::IID::toTUID ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** @return the TUID for an interface which uses the FUID and DECLARE_CLASS_IID method. */
|
||||
template <typename T,
|
||||
typename std::enable_if<!FUnknownPrivate::HasIIDType<T>::value>::type* = nullptr>
|
||||
const TUID& getTUID ()
|
||||
{
|
||||
return T::iid.toTUID ();
|
||||
}
|
||||
|
||||
#else // SMTG_CPP11_STDLIBSUPPORT
|
||||
|
||||
template<typename T>
|
||||
const TUID& getTUID ()
|
||||
{
|
||||
return T::iid.toTUID ();
|
||||
}
|
||||
|
||||
#endif // SMTG_CPP11_STDLIBSUPPORT
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline FUnknownPtr<I>::FUnknownPtr (FUnknown* unknown)
|
||||
{
|
||||
if (unknown && unknown->queryInterface (getTUID<I> (), (void**)&this->ptr) != kResultOk)
|
||||
this->ptr = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline I* FUnknownPtr<I>::operator= (FUnknown* unknown)
|
||||
{
|
||||
I* newPtr = 0;
|
||||
if (unknown && unknown->queryInterface (getTUID<I> (), (void**)&newPtr) == kResultOk)
|
||||
{
|
||||
OPtr<I> rel (newPtr);
|
||||
return IPtr<I>::operator= (newPtr);
|
||||
}
|
||||
|
||||
return IPtr<I>::operator= (0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FReleaser (obsolete)
|
||||
//------------------------------------------------------------------------
|
||||
/** Release an interface using automatic object (obsolete).
|
||||
This class is obsolete and is only kept for compatibility.
|
||||
The replacement for FReleaser is OPtr.
|
||||
|
||||
Usage example with FReleaser:
|
||||
\code{.cpp}
|
||||
void someFunction ()
|
||||
{
|
||||
IPath* path = pathCreateMethod ();
|
||||
FReleaser releaser (path);
|
||||
.... do something with path...
|
||||
.... path not used anymore, releaser will destroy it when leaving function scope
|
||||
}
|
||||
\endcode
|
||||
Usage example with OPtr:
|
||||
\code{.cpp}
|
||||
void someFunction ()
|
||||
{
|
||||
OPtr<IPath> path = pathCreateMethod ();
|
||||
.... do something with path...
|
||||
.... path not used anymore, OPtr will destroy it when leaving function scope
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
struct FReleaser
|
||||
{
|
||||
FReleaser (FUnknown* u) : u (u) {}
|
||||
~FReleaser ()
|
||||
{
|
||||
if (u)
|
||||
u->release ();
|
||||
}
|
||||
FUnknown* u;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,470 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/funknownimpl.h
|
||||
// Created by : Steinberg, 10/2021
|
||||
// Description : Steinberg Module Architecture Interface Implementation Helper
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/fplatform.h"
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if !(SMTG_CPP11)
|
||||
#error "C++11 is required for this header"
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
This header provides classes for working with FUnknown.
|
||||
|
||||
An interface which shall support Steinbergs Module Architecture should inherit from U::Unknown and provide a typedef
|
||||
@c IID of type U::UID.
|
||||
|
||||
On OS X you can generate an U::UID and copy it to the clipboard with the following shell command:
|
||||
@code
|
||||
uuidgen | { read id; echo -n "using IID = U::UID<0x${id:0:8}, 0x${id:9:4}${id:14:4}, 0x${id:19:4}${id:24:4}, 0x${id:28:8}>;" ; } | pbcopy
|
||||
@endcode
|
||||
|
||||
Example:
|
||||
@code{.cpp}
|
||||
struct IFoo : public U::Unknown
|
||||
{
|
||||
// Use a generated random uid here.
|
||||
using IID = U::UID<0x01234567, 0x89012345, 0x67890123, 0x45678901>;
|
||||
|
||||
virtual void bar () = 0;
|
||||
};
|
||||
@endcode
|
||||
|
||||
A class implementing the interface @c IFoo uses the U::Implements template to specify the
|
||||
interfaces it implements. All interfaces which the class should derive from need to be listed in the
|
||||
U::Directly template.
|
||||
|
||||
Example:
|
||||
@code{.cpp}
|
||||
struct FooImpl : public U::Implements<U::Directly<IFoo>>
|
||||
{
|
||||
void bar () override {}
|
||||
};
|
||||
@endcode
|
||||
|
||||
To check if a class can provide a specific interface use the U::cast function.
|
||||
|
||||
Example:
|
||||
@code{.cpp}
|
||||
void test (U::Unknown* obj)
|
||||
{
|
||||
if (auto foo = U::cast<IFoo> (obj))
|
||||
{
|
||||
// obj provided IFoo
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
The U::Implements class supports a second template parameter U::Indirectly for specifying
|
||||
a list of interfaces which should be available via @c queryInterface but not inherited from.
|
||||
This is useful if an interface extends another interface.
|
||||
|
||||
Example:
|
||||
@code{.cpp}
|
||||
struct IBar : public IFoo
|
||||
{
|
||||
using IID = U::UID<0x11223344, 0x55667788, 0x99001122, 0x33445566>;
|
||||
|
||||
virtual void baz () = 0;
|
||||
};
|
||||
|
||||
struct BarImpl : public U::Implements<U::Directly<IBar>, U::Indirectly<IFoo>>
|
||||
{
|
||||
void bar () override {}
|
||||
void baz () override {}
|
||||
};
|
||||
@endcode
|
||||
|
||||
In some cases a class shall be extended and an additional interface implemented.
|
||||
This is possible with the U::Extends template which is a generalization of the U::Implements
|
||||
template and allows specifying a base class from which should be inherited.
|
||||
|
||||
Example:
|
||||
@code{.cpp}
|
||||
struct ITest : public U::Unknown
|
||||
{
|
||||
using IID = U::UID<0x99887766, 0x55443322, 0x11009988, 0x77665544>;
|
||||
|
||||
virtual bool equal (int a, int b) const = 0;
|
||||
};
|
||||
|
||||
struct TestImpl : public U::Extends<FooImpl, U::Directly<ITest>>
|
||||
{
|
||||
bool equal (int a, int b) const override { return a == b; }
|
||||
};
|
||||
@endcode
|
||||
|
||||
To pass arbitrary arguments to the specified base class one can use the inherited @c Base
|
||||
typedef. All arguments passed to @c Base are automatically perfectly forwarded to the base class.
|
||||
|
||||
In the following example the value 42 is passed to the @c AlternativeFooImpl base class:
|
||||
@code{.cpp}
|
||||
struct AlternativeFooImpl : public U::Implements<U::Directly<IFoo>>
|
||||
{
|
||||
AlternativeFooImpl (int dummy = 0) : dummy {dummy} {}
|
||||
void bar () override {}
|
||||
|
||||
int dummy;
|
||||
};
|
||||
|
||||
struct AlternativeTestImpl : public U::Extends<AlternativeFooImpl, U::Directly<ITest>>
|
||||
{
|
||||
AlternativeTestImpl () : Base {42} {}
|
||||
|
||||
bool equal (int a, int b) const override { return a == b; }
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
// clang-format on
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace FUnknownImpl {
|
||||
|
||||
/** Typedef to keep everything in this namespace. */
|
||||
using Unknown = FUnknown;
|
||||
|
||||
/** A base class which hides the FUnknown::iid static var */
|
||||
struct HideIIDBase : FUnknown
|
||||
{
|
||||
using iid = void;
|
||||
};
|
||||
|
||||
/** Common destroyer policy for ski object instances.*/
|
||||
struct Destroyer
|
||||
{
|
||||
template <typename UnknownT>
|
||||
static void destroy (UnknownT* ptr)
|
||||
{
|
||||
if (!!ptr)
|
||||
ptr->release ();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base, typename D, typename I>
|
||||
class ImplementsImpl;
|
||||
|
||||
/**
|
||||
* This class provides a compile-time uid and enables interfaces to specify a UID as a simple
|
||||
* typedef. This way the FUID, DECLARE_CLASS_IID and DEF_CLASS_IID code can be omitted.
|
||||
*/
|
||||
template <uint32 t1, uint32 t2, uint32 t3, uint32 t4>
|
||||
struct UID
|
||||
{
|
||||
enum : int8
|
||||
{
|
||||
l1_1 = static_cast<int8> ((t1 & 0xFF000000) >> 24),
|
||||
l1_2 = static_cast<int8> ((t1 & 0x00FF0000) >> 16),
|
||||
l1_3 = static_cast<int8> ((t1 & 0x0000FF00) >> 8),
|
||||
l1_4 = static_cast<int8> ((t1 & 0x000000FF)),
|
||||
l2_1 = static_cast<int8> ((t2 & 0xFF000000) >> 24),
|
||||
l2_2 = static_cast<int8> ((t2 & 0x00FF0000) >> 16),
|
||||
l2_3 = static_cast<int8> ((t2 & 0x0000FF00) >> 8),
|
||||
l2_4 = static_cast<int8> ((t2 & 0x000000FF)),
|
||||
l3_1 = static_cast<int8> ((t3 & 0xFF000000) >> 24),
|
||||
l3_2 = static_cast<int8> ((t3 & 0x00FF0000) >> 16),
|
||||
l3_3 = static_cast<int8> ((t3 & 0x0000FF00) >> 8),
|
||||
l3_4 = static_cast<int8> ((t3 & 0x000000FF)),
|
||||
l4_1 = static_cast<int8> ((t4 & 0xFF000000) >> 24),
|
||||
l4_2 = static_cast<int8> ((t4 & 0x00FF0000) >> 16),
|
||||
l4_3 = static_cast<int8> ((t4 & 0x0000FF00) >> 8),
|
||||
l4_4 = static_cast<int8> ((t4 & 0x000000FF))
|
||||
};
|
||||
|
||||
UID () = delete;
|
||||
|
||||
static const TUID& toTUID ()
|
||||
{
|
||||
// clang-format off
|
||||
static TUID uuid = {
|
||||
#if COM_COMPATIBLE
|
||||
l1_4, l1_3, l1_2, l1_1,
|
||||
l2_2, l2_1, l2_4, l2_3,
|
||||
#else
|
||||
l1_1, l1_2, l1_3, l1_4,
|
||||
l2_1, l2_2, l2_3, l2_4,
|
||||
#endif
|
||||
l3_1, l3_2, l3_3, l3_4,
|
||||
l4_1, l4_2, l4_3, l4_4
|
||||
};
|
||||
// clang-format on
|
||||
return uuid;
|
||||
}
|
||||
};
|
||||
|
||||
/** @return the TUID for an interface. */
|
||||
template <typename T>
|
||||
const TUID& getTUID ()
|
||||
{
|
||||
return ::Steinberg::getTUID<T> ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given Unknown can provide the specified interface and returns it in an IPtr.
|
||||
*
|
||||
* @return an IPtr pointing to an instance of the requested interface or nullptr in case the
|
||||
* object does not provide the interface.
|
||||
*/
|
||||
template <typename I>
|
||||
IPtr<I> cast (Unknown* u)
|
||||
{
|
||||
I* out = nullptr;
|
||||
return u && u->queryInterface (getTUID<I> (), reinterpret_cast<void**> (&out)) == kResultOk ?
|
||||
owned (out) :
|
||||
nullptr;
|
||||
}
|
||||
|
||||
/** Casts to Unknown* and then to the specified interface. */
|
||||
template <typename I, typename S, typename T, typename U>
|
||||
IPtr<I> cast (ImplementsImpl<S, T, U>* u)
|
||||
{
|
||||
return cast<I> (u->unknownCast ());
|
||||
}
|
||||
|
||||
/** Casts to Unknown* and then to the specified interface. */
|
||||
template <typename I, typename T>
|
||||
IPtr<I> cast (const IPtr<T>& u)
|
||||
{
|
||||
return cast<I> (u.get ());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Detail {
|
||||
|
||||
/**
|
||||
* This struct implements reference counting for the @c U::Implements template.
|
||||
* It also provides a @c queryInterface method stub to support @c queryInterface
|
||||
* call made in the @c U::Implements template.
|
||||
*/
|
||||
struct RefCounted
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
RefCounted () = default;
|
||||
RefCounted (const RefCounted&) {}
|
||||
RefCounted (RefCounted&& other) SMTG_NOEXCEPT : refCount {other.refCount.load ()} {}
|
||||
virtual ~RefCounted () = default;
|
||||
|
||||
RefCounted& operator= (const RefCounted&) { return *this; }
|
||||
RefCounted& operator= (RefCounted&& other) SMTG_NOEXCEPT
|
||||
{
|
||||
refCount = other.refCount.load ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32 PLUGIN_API addRef () { return ++refCount; }
|
||||
|
||||
uint32 PLUGIN_API release ()
|
||||
{
|
||||
if (--refCount == 0)
|
||||
{
|
||||
destroyInstance ();
|
||||
refCount = -1000;
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
virtual void destroyInstance () {}
|
||||
|
||||
std::atomic<int32> refCount {1};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct NonDestroyable
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
NonDestroyable () = default;
|
||||
virtual ~NonDestroyable () = default;
|
||||
uint32 PLUGIN_API addRef () { return 1000; }
|
||||
uint32 PLUGIN_API release () { return 1000; }
|
||||
|
||||
private:
|
||||
virtual void destroyInstance () {}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct QueryInterfaceEnd : T
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API queryInterface (const TUID /*iid*/, void** obj)
|
||||
{
|
||||
*obj = nullptr;
|
||||
return kNoInterface;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Detail
|
||||
|
||||
/**
|
||||
* This struct is used to group a list of interfaces from which should be inherited and which
|
||||
* should be available via the @c queryInterface method.
|
||||
*/
|
||||
template <typename... T>
|
||||
struct Directly
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* This struct is used to group a list of interfaces from which should not be inherited but which
|
||||
* should be available via the @c queryInterface method.
|
||||
*/
|
||||
template <typename... T>
|
||||
struct Indirectly
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Base, typename D, typename I>
|
||||
class ImplementsImpl
|
||||
{
|
||||
static_assert (sizeof (Base) == -1, "use U::Directly and U::Indirectly to specify interfaces");
|
||||
};
|
||||
|
||||
template <typename Base, typename... DirectInterfaces, typename... IndirectInterfaces>
|
||||
class ImplementsImpl<Base, Indirectly<IndirectInterfaces...>, Directly<DirectInterfaces...>>
|
||||
{
|
||||
static_assert (sizeof (Base) == -1, "U::Indirectly only allowed after U::Directly");
|
||||
};
|
||||
|
||||
/** This class implements the required virtual methods for the U::Unknown class. */
|
||||
template <typename BaseClass, typename I, typename... DirectIFs, typename... IndirectIFs>
|
||||
class ImplementsImpl<BaseClass, Directly<I, DirectIFs...>, Indirectly<IndirectIFs...>>
|
||||
: public BaseClass, public I, public DirectIFs...
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* This is a convenience typedef for the deriving class to pass arguments to the
|
||||
* constructor, which are in turn passed to the base class of this class.
|
||||
*/
|
||||
using Base = ImplementsImpl<BaseClass, Directly<I, DirectIFs...>, Indirectly<IndirectIFs...>>;
|
||||
|
||||
template <typename... Args>
|
||||
ImplementsImpl (Args&&... args) : BaseClass {std::forward<Args> (args)...}
|
||||
{
|
||||
}
|
||||
|
||||
tresult PLUGIN_API queryInterface (const TUID tuid, void** obj) override
|
||||
{
|
||||
if (!obj)
|
||||
return kInvalidArgument;
|
||||
|
||||
if (queryInterfaceImpl<I, DirectIFs...> (tuid, *obj) ||
|
||||
queryInterfaceImpl<IndirectIFs...> (tuid, *obj))
|
||||
{
|
||||
static_cast<Unknown*> (*obj)->addRef ();
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
return BaseClass::queryInterface (tuid, obj);
|
||||
}
|
||||
|
||||
uint32 PLUGIN_API addRef () override { return BaseClass::addRef (); }
|
||||
uint32 PLUGIN_API release () override { return BaseClass::release (); }
|
||||
|
||||
Unknown* unknownCast () { return static_cast<Unknown*> (static_cast<I*> (this)); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
template <typename Interface>
|
||||
inline constexpr bool match (const TUID tuid) const noexcept
|
||||
{
|
||||
return reinterpret_cast<const uint64*> (tuid)[0] ==
|
||||
reinterpret_cast<const uint64*> (getTUID<Interface> ())[0] &&
|
||||
reinterpret_cast<const uint64*> (tuid)[1] ==
|
||||
reinterpret_cast<const uint64*> (getTUID<Interface> ())[1];
|
||||
}
|
||||
|
||||
template <int = 0>
|
||||
inline constexpr bool queryInterfaceImpl (const TUID, void*&) const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Interface, typename... RemainingInterfaces>
|
||||
inline bool queryInterfaceImpl (const TUID tuid, void*& obj) noexcept
|
||||
{
|
||||
if (match<Interface> (tuid) || match<Unknown> (tuid))
|
||||
{
|
||||
obj = static_cast<Interface*> (this->unknownCast ());
|
||||
return true;
|
||||
}
|
||||
|
||||
obj = getInterface<RemainingInterfaces...> (tuid);
|
||||
return obj != nullptr;
|
||||
}
|
||||
|
||||
template <int = 0>
|
||||
inline constexpr void* getInterface (const TUID) const noexcept
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Interface, typename... RemainingInterfaces>
|
||||
inline void* getInterface (const TUID tuid) noexcept
|
||||
{
|
||||
return match<Interface> (tuid) ? static_cast<Interface*> (this) :
|
||||
getInterface<RemainingInterfaces...> (tuid);
|
||||
}
|
||||
};
|
||||
|
||||
/** This typedef enables using a custom base class with the interface implementation. */
|
||||
template <typename BaseClass, typename D, typename I = Indirectly<>>
|
||||
using Extends = ImplementsImpl<BaseClass, D, I>;
|
||||
|
||||
/** This typedef provides the interface implementation. */
|
||||
template <typename D, typename I = Indirectly<>>
|
||||
using Implements = ImplementsImpl<Detail::QueryInterfaceEnd<Detail::RefCounted>, D, I>;
|
||||
|
||||
/** This typedef provides the interface implementation for objects which should not be destroyed via
|
||||
* FUnknown::release (like singletons). */
|
||||
template <typename D, typename I = Indirectly<>>
|
||||
using ImplementsNonDestroyable =
|
||||
ImplementsImpl<Detail::QueryInterfaceEnd<Detail::NonDestroyable>, D, I>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // FUnknownImpl
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Shortcut namespace for implementing FUnknown based objects. */
|
||||
namespace U {
|
||||
|
||||
using Unknown = FUnknownImpl::HideIIDBase;
|
||||
using FUnknownImpl::UID;
|
||||
using FUnknownImpl::Extends;
|
||||
using FUnknownImpl::Implements;
|
||||
using FUnknownImpl::ImplementsNonDestroyable;
|
||||
using FUnknownImpl::Directly;
|
||||
using FUnknownImpl::Indirectly;
|
||||
using FUnknownImpl::cast;
|
||||
using FUnknownImpl::getTUID;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace U
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/futils.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic utilities
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/ftypes.h"
|
||||
|
||||
namespace Steinberg {
|
||||
//----------------------------------------------------------------------------
|
||||
// min/max/etc. template functions
|
||||
template <class T>
|
||||
inline const T& Min (const T& a, const T& b)
|
||||
{
|
||||
return b < a ? b : a;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline const T& Max (const T& a, const T& b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline T Abs (const T& value)
|
||||
{
|
||||
return (value >= (T)0) ? value : -value;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline T Sign (const T& value)
|
||||
{
|
||||
return (value == (T)0) ? 0 : ((value >= (T)0) ? 1 : -1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline T Bound (T minval, T maxval, T x)
|
||||
{
|
||||
if (x < minval)
|
||||
return minval;
|
||||
if (x > maxval)
|
||||
return maxval;
|
||||
return x;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
void Swap (T& t1, T& t2)
|
||||
{
|
||||
T tmp = t1;
|
||||
t1 = t2;
|
||||
t2 = tmp;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
bool IsApproximateEqual (T t1, T t2, T epsilon)
|
||||
{
|
||||
if (t1 == t2)
|
||||
return true;
|
||||
T diff = t1 - t2;
|
||||
if (diff < 0.0)
|
||||
diff = -diff;
|
||||
if (diff < epsilon)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline T ToNormalized (const T& value, const int32 numSteps)
|
||||
{
|
||||
return value / T (numSteps);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline int32 FromNormalized (const T& norm, const int32 numSteps)
|
||||
{
|
||||
return Min<int32> (numSteps, int32 (norm * (numSteps + 1)));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Four character constant
|
||||
#ifndef CCONST
|
||||
#define CCONST(a, b, c, d) \
|
||||
((((int32) (a)) << 24) | (((int32) (b)) << 16) | (((int32) (c)) << 8) | (((int32) (d)) << 0))
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/fvariant.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/fstrdefs.h"
|
||||
#include "pluginterfaces/base/funknown.h"
|
||||
#include <cstdlib>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
|
||||
class FUnknown;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// FVariant struct declaration
|
||||
//------------------------------------------------------------------------
|
||||
/** A Value of variable type.
|
||||
\ingroup pluginBase
|
||||
*/
|
||||
class FVariant
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kEmpty = 0,
|
||||
kInteger = 1 << 0,
|
||||
kFloat = 1 << 1,
|
||||
kString8 = 1 << 2,
|
||||
kObject = 1 << 3,
|
||||
kOwner = 1 << 4,
|
||||
kString16 = 1 << 5
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// ctors
|
||||
inline FVariant () { memset (this, 0, sizeof (FVariant)); }
|
||||
inline FVariant (const FVariant& variant);
|
||||
|
||||
inline FVariant (bool b) : type (kInteger), intValue (b) {}
|
||||
inline FVariant (uint32 v) : type (kInteger), intValue (v) {}
|
||||
inline FVariant (int64 v) : type (kInteger), intValue (v) {}
|
||||
inline FVariant (double v) : type (kFloat), floatValue (v) {}
|
||||
inline FVariant (const char8* str) : type (kString8), string8 (str) {}
|
||||
inline FVariant (const char16* str) : type (kString16), string16 (str) {}
|
||||
inline FVariant (FUnknown* obj, bool owner = false) : type (kObject), object (obj)
|
||||
{
|
||||
setOwner (owner);
|
||||
}
|
||||
inline ~FVariant () { empty (); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline FVariant& operator= (const FVariant& variant);
|
||||
|
||||
inline void set (bool b)
|
||||
{
|
||||
setInt (b);
|
||||
}
|
||||
|
||||
inline void set (uint32 v)
|
||||
{
|
||||
setInt (v);
|
||||
}
|
||||
|
||||
inline void set (int64 v)
|
||||
{
|
||||
setInt (v);
|
||||
}
|
||||
|
||||
inline void set (double v)
|
||||
{
|
||||
setFloat (v);
|
||||
}
|
||||
|
||||
inline void set (const char8* c)
|
||||
{
|
||||
setString8 (c);
|
||||
}
|
||||
|
||||
inline void set (const char16* c)
|
||||
{
|
||||
setString16 (c);
|
||||
}
|
||||
|
||||
inline void setInt (int64 v)
|
||||
{
|
||||
empty ();
|
||||
type = kInteger;
|
||||
intValue = v;
|
||||
}
|
||||
|
||||
inline void setFloat (double v)
|
||||
{
|
||||
empty ();
|
||||
type = kFloat;
|
||||
floatValue = v;
|
||||
}
|
||||
inline void setString8 (const char8* v)
|
||||
{
|
||||
empty ();
|
||||
type = kString8;
|
||||
string8 = v;
|
||||
}
|
||||
inline void setString16 (const char16* v)
|
||||
{
|
||||
empty ();
|
||||
type = kString16;
|
||||
string16 = v;
|
||||
}
|
||||
|
||||
inline void setObject (FUnknown* obj)
|
||||
{
|
||||
empty ();
|
||||
type = kObject;
|
||||
object = obj;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T get () const;
|
||||
|
||||
inline int64 getInt () const { return (type & kInteger) ? intValue : 0; }
|
||||
inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; }
|
||||
inline double getNumber () const
|
||||
{
|
||||
return (type & kInteger) ? static_cast<double> (intValue) : (type & kFloat) ? floatValue :
|
||||
0.;
|
||||
}
|
||||
inline const char8* getString8 () const { return (type & kString8) ? string8 : nullptr; }
|
||||
inline const char16* getString16 () const { return (type & kString16) ? string16 : nullptr; }
|
||||
|
||||
inline FUnknown* getObject () const { return (type & kObject) ? object : nullptr; }
|
||||
|
||||
inline uint16 getType () const { return static_cast<uint16> (type & ~(kOwner)); }
|
||||
inline bool isEmpty () const { return getType () == kEmpty; }
|
||||
inline bool isOwner () const { return (type & kOwner) != 0; }
|
||||
inline bool isString () const { return (type & (kString8 | kString16)) != 0; }
|
||||
inline void setOwner (bool state)
|
||||
{
|
||||
if (state)
|
||||
type |= kOwner;
|
||||
else
|
||||
type &= ~kOwner;
|
||||
}
|
||||
|
||||
void empty ();
|
||||
//------------------------------------------------------------------------
|
||||
uint16 type;
|
||||
union
|
||||
{
|
||||
int64 intValue;
|
||||
double floatValue;
|
||||
const char8* string8;
|
||||
const char16* string16;
|
||||
FUnknown* object;
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool operator== (const FVariant& v1, const FVariant& v2)
|
||||
{
|
||||
#if SMTG_PLATFORM_64
|
||||
return v1.type == v2.type && v1.intValue == v2.intValue;
|
||||
#else
|
||||
if (v1.type != v2.type)
|
||||
return false;
|
||||
if (v1.type & (FVariant::kString8 | FVariant::kString16 | FVariant::kObject))
|
||||
return v1.string8 == v2.string8; // pointer type comparisons
|
||||
return v1.intValue == v2.intValue; // intValue & double comparison
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool FVariant::get<bool> () const
|
||||
{
|
||||
return getInt () != 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline uint32 FVariant::get<uint32> () const
|
||||
{
|
||||
return static_cast<uint32> (getInt ());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int32 FVariant::get<int32> () const
|
||||
{
|
||||
return static_cast<int32> (getInt ());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int64 FVariant::get<int64> () const
|
||||
{
|
||||
return static_cast<int64> (getInt ());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float FVariant::get<float> () const
|
||||
{
|
||||
return static_cast<float> (getFloat ());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double FVariant::get<double> () const
|
||||
{
|
||||
return getFloat ();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const char8* FVariant::get<const char8*> () const
|
||||
{
|
||||
return getString8 ();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const char16* FVariant::get<const char16*> () const
|
||||
{
|
||||
return getString16 ();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline FUnknown* FVariant::get<FUnknown*> () const
|
||||
{
|
||||
return getObject ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline bool operator!= (const FVariant& v1, const FVariant& v2) { return !(v1 == v2); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline FVariant::FVariant (const FVariant& variant) : type (kEmpty) { *this = variant; }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline void FVariant::empty ()
|
||||
{
|
||||
if (type & kOwner)
|
||||
{
|
||||
if ((type & kString8) && string8)
|
||||
free (const_cast<char8*> (string8)); // should match DELETESTR8
|
||||
else if ((type & kString16) && string16)
|
||||
free (const_cast<char16*> (string16)); // should match DELETESTR16
|
||||
|
||||
else if ((type & kObject) && object)
|
||||
object->release ();
|
||||
}
|
||||
memset (this, 0, sizeof (FVariant));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline FVariant& FVariant::operator= (const FVariant& variant)
|
||||
{
|
||||
empty ();
|
||||
|
||||
type = variant.type;
|
||||
|
||||
if ((type & kString8) && variant.string8)
|
||||
{
|
||||
string8 = static_cast<char8*> (malloc (strlen (variant.string8) + 1)); // should match NEWSTR8
|
||||
strcpy (const_cast<char8*> (string8), variant.string8);
|
||||
type |= kOwner;
|
||||
}
|
||||
else if ((type & kString16) && variant.string16)
|
||||
{
|
||||
auto len = static_cast<size_t> (strlen16 (variant.string16));
|
||||
string16 = static_cast<char16*> (malloc ((len + 1) * sizeof (char16))); // should match NEWSTR16
|
||||
char16* tmp = const_cast<char16*> (string16);
|
||||
memcpy (tmp, variant.string16, len * sizeof (char16));
|
||||
tmp[len] = 0;
|
||||
type |= kOwner;
|
||||
}
|
||||
else if ((type & kObject) && variant.object)
|
||||
{
|
||||
object = variant.object;
|
||||
object->addRef ();
|
||||
type |= kOwner;
|
||||
}
|
||||
else
|
||||
intValue = variant.intValue; // copy memory
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/ibstream.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Interface for reading/writing streams
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "funknown.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Base class for streams.
|
||||
\ingroup pluginBase
|
||||
- read/write binary data from/to stream
|
||||
- get/set stream read-write position (read and write position is the same)
|
||||
*/
|
||||
class IBStream: public FUnknown
|
||||
{
|
||||
public:
|
||||
enum IStreamSeekMode
|
||||
{
|
||||
kIBSeekSet = 0, ///< set absolute seek position
|
||||
kIBSeekCur, ///< set seek position relative to current position
|
||||
kIBSeekEnd ///< set seek position relative to stream end
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Reads binary data from stream.
|
||||
\param buffer : destination buffer
|
||||
\param numBytes : amount of bytes to be read
|
||||
\param numBytesRead : result - how many bytes have been read from stream (set to 0 if this is of no interest) */
|
||||
virtual tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead = nullptr) = 0;
|
||||
|
||||
/** Writes binary data to stream.
|
||||
\param buffer : source buffer
|
||||
\param numBytes : amount of bytes to write
|
||||
\param numBytesWritten : result - how many bytes have been written to stream (set to 0 if this is of no interest) */
|
||||
virtual tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = nullptr) = 0;
|
||||
|
||||
/** Sets stream read-write position.
|
||||
\param pos : new stream position (dependent on mode)
|
||||
\param mode : value of enum IStreamSeekMode
|
||||
\param result : new seek position (set to 0 if this is of no interest) */
|
||||
virtual tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result = nullptr) = 0;
|
||||
|
||||
/** Gets current stream read-write position.
|
||||
\param pos : is assigned the current position if function succeeds */
|
||||
virtual tresult PLUGIN_API tell (int64* pos) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IBStream, 0xC3BF6EA2, 0x30994752, 0x9B6BF990, 0x1EE33E9B)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Stream with a size.
|
||||
\ingroup pluginBase
|
||||
[extends IBStream] when stream type supports it (like file and memory stream)
|
||||
*/
|
||||
class ISizeableStream: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Return the stream size */
|
||||
virtual tresult PLUGIN_API getStreamSize (int64& size) = 0;
|
||||
/** Set the steam size. File streams can only be resized if they are write enabled. */
|
||||
virtual tresult PLUGIN_API setStreamSize (int64 size) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (ISizeableStream, 0x04F9549E, 0xE02F4E6E, 0x87E86A87, 0x47F4E17F)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/icloneable.h
|
||||
// Created by : Steinberg, 11/2007
|
||||
// Description : Interface for object copies
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "funknown.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Interface allowing an object to be copied.
|
||||
- [plug & host imp]
|
||||
- [released: N4.12]
|
||||
*/
|
||||
class ICloneable : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Create exact copy of the object */
|
||||
virtual FUnknown* PLUGIN_API clone () = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (ICloneable, 0xD45406B9, 0x3A2D4443, 0x9DAD9BA9, 0x85A1454B)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/ipersistent.h
|
||||
// Created by : Steinberg, 09/2004
|
||||
// Description : Plug-In Storage Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
class FVariant;
|
||||
class IAttributes;
|
||||
//------------------------------------------------------------------------
|
||||
/** Persistent Object Interface.
|
||||
[plug imp] \n
|
||||
This interface is used to store/restore attributes of an object.
|
||||
An IPlugController can implement this interface to handle presets.
|
||||
The gui-xml for a preset control looks like this:
|
||||
\code
|
||||
....
|
||||
<view name="PresetView" data="Preset"/>
|
||||
....
|
||||
<template name="PresetView">
|
||||
<view name="preset control" size="0, 0, 100, 20"/>
|
||||
<switch name="store preset" size="125,0,80,20" style="push|immediate" title="Store" />
|
||||
<switch name="remove preset" size="220,0,80,20" style="push|immediate" title="Delete" />
|
||||
</template>
|
||||
\endcode
|
||||
The tag data="Preset" tells the host to create a preset controller that handles the
|
||||
3 values named "preset control", "store preset", and "remove preset".
|
||||
*/
|
||||
class IPersistent: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** The class ID must be a 16 bytes unique id that is used to create the object.
|
||||
This ID is also used to identify the preset list when used with presets. */
|
||||
virtual tresult PLUGIN_API getClassID (char8* uid) = 0;
|
||||
/** Store all members/data in the passed IAttributes. */
|
||||
virtual tresult PLUGIN_API saveAttributes (IAttributes* ) = 0;
|
||||
/** Restore all members/data from the passed IAttributes. */
|
||||
virtual tresult PLUGIN_API loadAttributes (IAttributes* ) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPersistent, 0xBA1A4637, 0x3C9F46D0, 0xA65DBA0E, 0xB85DA829)
|
||||
|
||||
|
||||
typedef FIDString IAttrID;
|
||||
//------------------------------------------------------------------------
|
||||
/** Object Data Archive Interface.
|
||||
- [host imp]
|
||||
|
||||
- store data/objects/binary/subattributes in the archive
|
||||
- read stored data from the archive
|
||||
|
||||
All data stored to the archive are identified by a string (IAttrID), which must be unique on each
|
||||
IAttribute level.
|
||||
|
||||
The basic set/get methods make use of the FVariant class defined in 'funknown.h'.
|
||||
For a more convenient usage of this interface, you should use the functions defined
|
||||
in namespace PAttributes (public.sdk/source/common/pattributes.h+cpp) !!
|
||||
|
||||
\ingroup frameworkHostClasses
|
||||
*/
|
||||
class IAttributes: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/*! \name Methods to write attributes
|
||||
******************************************************************************************************** */
|
||||
//@{
|
||||
/** Store any data in the archive. It is even possible to store sub-attributes by creating
|
||||
a new IAttributes instance via the IHostClasses interface and pass it to the parent in the
|
||||
FVariant. In this case the archive must take the ownership of the newly created object, which
|
||||
is true for all objects that have been created only for storing. You tell the archive to take
|
||||
ownership by adding the FVariant::kOwner flag to the FVariant::type member (data.type |= FVariant::kOwner).
|
||||
When using the PAttributes functions, this is done through a function parameter.*/
|
||||
virtual tresult PLUGIN_API set (IAttrID attrID, const FVariant& data) = 0;
|
||||
|
||||
/** Store a list of data in the archive. Please note that the type of data is not mixable! So
|
||||
you can only store a list of integers or a list of doubles/strings/etc. You can also store a list
|
||||
of subattributes or other objects that implement the IPersistent interface.*/
|
||||
virtual tresult PLUGIN_API queue (IAttrID listID, const FVariant& data) = 0;
|
||||
|
||||
/** Store binary data in the archive. Parameter 'copyBytes' specifies if the passed data should be copied.
|
||||
The archive cannot take the ownership of binary data. Either it just references a buffer in order
|
||||
to write it to a file (copyBytes = false) or it copies the data to its own buffers (copyBytes = true).
|
||||
When binary data should be stored in the default pool for example, you must always copy it!*/
|
||||
virtual tresult PLUGIN_API setBinaryData (IAttrID attrID, void* data, uint32 bytes, bool copyBytes) = 0;
|
||||
//@}
|
||||
|
||||
/*! \name Methods to read attributes
|
||||
******************************************************************************************************** */
|
||||
//@{
|
||||
/** Get data previously stored to the archive. */
|
||||
virtual tresult PLUGIN_API get (IAttrID attrID, FVariant& data) = 0;
|
||||
|
||||
/** Get list of data previously stored to the archive. As long as there are queue members the method
|
||||
will return kResultTrue. When the queue is empty, the methods returns kResultFalse. All lists except from
|
||||
object lists can be reset which means that the items can be read once again. \see IAttributes::resetQueue */
|
||||
virtual tresult PLUGIN_API unqueue (IAttrID listID, FVariant& data) = 0;
|
||||
|
||||
/** Get the amount of items in a queue. */
|
||||
virtual int32 PLUGIN_API getQueueItemCount (IAttrID) = 0;
|
||||
|
||||
/** Reset a queue. If you need to restart reading a queue, you have to reset it. You can reset a queue at any time.*/
|
||||
virtual tresult PLUGIN_API resetQueue (IAttrID attrID) = 0;
|
||||
|
||||
/** Reset all queues in the archive.*/
|
||||
virtual tresult PLUGIN_API resetAllQueues () = 0;
|
||||
|
||||
/** Read binary data from the archive. The data is copied into the passed buffer. The size of that buffer
|
||||
must fit the size of data stored in the archive which can be queried via IAttributes::getBinaryDataSize */
|
||||
virtual tresult PLUGIN_API getBinaryData (IAttrID attrID, void* data, uint32 bytes) = 0;
|
||||
/** Get the size in bytes of binary data in the archive. */
|
||||
virtual uint32 PLUGIN_API getBinaryDataSize (IAttrID attrID) = 0;
|
||||
//@}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IAttributes, 0xFA1E32F9, 0xCA6D46F5, 0xA982F956, 0xB1191B58)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended access to Attributes; supports Attribute retrieval via iteration.
|
||||
- [host imp]
|
||||
- [released] C7/N6
|
||||
|
||||
\ingroup frameworkHostClasses
|
||||
*/
|
||||
class IAttributes2 : public IAttributes
|
||||
{
|
||||
public:
|
||||
/** Returns the number of existing attributes. */
|
||||
virtual int32 PLUGIN_API countAttributes () const = 0;
|
||||
/** Returns the attribute's ID for the given index. */
|
||||
virtual IAttrID PLUGIN_API getAttributeID (int32 index) const = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IAttributes2, 0x1382126A, 0xFECA4871, 0x97D52A45, 0xB042AE99)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,520 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/ipluginbase.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic Plug-in Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "funknown.h"
|
||||
#include "fstrdefs.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Basic interface to a plug-in component: IPluginBase
|
||||
\ingroup pluginBase
|
||||
- [plug imp]
|
||||
- initialize/terminate the plug-in component
|
||||
|
||||
The host uses this interface to initialize and to terminate the plug-in component.
|
||||
The context that is passed to the initialize method contains any interface to the
|
||||
host that the plug-in will need to work. These interfaces can vary from category to category.
|
||||
A list of supported host context interfaces should be included in the documentation
|
||||
of a specific category.
|
||||
*/
|
||||
class IPluginBase: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** The host passes a number of interfaces as context to initialize the plug-in class.
|
||||
\param context, passed by the host, is mandatory and should implement IHostApplication
|
||||
@note Extensive memory allocations etc. should be performed in this method rather than in
|
||||
the class' constructor! If the method does NOT return kResultOk, the object is released
|
||||
immediately. In this case terminate is not called! */
|
||||
virtual tresult PLUGIN_API initialize (FUnknown* context) = 0;
|
||||
|
||||
/** This function is called before the plug-in is unloaded and can be used for
|
||||
cleanups. You have to release all references to any host application interfaces. */
|
||||
virtual tresult PLUGIN_API terminate () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPluginBase, 0x22888DDB, 0x156E45AE, 0x8358B348, 0x08190625)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Basic Information about the class factory of the plug-in.
|
||||
\ingroup pluginBase
|
||||
*/
|
||||
struct PFactoryInfo
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
enum FactoryFlags
|
||||
{
|
||||
/** Nothing */
|
||||
kNoFlags = 0,
|
||||
|
||||
/** The number of exported classes can change each time the Module is loaded. If this flag
|
||||
is set, the host does not cache class information. This leads to a longer startup time
|
||||
because the host always has to load the Module to get the current class information. */
|
||||
kClassesDiscardable = 1 << 0,
|
||||
|
||||
/** This flag is deprecated, do not use anymore, resp. it will get ignored from
|
||||
Cubase/Nuendo 12 and later. */
|
||||
kLicenseCheck = 1 << 1,
|
||||
|
||||
/** Component will not be unloaded until process exit */
|
||||
kComponentNonDiscardable = 1 << 3,
|
||||
|
||||
/** Components have entirely unicode encoded strings (True for VST 3 plug-ins so far). */
|
||||
kUnicode = 1 << 4
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kURLSize = 256,
|
||||
kEmailSize = 128,
|
||||
kNameSize = 64
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
char8 vendor[kNameSize]; ///< e.g. "Steinberg Media Technologies"
|
||||
char8 url[kURLSize]; ///< e.g. "http://www.steinberg.de"
|
||||
char8 email[kEmailSize]; ///< e.g. "info@steinberg.de"
|
||||
int32 flags; ///< (see FactoryFlags above)
|
||||
//------------------------------------------------------------------------
|
||||
SMTG_CONSTEXPR14 PFactoryInfo (const char8* _vendor, const char8* _url, const char8* _email,
|
||||
int32 _flags)
|
||||
#if SMTG_CPP14
|
||||
: vendor (), url (), email (), flags ()
|
||||
#endif
|
||||
{
|
||||
strncpy8 (vendor, _vendor, kNameSize);
|
||||
strncpy8 (url, _url, kURLSize);
|
||||
strncpy8 (email, _email, kEmailSize);
|
||||
flags = _flags;
|
||||
#ifdef UNICODE
|
||||
flags |= kUnicode;
|
||||
#endif
|
||||
}
|
||||
#if SMTG_CPP11
|
||||
constexpr PFactoryInfo () : vendor (), url (), email (), flags () {}
|
||||
#else
|
||||
PFactoryInfo () { memset (this, 0, sizeof (PFactoryInfo)); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Basic Information about a class provided by the plug-in.
|
||||
\ingroup pluginBase
|
||||
*/
|
||||
struct PClassInfo
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
enum ClassCardinality
|
||||
{
|
||||
kManyInstances = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kCategorySize = 32,
|
||||
kNameSize = 64
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
/** Class ID 16 Byte class GUID */
|
||||
TUID cid;
|
||||
|
||||
/** Cardinality of the class, set to kManyInstances (see \ref PClassInfo::ClassCardinality) */
|
||||
int32 cardinality;
|
||||
|
||||
/** Class category, host uses this to categorize interfaces */
|
||||
char8 category[kCategorySize];
|
||||
|
||||
/** Class name, visible to the user */
|
||||
char8 name[kNameSize];
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
SMTG_CONSTEXPR14 PClassInfo (const TUID _cid, int32 _cardinality, const char8* _category,
|
||||
const char8* _name)
|
||||
#if SMTG_CPP14
|
||||
: cid (), cardinality (), category (), name ()
|
||||
#endif
|
||||
{
|
||||
#if SMTG_CPP14
|
||||
copyTUID (cid, _cid);
|
||||
#else
|
||||
memset (this, 0, sizeof (PClassInfo));
|
||||
memcpy (cid, _cid, sizeof (TUID));
|
||||
#endif
|
||||
if (_category)
|
||||
strncpy8 (category, _category, kCategorySize);
|
||||
if (_name)
|
||||
strncpy8 (name, _name, kNameSize);
|
||||
cardinality = _cardinality;
|
||||
}
|
||||
#if SMTG_CPP11
|
||||
constexpr PClassInfo () : cid (), cardinality (), category (), name () {}
|
||||
#else
|
||||
PClassInfo () { memset (this, 0, sizeof (PClassInfo)); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IPluginFactory interface declaration
|
||||
//------------------------------------------------------------------------
|
||||
/** Class factory that any plug-in defines for creating class instances: IPluginFactory
|
||||
\ingroup pluginBase
|
||||
- [plug imp]
|
||||
|
||||
From the host's point of view a plug-in module is a factory which can create
|
||||
a certain kind of object(s). The interface IPluginFactory provides methods
|
||||
to get information about the classes exported by the plug-in and a
|
||||
mechanism to create instances of these classes (that usually define the IPluginBase interface).
|
||||
|
||||
<b> An implementation is provided in public.sdk/source/common/pluginfactory.cpp </b>
|
||||
\see GetPluginFactory
|
||||
*/
|
||||
class IPluginFactory : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Fill a PFactoryInfo structure with information about the plug-in vendor. */
|
||||
virtual tresult PLUGIN_API getFactoryInfo (PFactoryInfo* info) = 0;
|
||||
|
||||
/** Returns the number of exported classes by this factory. If you are using the CPluginFactory
|
||||
* implementation provided by the SDK, it returns the number of classes you registered with
|
||||
* CPluginFactory::registerClass. */
|
||||
virtual int32 PLUGIN_API countClasses () = 0;
|
||||
|
||||
/** Fill a PClassInfo structure with information about the class at the specified index. */
|
||||
virtual tresult PLUGIN_API getClassInfo (int32 index, PClassInfo* info) = 0;
|
||||
|
||||
/** Create a new class instance. */
|
||||
virtual tresult PLUGIN_API createInstance (FIDString cid, FIDString _iid, void** obj) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPluginFactory, 0x7A4D811C, 0x52114A1F, 0xAED9D2EE, 0x0B43BF9F)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Version 2 of Basic Information about a class provided by the plug-in.
|
||||
\ingroup pluginBase
|
||||
*/
|
||||
struct PClassInfo2
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
/** Class ID 16 Byte class GUID */
|
||||
TUID cid;
|
||||
|
||||
/** Cardinality of the class, set to kManyInstances (see \ref PClassInfo::ClassCardinality) */
|
||||
int32 cardinality;
|
||||
|
||||
/** Class category, host uses this to categorize interfaces */
|
||||
char8 category[PClassInfo::kCategorySize];
|
||||
|
||||
/** Class name, visible to the user */
|
||||
char8 name[PClassInfo::kNameSize];
|
||||
|
||||
enum {
|
||||
kVendorSize = 64,
|
||||
kVersionSize = 64,
|
||||
kSubCategoriesSize = 128
|
||||
};
|
||||
|
||||
/** flags used for a specific category, must be defined where category is defined */
|
||||
uint32 classFlags;
|
||||
|
||||
/** module specific subcategories, can be more than one, logically added by the OR operator */
|
||||
char8 subCategories[kSubCategoriesSize];
|
||||
|
||||
/** overwrite vendor information from factory info */
|
||||
char8 vendor[kVendorSize];
|
||||
|
||||
/** Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) */
|
||||
char8 version[kVersionSize];
|
||||
|
||||
/** SDK version used to build this class (e.g. "VST 3.0") */
|
||||
char8 sdkVersion[kVersionSize];
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
SMTG_CONSTEXPR14 PClassInfo2 (const TUID _cid, int32 _cardinality, const char8* _category,
|
||||
const char8* _name, int32 _classFlags,
|
||||
const char8* _subCategories, const char8* _vendor,
|
||||
const char8* _version, const char8* _sdkVersion)
|
||||
#if SMTG_CPP14
|
||||
: cid ()
|
||||
, cardinality ()
|
||||
, category ()
|
||||
, name ()
|
||||
, classFlags ()
|
||||
, subCategories ()
|
||||
, vendor ()
|
||||
, version ()
|
||||
, sdkVersion ()
|
||||
#endif
|
||||
{
|
||||
#if SMTG_CPP14
|
||||
copyTUID (cid, _cid);
|
||||
#else
|
||||
memset (this, 0, sizeof (PClassInfo2));
|
||||
memcpy (cid, _cid, sizeof (TUID));
|
||||
#endif
|
||||
cardinality = _cardinality;
|
||||
if (_category)
|
||||
strncpy8 (category, _category, PClassInfo::kCategorySize);
|
||||
if (_name)
|
||||
strncpy8 (name, _name, PClassInfo::kNameSize);
|
||||
classFlags = static_cast<uint32> (_classFlags);
|
||||
if (_subCategories)
|
||||
strncpy8 (subCategories, _subCategories, kSubCategoriesSize);
|
||||
if (_vendor)
|
||||
strncpy8 (vendor, _vendor, kVendorSize);
|
||||
if (_version)
|
||||
strncpy8 (version, _version, kVersionSize);
|
||||
if (_sdkVersion)
|
||||
strncpy8 (sdkVersion, _sdkVersion, kVersionSize);
|
||||
}
|
||||
#if SMTG_CPP11
|
||||
constexpr PClassInfo2 ()
|
||||
: cid ()
|
||||
, cardinality ()
|
||||
, category ()
|
||||
, name ()
|
||||
, classFlags ()
|
||||
, subCategories ()
|
||||
, vendor ()
|
||||
, version ()
|
||||
, sdkVersion ()
|
||||
{
|
||||
}
|
||||
#else
|
||||
PClassInfo2 () { memset (this, 0, sizeof (PClassInfo2)); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IPluginFactory2 interface declaration
|
||||
//------------------------------------------------------------------------
|
||||
/** Version 2 of class factory supporting PClassInfo2: IPluginFactory2
|
||||
\ingroup pluginBase
|
||||
\copydoc IPluginFactory
|
||||
*/
|
||||
class IPluginFactory2 : public IPluginFactory
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns the class info (version 2) for a given index. */
|
||||
virtual tresult PLUGIN_API getClassInfo2 (int32 index, PClassInfo2* info) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (IPluginFactory2, 0x0007B650, 0xF24B4C0B, 0xA464EDB9, 0xF00B2ABB)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Unicode Version of Basic Information about a class provided by the plug-in
|
||||
*/
|
||||
struct PClassInfoW
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
TUID cid; ///< see \ref PClassInfo
|
||||
int32 cardinality; ///< see \ref PClassInfo
|
||||
char8 category[PClassInfo::kCategorySize]; ///< see \ref PClassInfo
|
||||
char16 name[PClassInfo::kNameSize]; ///< see \ref PClassInfo
|
||||
|
||||
enum {
|
||||
kVendorSize = 64,
|
||||
kVersionSize = 64,
|
||||
kSubCategoriesSize = 128
|
||||
};
|
||||
|
||||
/** flags used for a specific category, must be defined where category is defined */
|
||||
uint32 classFlags;
|
||||
|
||||
/** module specific subcategories, can be more than one, logically added by the OR operator */
|
||||
char8 subCategories[kSubCategoriesSize];
|
||||
|
||||
/** overwrite vendor information from factory info */
|
||||
char16 vendor[kVendorSize];
|
||||
|
||||
/** Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) */
|
||||
char16 version[kVersionSize];
|
||||
|
||||
/** SDK version used to build this class (e.g. "VST 3.0") */
|
||||
char16 sdkVersion[kVersionSize];
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
SMTG_CONSTEXPR14 PClassInfoW (const TUID _cid, int32 _cardinality, const char8* _category,
|
||||
const char16* _name, int32 _classFlags,
|
||||
const char8* _subCategories, const char16* _vendor,
|
||||
const char16* _version, const char16* _sdkVersion)
|
||||
#if SMTG_CPP14
|
||||
: cid ()
|
||||
, cardinality ()
|
||||
, category ()
|
||||
, name ()
|
||||
, classFlags ()
|
||||
, subCategories ()
|
||||
, vendor ()
|
||||
, version ()
|
||||
, sdkVersion ()
|
||||
#endif
|
||||
{
|
||||
#if SMTG_CPP14
|
||||
copyTUID (cid, _cid);
|
||||
#else
|
||||
memset (this, 0, sizeof (PClassInfoW));
|
||||
memcpy (cid, _cid, sizeof (TUID));
|
||||
#endif
|
||||
cardinality = _cardinality;
|
||||
if (_category)
|
||||
strncpy8 (category, _category, PClassInfo::kCategorySize);
|
||||
if (_name)
|
||||
strncpy16 (name, _name, PClassInfo::kNameSize);
|
||||
classFlags = static_cast<uint32> (_classFlags);
|
||||
if (_subCategories)
|
||||
strncpy8 (subCategories, _subCategories, kSubCategoriesSize);
|
||||
if (_vendor)
|
||||
strncpy16 (vendor, _vendor, kVendorSize);
|
||||
if (_version)
|
||||
strncpy16 (version, _version, kVersionSize);
|
||||
if (_sdkVersion)
|
||||
strncpy16 (sdkVersion, _sdkVersion, kVersionSize);
|
||||
}
|
||||
#if SMTG_CPP11
|
||||
constexpr PClassInfoW ()
|
||||
: cid ()
|
||||
, cardinality ()
|
||||
, category ()
|
||||
, name ()
|
||||
, classFlags ()
|
||||
, subCategories ()
|
||||
, vendor ()
|
||||
, version ()
|
||||
, sdkVersion ()
|
||||
{
|
||||
}
|
||||
#else
|
||||
PClassInfoW () { memset (this, 0, sizeof (PClassInfoW)); }
|
||||
#endif
|
||||
|
||||
SMTG_CONSTEXPR14 void fromAscii (const PClassInfo2& ci2)
|
||||
{
|
||||
#if SMTG_CPP14
|
||||
copyTUID (cid, ci2.cid);
|
||||
#else
|
||||
memcpy (cid, ci2.cid, sizeof (TUID));
|
||||
#endif
|
||||
cardinality = ci2.cardinality;
|
||||
strncpy8 (category, ci2.category, PClassInfo::kCategorySize);
|
||||
str8ToStr16 (name, ci2.name, PClassInfo::kNameSize);
|
||||
classFlags = ci2.classFlags;
|
||||
strncpy8 (subCategories, ci2.subCategories, kSubCategoriesSize);
|
||||
|
||||
str8ToStr16 (vendor, ci2.vendor, kVendorSize);
|
||||
str8ToStr16 (version, ci2.version, kVersionSize);
|
||||
str8ToStr16 (sdkVersion, ci2.sdkVersion, kVersionSize);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IPluginFactory3 interface declaration
|
||||
//------------------------------------------------------------------------
|
||||
/** Version 3 of class factory supporting PClassInfoW: IPluginFactory3
|
||||
\ingroup pluginBase
|
||||
\copydoc IPluginFactory
|
||||
*/
|
||||
class IPluginFactory3 : public IPluginFactory2
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns the unicode class info for a given index. */
|
||||
virtual tresult PLUGIN_API getClassInfoUnicode (int32 index, PClassInfoW* info) = 0;
|
||||
|
||||
/** Receives information about host*/
|
||||
virtual tresult PLUGIN_API setHostContext (FUnknown* context) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (IPluginFactory3, 0x4555A2AB, 0xC1234E57, 0x9B122910, 0x36878931)
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define LICENCE_UID(l1, l2, l3, l4) \
|
||||
{ \
|
||||
(int8)((l1 & 0xFF000000) >> 24), (int8)((l1 & 0x00FF0000) >> 16), \
|
||||
(int8)((l1 & 0x0000FF00) >> 8), (int8)((l1 & 0x000000FF) ), \
|
||||
(int8)((l2 & 0xFF000000) >> 24), (int8)((l2 & 0x00FF0000) >> 16), \
|
||||
(int8)((l2 & 0x0000FF00) >> 8), (int8)((l2 & 0x000000FF) ), \
|
||||
(int8)((l3 & 0xFF000000) >> 24), (int8)((l3 & 0x00FF0000) >> 16), \
|
||||
(int8)((l3 & 0x0000FF00) >> 8), (int8)((l3 & 0x000000FF) ), \
|
||||
(int8)((l4 & 0xFF000000) >> 24), (int8)((l4 & 0x00FF0000) >> 16), \
|
||||
(int8)((l4 & 0x0000FF00) >> 8), (int8)((l4 & 0x000000FF) ) \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// GetPluginFactory
|
||||
//------------------------------------------------------------------------
|
||||
/** Plug-in entry point.
|
||||
\ingroup pluginBase
|
||||
Any plug-in must define and export this function. \n
|
||||
A typical implementation of GetPluginFactory looks like this
|
||||
\code{.cpp}
|
||||
SMTG_EXPORT_SYMBOL IPluginFactory* PLUGIN_API GetPluginFactory ()
|
||||
{
|
||||
if (!gPluginFactory)
|
||||
{
|
||||
static PFactoryInfo factoryInfo =
|
||||
{
|
||||
"My Company Name",
|
||||
"http://www.mywebpage.com",
|
||||
"mailto:myemail@address.com",
|
||||
PFactoryInfo::kNoFlags
|
||||
};
|
||||
|
||||
gPluginFactory = new CPluginFactory (factoryInfo);
|
||||
|
||||
static PClassInfo componentClass =
|
||||
{
|
||||
INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000), // replace by a valid uid
|
||||
1,
|
||||
"Service", // category
|
||||
"Name"
|
||||
};
|
||||
|
||||
gPluginFactory->registerClass (&componentClass, MyComponentClass::newInstance);
|
||||
}
|
||||
else
|
||||
gPluginFactory->addRef ();
|
||||
|
||||
return gPluginFactory;
|
||||
}
|
||||
\endcode
|
||||
\see \ref loadPlugin
|
||||
*/
|
||||
extern "C"
|
||||
{
|
||||
SMTG_EXPORT_SYMBOL Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory ();
|
||||
typedef Steinberg::IPluginFactory* (PLUGIN_API *GetFactoryProc) ();
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/iplugincompatibility.h
|
||||
// Created by : Steinberg, 02/2022
|
||||
// Description : Basic Plug-in Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "ibstream.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** moduleinfo.json
|
||||
|
||||
The moduleinfo.json describes the contents of the plug-in in a JSON5 compatible format (See https://json5.org/).
|
||||
It contains the factory info (see PFactoryInfo), the contained classes (see PClassInfo), the
|
||||
included snapshots and a list of compatibility of the included classes.
|
||||
|
||||
An example moduleinfo.json:
|
||||
|
||||
\code
|
||||
{
|
||||
"Name": "",
|
||||
"Version": "1.0",
|
||||
"Factory Info": {
|
||||
"Vendor": "Steinberg Media Technologies",
|
||||
"URL": "http://www.steinberg.net",
|
||||
"E-Mail": "mailto:info@steinberg.de",
|
||||
"Flags": {
|
||||
"Unicode": true,
|
||||
"Classes Discardable": false,
|
||||
"Component Non Discardable": false,
|
||||
},
|
||||
},
|
||||
"Compatibility": [
|
||||
{
|
||||
"New": "B9F9ADE1CD9C4B6DA57E61E3123535FD",
|
||||
"Old": [
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // just an example
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", // another example
|
||||
],
|
||||
},
|
||||
],
|
||||
"Classes": [
|
||||
{
|
||||
"CID": "B9F9ADE1CD9C4B6DA57E61E3123535FD",
|
||||
"Category": "Audio Module Class",
|
||||
"Name": "AGainSimple VST3",
|
||||
"Vendor": "Steinberg Media Technologies",
|
||||
"Version": "1.3.0.1",
|
||||
"SDKVersion": "VST 3.7.4",
|
||||
"Sub Categories": [
|
||||
"Fx",
|
||||
],
|
||||
"Class Flags": 0,
|
||||
"Cardinality": 2147483647,
|
||||
"Snapshots": [
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
#define kPluginCompatibilityClass "Plugin Compatibility Class"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** optional interface to query the compatibility of the plug-ins classes
|
||||
- [plug imp]
|
||||
|
||||
A plug-in can add a class with this interface to its class factory if it cannot provide a
|
||||
moduleinfo.json file in its plug-in package/bundle where the compatibility is normally part of.
|
||||
|
||||
If the module contains a moduleinfo.json the host will ignore this class.
|
||||
|
||||
The class must write into the stream an UTF-8 encoded json description of the compatibility of
|
||||
the other classes in the factory.
|
||||
|
||||
It is expected that the JSON5 written starts with an array:
|
||||
\code
|
||||
[
|
||||
{
|
||||
"New": "B9F9ADE1CD9C4B6DA57E61E3123535FD",
|
||||
"Old": [
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // just an example
|
||||
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", // another example
|
||||
],
|
||||
},
|
||||
]
|
||||
\endcode
|
||||
*/
|
||||
class IPluginCompatibility : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** get the compatibility stream
|
||||
* @param stream the stream the plug-in must write the UTF8 encoded JSON5 compatibility
|
||||
* string.
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API getCompatibilityJSON (IBStream* stream) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPluginCompatibility, 0x4AFD4B6A, 0x35D7C240, 0xA5C31414, 0xFB7D15E6)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Steinberg
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/istringresult.h
|
||||
// Created by : Steinberg, 01/2005
|
||||
// Description : Strings Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Interface to return an ascii string of variable size.
|
||||
In order to manage memory allocation and deallocation properly,
|
||||
this interface is used to transfer a string as result parameter of
|
||||
a method requires a string of unknown size.
|
||||
- [host imp] or [plug imp]
|
||||
- [released: SX 4]
|
||||
*/
|
||||
class IStringResult : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
virtual void PLUGIN_API setText (const char8* text) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IStringResult, 0x550798BC, 0x872049DB, 0x84920A15, 0x3B50B7A8)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Interface to a string of variable size and encoding.
|
||||
- [host imp] or [plug imp]
|
||||
- [released: ]
|
||||
*/
|
||||
class IString : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Assign ASCII string */
|
||||
virtual void PLUGIN_API setText8 (const char8* text) = 0;
|
||||
/** Assign unicode string */
|
||||
virtual void PLUGIN_API setText16 (const char16* text) = 0;
|
||||
|
||||
/** Return ASCII string. If the string is unicode so far, it will be converted.
|
||||
So you need to be careful, because the conversion can result in data loss.
|
||||
It is save though to call getText8 if isWideString() returns false */
|
||||
virtual const char8* PLUGIN_API getText8 () = 0;
|
||||
/** Return unicode string. If the string is ASCII so far, it will be converted. */
|
||||
virtual const char16* PLUGIN_API getText16 () = 0;
|
||||
|
||||
/** !Do not use this method! Early implementations take the given pointer as
|
||||
internal string and this will cause problems because 'free' will be used to delete the passed memory.
|
||||
Later implementations will redirect 'take' to setText8 and setText16 */
|
||||
virtual void PLUGIN_API take (void* s, bool isWide) = 0;
|
||||
|
||||
/** Returns true if the string is in unicode format, returns false if the string is ASCII */
|
||||
virtual bool PLUGIN_API isWideString () const = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IString, 0xF99DB7A3, 0x0FC14821, 0x800B0CF9, 0x8E348EDF)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : Steinberg Module Architecture SDK
|
||||
//
|
||||
// Category : Basic Host Service Interfaces
|
||||
// Filename : pluginterfaces/base/iupdatehandler.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Update handling
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
class IDependent;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Host implements dependency handling for plugins.
|
||||
- [host imp]
|
||||
- [get this interface from IHostClasses]
|
||||
- [released N3.1]
|
||||
|
||||
- Install/Remove change notifications
|
||||
- Trigger updates when an object has changed
|
||||
|
||||
Can be used between host-objects and the Plug-In or
|
||||
inside the Plug-In to handle internal updates!
|
||||
|
||||
\see IDependent
|
||||
\ingroup frameworkHostClasses
|
||||
*/
|
||||
class IUpdateHandler: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Install update notification for given object. It is essential to
|
||||
remove all dependencies again using 'removeDependent'! Dependencies
|
||||
are not removed automatically when the 'object' is released!
|
||||
\param object : interface to object that sends change notifications
|
||||
\param dependent : interface through which the update is passed */
|
||||
virtual tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) = 0;
|
||||
|
||||
/** Remove a previously installed dependency.*/
|
||||
virtual tresult PLUGIN_API removeDependent (FUnknown* object, IDependent* dependent) = 0;
|
||||
|
||||
/** Inform all dependents, that object has changed.
|
||||
\param object is the object that has changed
|
||||
\param message is a value of enum IDependent::ChangeMessage, usually IDependent::kChanged - can be
|
||||
a private message as well (only known to sender and dependent)*/
|
||||
virtual tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) = 0;
|
||||
|
||||
/** Same as triggerUpdates, but delivered in idle (usefull to collect updates).*/
|
||||
virtual tresult PLUGIN_API deferUpdates (FUnknown* object, int32 message) = 0;
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IUpdateHandler, 0xF5246D56, 0x86544d60, 0xB026AFB5, 0x7B697B37)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** A dependent will get notified about changes of a model.
|
||||
[plug imp]
|
||||
- notify changes of a model
|
||||
|
||||
\see IUpdateHandler
|
||||
\ingroup frameworkHostClasses
|
||||
*/
|
||||
class IDependent: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Inform the dependent, that the passed FUnknown has changed. */
|
||||
virtual void PLUGIN_API update (FUnknown* changedUnknown, int32 message) = 0;
|
||||
|
||||
enum ChangeMessage
|
||||
{
|
||||
kWillChange,
|
||||
kChanged,
|
||||
kDestroyed,
|
||||
kWillDestroy,
|
||||
|
||||
kStdChangeMessageLast = kWillDestroy
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IDependent, 0xF52B7AAE, 0xDE72416d, 0x8AF18ACE, 0x9DD7BD5E)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,386 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/smartpointer.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Basic Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/fplatform.h"
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IPtr
|
||||
//------------------------------------------------------------------------
|
||||
/** IPtr - Smart pointer template class.
|
||||
\ingroup pluginBase
|
||||
|
||||
- can be used as an I* pointer
|
||||
- handles refCount of the interface
|
||||
- Usage example:
|
||||
\code
|
||||
IPtr<IPath> path (sharedPath);
|
||||
if (path)
|
||||
path->ascend ();
|
||||
\endcode
|
||||
*/
|
||||
template <class I>
|
||||
class IPtr
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
inline IPtr (I* ptr, bool addRef = true);
|
||||
inline IPtr (const IPtr&);
|
||||
|
||||
template <class T>
|
||||
inline IPtr (const IPtr<T>& other) : ptr (other.get ())
|
||||
{
|
||||
if (ptr)
|
||||
ptr->addRef ();
|
||||
}
|
||||
|
||||
inline IPtr ();
|
||||
inline ~IPtr ();
|
||||
|
||||
inline I* operator= (I* ptr);
|
||||
|
||||
inline IPtr& operator= (const IPtr& other);
|
||||
|
||||
template <class T>
|
||||
inline IPtr& operator= (const IPtr<T>& other)
|
||||
{
|
||||
operator= (other.get ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator I* () const { return ptr; } // act as I*
|
||||
inline I* operator-> () const { return ptr; } // act as I*
|
||||
|
||||
inline I* get () const { return ptr; }
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
inline IPtr (IPtr<I>&& movePtr) SMTG_NOEXCEPT : ptr (movePtr.take ()) { }
|
||||
|
||||
template <typename T>
|
||||
inline IPtr (IPtr<T>&& movePtr) SMTG_NOEXCEPT : ptr (movePtr.take ()) { }
|
||||
|
||||
inline IPtr& operator= (IPtr<I>&& movePtr) SMTG_NOEXCEPT
|
||||
{
|
||||
if (ptr)
|
||||
ptr->release ();
|
||||
|
||||
ptr = movePtr.take ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline IPtr& operator= (IPtr<T>&& movePtr)
|
||||
{
|
||||
if (ptr)
|
||||
ptr->release ();
|
||||
|
||||
ptr = movePtr.take ();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void reset (I* obj = nullptr)
|
||||
{
|
||||
if (ptr)
|
||||
ptr->release();
|
||||
ptr = obj;
|
||||
}
|
||||
|
||||
I* take () SMTG_NOEXCEPT
|
||||
{
|
||||
I* out = ptr;
|
||||
ptr = nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static IPtr<T> adopt (T* obj) SMTG_NOEXCEPT { return IPtr<T> (obj, false); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
I* ptr;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline IPtr<I>::IPtr (I* _ptr, bool addRef) : ptr (_ptr)
|
||||
{
|
||||
if (ptr && addRef)
|
||||
ptr->addRef ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline IPtr<I>::IPtr (const IPtr<I>& other) : ptr (other.ptr)
|
||||
{
|
||||
if (ptr)
|
||||
ptr->addRef ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline IPtr<I>::IPtr () : ptr (0)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline IPtr<I>::~IPtr ()
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
ptr->release ();
|
||||
ptr = nullptr; //TODO_CORE: how much does this cost? is this something hiding for us?
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline I* IPtr<I>::operator= (I* _ptr)
|
||||
{
|
||||
if (_ptr != ptr)
|
||||
{
|
||||
if (ptr)
|
||||
ptr->release ();
|
||||
ptr = _ptr;
|
||||
if (ptr)
|
||||
ptr->addRef ();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <class I>
|
||||
inline IPtr<I>& IPtr<I>::operator= (const IPtr<I>& _ptr)
|
||||
{
|
||||
operator= (_ptr.ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** OPtr - "owning" smart pointer used for newly created FObjects.
|
||||
\ingroup pluginBase
|
||||
|
||||
FUnknown implementations are supposed to have a refCount of 1 right after creation.
|
||||
So using an IPtr on newly created objects would lead to a leak.
|
||||
Instead the OPtr can be used in this case. \n
|
||||
Example:
|
||||
\code
|
||||
OPtr<IPath> path = FHostCreate (IPath, hostClasses);
|
||||
// no release is needed...
|
||||
\endcode
|
||||
The assignment operator takes ownership of a new object and releases the old.
|
||||
So its safe to write:
|
||||
\code
|
||||
OPtr<IPath> path = FHostCreate (IPath, hostClasses);
|
||||
path = FHostCreate (IPath, hostClasses);
|
||||
path = 0;
|
||||
\endcode
|
||||
This is the difference to using an IPtr with addRef=false.
|
||||
\code
|
||||
// DONT DO THIS:
|
||||
IPtr<IPath> path (FHostCreate (IPath, hostClasses), false);
|
||||
path = FHostCreate (IPath, hostClasses);
|
||||
path = 0;
|
||||
\endcode
|
||||
This will lead to a leak!
|
||||
*/
|
||||
template <class I>
|
||||
class OPtr : public IPtr<I>
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
inline OPtr (I* p) : IPtr<I> (p, false) {}
|
||||
inline OPtr (const IPtr<I>& p) : IPtr<I> (p) {}
|
||||
inline OPtr (const OPtr<I>& p) : IPtr<I> (p) {}
|
||||
inline OPtr () {}
|
||||
inline I* operator= (I* _ptr)
|
||||
{
|
||||
if (_ptr != this->ptr)
|
||||
{
|
||||
if (this->ptr)
|
||||
this->ptr->release ();
|
||||
this->ptr = _ptr;
|
||||
}
|
||||
return this->ptr;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Assigning newly created object to an IPtr.
|
||||
Example:
|
||||
\code
|
||||
IPtr<IPath> path = owned (FHostCreate (IPath, hostClasses));
|
||||
\endcode
|
||||
which is a slightly shorter form of writing:
|
||||
\code
|
||||
IPtr<IPath> path = OPtr<IPath> (FHostCreate (IPath, hostClasses));
|
||||
\endcode
|
||||
*/
|
||||
template <class I>
|
||||
IPtr<I> owned (I* p)
|
||||
{
|
||||
return IPtr<I> (p, false);
|
||||
}
|
||||
|
||||
/** Assigning shared object to an IPtr.
|
||||
Example:
|
||||
\code
|
||||
IPtr<IPath> path = shared (iface.getXY ());
|
||||
\endcode
|
||||
*/
|
||||
template <class I>
|
||||
IPtr<I> shared (I* p)
|
||||
{
|
||||
return IPtr<I> (p, true);
|
||||
}
|
||||
|
||||
#if SMTG_CPP11_STDLIBSUPPORT
|
||||
//------------------------------------------------------------------------
|
||||
// Ownership functionality
|
||||
//------------------------------------------------------------------------
|
||||
namespace SKI {
|
||||
namespace Detail {
|
||||
struct Adopt;
|
||||
} // Detail
|
||||
|
||||
/** Strong typedef for shared reference counted objects.
|
||||
* Use SKI::adopt to unwrap the provided object.
|
||||
* @tparam T Referenced counted type.
|
||||
*/
|
||||
template <typename T>
|
||||
class Shared
|
||||
{
|
||||
friend struct Detail::Adopt;
|
||||
T* obj = nullptr;
|
||||
};
|
||||
|
||||
/** Strong typedef for transferring the ownership of reference counted objects.
|
||||
* Use SKI::adopt to unwrap the provided object.
|
||||
* After calling adopt the reference in this object is null.
|
||||
* @tparam T Referenced counted type.
|
||||
*/
|
||||
template <typename T>
|
||||
class Owned
|
||||
{
|
||||
friend struct Detail::Adopt;
|
||||
T* obj = nullptr;
|
||||
};
|
||||
|
||||
/** Strong typedef for using reference counted objects.
|
||||
* Use SKI::adopt to unwrap the provided object.
|
||||
* After calling adopt the reference in this object is null.
|
||||
* @tparam T Referenced counted type.
|
||||
*/
|
||||
template <typename T>
|
||||
class Used
|
||||
{
|
||||
friend struct Detail::Adopt;
|
||||
T* obj = nullptr;
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
|
||||
struct Adopt
|
||||
{
|
||||
template <typename T>
|
||||
static IPtr<T> adopt (Shared<T>& ref)
|
||||
{
|
||||
using Steinberg::shared;
|
||||
return shared (ref.obj);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static IPtr<T> adopt (Owned<T>& ref)
|
||||
{
|
||||
using Steinberg::owned;
|
||||
IPtr<T> out = owned (ref.obj);
|
||||
ref.obj = nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T* adopt (Used<T>& ref)
|
||||
{
|
||||
return ref.obj;
|
||||
}
|
||||
|
||||
template <template <typename> class OwnerType, typename T>
|
||||
static OwnerType<T> toOwnerType (T* obj)
|
||||
{
|
||||
OwnerType<T> out;
|
||||
out.obj = obj;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
} // Detail
|
||||
|
||||
/** Common function to adopt referenced counted object.
|
||||
* @tparam T Referenced counted type.
|
||||
* @param ref The reference to be adopted in a smart pointer.
|
||||
*/
|
||||
template <typename T>
|
||||
IPtr<T> adopt (Shared<T>& ref) { return Detail::Adopt::adopt (ref); }
|
||||
|
||||
template <typename T>
|
||||
IPtr<T> adopt (Shared<T>&& ref) { return Detail::Adopt::adopt (ref); }
|
||||
|
||||
/** Common function to adopt referenced counted object.
|
||||
* @tparam T Referenced counted type.
|
||||
* @param ref The reference to be adopted in a smart pointer.
|
||||
*/
|
||||
template <typename T>
|
||||
IPtr<T> adopt (Owned<T>& ref) { return Detail::Adopt::adopt (ref); }
|
||||
|
||||
template <typename T>
|
||||
IPtr<T> adopt (Owned<T>&& ref) { return Detail::Adopt::adopt (ref); }
|
||||
|
||||
/** Common function to adopt referenced counted object.
|
||||
* @tparam T Referenced counted type.
|
||||
* @param ref The reference to be adopted in a smart pointer.
|
||||
*/
|
||||
template <typename T>
|
||||
T* adopt (Used<T>& ref) { return Detail::Adopt::adopt (ref); }
|
||||
|
||||
template <typename T>
|
||||
T* adopt (Used<T>&& ref) { return Detail::Adopt::adopt (ref); }
|
||||
|
||||
/** Common function to wrap owned instances. */
|
||||
template <typename T>
|
||||
Owned<T> toOwned (T* obj) { return Detail::Adopt::toOwnerType<Owned> (obj); }
|
||||
|
||||
/** Common function to wrap shared instances. */
|
||||
template <typename T>
|
||||
Shared<T> toShared (T* obj) { return Detail::Adopt::toOwnerType<Shared> (obj); }
|
||||
|
||||
/** Common function to wrap used instances. */
|
||||
template <typename T>
|
||||
Used<T> toUsed (T* obj) { return Detail::Adopt::toOwnerType<Used> (obj); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // SKI
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK Core Interfaces
|
||||
// Filename : pluginterfaces/base/typesizecheck.h
|
||||
// Created by : Steinberg, 08/2018
|
||||
// Description : Compile time type size check macro
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/fplatform.h"
|
||||
|
||||
#if SMTG_CPP11
|
||||
#define SMTG_TYPE_STATIC_CHECK(Operator, Type, Platform64Size, MacOS32Size, Win32Size, \
|
||||
Linux32Size) \
|
||||
namespace { \
|
||||
template <typename Type, size_t w, size_t x, size_t y, size_t z> \
|
||||
struct Operator##Check##Type \
|
||||
{ \
|
||||
constexpr Operator##Check##Type () \
|
||||
{ \
|
||||
static_assert (Operator (Type) == \
|
||||
(SMTG_PLATFORM_64 ? w : SMTG_OS_MACOS ? x : SMTG_OS_LINUX ? z : y), \
|
||||
"Struct " #Operator " error: " #Type); \
|
||||
} \
|
||||
}; \
|
||||
static constexpr Operator##Check##Type<Type, Platform64Size, MacOS32Size, Win32Size, \
|
||||
Linux32Size> \
|
||||
instance##Operator##Type; \
|
||||
}
|
||||
|
||||
/** Check the size of a structure depending on compilation platform
|
||||
* Used to check that structure sizes don't change between SDK releases.
|
||||
*/
|
||||
#define SMTG_TYPE_SIZE_CHECK(Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size) \
|
||||
SMTG_TYPE_STATIC_CHECK (sizeof, Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size)
|
||||
|
||||
/** Check the alignment of a structure depending on compilation platform
|
||||
* Used to check that structure alignments don't change between SDK releases.
|
||||
*/
|
||||
#define SMTG_TYPE_ALIGN_CHECK(Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size) \
|
||||
SMTG_TYPE_STATIC_CHECK (alignof, Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size)
|
||||
|
||||
#else
|
||||
// need static_assert
|
||||
#define SMTG_TYPE_SIZE_CHECK(Type, Platform64Size, MacOS32Size, Win32Size, Linux32Size)
|
||||
#endif
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : pluginterfaces/base/ustring.cpp
|
||||
// Created by : Steinberg, 12/2005
|
||||
// Description : UTF-16 String class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ustring.h"
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4996) // deprecated functions
|
||||
#endif
|
||||
|
||||
#elif SMTG_OS_MACOS
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#elif SMTG_OS_LINUX
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <codecvt>
|
||||
#include <sstream>
|
||||
#include <locale>
|
||||
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#if SMTG_OS_LINUX
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
using Converter = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Converter& converter ()
|
||||
{
|
||||
static Converter instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // anonymous
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#endif // SMTG_OS_LINUX
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Copy strings of different character width. */
|
||||
//------------------------------------------------------------------------
|
||||
template <class TDstChar, class TSrcChar>
|
||||
void StringCopy (TDstChar* dst, int32 dstSize, const TSrcChar* src, int32 srcSize = -1)
|
||||
{
|
||||
int32 count = dstSize;
|
||||
if (srcSize >= 0 && srcSize < dstSize)
|
||||
count = srcSize;
|
||||
for (int32 i = 0; i < count; i++)
|
||||
{
|
||||
dst[i] = (TDstChar)src[i];
|
||||
if (src[i] == 0)
|
||||
break;
|
||||
}
|
||||
dst[dstSize - 1] = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Find length of null-terminated string, i.e. StringLength (L"ABC\0") => 3 */
|
||||
//------------------------------------------------------------------------
|
||||
template <class TSrcChar>
|
||||
int32 StringLength (const TSrcChar* src, int32 srcSize = -1)
|
||||
{
|
||||
if (srcSize == 0)
|
||||
return 0;
|
||||
int32 length = 0;
|
||||
while (src[length])
|
||||
{
|
||||
length++;
|
||||
if (srcSize > 0 && length >= srcSize)
|
||||
break;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// UString
|
||||
//------------------------------------------------------------------------
|
||||
int32 UString::getLength () const
|
||||
{
|
||||
return StringLength<char16> (thisBuffer, thisSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
UString& UString::assign (const char16* src, int32 srcSize)
|
||||
{
|
||||
StringCopy<char16, char16> (thisBuffer, thisSize, src, srcSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
UString& UString::append (const char16* src, int32 srcSize)
|
||||
{
|
||||
int32 length = getLength ();
|
||||
StringCopy<char16, char16> (thisBuffer + length, thisSize - length, src, srcSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const UString& UString::copyTo (char16* dst, int32 dstSize) const
|
||||
{
|
||||
StringCopy<char16, char16> (dst, dstSize, thisBuffer, thisSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
UString& UString::fromAscii (const char* src, int32 srcSize)
|
||||
{
|
||||
StringCopy<char16, char> (thisBuffer, thisSize, src, srcSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const UString& UString::toAscii (char* dst, int32 dstSize) const
|
||||
{
|
||||
StringCopy<char, char16> (dst, dstSize, thisBuffer, thisSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UString::scanFloat (double& value) const
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
return swscanf ((const wchar_t*)thisBuffer, L"%lf", &value) != -1;
|
||||
|
||||
#elif TARGET_API_MAC_CARBON
|
||||
CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
|
||||
if (cfStr)
|
||||
{
|
||||
value = CFStringGetDoubleValue (cfStr);
|
||||
CFRelease (cfStr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
#elif SMTG_OS_LINUX
|
||||
auto str = converter ().to_bytes (thisBuffer);
|
||||
return sscanf (str.data (), "%lf", &value) == 1;
|
||||
|
||||
#else
|
||||
#warning Implement me
|
||||
// implement me!
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UString::printFloat (double value, int32 precision)
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1;
|
||||
#elif SMTG_OS_MACOS
|
||||
bool result = false;
|
||||
CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%.*lf"), precision, value);
|
||||
if (cfStr)
|
||||
{
|
||||
memset (thisBuffer, 0, thisSize);
|
||||
CFRange range = {0, CFStringGetLength (cfStr)};
|
||||
CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
|
||||
CFRelease (cfStr);
|
||||
return true;
|
||||
}
|
||||
return result;
|
||||
#elif SMTG_OS_LINUX
|
||||
auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
|
||||
auto len = snprintf (utf8Buffer, thisSize, "%.*lf", precision, value);
|
||||
if (len > 0)
|
||||
{
|
||||
auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
|
||||
utf16Buffer[len] = 0;
|
||||
while (--len >= 0)
|
||||
{
|
||||
utf16Buffer[len] = utf8Buffer[len];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
#warning Implement me
|
||||
// implement me!
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UString::scanInt (int64& value) const
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1;
|
||||
|
||||
#elif SMTG_OS_MACOS
|
||||
CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
|
||||
if (cfStr)
|
||||
{
|
||||
value = CFStringGetIntValue (cfStr);
|
||||
CFRelease (cfStr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
#elif SMTG_OS_LINUX
|
||||
auto str = converter ().to_bytes (thisBuffer);
|
||||
return sscanf (str.data (), "%lld", &value) == 1;
|
||||
|
||||
#else
|
||||
#warning Implement me
|
||||
// implement me!
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool UString::printInt (int64 value)
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1;
|
||||
|
||||
#elif SMTG_OS_MACOS
|
||||
CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%lld"), value);
|
||||
if (cfStr)
|
||||
{
|
||||
memset (thisBuffer, 0, thisSize);
|
||||
CFRange range = {0, CFStringGetLength (cfStr)};
|
||||
CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
|
||||
CFRelease (cfStr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#elif SMTG_OS_LINUX
|
||||
auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
|
||||
auto len = snprintf (utf8Buffer, thisSize, "%lld", value);
|
||||
if (len > 0)
|
||||
{
|
||||
auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
|
||||
utf16Buffer[len] = 0;
|
||||
while (--len >= 0)
|
||||
{
|
||||
utf16Buffer[len] = utf8Buffer[len];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
#else
|
||||
#warning Implement me
|
||||
// implement me!
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : pluginterfaces/base/ustring.h
|
||||
// Created by : Steinberg, 12/2005
|
||||
// Description : UTF-16 String class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "ftypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** UTF-16 string class without buffer management.
|
||||
Note: that some characters are encoded in 2 UTF16 code units (surrogate pair),
|
||||
this means that getLength returns the number of code unit, not the count of character! */
|
||||
class UString
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Construct from UTF-16 string, size is in code unit (count of char16) */
|
||||
UString (char16* buffer, int32 size) : thisBuffer (buffer), thisSize (size) {}
|
||||
|
||||
/** returns buffer size */
|
||||
int32 getSize () const { return thisSize; }
|
||||
|
||||
/** cast to char16* */
|
||||
operator const char16* () const { return thisBuffer; }
|
||||
|
||||
/** Returns length of string (in code unit). Note this is not the count of character! */
|
||||
int32 getLength () const;
|
||||
|
||||
/** Copy from UTF-16 buffer (srcSize is in code unit (count of char16)). */
|
||||
UString& assign (const char16* src, int32 srcSize = -1);
|
||||
|
||||
/** Append UTF-16 buffer (srcSize is in code unit (count of char16)). */
|
||||
UString& append (const char16* src, int32 srcSize = -1);
|
||||
|
||||
/** Copy to UTF-16 buffer (dstSize is in code unit (count of char16)). */
|
||||
const UString& copyTo (char16* dst, int32 dstSize) const;
|
||||
|
||||
/** Copy from ASCII string (srcSize is in code unit (count of char16)). */
|
||||
UString& fromAscii (const char* src, int32 srcSize = -1);
|
||||
UString& assign (const char* src, int32 srcSize = -1) { return fromAscii (src, srcSize); }
|
||||
|
||||
/** Copy to ASCII string. */
|
||||
const UString& toAscii (char* dst, int32 dstSize) const;
|
||||
|
||||
/** Scan integer from string. */
|
||||
bool scanInt (int64& value) const;
|
||||
|
||||
/** Print integer to string. */
|
||||
bool printInt (int64 value);
|
||||
|
||||
/** Scan float from string. */
|
||||
bool scanFloat (double& value) const;
|
||||
|
||||
/** Print float to string. */
|
||||
bool printFloat (double value, int32 precision = 4);
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
char16* thisBuffer;
|
||||
int32 thisSize; ///< size in code unit (not in byte!)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** UTF-16 string with fixed buffer size.
|
||||
*/
|
||||
template <int32 maxSize>
|
||||
class UStringBuffer : public UString
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
UStringBuffer () : UString (data, maxSize) { data[0] = 0; }
|
||||
|
||||
/** Construct from UTF-16 string. */
|
||||
UStringBuffer (const char16* src, int32 srcSize = -1) : UString (data, maxSize)
|
||||
{
|
||||
data[0] = 0;
|
||||
if (src)
|
||||
assign (src, srcSize);
|
||||
}
|
||||
|
||||
/** Construct from ASCII string. */
|
||||
UStringBuffer (const char* src, int32 srcSize = -1) : UString (data, maxSize)
|
||||
{
|
||||
data[0] = 0;
|
||||
if (src)
|
||||
fromAscii (src, srcSize);
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
char16 data[maxSize];
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
typedef UStringBuffer<128> UString128; ///< 128 character UTF-16 string
|
||||
typedef UStringBuffer<256> UString256; ///< 256 character UTF-16 string
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#define USTRING(asciiString) Steinberg::UString256 (asciiString)
|
||||
#define USTRINGSIZE(var) (sizeof (var) / sizeof (Steinberg::char16))
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,287 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK GUI Interfaces
|
||||
// Filename : pluginterfaces/gui/iplugview.h
|
||||
// Created by : Steinberg, 12/2007
|
||||
// Description : Plug-in User Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/base/typesizecheck.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
class IPlugFrame;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*! \defgroup pluginGUI Graphical User Interface
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Graphical rectangle structure. Used with IPlugView.
|
||||
\ingroup pluginGUI
|
||||
*/
|
||||
struct ViewRect
|
||||
{
|
||||
ViewRect (int32 l = 0, int32 t = 0, int32 r = 0, int32 b = 0)
|
||||
: left (l), top (t), right (r), bottom (b)
|
||||
{
|
||||
}
|
||||
|
||||
int32 left;
|
||||
int32 top;
|
||||
int32 right;
|
||||
int32 bottom;
|
||||
|
||||
//--- ---------------------------------------------------------------------
|
||||
int32 getWidth () const { return right - left; }
|
||||
int32 getHeight () const { return bottom - top; }
|
||||
};
|
||||
|
||||
SMTG_TYPE_SIZE_CHECK (ViewRect, 16, 16, 16, 16)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup platformUIType Platform UI Types
|
||||
\ingroup pluginGUI
|
||||
List of Platform UI types for IPlugView. This list is used to match the GUI-System between
|
||||
the host and a plug-in in case that an OS provides multiple GUI-APIs.
|
||||
*/
|
||||
/*@{*/
|
||||
/** The parent parameter in IPlugView::attached() is a HWND handle.
|
||||
* You should attach a child window to it. */
|
||||
const FIDString kPlatformTypeHWND = "HWND"; ///< HWND handle. (Microsoft Windows)
|
||||
|
||||
/** The parent parameter in IPlugView::attached() is a WindowRef.
|
||||
* You should attach a HIViewRef to the content view of the window. */
|
||||
const FIDString kPlatformTypeHIView = "HIView"; ///< HIViewRef. (Mac OS X)
|
||||
|
||||
/** The parent parameter in IPlugView::attached() is a NSView pointer.
|
||||
* You should attach a NSView to it. */
|
||||
const FIDString kPlatformTypeNSView = "NSView"; ///< NSView pointer. (Mac OS X)
|
||||
|
||||
/** The parent parameter in IPlugView::attached() is a UIView pointer.
|
||||
* You should attach an UIView to it. */
|
||||
const FIDString kPlatformTypeUIView = "UIView"; ///< UIView pointer. (iOS)
|
||||
|
||||
/** The parent parameter in IPlugView::attached() is a X11 Window supporting XEmbed.
|
||||
* You should attach a Window to it that supports the XEmbed extension.
|
||||
* See https://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html */
|
||||
const FIDString kPlatformTypeX11EmbedWindowID = "X11EmbedWindowID"; ///< X11 Window ID. (X11)
|
||||
|
||||
/*@}*/
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Plug-in definition of a view.
|
||||
\ingroup pluginGUI vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [released: 3.0.0]
|
||||
|
||||
\par Sizing of a view
|
||||
Usually, the size of a plug-in view is fixed. But both the host and the plug-in can cause
|
||||
a view to be resized:
|
||||
\n
|
||||
- \b Host: If IPlugView::canResize () returns kResultTrue the host will set up the window
|
||||
so that the user can resize it. While the user resizes the window,
|
||||
IPlugView::checkSizeConstraint () is called, allowing the plug-in to change the size to a valid
|
||||
a valid supported rectangle size. The host then resizes the window to this rect and has to call IPlugView::onSize ().
|
||||
\n
|
||||
\n
|
||||
- \b Plug-in: The plug-in can call IPlugFrame::resizeView () and cause the host to resize the
|
||||
window.\n\n
|
||||
Afterwards, in the same callstack, the host has to call IPlugView::onSize () if a resize is needed (size was changed).
|
||||
Note that if the host calls IPlugView::getSize () before calling IPlugView::onSize () (if needed),
|
||||
it will get the current (old) size not the wanted one!!\n
|
||||
Here the calling sequence:\n
|
||||
- plug-in->host: IPlugFrame::resizeView (newSize)
|
||||
- host->plug-in (optional): IPlugView::getSize () returns the currentSize (not the newSize!)
|
||||
- host->plug-in: if newSize is different from the current size: IPlugView::onSize (newSize)
|
||||
- host->plug-in (optional): IPlugView::getSize () returns the newSize
|
||||
\n
|
||||
<b>Please only resize the platform representation of the view when IPlugView::onSize () is
|
||||
called.</b>
|
||||
|
||||
\par Keyboard handling
|
||||
The plug-in view receives keyboard events from the host. A view implementation must not handle
|
||||
keyboard events by the means of platform callbacks, but let the host pass them to the view. The host
|
||||
depends on a proper return value when IPlugView::onKeyDown is called, otherwise the plug-in view may
|
||||
cause a malfunction of the host's key command handling.
|
||||
|
||||
\see IPlugFrame, \ref platformUIType
|
||||
*/
|
||||
class IPlugView : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Is Platform UI Type supported
|
||||
\param type : IDString of \ref platformUIType */
|
||||
virtual tresult PLUGIN_API isPlatformTypeSupported (FIDString type) = 0;
|
||||
|
||||
/** The parent window of the view has been created, the (platform) representation of the view
|
||||
should now be created as well.
|
||||
Note that the parent is owned by the caller and you are not allowed to alter it in any way
|
||||
other than adding your own views.
|
||||
Note that in this call the plug-in could call a IPlugFrame::resizeView ()!
|
||||
\param parent : platform handle of the parent window or view
|
||||
\param type : \ref platformUIType which should be created */
|
||||
virtual tresult PLUGIN_API attached (void* parent, FIDString type) = 0;
|
||||
|
||||
/** The parent window of the view is about to be destroyed.
|
||||
You have to remove all your own views from the parent window or view. */
|
||||
virtual tresult PLUGIN_API removed () = 0;
|
||||
|
||||
/** Handling of mouse wheel. */
|
||||
virtual tresult PLUGIN_API onWheel (float distance) = 0;
|
||||
|
||||
/** Handling of keyboard events : Key Down.
|
||||
\param key : unicode code of key
|
||||
\param keyCode : virtual keycode for non ascii keys - see \ref VirtualKeyCodes in keycodes.h
|
||||
\param modifiers : any combination of modifiers - see \ref KeyModifier in keycodes.h
|
||||
\return kResultTrue if the key is handled, otherwise kResultFalse. \n
|
||||
<b> Please note that kResultTrue must only be returned if the key has really been
|
||||
handled. </b> Otherwise key command handling of the host might be blocked! */
|
||||
virtual tresult PLUGIN_API onKeyDown (char16 key, int16 keyCode, int16 modifiers) = 0;
|
||||
|
||||
/** Handling of keyboard events : Key Up.
|
||||
\param key : unicode code of key
|
||||
\param keyCode : virtual keycode for non ascii keys - see \ref VirtualKeyCodes in keycodes.h
|
||||
\param modifiers : any combination of KeyModifier - see \ref KeyModifier in keycodes.h
|
||||
\return kResultTrue if the key is handled, otherwise return kResultFalse. */
|
||||
virtual tresult PLUGIN_API onKeyUp (char16 key, int16 keyCode, int16 modifiers) = 0;
|
||||
|
||||
/** Returns the size of the platform representation of the view. */
|
||||
virtual tresult PLUGIN_API getSize (ViewRect* size) = 0;
|
||||
|
||||
/** Resizes the platform representation of the view to the given rect. Note that if the plug-in
|
||||
* requests a resize (IPlugFrame::resizeView ()) onSize has to be called afterward. */
|
||||
virtual tresult PLUGIN_API onSize (ViewRect* newSize) = 0;
|
||||
|
||||
/** Focus changed message. */
|
||||
virtual tresult PLUGIN_API onFocus (TBool state) = 0;
|
||||
|
||||
/** Sets IPlugFrame object to allow the plug-in to inform the host about resizing. */
|
||||
virtual tresult PLUGIN_API setFrame (IPlugFrame* frame) = 0;
|
||||
|
||||
/** Is view sizable by user. */
|
||||
virtual tresult PLUGIN_API canResize () = 0;
|
||||
|
||||
/** On live resize this is called to check if the view can be resized to the given rect, if not
|
||||
* adjust the rect to the allowed size. */
|
||||
virtual tresult PLUGIN_API checkSizeConstraint (ViewRect* rect) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPlugView, 0x5BC32507, 0xD06049EA, 0xA6151B52, 0x2B755B29)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Callback interface passed to IPlugView.
|
||||
\ingroup pluginGUI vstIHost vst300
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
Enables a plug-in to resize the view and cause the host to resize the window.
|
||||
*/
|
||||
class IPlugFrame : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Called to inform the host about the resize of a given view.
|
||||
* Afterwards the host has to call IPlugView::onSize (). */
|
||||
virtual tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPlugFrame, 0x367FAF01, 0xAFA94693, 0x8D4DA2A0, 0xED0882A3)
|
||||
|
||||
#if SMTG_OS_LINUX
|
||||
//------------------------------------------------------------------------
|
||||
namespace Linux {
|
||||
|
||||
using TimerInterval = uint64;
|
||||
using FileDescriptor = int;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Linux event handler interface
|
||||
\ingroup pluginGUI vst368
|
||||
- [plug imp]
|
||||
- [released: 3.6.8]
|
||||
\see IRunLoop
|
||||
*/
|
||||
class IEventHandler : public FUnknown
|
||||
{
|
||||
public:
|
||||
virtual void PLUGIN_API onFDIsSet (FileDescriptor fd) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (IEventHandler, 0x561E65C9, 0x13A0496F, 0x813A2C35, 0x654D7983)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Linux timer handler interface
|
||||
\ingroup pluginGUI vst368
|
||||
- [plug imp]
|
||||
- [released: 3.6.8]
|
||||
\see IRunLoop
|
||||
*/
|
||||
class ITimerHandler : public FUnknown
|
||||
{
|
||||
public:
|
||||
virtual void PLUGIN_API onTimer () = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (ITimerHandler, 0x10BDD94F, 0x41424774, 0x821FAD8F, 0xECA72CA9)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Linux host run loop interface
|
||||
\ingroup pluginGUI vst368
|
||||
- [host imp]
|
||||
- [extends IPlugFrame]
|
||||
- [released: 3.6.8]
|
||||
|
||||
On Linux the host has to provide this interface to the plug-in as there's no global event run loop
|
||||
defined as on other platforms.
|
||||
|
||||
This can be done by IPlugFrame and the context which is passed to the plug-in as an argument
|
||||
in the method IPlugFactory3::setHostContext. This way the plug-in can get a runloop even if
|
||||
it does not have an editor.
|
||||
|
||||
A plug-in can register an event handler for a file descriptor. The host has to call the event
|
||||
handler when the file descriptor is marked readable.
|
||||
|
||||
A plug-in also can register a timer which will be called repeatedly until it is unregistered.
|
||||
*/
|
||||
class IRunLoop : public FUnknown
|
||||
{
|
||||
public:
|
||||
virtual tresult PLUGIN_API registerEventHandler (IEventHandler* handler, FileDescriptor fd) = 0;
|
||||
virtual tresult PLUGIN_API unregisterEventHandler (IEventHandler* handler) = 0;
|
||||
|
||||
virtual tresult PLUGIN_API registerTimer (ITimerHandler* handler,
|
||||
TimerInterval milliseconds) = 0;
|
||||
virtual tresult PLUGIN_API unregisterTimer (ITimerHandler* handler) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (IRunLoop, 0x18C35366, 0x97764F1A, 0x9C5B8385, 0x7A871389)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Linux
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : SDK GUI Interfaces
|
||||
// Filename : pluginterfaces/gui/iplugviewcontentscalesupport.h
|
||||
// Created by : Steinberg, 06/2016
|
||||
// Description : Plug-in User Interface Scaling
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Plug-in view content scale support
|
||||
\ingroup pluginGUI vstIPlug vst366
|
||||
- [plug impl]
|
||||
- [extends IPlugView]
|
||||
- [released: 3.6.6]
|
||||
- [optional]
|
||||
|
||||
This interface communicates the content scale factor from the host to the plug-in view on
|
||||
systems where plug-ins cannot get this information directly like Microsoft Windows.
|
||||
|
||||
The host calls setContentScaleFactor directly before or after the plug-in view is attached and when
|
||||
the scale factor changes while the view is attached (system change or window moved to another screen
|
||||
with different scaling settings).
|
||||
|
||||
The host may call setContentScaleFactor in a different context, for example: scaling the plug-in
|
||||
editor for better readability.
|
||||
|
||||
When a plug-in handles this (by returning kResultTrue), it needs to scale the width and height of
|
||||
its view by the scale factor and inform the host via a IPlugFrame::resizeView(). The host will then
|
||||
call IPlugView::onSize().
|
||||
|
||||
Note that the host is allowed to call setContentScaleFactor() at any time the IPlugView is valid.
|
||||
If this happens before the IPlugFrame object is set on your view, make sure that when the host calls
|
||||
IPlugView::getSize() afterwards you return the size of your view for that new scale factor.
|
||||
|
||||
It is recommended to implement this interface on Microsoft Windows to let the host know that the
|
||||
plug-in is able to render in different scalings.
|
||||
*/
|
||||
class IPlugViewContentScaleSupport : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
typedef float ScaleFactor;
|
||||
|
||||
virtual tresult PLUGIN_API setContentScaleFactor (ScaleFactor factor) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPlugViewContentScaleSupport, 0x65ED9690, 0x8AC44525, 0x8AADEF7A, 0x72EA703F)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstattributes.h
|
||||
// Created by : Steinberg, 05/2006
|
||||
// Description : VST Attribute Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Attribute list used in IMessage and IStreamAttributes: Vst::IAttributeList
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
An attribute list associates values with a key (id: some predefined keys can be found in \ref
|
||||
presetAttributes).
|
||||
*/
|
||||
class IAttributeList : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
typedef const char* AttrID;
|
||||
|
||||
/** Sets integer value. */
|
||||
virtual tresult PLUGIN_API setInt (AttrID id, int64 value) = 0;
|
||||
|
||||
/** Gets integer value. */
|
||||
virtual tresult PLUGIN_API getInt (AttrID id, int64& value) = 0;
|
||||
|
||||
/** Sets float value. */
|
||||
virtual tresult PLUGIN_API setFloat (AttrID id, double value) = 0;
|
||||
|
||||
/** Gets float value. */
|
||||
virtual tresult PLUGIN_API getFloat (AttrID id, double& value) = 0;
|
||||
|
||||
/** Sets string value (UTF16) (must be null-terminated!). */
|
||||
virtual tresult PLUGIN_API setString (AttrID id, const TChar* string) = 0;
|
||||
|
||||
/** Gets string value (UTF16). Note that Size is in Byte, not the string Length!
|
||||
Do not forget to multiply the length by sizeof (TChar)! */
|
||||
virtual tresult PLUGIN_API getString (AttrID id, TChar* string, uint32 sizeInBytes) = 0;
|
||||
|
||||
/** Sets binary data. */
|
||||
virtual tresult PLUGIN_API setBinary (AttrID id, const void* data, uint32 sizeInBytes) = 0;
|
||||
|
||||
/** Gets binary data. */
|
||||
virtual tresult PLUGIN_API getBinary (AttrID id, const void*& data, uint32& sizeInBytes) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IAttributeList, 0x1E5F0AEB, 0xCC7F4533, 0xA2544011, 0x38AD5EE4)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Meta attributes of a stream: Vst::IStreamAttributes
|
||||
\ingroup vstIHost vst360
|
||||
- [host imp]
|
||||
- [extends IBStream]
|
||||
- [released: 3.6.0]
|
||||
- [optional]
|
||||
|
||||
Interface to access preset meta information from stream, used, for example, in setState in order to inform the plug-in about
|
||||
the current context in which the preset loading occurs (Project context or Preset load (see \ref StateType))
|
||||
or used to get the full file path of the loaded preset (if available).
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/ustring.h"
|
||||
#include "pluginterfaces/vst/vstpresetkeys.h"
|
||||
...
|
||||
|
||||
tresult PLUGIN_API MyPlugin::setState (IBStream* state)
|
||||
{
|
||||
FUnknownPtr<IStreamAttributes> stream (state);
|
||||
if (stream)
|
||||
{
|
||||
IAttributeList* list = stream->getAttributes ();
|
||||
if (list)
|
||||
{
|
||||
// get the current type (project/Default..) of this state
|
||||
String128 string;
|
||||
if (list->getString (PresetAttributes::kStateType, string, 128 * sizeof (TChar)) == kResultTrue)
|
||||
{
|
||||
UString128 tmp (string);
|
||||
char ascii[128];
|
||||
tmp.toAscii (ascii, 128);
|
||||
if (strncmp (ascii, StateType::kProject, strlen (StateType::kProject)) == 0)
|
||||
{
|
||||
// we are in project loading context...
|
||||
}
|
||||
}
|
||||
|
||||
// get the full file path of this state
|
||||
TChar fullPath[1024];
|
||||
if (list->getString (PresetAttributes::kFilePathStringType, fullPath, 1024 * sizeof (TChar)) == kResultTrue)
|
||||
{
|
||||
// here we have the full path ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//...read the state here.....
|
||||
return kResultTrue;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class IStreamAttributes : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Gets filename (without file extension) of the stream. */
|
||||
virtual tresult PLUGIN_API getFileName (String128 name) = 0;
|
||||
|
||||
/** Gets meta information list. */
|
||||
virtual IAttributeList* PLUGIN_API getAttributes () = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IStreamAttributes, 0xD6CE2FFC, 0xEFAF4B8C, 0x9E74F1BB, 0x12DA44B4)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,434 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstaudioprocessor.h
|
||||
// Created by : Steinberg, 10/2005
|
||||
// Description : VST Audio Processing Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 "ivstcomponent.h"
|
||||
#include "vstspeaker.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Class Category Name for Audio Processor Component */
|
||||
//------------------------------------------------------------------------
|
||||
#ifndef kVstAudioEffectClass
|
||||
#define kVstAudioEffectClass "Audio Module Class"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
class IEventList;
|
||||
class IParameterChanges;
|
||||
struct ProcessContext;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Component Types used as subCategories in PClassInfo2 */
|
||||
namespace PlugType
|
||||
{
|
||||
/**
|
||||
\defgroup plugType Plug-in Type used for subCategories */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
SMTG_CONSTEXPR const CString kFx = "Fx"; ///< others type (not categorized)
|
||||
SMTG_CONSTEXPR const CString kFxAnalyzer = "Fx|Analyzer"; ///< Scope, FFT-Display, Loudness Processing...
|
||||
SMTG_CONSTEXPR const CString kFxBass = "Fx|Bass"; ///< Tools dedicated to Bass Guitar
|
||||
SMTG_CONSTEXPR const CString kFxChannelStrip = "Fx|Channel Strip"; ///< Tools dedicated to Channel Strip
|
||||
SMTG_CONSTEXPR const CString kFxDelay = "Fx|Delay"; ///< Delay, Multi-tap Delay, Ping-Pong Delay...
|
||||
SMTG_CONSTEXPR const CString kFxDistortion = "Fx|Distortion"; ///< Amp Simulator, Sub-Harmonic, SoftClipper...
|
||||
SMTG_CONSTEXPR const CString kFxDrums = "Fx|Drums"; ///< Tools dedicated to Drums...
|
||||
SMTG_CONSTEXPR const CString kFxDynamics = "Fx|Dynamics"; ///< Compressor, Expander, Gate, Limiter, Maximizer, Tape Simulator, EnvelopeShaper...
|
||||
SMTG_CONSTEXPR const CString kFxEQ = "Fx|EQ"; ///< Equalization, Graphical EQ...
|
||||
SMTG_CONSTEXPR const CString kFxFilter = "Fx|Filter"; ///< WahWah, ToneBooster, Specific Filter,...
|
||||
SMTG_CONSTEXPR const CString kFxGenerator = "Fx|Generator"; ///< Tone Generator, Noise Generator...
|
||||
SMTG_CONSTEXPR const CString kFxGuitar = "Fx|Guitar"; ///< Tools dedicated to Guitar
|
||||
SMTG_CONSTEXPR const CString kFxInstrument = "Fx|Instrument"; ///< Fx which could be loaded as Instrument too
|
||||
SMTG_CONSTEXPR const CString kFxInstrumentExternal = "Fx|Instrument|External"; ///< Fx which could be loaded as Instrument too and is external (wrapped Hardware)
|
||||
SMTG_CONSTEXPR const CString kFxMastering = "Fx|Mastering"; ///< Dither, Noise Shaping,...
|
||||
SMTG_CONSTEXPR const CString kFxMicrophone = "Fx|Microphone"; ///< Tools dedicated to Microphone
|
||||
SMTG_CONSTEXPR const CString kFxModulation = "Fx|Modulation"; ///< Phaser, Flanger, Chorus, Tremolo, Vibrato, AutoPan, Rotary, Cloner...
|
||||
SMTG_CONSTEXPR const CString kFxNetwork = "Fx|Network"; ///< using Network
|
||||
SMTG_CONSTEXPR const CString kFxPitchShift = "Fx|Pitch Shift"; ///< Pitch Processing, Pitch Correction, Vocal Tuning...
|
||||
SMTG_CONSTEXPR const CString kFxRestoration = "Fx|Restoration"; ///< Denoiser, Declicker,...
|
||||
SMTG_CONSTEXPR const CString kFxReverb = "Fx|Reverb"; ///< Reverberation, Room Simulation, Convolution Reverb...
|
||||
SMTG_CONSTEXPR const CString kFxSpatial = "Fx|Spatial"; ///< MonoToStereo, StereoEnhancer,...
|
||||
SMTG_CONSTEXPR const CString kFxSurround = "Fx|Surround"; ///< dedicated to surround processing: LFE Splitter, Bass Manager...
|
||||
SMTG_CONSTEXPR const CString kFxTools = "Fx|Tools"; ///< Volume, Mixer, Tuner...
|
||||
SMTG_CONSTEXPR const CString kFxVocals = "Fx|Vocals"; ///< Tools dedicated to Vocals
|
||||
|
||||
SMTG_CONSTEXPR const CString kInstrument = "Instrument"; ///< Effect used as instrument (sound generator), not as insert
|
||||
SMTG_CONSTEXPR const CString kInstrumentDrum = "Instrument|Drum"; ///< Instrument for Drum sounds
|
||||
SMTG_CONSTEXPR const CString kInstrumentExternal = "Instrument|External";///< External Instrument (wrapped Hardware)
|
||||
SMTG_CONSTEXPR const CString kInstrumentPiano = "Instrument|Piano"; ///< Instrument for Piano sounds
|
||||
SMTG_CONSTEXPR const CString kInstrumentSampler = "Instrument|Sampler"; ///< Instrument based on Samples
|
||||
SMTG_CONSTEXPR const CString kInstrumentSynth = "Instrument|Synth"; ///< Instrument based on Synthesis
|
||||
SMTG_CONSTEXPR const CString kInstrumentSynthSampler = "Instrument|Synth|Sampler"; ///< Instrument based on Synthesis and Samples
|
||||
|
||||
SMTG_CONSTEXPR const CString kAmbisonics = "Ambisonics"; ///< used for Ambisonics channel (FX or Panner/Mixconverter/Up-Mixer/Down-Mixer when combined with other category)
|
||||
SMTG_CONSTEXPR const CString kAnalyzer = "Analyzer"; ///< Meter, Scope, FFT-Display, not selectable as insert plug-in
|
||||
SMTG_CONSTEXPR const CString kNoOfflineProcess = "NoOfflineProcess"; ///< will be NOT used for plug-in offline processing (will work as normal insert plug-in)
|
||||
SMTG_CONSTEXPR const CString kOnlyARA = "OnlyARA"; ///< used for plug-ins that require ARA to operate (will not work as normal insert plug-in)
|
||||
SMTG_CONSTEXPR const CString kOnlyOfflineProcess = "OnlyOfflineProcess"; ///< used for plug-in offline processing (will not work as normal insert plug-in)
|
||||
SMTG_CONSTEXPR const CString kOnlyRealTime = "OnlyRT"; ///< indicates that it supports only realtime process call, no processing faster than realtime
|
||||
SMTG_CONSTEXPR const CString kSpatial = "Spatial"; ///< used for SurroundPanner
|
||||
SMTG_CONSTEXPR const CString kSpatialFx = "Spatial|Fx"; ///< used for SurroundPanner and as insert effect
|
||||
SMTG_CONSTEXPR const CString kUpDownMix = "Up-Downmix"; ///< used for Mixconverter/Up-Mixer/Down-Mixer
|
||||
|
||||
SMTG_CONSTEXPR const CString kMono = "Mono"; ///< used for Mono only plug-in [optional]
|
||||
SMTG_CONSTEXPR const CString kStereo = "Stereo"; ///< used for Stereo only plug-in [optional]
|
||||
SMTG_CONSTEXPR const CString kSurround = "Surround"; ///< used for Surround only plug-in [optional]
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*@}*/
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Component Flags used as classFlags in PClassInfo2 */
|
||||
enum ComponentFlags
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
kDistributable = 1 << 0, ///< Component can be run on remote computer
|
||||
kSimpleModeSupported = 1 << 1 ///< Component supports simple IO mode (or works in simple mode anyway) see \ref vst3IoMode
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Symbolic sample size.
|
||||
\see ProcessSetup, ProcessData
|
||||
*/
|
||||
enum SymbolicSampleSizes
|
||||
{
|
||||
kSample32, ///< 32-bit precision
|
||||
kSample64 ///< 64-bit precision
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Processing mode informs the plug-in about the context and at which frequency the process call is called.
|
||||
VST3 defines 3 modes:
|
||||
- kRealtime: each process call is called at a realtime frequency (defined by [numSamples of ProcessData] / samplerate).
|
||||
The plug-in should always try to process as fast as possible in order to let enough time slice to other plug-ins.
|
||||
- kPrefetch: each process call could be called at a variable frequency (jitter, slower / faster than realtime),
|
||||
the plug-in should process at the same quality level than realtime, plug-in must not slow down to realtime
|
||||
(e.g. disk streaming)!
|
||||
The host should avoid to process in kPrefetch mode such sampler based plug-in.
|
||||
- kOffline: each process call could be faster than realtime or slower, higher quality than realtime could be used.
|
||||
plug-ins using disk streaming should be sure that they have enough time in the process call for streaming,
|
||||
if needed by slowing down to realtime or slower.
|
||||
.
|
||||
Note about Process Modes switching:
|
||||
- Switching between kRealtime and kPrefetch process modes are done in realtime thread without need of calling
|
||||
IAudioProcessor::setupProcessing, the plug-in should check in process call the member processMode of ProcessData
|
||||
in order to know in which mode it is processed.
|
||||
- Switching between kRealtime (or kPrefetch) and kOffline requires that the host calls IAudioProcessor::setupProcessing
|
||||
in order to inform the plug-in about this mode change.
|
||||
.
|
||||
\see ProcessSetup, ProcessData
|
||||
*/
|
||||
enum ProcessModes
|
||||
{
|
||||
kRealtime, ///< realtime processing
|
||||
kPrefetch, ///< prefetch processing
|
||||
kOffline ///< offline processing
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** kNoTail
|
||||
*
|
||||
* to be returned by getTailSamples when no tail is wanted
|
||||
\see IAudioProcessor::getTailSamples
|
||||
*/
|
||||
static const uint32 kNoTail = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** kInfiniteTail
|
||||
*
|
||||
* to be returned by getTailSamples when infinite tail is wanted
|
||||
\see IAudioProcessor::getTailSamples
|
||||
*/
|
||||
static const uint32 kInfiniteTail = kMaxInt32u;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Audio processing setup.
|
||||
\see IAudioProcessor::setupProcessing
|
||||
*/
|
||||
struct ProcessSetup
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
int32 processMode; ///< \ref ProcessModes
|
||||
int32 symbolicSampleSize; ///< \ref SymbolicSampleSizes
|
||||
int32 maxSamplesPerBlock; ///< maximum number of samples per audio block
|
||||
SampleRate sampleRate; ///< sample rate
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Processing buffers of an audio bus.
|
||||
This structure contains the processing buffer for each channel of an audio bus.
|
||||
- The number of channels (numChannels) must always match the current bus arrangement.
|
||||
It could be set to value '0' when the host wants to flush the parameters (when the plug-in is not processed).
|
||||
- The size of the channel buffer array must always match the number of channels. So the host
|
||||
must always supply an array for the channel buffers, regardless if the
|
||||
bus is active or not. However, if an audio bus is currently inactive, the actual sample
|
||||
buffer addresses are safe to be null.
|
||||
- The silence flag is set when every sample of the according buffer has the value '0'. It is
|
||||
intended to be used as help for optimizations allowing a plug-in to reduce processing activities.
|
||||
But even if this flag is set for a channel, the channel buffers must still point to valid memory!
|
||||
This flag is optional. A host is free to support it or not.
|
||||
.
|
||||
\see ProcessData
|
||||
*/
|
||||
struct AudioBusBuffers
|
||||
{
|
||||
AudioBusBuffers () : numChannels (0), silenceFlags (0), channelBuffers64 (nullptr) {}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32 numChannels; ///< number of audio channels in bus
|
||||
uint64 silenceFlags; ///< Bitset of silence state per channel
|
||||
union
|
||||
{
|
||||
Sample32** channelBuffers32; ///< sample buffers to process with 32-bit precision
|
||||
Sample64** channelBuffers64; ///< sample buffers to process with 64-bit precision
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Any data needed in audio processing.
|
||||
The host prepares AudioBusBuffers for each input/output bus,
|
||||
regardless of the bus activation state. Bus buffer indices always match
|
||||
with bus indices used in IComponent::getBusInfo of media type kAudio.
|
||||
\see AudioBusBuffers, IParameterChanges, IEventList, ProcessContext, IProcessContextRequirements
|
||||
*/
|
||||
struct ProcessData
|
||||
{
|
||||
ProcessData ()
|
||||
: processMode (0)
|
||||
, symbolicSampleSize (kSample32)
|
||||
, numSamples (0)
|
||||
, numInputs (0)
|
||||
, numOutputs (0)
|
||||
, inputs (nullptr)
|
||||
, outputs (nullptr)
|
||||
, inputParameterChanges (nullptr)
|
||||
, outputParameterChanges (nullptr)
|
||||
, inputEvents (nullptr)
|
||||
, outputEvents (nullptr)
|
||||
, processContext (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32 processMode; ///< processing mode - value of \ref ProcessModes
|
||||
int32 symbolicSampleSize; ///< sample size - value of \ref SymbolicSampleSizes
|
||||
int32 numSamples; ///< number of samples to process
|
||||
int32 numInputs; ///< number of audio input busses
|
||||
int32 numOutputs; ///< number of audio output busses
|
||||
AudioBusBuffers* inputs; ///< buffers of input busses
|
||||
AudioBusBuffers* outputs; ///< buffers of output busses
|
||||
|
||||
IParameterChanges* inputParameterChanges; ///< incoming parameter changes for this block
|
||||
IParameterChanges* outputParameterChanges; ///< outgoing parameter changes for this block (optional)
|
||||
IEventList* inputEvents; ///< incoming events for this block (optional)
|
||||
IEventList* outputEvents; ///< outgoing events for this block (optional)
|
||||
ProcessContext* processContext; ///< processing context (optional, but most welcome)
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Audio processing interface: Vst::IAudioProcessor
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [extends IComponent]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
This interface must always be supported by audio processing plug-ins.
|
||||
*/
|
||||
class IAudioProcessor : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Try to set (host => plug-in) a wanted arrangement for inputs and outputs.
|
||||
The host should always deliver the same number of input and output busses than the plug-in
|
||||
needs (see \ref IComponent::getBusCount). The plug-in has 3 possibilities to react on this
|
||||
setBusArrangements call:\n
|
||||
1. The plug-in accepts these arrangements, then it should modify, if needed, its busses to match
|
||||
these new arrangements (later on asked by the host with IComponent::getBusInfo () or
|
||||
IAudioProcessor::getBusArrangement ()) and then should return kResultTrue.\n
|
||||
2. The plug-in does not accept or support these requested arrangements for all
|
||||
inputs/outputs or just for some or only one bus, but the plug-in can try to adapt its current
|
||||
arrangements according to the requested ones (requested arrangements for kMain busses should be
|
||||
handled with more priority than the ones for kAux busses), then it should modify its busses arrangements
|
||||
and should return kResultFalse.\n
|
||||
3. Same than the point 2 above the plug-in does not support these requested arrangements
|
||||
but the plug-in cannot find corresponding arrangements, the plug-in could keep its current arrangement
|
||||
or fall back to a default arrangement by modifying its busses arrangements and should return kResultFalse.\n
|
||||
\param inputs pointer to an array of /ref SpeakerArrangement
|
||||
\param numIns number of /ref SpeakerArrangement in inputs array
|
||||
\param outputs pointer to an array of /ref SpeakerArrangement
|
||||
\param numOuts number of /ref SpeakerArrangement in outputs array
|
||||
Returns kResultTrue when Arrangements is supported and is the current one, else returns kResultFalse. */
|
||||
virtual tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
|
||||
SpeakerArrangement* outputs, int32 numOuts) = 0;
|
||||
|
||||
/** Gets the bus arrangement for a given direction (input/output) and index.
|
||||
Note: IComponent::getBusInfo () and IAudioProcessor::getBusArrangement () should be always return the same
|
||||
information about the busses arrangements. */
|
||||
virtual tresult PLUGIN_API getBusArrangement (BusDirection dir, int32 index, SpeakerArrangement& arr) = 0;
|
||||
|
||||
/** Asks if a given sample size is supported see \ref SymbolicSampleSizes. */
|
||||
virtual tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) = 0;
|
||||
|
||||
/** Gets the current Latency in samples.
|
||||
The returned value defines the group delay or the latency of the plug-in. For example, if the plug-in internally needs
|
||||
to look in advance (like compressors) 512 samples then this plug-in should report 512 as latency.
|
||||
If during the use of the plug-in this latency change, the plug-in has to inform the host by
|
||||
using IComponentHandler::restartComponent (kLatencyChanged), this could lead to audio playback interruption
|
||||
because the host has to recompute its internal mixer delay compensation.
|
||||
Note that for player live recording this latency should be zero or small. */
|
||||
virtual uint32 PLUGIN_API getLatencySamples () = 0;
|
||||
|
||||
/** Called in disable state (setActive not called with true) before setProcessing is called and processing will begin. */
|
||||
virtual tresult PLUGIN_API setupProcessing (ProcessSetup& setup) = 0;
|
||||
|
||||
/** Informs the plug-in about the processing state. This will be called before any process calls
|
||||
start with true and after with false.
|
||||
Note that setProcessing (false) may be called after setProcessing (true) without any process
|
||||
calls.
|
||||
Note this function could be called in the UI or in Processing Thread, thats why the plug-in
|
||||
should only light operation (no memory allocation or big setup reconfiguration),
|
||||
this could be used to reset some buffers (like Delay line or Reverb).
|
||||
The host has to be sure that it is called only when the plug-in is enable (setActive (true)
|
||||
was called). */
|
||||
virtual tresult PLUGIN_API setProcessing (TBool state) = 0;
|
||||
|
||||
/** The Process call, where all information (parameter changes, event, audio buffer) are passed. */
|
||||
virtual tresult PLUGIN_API process (ProcessData& data) = 0;
|
||||
|
||||
/** Gets tail size in samples. For example, if the plug-in is a Reverb plug-in and it knows that
|
||||
the maximum length of the Reverb is 2sec, then it has to return in getTailSamples()
|
||||
(in VST2 it was getGetTailSize ()): 2*sampleRate.
|
||||
This information could be used by host for offline processing, process optimization and
|
||||
downmix (avoiding signal cut (clicks)).
|
||||
It should return:
|
||||
- kNoTail when no tail
|
||||
- x * sampleRate when x Sec tail.
|
||||
- kInfiniteTail when infinite tail. */
|
||||
virtual uint32 PLUGIN_API getTailSamples () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IAudioProcessor, 0x42043F99, 0xB7DA453C, 0xA569E79D, 0x9AAEC33D)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended IAudioProcessor interface for a component: Vst::IAudioPresentationLatency
|
||||
\ingroup vstIPlug vst310
|
||||
- [plug imp]
|
||||
- [extends IAudioProcessor]
|
||||
- [released: 3.1.0]
|
||||
- [optional]
|
||||
|
||||
Inform the plug-in about how long from the moment of generation/acquiring (from file or from Input)
|
||||
it will take for its input to arrive, and how long it will take for its output to be presented (to output or to speaker).
|
||||
|
||||
Note for Input Presentation Latency: when reading from file, the first plug-in will have an input presentation latency set to zero.
|
||||
When monitoring audio input from an audio device, the initial input latency is the input latency of the audio device itself.
|
||||
|
||||
Note for Output Presentation Latency: when writing to a file, the last plug-in will have an output presentation latency set to zero.
|
||||
When the output of this plug-in is connected to an audio device, the initial output latency is the output
|
||||
latency of the audio device itself.
|
||||
|
||||
A value of zero either means no latency or an unknown latency.
|
||||
|
||||
Each plug-in adding a latency (returning a none zero value for IAudioProcessor::getLatencySamples) will modify the input
|
||||
presentation latency of the next plug-ins in the mixer routing graph and will modify the output presentation latency
|
||||
of the previous plug-ins.
|
||||
|
||||
\n
|
||||
\image html "iaudiopresentationlatency_usage.png"
|
||||
\n
|
||||
\see IAudioProcessor
|
||||
\see IComponent
|
||||
*/
|
||||
class IAudioPresentationLatency : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Informs the plug-in about the Audio Presentation Latency in samples for a given direction (kInput/kOutput) and bus index. */
|
||||
virtual tresult PLUGIN_API setAudioPresentationLatencySamples (BusDirection dir, int32 busIndex, uint32 latencyInSamples) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IAudioPresentationLatency, 0x309ECE78, 0xEB7D4fae, 0x8B2225D9, 0x09FD08B6)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended IAudioProcessor interface for a component: Vst::IProcessContextRequirements
|
||||
\ingroup vstIPlug vst370
|
||||
- [plug imp]
|
||||
- [extends IAudioProcessor]
|
||||
- [released: 3.7.0]
|
||||
- [mandatory]
|
||||
|
||||
To get accurate process context information (Vst::ProcessContext), it is now required to implement this interface and
|
||||
return the desired bit mask of flags which your audio effect needs. If you do not implement this
|
||||
interface, you may not get any information at all of the process function.
|
||||
|
||||
The host asks for this information once between initialize and setActive. It cannot be changed afterwards.
|
||||
|
||||
This gives the host the opportunity to better optimize the audio process graph when it knows which
|
||||
plug-ins need which information.
|
||||
|
||||
Plug-Ins built with an earlier SDK version (< 3.7) will still get the old information, but the information
|
||||
may not be as accurate as when using this interface.
|
||||
*/
|
||||
class IProcessContextRequirements : public FUnknown
|
||||
{
|
||||
public:
|
||||
enum Flags
|
||||
{
|
||||
kNeedSystemTime = 1 << 0, // kSystemTimeValid
|
||||
kNeedContinousTimeSamples = 1 << 1, // kContTimeValid
|
||||
kNeedProjectTimeMusic = 1 << 2, // kProjectTimeMusicValid
|
||||
kNeedBarPositionMusic = 1 << 3, // kBarPositionValid
|
||||
kNeedCycleMusic = 1 << 4, // kCycleValid
|
||||
kNeedSamplesToNextClock = 1 << 5, // kClockValid
|
||||
kNeedTempo = 1 << 6, // kTempoValid
|
||||
kNeedTimeSignature = 1 << 7, // kTimeSigValid
|
||||
kNeedChord = 1 << 8, // kChordValid
|
||||
kNeedFrameRate = 1 << 9, // kSmpteValid
|
||||
kNeedTransportState = 1 << 10, // kPlaying, kCycleActive, kRecording
|
||||
};
|
||||
virtual uint32 PLUGIN_API getProcessContextRequirements () = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IProcessContextRequirements, 0x2A654303, 0xEF764E3D, 0x95B5FE83, 0x730EF6D0)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstautomationstate.h
|
||||
// Created by : Steinberg, 02/2015
|
||||
// Description : VST Automation State Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController: Vst::IAutomationState
|
||||
\ingroup vstIPlug vst365
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.6.5]
|
||||
- [optional]
|
||||
|
||||
Hosts can inform the plug-in about its current automation state (Read/Write/Nothing).
|
||||
*/
|
||||
class IAutomationState : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
enum AutomationStates
|
||||
{
|
||||
kNoAutomation = 0, ///< Not Read and not Write
|
||||
kReadState = 1 << 0, ///< Read state
|
||||
kWriteState = 1 << 1, ///< Write state
|
||||
|
||||
kReadWriteState = kReadState | kWriteState, ///< Read and Write enable
|
||||
};
|
||||
|
||||
/** Sets the current Automation state. */
|
||||
virtual tresult PLUGIN_API setAutomationState (int32 state) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IAutomationState, 0xB4E8287F, 0x1BB346AA, 0x83A46667, 0x68937BAB)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstchannelcontextinfo.h
|
||||
// Created by : Steinberg, 02/2014
|
||||
// Description : VST Channel Context Info Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/vsttypes.h"
|
||||
#include "pluginterfaces/vst/ivstattributes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
/** For Channel Context Info Interface */
|
||||
namespace ChannelContext {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
/** Channel context interface: Vst::IInfoListener
|
||||
\ingroup vstIHost vst365
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.6.5]
|
||||
- [optional]
|
||||
|
||||
Allows the host to inform the plug-in about the context in which the plug-in is instantiated,
|
||||
mainly channel based info (color, name, index,...). Index can be defined inside a namespace
|
||||
(for example, index start from 1 to N for Type Input/Output Channel (Index namespace) and index
|
||||
start from 1 to M for Type Audio Channel).\n
|
||||
As soon as the plug-in provides this IInfoListener interface, the host will call setChannelContextInfos
|
||||
for each change occurring to this channel (new name, new color, new indexation,...)
|
||||
|
||||
\section IChannelContextExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyPlugin::setChannelContextInfos (IAttributeList* list)
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
// optional we can ask for the Channel Name Length
|
||||
int64 length;
|
||||
if (list->getInt (ChannelContext::kChannelNameLengthKey, length) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get the Channel Name where we, as plug-in, are instantiated
|
||||
String128 name;
|
||||
if (list->getString (ChannelContext::kChannelNameKey, name, sizeof (name)) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get the Channel UID
|
||||
if (list->getString (ChannelContext::kChannelUIDKey, name, sizeof (name)) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get Channel Index
|
||||
int64 index;
|
||||
if (list->getInt (ChannelContext::kChannelIndexKey, index) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get the Channel Color
|
||||
int64 color;
|
||||
if (list->getInt (ChannelContext::kChannelColorKey, color) == kResultTrue)
|
||||
{
|
||||
uint32 channelColor = (uint32)color;
|
||||
String str;
|
||||
str.printf ("%x%x%x%x", ChannelContext::GetAlpha (channelColor),
|
||||
ChannelContext::GetRed (channelColor),
|
||||
ChannelContext::GetGreen (channelColor),
|
||||
ChannelContext::GetBlue (channelColor));
|
||||
String128 string128;
|
||||
Steinberg::UString (string128, 128).fromAscii (str);
|
||||
...
|
||||
}
|
||||
|
||||
// get Channel Index Namespace Order of the current used index namespace
|
||||
if (list->getInt (ChannelContext::kChannelIndexNamespaceOrderKey, index) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get the channel Index Namespace Length
|
||||
if (list->getInt (ChannelContext::kChannelIndexNamespaceLengthKey, length) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get the channel Index Namespace
|
||||
String128 namespaceName;
|
||||
if (list->getString (ChannelContext::kChannelIndexNamespaceKey, namespaceName, sizeof (namespaceName)) == kResultTrue)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
// get plug-in Channel Location
|
||||
int64 location;
|
||||
if (list->getInt (ChannelContext::kChannelPluginLocationKey, location) == kResultTrue)
|
||||
{
|
||||
String128 string128;
|
||||
switch (location)
|
||||
{
|
||||
case ChannelContext::kPreVolumeFader:
|
||||
Steinberg::UString (string128, 128).fromAscii ("PreVolFader");
|
||||
break;
|
||||
case ChannelContext::kPostVolumeFader:
|
||||
Steinberg::UString (string128, 128).fromAscii ("PostVolFader");
|
||||
break;
|
||||
case ChannelContext::kUsedAsPanner:
|
||||
Steinberg::UString (string128, 128).fromAscii ("UsedAsPanner");
|
||||
break;
|
||||
default: Steinberg::UString (string128, 128).fromAscii ("unknown!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do not forget to call addRef () if you want to keep this list
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class IInfoListener : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Receive the channel context infos from host. */
|
||||
virtual tresult PLUGIN_API setChannelContextInfos (IAttributeList* list) = 0;
|
||||
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IInfoListener, 0x0F194781, 0x8D984ADA, 0xBBA0C1EF, 0xC011D8D0)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Values used for kChannelPluginLocationKey */
|
||||
enum ChannelPluginLocation
|
||||
{
|
||||
kPreVolumeFader = 0,
|
||||
kPostVolumeFader,
|
||||
kUsedAsPanner
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
// Colors
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup vst3typedef VST 3 Data Types */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
/** ARGB (Alpha-Red-Green-Blue) */
|
||||
typedef uint32 ColorSpec;
|
||||
typedef uint8 ColorComponent;
|
||||
/*@}*/
|
||||
|
||||
/** Returns the Blue part of the given ColorSpec */
|
||||
inline ColorComponent GetBlue (ColorSpec cs) {return (ColorComponent)(cs & 0x000000FF); }
|
||||
/** Returns the Green part of the given ColorSpec */
|
||||
inline ColorComponent GetGreen (ColorSpec cs) {return (ColorComponent)((cs >> 8) & 0x000000FF); }
|
||||
/** Returns the Red part of the given ColorSpec */
|
||||
inline ColorComponent GetRed (ColorSpec cs) {return (ColorComponent)((cs >> 16) & 0x000000FF); }
|
||||
/** Returns the Alpha part of the given ColorSpec */
|
||||
inline ColorComponent GetAlpha (ColorSpec cs) {return (ColorComponent)((cs >> 24) & 0x000000FF); }
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Keys used as AttrID (Attribute ID) in the return IAttributeList of
|
||||
* IInfoListener::setChannelContextInfos */
|
||||
//------------------------------------------------------------------------
|
||||
/** string (TChar) [optional]: unique id string used to identify a channel */
|
||||
const CString kChannelUIDKey = "channel uid";
|
||||
|
||||
/** integer (int64) [optional]: number of characters in kChannelUIDKey */
|
||||
const CString kChannelUIDLengthKey = "channel uid length";
|
||||
|
||||
/** string (TChar) [optional]: name of the channel like displayed in the mixer */
|
||||
const CString kChannelNameKey = "channel name";
|
||||
|
||||
/** integer (int64) [optional]: number of characters in kChannelNameKey */
|
||||
const CString kChannelNameLengthKey = "channel name length";
|
||||
|
||||
/** color (ColorSpec) [optional]: used color for the channel in mixer or track */
|
||||
const CString kChannelColorKey = "channel color";
|
||||
|
||||
/** integer (int64) [optional]: index of the channel in a channel index namespace, start with 1 not * 0! */
|
||||
const CString kChannelIndexKey = "channel index";
|
||||
|
||||
/** integer (int64) [optional]: define the order of the current used index namespace, start with 1 not 0!
|
||||
For example:
|
||||
index namespace is "Input" -> order 1,
|
||||
index namespace is "Channel" -> order 2,
|
||||
index namespace is "Output" -> order 3 */
|
||||
const CString kChannelIndexNamespaceOrderKey = "channel index namespace order";
|
||||
|
||||
/** string (TChar) [optional]: name of the channel index namespace for example "Input", "Output", "Channel", ... */
|
||||
const CString kChannelIndexNamespaceKey = "channel index namespace";
|
||||
|
||||
/** integer (int64) [optional]: number of characters in kChannelIndexNamespaceKey */
|
||||
const CString kChannelIndexNamespaceLengthKey = "channel index namespace length";
|
||||
|
||||
/** PNG image representation as binary [optional] */
|
||||
const CString kChannelImageKey = "channel image";
|
||||
|
||||
/** integer (int64) [optional]: routing position of the plug-in in the channel (see ChannelPluginLocation) */
|
||||
const CString kChannelPluginLocationKey = "channel plugin location";
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace ChannelContext
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstcomponent.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : Basic VST Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/ipluginbase.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
class IBStream;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** All VST specific interfaces are located in Vst namespace */
|
||||
namespace Vst {
|
||||
|
||||
/** Standard value for PFactoryInfo::flags */
|
||||
const int32 kDefaultFactoryFlags = PFactoryInfo::kUnicode;
|
||||
|
||||
#define BEGIN_FACTORY_DEF(vendor,url,email) using namespace Steinberg; \
|
||||
SMTG_EXPORT_SYMBOL IPluginFactory* PLUGIN_API GetPluginFactory () { \
|
||||
if (!gPluginFactory) \
|
||||
{ \
|
||||
static PFactoryInfo factoryInfo (vendor, url, email, Vst::kDefaultFactoryFlags); \
|
||||
gPluginFactory = new CPluginFactory (factoryInfo);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup vstBus VST busses
|
||||
Bus Description
|
||||
|
||||
A bus can be understood as a "collection of data channels" belonging together.
|
||||
It describes a data input or a data output of the plug-in.
|
||||
A VST component can define any desired number of busses.
|
||||
Dynamic usage of busses is handled in the host by activating and deactivating busses.
|
||||
All busses are initially inactive.
|
||||
The component has to define the maximum number of supported busses and it has to
|
||||
define which of them have to be activated by default after instantiation of the plug-in (This is
|
||||
only a wish, the host is allow to not follow it, and only activate the first bus for example).
|
||||
A host that can handle multiple busses, allows the user to activate busses which are initially all inactive.
|
||||
The kMain busses have to place before any others kAux busses.
|
||||
|
||||
See also: IComponent::getBusInfo, IComponent::activateBus
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Bus media types */
|
||||
enum MediaTypes
|
||||
{
|
||||
kAudio = 0, ///< audio
|
||||
kEvent, ///< events
|
||||
kNumMediaTypes
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Bus directions */
|
||||
enum BusDirections
|
||||
{
|
||||
kInput = 0, ///< input bus
|
||||
kOutput ///< output bus
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Bus types */
|
||||
enum BusTypes
|
||||
{
|
||||
kMain = 0, ///< main bus
|
||||
kAux ///< auxiliary bus (sidechain)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** BusInfo:
|
||||
This is the structure used with getBusInfo, informing the host about what is a specific given bus.
|
||||
\n See also: Steinberg::Vst::IComponent::getBusInfo
|
||||
*/
|
||||
struct BusInfo
|
||||
{
|
||||
MediaType mediaType; ///< Media type - has to be a value of \ref MediaTypes
|
||||
BusDirection direction; ///< input or output \ref BusDirections
|
||||
int32 channelCount; ///< number of channels (if used then need to be recheck after \ref
|
||||
/// IAudioProcessor::setBusArrangements is called).
|
||||
/// For a bus of type MediaTypes::kEvent the channelCount corresponds
|
||||
/// to the number of supported MIDI channels by this bus
|
||||
String128 name; ///< name of the bus
|
||||
BusType busType; ///< main or aux - has to be a value of \ref BusTypes
|
||||
uint32 flags; ///< flags - a combination of \ref BusFlags
|
||||
enum BusFlags
|
||||
{
|
||||
/** The bus should be activated by the host per default on instantiation (activateBus call is requested).
|
||||
By default a bus is inactive. */
|
||||
kDefaultActive = 1 << 0,
|
||||
/** The bus does not contain ordinary audio data, but data used for control changes at sample rate.
|
||||
The data is in the same format as the audio data [-1..1].
|
||||
A host has to prevent unintended routing to speakers to prevent damage.
|
||||
Only valid for audio media type busses.
|
||||
[released: 3.7.0] */
|
||||
kIsControlVoltage = 1 << 1
|
||||
};
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** I/O modes */
|
||||
enum IoModes
|
||||
{
|
||||
kSimple = 0, ///< 1:1 Input / Output. Only used for Instruments. See \ref vst3IoMode
|
||||
kAdvanced, ///< n:m Input / Output. Only used for Instruments.
|
||||
kOfflineProcessing ///< plug-in used in an offline processing context
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Routing Information:
|
||||
When the plug-in supports multiple I/O busses, a host may want to know how the busses are related. The
|
||||
relation of an event-input-channel to an audio-output-bus in particular is of interest to the host
|
||||
(in order to relate MIDI-tracks to audio-channels)
|
||||
\n See also: IComponent::getRoutingInfo, \ref vst3Routing
|
||||
*/
|
||||
struct RoutingInfo
|
||||
{
|
||||
MediaType mediaType; ///< media type see \ref MediaTypes
|
||||
int32 busIndex; ///< bus index
|
||||
int32 channel; ///< channel (-1 for all channels)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IComponent Interface
|
||||
//------------------------------------------------------------------------
|
||||
/** Component base interface: Vst::IComponent
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
This is the basic interface for a VST component and must always be supported.
|
||||
It contains the common parts of any kind of processing class. The parts that
|
||||
are specific to a media type are defined in a separate interface. An implementation
|
||||
component must provide both the specific interface and IComponent.
|
||||
\see IPluginBase
|
||||
*/
|
||||
class IComponent : public IPluginBase
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Called before initializing the component to get information about the controller class. */
|
||||
virtual tresult PLUGIN_API getControllerClassId (TUID classId) = 0;
|
||||
|
||||
/** Called before 'initialize' to set the component usage (optional). See \ref IoModes */
|
||||
virtual tresult PLUGIN_API setIoMode (IoMode mode) = 0;
|
||||
|
||||
/** Called after the plug-in is initialized. See \ref MediaTypes, BusDirections */
|
||||
virtual int32 PLUGIN_API getBusCount (MediaType type, BusDirection dir) = 0;
|
||||
|
||||
/** Called after the plug-in is initialized. See \ref MediaTypes, BusDirections */
|
||||
virtual tresult PLUGIN_API getBusInfo (MediaType type, BusDirection dir, int32 index, BusInfo& bus /*out*/) = 0;
|
||||
|
||||
/** Retrieves routing information (to be implemented when more than one regular input or output bus exists).
|
||||
The inInfo always refers to an input bus while the returned outInfo must refer to an output bus! */
|
||||
virtual tresult PLUGIN_API getRoutingInfo (RoutingInfo& inInfo, RoutingInfo& outInfo /*out*/) = 0;
|
||||
|
||||
/** Called upon (de-)activating a bus in the host application. The plug-in should only processed
|
||||
an activated bus, the host could provide less see \ref AudioBusBuffers in the process call
|
||||
(see \ref IAudioProcessor::process) if last busses are not activated. An already activated bus
|
||||
does not need to be reactivated after a IAudioProcessor::setBusArrangements call. */
|
||||
virtual tresult PLUGIN_API activateBus (MediaType type, BusDirection dir, int32 index,
|
||||
TBool state) = 0;
|
||||
|
||||
/** Activates / deactivates the component. */
|
||||
virtual tresult PLUGIN_API setActive (TBool state) = 0;
|
||||
|
||||
/** Sets complete state of component. */
|
||||
virtual tresult PLUGIN_API setState (IBStream* state) = 0;
|
||||
|
||||
/** Retrieves complete state of component. */
|
||||
virtual tresult PLUGIN_API getState (IBStream* state) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IComponent, 0xE831FF31, 0xF2D54301, 0x928EBBEE, 0x25697802)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,219 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstcontextmenu.h
|
||||
// Created by : Steinberg, 10/2010
|
||||
// Description : VST Context Menu Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
namespace Steinberg {
|
||||
class IPlugView;
|
||||
|
||||
namespace Vst {
|
||||
class IContextMenu;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended host callback interface Vst::IComponentHandler3 for an edit controller.
|
||||
\ingroup vstIHost vst350
|
||||
- [host imp]
|
||||
- [extends IComponentHandler]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
A plug-in can ask the host to create a context menu for a given exported parameter ID or a generic context menu.\n
|
||||
|
||||
The host may pre-fill this context menu with specific items regarding the parameter ID like "Show automation for parameter",
|
||||
"MIDI learn" etc...\n
|
||||
|
||||
The plug-in can use the context menu in two ways :
|
||||
- add its own items to the menu via the IContextMenu interface and call IContextMenu::popup(..) to create the pop-up. See the \ref IContextMenuExample.
|
||||
- extract the host menu items and add them to a context menu created by the plug-in.
|
||||
|
||||
\b Note: You can and should use this even if you do not add your own items to the menu as this is considered to be a big user value.
|
||||
|
||||
\sa IContextMenu
|
||||
\sa IContextMenuTarget
|
||||
|
||||
\section IContextMenuExample Examples
|
||||
- For example, Cubase adds its owned entries in the context menu opened with right-click on an exported parameter when the plug-in uses createContextMenu.
|
||||
\image html "contextmenuexample.png"
|
||||
\n
|
||||
- Adding plug-in specific items to the context menu:
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
class PluginContextMenuTarget : public IContextMenuTarget, public FObject
|
||||
{
|
||||
public:
|
||||
PluginContextMenuTarget () {}
|
||||
|
||||
virtual tresult PLUGIN_API executeMenuItem (int32 tag)
|
||||
{
|
||||
// this will be called if the user has executed one of the menu items of the plug-in.
|
||||
// It will not be called for items of the host.
|
||||
switch (tag)
|
||||
{
|
||||
case 1: break;
|
||||
case 2: break;
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
OBJ_METHODS(PluginContextMenuTarget, FObject)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (IContextMenuTarget)
|
||||
END_DEFINE_INTERFACES (FObject)
|
||||
REFCOUNT_METHODS(FObject)
|
||||
};
|
||||
|
||||
// The following is the code to create the context menu
|
||||
void popupContextMenu (IComponentHandler* componentHandler, IPlugView* view, const ParamID* paramID, UCoord x, UCoord y)
|
||||
{
|
||||
if (componentHandler == 0 || view == 0)
|
||||
return;
|
||||
FUnknownPtr<IComponentHandler3> handler (componentHandler);
|
||||
if (handler == 0)
|
||||
return;
|
||||
IContextMenu* menu = handler->createContextMenu (view, paramID);
|
||||
if (menu)
|
||||
{
|
||||
// here you can add your entries (optional)
|
||||
PluginContextMenuTarget* target = new PluginContextMenuTarget ();
|
||||
|
||||
IContextMenu::Item item = {0};
|
||||
UString128 ("My Item 1").copyTo (item.name, 128);
|
||||
item.tag = 1;
|
||||
menu->addItem (item, target);
|
||||
|
||||
UString128 ("My Item 2").copyTo (item.name, 128);
|
||||
item.tag = 2;
|
||||
menu->addItem (item, target);
|
||||
target->release ();
|
||||
//--end of adding new entries
|
||||
|
||||
// here the the context menu will be pop-up (and it waits a user interaction)
|
||||
menu->popup (x, y);
|
||||
menu->release ();
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class IComponentHandler3 : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Creates a host context menu for a plug-in:
|
||||
- If paramID is zero, the host may create a generic context menu.
|
||||
- The IPlugView object must be valid.
|
||||
- The return IContextMenu object needs to be released afterwards by the plug-in.
|
||||
*/
|
||||
virtual IContextMenu* PLUGIN_API createContextMenu (IPlugView* plugView, const ParamID* paramID) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IComponentHandler3, 0x69F11617, 0xD26B400D, 0xA4B6B964, 0x7B6EBBAB)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Context Menu Item Target interface: Vst::IContextMenuTarget
|
||||
\ingroup vstIHost vstIPlug vst350
|
||||
- [host imp]
|
||||
- [plug imp]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
A receiver of a menu item should implement this interface, which will be called after the user has selected
|
||||
this menu item.
|
||||
|
||||
\see IComponentHandler3 for more information.
|
||||
*/
|
||||
class IContextMenuTarget : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Called when an menu item was executed. */
|
||||
virtual tresult PLUGIN_API executeMenuItem (int32 tag) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IContextMenuTarget, 0x3CDF2E75, 0x85D34144, 0xBF86D36B, 0xD7C4894D)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** IContextMenuItem is an entry element of the context menu. */
|
||||
struct IContextMenuItem
|
||||
{
|
||||
String128 name; ///< Name of the item
|
||||
int32 tag; ///< Identifier tag of the item
|
||||
int32 flags; ///< Flags of the item
|
||||
|
||||
enum Flags {
|
||||
kIsSeparator = 1 << 0, ///< Item is a separator
|
||||
kIsDisabled = 1 << 1, ///< Item is disabled
|
||||
kIsChecked = 1 << 2, ///< Item is checked
|
||||
kIsGroupStart = 1 << 3 | kIsDisabled, ///< Item is a group start (like sub folder)
|
||||
kIsGroupEnd = 1 << 4 | kIsSeparator, ///< Item is a group end
|
||||
};
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
/** Context Menu interface: Vst::IContextMenu
|
||||
\ingroup vstIHost vst350
|
||||
- [host imp]
|
||||
- [create with IComponentHandler3::createContextMenu(..)]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
A context menu is composed of Item (entry). A Item is defined by a name, a tag, a flag
|
||||
and a associated target (called when this item will be selected/executed).
|
||||
With IContextMenu the plug-in can retrieve a Item, add a Item, remove a Item and pop-up the menu.
|
||||
|
||||
\see IComponentHandler3 for more information.
|
||||
*/
|
||||
class IContextMenu : public FUnknown
|
||||
{
|
||||
public:
|
||||
typedef IContextMenuItem Item;
|
||||
|
||||
/** Gets the number of menu items. */
|
||||
virtual int32 PLUGIN_API getItemCount () = 0;
|
||||
|
||||
/** Gets a menu item and its target (target could be not assigned). */
|
||||
virtual tresult PLUGIN_API getItem (int32 index, Item& item /*out*/, IContextMenuTarget** target /*out*/) = 0;
|
||||
|
||||
/** Adds a menu item and its target. */
|
||||
virtual tresult PLUGIN_API addItem (const Item& item, IContextMenuTarget* target) = 0;
|
||||
|
||||
/** Removes a menu item. */
|
||||
virtual tresult PLUGIN_API removeItem (const Item& item, IContextMenuTarget* target) = 0;
|
||||
|
||||
/** Pop-ups the menu. Coordinates are relative to the top-left position of the plug-ins view. */
|
||||
virtual tresult PLUGIN_API popup (UCoord x, UCoord y) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IContextMenu, 0x2E93C863, 0x0C9C4588, 0x97DBECF5, 0xAD17817D)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstdataexchange.h
|
||||
// Created by : Steinberg, 06/2022
|
||||
// Description : VST Data Exchange Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class IAudioProcessor;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
typedef uint32 DataExchangeQueueID;
|
||||
typedef uint32 DataExchangeBlockID;
|
||||
typedef uint32 DataExchangeUserContextID;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static SMTG_CONSTEXPR DataExchangeQueueID InvalidDataExchangeQueueID = kMaxInt32;
|
||||
static SMTG_CONSTEXPR DataExchangeBlockID InvalidDataExchangeBlockID = kMaxInt32;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct DataExchangeBlock
|
||||
{
|
||||
/** pointer to the memory buffer */
|
||||
void* data;
|
||||
/** size of the memory buffer */
|
||||
uint32 size;
|
||||
/** block identifier */
|
||||
DataExchangeBlockID blockID;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Host Data Exchange handler interface: Vst::IDataExchangeHandler
|
||||
\ingroup vstHost vst379
|
||||
- [host imp]
|
||||
- [context interface]
|
||||
- [released: 3.7.9]
|
||||
- [optional]
|
||||
|
||||
The IDataExchangeHandler implements a direct and thread-safe connection from the realtime
|
||||
audio context of the audio processor to the non-realtime audio context of the edit controller.
|
||||
This should be used when the edit controller needs continuous data from the audio process for
|
||||
visualization or other use-cases. To circumvent the bottleneck on the main thread it is possible
|
||||
to configure the connection in a way that the calls to the edit controller will happen on a
|
||||
background thread.
|
||||
|
||||
Opening a queue:
|
||||
The main operation for a plug-in is to open a queue via the handler before the plug-in is activated
|
||||
(but it must be connected to the edit controller via the IConnectionPoint when the plug-in is using
|
||||
the recommended separation of edit controller and audio processor). The best place to do this is in
|
||||
the IAudioProcessor::setupProcessing method as this is also the place where the plug-in knows the
|
||||
sample rate and maximum block size which the plug-in may need to calculate the queue block size.
|
||||
When a queue is opened the edit controller gets a notification about it and the controller can
|
||||
decide if it wishes to receive the data on the main thread or the background thread.
|
||||
|
||||
Sending data:
|
||||
In the IAudioProcessor::process call the plug-in can now lock a block from the handler, fill it and
|
||||
when done free the block via the handler which then sends the block to the edit controller. The edit
|
||||
controller then receives the block either on the main thread or on a background thread depending on
|
||||
the setup of the queue.
|
||||
The host guarantees that all blocks are send before the plug-in is deactivated.
|
||||
|
||||
Closing a queue:
|
||||
The audio processor must close an opened queue and this has to be done after the processor was
|
||||
deactivated and before it is disconnected from the edit controller (see IConnectionPoint).
|
||||
|
||||
What to do when the queue is full and no block can be locked?
|
||||
The plug-in needs to be prepared for this situation as constraints in the overall system may cause
|
||||
the queue to get full. If you need to get this information to the controller you can declare a
|
||||
hidden parameter which you set to a special value and send this parameter change in your audio
|
||||
process method.
|
||||
*/
|
||||
class IDataExchangeHandler : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** open a new queue
|
||||
*
|
||||
* only allowed to be called from the main thread when the component is not active but
|
||||
* initialized and connected (see IConnectionPoint)
|
||||
*
|
||||
* @param processor the processor who wants to open the queue
|
||||
* @param blockSize size of one block
|
||||
* @param numBlocks number of blocks in the queue
|
||||
* @param alignment data alignment, if zero will use the platform default alignment if any
|
||||
* @param userContextID an identifier internal to the processor
|
||||
* @param outID on return the ID of the queue
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API openQueue (IAudioProcessor* processor, uint32 blockSize,
|
||||
uint32 numBlocks, uint32 alignment,
|
||||
DataExchangeUserContextID userContextID,
|
||||
DataExchangeQueueID* outID) = 0;
|
||||
/** close a queue
|
||||
*
|
||||
* closes and frees all memory of a previously opened queue
|
||||
* if there are locked blocks in the queue, they are freed and made invalid
|
||||
*
|
||||
* only allowed to be called from the main thread when the component is not active but
|
||||
* initialized and connected
|
||||
*
|
||||
* @param queueID the ID of the queue to close
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API closeQueue (DataExchangeQueueID queueID) = 0;
|
||||
|
||||
/** lock a block if available
|
||||
*
|
||||
* only allowed to be called from within the IAudioProcessor::process call
|
||||
*
|
||||
* @param queueID the ID of the queue
|
||||
* @param block on return will contain the data pointer and size of the block
|
||||
* @return kResultTrue if a free block was found and kOutOfMemory if all blocks are locked
|
||||
*/
|
||||
virtual tresult PLUGIN_API lockBlock (DataExchangeQueueID queueId,
|
||||
DataExchangeBlock* block) = 0;
|
||||
|
||||
/** free a previously locked block
|
||||
*
|
||||
* only allowed to be called from within the IAudioProcessor::process call
|
||||
*
|
||||
* @param queueID the ID of the queue
|
||||
* @param blockID the ID of the block
|
||||
* @param sendToController if true the block data will be send to the IEditController otherwise
|
||||
* it will be discarded
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API freeBlock (DataExchangeQueueID queueId, DataExchangeBlockID blockID,
|
||||
TBool sendToController) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IDataExchangeHandler, 0x36D551BD, 0x6FF54F08, 0xB48E830D, 0x8BD5A03B)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Data Exchange Receiver interface: Vst::IDataExchangeReceiver
|
||||
\ingroup vstPlug vst379
|
||||
- [plug imp]
|
||||
- [released: 3.7.9
|
||||
- [optional]
|
||||
|
||||
The receiver interface is required to receive data from the realtime audio process via the
|
||||
IDataExchangeHandler.
|
||||
|
||||
\see \ref IDataExchangeHandler
|
||||
*/
|
||||
class IDataExchangeReceiver : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** queue opened notification
|
||||
*
|
||||
* called on the main thread when the processor has opened a queue
|
||||
*
|
||||
* @param userContextID the user context ID of the queue
|
||||
* @param blockSize the size of one block of the queue
|
||||
* @param dispatchedOnBackgroundThread if true on output the blocks are dispatched on a
|
||||
* background thread [defaults to false in which case the
|
||||
* blocks are dispatched on the main thread]
|
||||
*/
|
||||
virtual void PLUGIN_API queueOpened (DataExchangeUserContextID userContextID, uint32 blockSize,
|
||||
TBool& dispatchOnBackgroundThread) = 0;
|
||||
/** queue closed notification
|
||||
*
|
||||
* called on the main thread when the processor has closed a queue
|
||||
*
|
||||
* @param userContextID the user context ID of the queue
|
||||
*/
|
||||
virtual void PLUGIN_API queueClosed (DataExchangeUserContextID userContextID) = 0;
|
||||
|
||||
/** one or more blocks were received
|
||||
*
|
||||
* called either on the main thread or a background thread depending on the
|
||||
* dispatchOnBackgroundThread value in the queueOpened call.
|
||||
*
|
||||
* the data of the blocks are only valid inside this call and the blocks only become available
|
||||
* to the queue afterwards.
|
||||
*
|
||||
* @param userContextID the user context ID of the queue
|
||||
* @param numBlocks number of blocks
|
||||
* @param blocks the blocks
|
||||
* @param onBackgroundThread true if the call is done on a background thread
|
||||
*/
|
||||
virtual void PLUGIN_API onDataExchangeBlocksReceived (DataExchangeUserContextID userContextID,
|
||||
uint32 numBlocks,
|
||||
DataExchangeBlock* blocks,
|
||||
TBool onBackgroundThread) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IDataExchangeReceiver, 0x45A759DC, 0x84FA4907, 0xABCB6175, 0x2FC786B6)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,720 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivsteditcontroller.h
|
||||
// Created by : Steinberg, 09/2005
|
||||
// Description : VST Edit Controller Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/ipluginbase.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Class Category Name for Controller Component */
|
||||
//------------------------------------------------------------------------
|
||||
#ifndef kVstComponentControllerClass
|
||||
#define kVstComponentControllerClass "Component Controller Class"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
class IPlugView;
|
||||
class IBStream;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Controller Parameter Info.
|
||||
* A parameter info describes a parameter of the controller.
|
||||
* The id must always be the same for a parameter as this uniquely identifies the parameter.
|
||||
*/
|
||||
struct ParameterInfo
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
ParamID id; ///< unique identifier of this parameter (named tag too)
|
||||
String128 title; ///< parameter title (e.g. "Volume")
|
||||
String128 shortTitle; ///< parameter shortTitle (e.g. "Vol")
|
||||
String128 units; ///< parameter unit (e.g. "dB")
|
||||
int32 stepCount; ///< number of discrete steps (0: continuous, 1: toggle, discrete value
|
||||
/// otherwise (corresponding to max - min, for example:
|
||||
/// 127 for min = 0 and max = 127) - see \ref vst3ParameterIntro)
|
||||
ParamValue defaultNormalizedValue; ///< default normalized value [0,1]
|
||||
/// in case of discrete value:
|
||||
/// defaultNormalizedValue = defDiscreteValue/stepCount
|
||||
UnitID unitId; ///< id of unit this parameter belongs to (see \ref vst3Units)
|
||||
|
||||
int32 flags; ///< ParameterFlags (see below)
|
||||
|
||||
enum ParameterFlags : int32
|
||||
{
|
||||
/** No flags wanted.
|
||||
* [SDK 3.0.0] */
|
||||
kNoFlags = 0,
|
||||
|
||||
/** Parameter can be automated.
|
||||
* [SDK 3.0.0] */
|
||||
kCanAutomate = 1 << 0,
|
||||
|
||||
/** Parameter cannot be changed from outside the plug-in
|
||||
* (implies that kCanAutomate is NOT set).
|
||||
* [SDK 3.0.0] */
|
||||
kIsReadOnly = 1 << 1,
|
||||
|
||||
/** Attempts to set the parameter value out of the limits will result in a wrap around.
|
||||
* [SDK 3.0.2] */
|
||||
kIsWrapAround = 1 << 2,
|
||||
|
||||
/** Parameter should be displayed as list in generic editor or automation editing.
|
||||
* [SDK 3.1.0] */
|
||||
kIsList = 1 << 3,
|
||||
/** Parameter should be NOT displayed and cannot be changed from outside the plug-in.
|
||||
* It implies that kCanAutomate is NOT set and kIsReadOnly is set.
|
||||
* [SDK 3.7.0] */
|
||||
kIsHidden = 1 << 4,
|
||||
|
||||
/** Parameter is a program change (unitId gives info about associated unit - see \ref
|
||||
* vst3ProgramLists).
|
||||
* [SDK 3.0.0] */
|
||||
kIsProgramChange = 1 << 15,
|
||||
|
||||
/** Special bypass parameter (only one allowed): plug-in can handle bypass.
|
||||
* Highly recommended to export a bypass parameter for effect plug-in.
|
||||
* [SDK 3.0.0] */
|
||||
kIsBypass = 1 << 16
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** View Types used for IEditController::createView */
|
||||
//------------------------------------------------------------------------
|
||||
namespace ViewType {
|
||||
const CString kEditor = "editor";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Flags used for IComponentHandler::restartComponent */
|
||||
enum RestartFlags : int32
|
||||
{
|
||||
/** The Component should be reloaded
|
||||
* The host has to unload completely the plug-in (controller/processor) and reload it.
|
||||
* [SDK 3.0.0] */
|
||||
kReloadComponent = 1 << 0,
|
||||
|
||||
/** Input/Output Bus configuration has changed
|
||||
* The plug-in informs the host that either the bus configuration or the bus count has changed.
|
||||
* The host has to deactivate the plug-in, asks the plug-in for its wanted new bus
|
||||
* configurations, adapts its processing graph and reactivate the plug-in.
|
||||
* [SDK 3.0.0] */
|
||||
kIoChanged = 1 << 1,
|
||||
|
||||
/** Multiple parameter values have changed (as result of a program change for example)
|
||||
* The host invalidates all caches of parameter values and asks the edit controller for the
|
||||
* current values.
|
||||
* [SDK 3.0.0] */
|
||||
kParamValuesChanged = 1 << 2,
|
||||
|
||||
/** Latency has changed
|
||||
* The plug informs the host that its latency has changed, getLatencySamples should return the new latency after setActive (true) was called
|
||||
* The host has to deactivate and reactivate the plug-in, then afterwards the host could ask for the current latency (getLatencySamples)
|
||||
* See IAudioProcessor::getLatencySamples
|
||||
* [SDK 3.0.0] */
|
||||
kLatencyChanged = 1 << 3,
|
||||
|
||||
/** Parameter titles (title, shortTitle and units), default values, stepCount or flags (ParameterFlags) have changed
|
||||
* The host invalidates all caches of parameter infos and asks the edit controller for the
|
||||
* current infos.
|
||||
* [SDK 3.0.0] */
|
||||
kParamTitlesChanged = 1 << 4,
|
||||
|
||||
/** MIDI Controllers and/or Program Changes Assignments have changed
|
||||
* The plug-in informs the host that its MIDI-CC mapping has changed (for example after a MIDI learn or new loaded preset)
|
||||
* or if the stepCount or UnitID of a ProgramChange parameter has changed.
|
||||
* The host has to rebuild the MIDI-CC => parameter mapping (getMidiControllerAssignment)
|
||||
* and reread program changes parameters (stepCount and associated unitID)
|
||||
* [SDK 3.0.1] */
|
||||
kMidiCCAssignmentChanged = 1 << 5,
|
||||
|
||||
/** Note Expression has changed (info, count, PhysicalUIMapping, ...)
|
||||
* Either the note expression type info, the count of note expressions or the physical UI mapping has changed.
|
||||
* The host invalidates all caches of note expression infos and asks the edit controller for the current ones.
|
||||
* See INoteExpressionController, NoteExpressionTypeInfo and INoteExpressionPhysicalUIMapping
|
||||
* [SDK 3.5.0] */
|
||||
kNoteExpressionChanged = 1 << 6,
|
||||
|
||||
/** Input / Output bus titles have changed
|
||||
* The host invalidates all caches of bus titles and asks the edit controller for the current titles.
|
||||
* [SDK 3.5.0] */
|
||||
kIoTitlesChanged = 1 << 7,
|
||||
|
||||
/** Prefetch support has changed
|
||||
* The plug-in informs the host that its PrefetchSupport has changed
|
||||
* The host has to deactivate the plug-in, calls IPrefetchableSupport::getPrefetchableSupport
|
||||
* and reactivate the plug-in.
|
||||
* See IPrefetchableSupport
|
||||
* [SDK 3.6.1] */
|
||||
kPrefetchableSupportChanged = 1 << 8,
|
||||
|
||||
/** RoutingInfo has changed
|
||||
* The plug-in informs the host that its internal routing (relation of an event-input-channel to
|
||||
* an audio-output-bus) has changed. The host asks the plug-in for the new routing with
|
||||
* IComponent::getRoutingInfo, \ref vst3Routing
|
||||
* See IComponent
|
||||
* [SDK 3.6.6] */
|
||||
kRoutingInfoChanged = 1 << 9,
|
||||
|
||||
/** Key switches has changed (info, count)
|
||||
* Either the Key switches info, the count of Key switches has changed.
|
||||
* The host invalidates all caches of Key switches infos and asks the edit controller
|
||||
* (IKeyswitchController) for the current ones.
|
||||
* See IKeyswitchController
|
||||
* [SDK 3.7.3] */
|
||||
kKeyswitchChanged = 1 << 10,
|
||||
|
||||
/** Mapping of ParamID has changed
|
||||
* The Plug-in informs the host that its parameters ID has changed. This has to be called by the
|
||||
* edit controller in the method setComponentState or setState (during projects loading) when the
|
||||
* plug-in detects that the given state was associated to an older version of the plug-in, or to a
|
||||
* plug-in to replace (for ex. migrating VST2 => VST3), with a different set of parameter IDs, then
|
||||
* the host could remap any used parameters like automation by asking the IRemapParamID interface
|
||||
* (which extends IEditController).
|
||||
* See IRemapParamID
|
||||
* [SDK 3.7.11] */
|
||||
kParamIDMappingChanged = 1 << 11
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Host callback interface for an edit controller: Vst::IComponentHandler
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
Allow transfer of parameter editing to component (processor) via host and support automation.
|
||||
Cause the host to react on configuration changes (restartComponent).
|
||||
|
||||
\see \ref IEditController
|
||||
*/
|
||||
class IComponentHandler : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** To be called before calling a performEdit (e.g. on mouse-click-down event).
|
||||
* This must be called in the UI-Thread context! */
|
||||
virtual tresult PLUGIN_API beginEdit (ParamID id /*in*/) = 0;
|
||||
|
||||
/** Called between beginEdit and endEdit to inform the handler that a given parameter has a new
|
||||
* value. This must be called in the UI-Thread context! */
|
||||
virtual tresult PLUGIN_API performEdit (ParamID id /*in*/,
|
||||
ParamValue valueNormalized /*in*/) = 0;
|
||||
|
||||
/** To be called after calling a performEdit (e.g. on mouse-click-up event).
|
||||
* This must be called in the UI-Thread context! */
|
||||
virtual tresult PLUGIN_API endEdit (ParamID id /*in*/) = 0;
|
||||
|
||||
/** Instructs host to restart the component. This must be called in the UI-Thread context!
|
||||
* @param[in] flags is a combination of RestartFlags */
|
||||
virtual tresult PLUGIN_API restartComponent (int32 flags /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IComponentHandler, 0x93A0BEA3, 0x0BD045DB, 0x8E890B0C, 0xC1E46AC6)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended host callback interface for an edit controller: Vst::IComponentHandler2
|
||||
\ingroup vstIHost vst310
|
||||
- [host imp]
|
||||
- [extends IComponentHandler]
|
||||
- [released: 3.1.0]
|
||||
- [optional]
|
||||
|
||||
One part handles:
|
||||
- Setting dirty state of the plug-in
|
||||
- Requesting the host to open the editor
|
||||
|
||||
The other part handles parameter group editing from the plug-in UI. It wraps a set of \ref
|
||||
IComponentHandler::beginEdit / \ref Steinberg::Vst::IComponentHandler::performEdit / \ref
|
||||
Steinberg::Vst::IComponentHandler::endEdit functions (see \ref IComponentHandler) which should use
|
||||
the same timestamp in the host when writing automation. This allows for better synchronizing of
|
||||
multiple parameter changes at once.
|
||||
|
||||
\section IComponentHandler2Example Examples of different use cases
|
||||
|
||||
\code{.cpp}
|
||||
//--------------------------------------
|
||||
// we are in the editcontroller...
|
||||
// in case of multiple switch buttons (with associated ParamID 1 and 3)
|
||||
// on mouse down :
|
||||
hostHandler2->startGroupEdit ();
|
||||
hostHandler->beginEdit (1);
|
||||
hostHandler->beginEdit (3);
|
||||
hostHandler->performEdit (1, 1.0);
|
||||
hostHandler->performEdit (3, 0.0); // the opposite of paramID 1 for example
|
||||
....
|
||||
// on mouse up :
|
||||
hostHandler->endEdit (1);
|
||||
hostHandler->endEdit (3);
|
||||
hostHandler2->finishGroupEdit ();
|
||||
....
|
||||
....
|
||||
//--------------------------------------
|
||||
// in case of multiple faders (with associated ParamID 1 and 3)
|
||||
// on mouse down :
|
||||
hostHandler2->startGroupEdit ();
|
||||
hostHandler->beginEdit (1);
|
||||
hostHandler->beginEdit (3);
|
||||
hostHandler2->finishGroupEdit ();
|
||||
....
|
||||
// on mouse move :
|
||||
hostHandler2->startGroupEdit ();
|
||||
hostHandler->performEdit (1, x); // x the wanted value
|
||||
hostHandler->performEdit (3, x);
|
||||
hostHandler2->finishGroupEdit ();
|
||||
....
|
||||
// on mouse up :
|
||||
hostHandler2->startGroupEdit ();
|
||||
hostHandler->endEdit (1);
|
||||
hostHandler->endEdit (3);
|
||||
hostHandler2->finishGroupEdit ();
|
||||
\endcode
|
||||
\see \ref IComponentHandler, \ref IEditController
|
||||
*/
|
||||
class IComponentHandler2 : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Tells host that the plug-in is dirty (something besides parameters has changed since last
|
||||
* save), if true the host should apply a save before quitting. */
|
||||
virtual tresult PLUGIN_API setDirty (TBool state /*in*/) = 0;
|
||||
|
||||
/** Tells host that it should open the plug-in editor the next time it's possible. You should
|
||||
* use this instead of showing an alert and blocking the program flow (especially on loading
|
||||
* projects). */
|
||||
virtual tresult PLUGIN_API requestOpenEditor (FIDString name = ViewType::kEditor) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Starts the group editing (call before a \ref IComponentHandler::beginEdit),
|
||||
* the host will keep the current timestamp at this call and will use it for all
|
||||
* \ref IComponentHandler::beginEdit, \ref IComponentHandler::performEdit,
|
||||
* \ref IComponentHandler::endEdit calls until a \ref finishGroupEdit (). */
|
||||
virtual tresult PLUGIN_API startGroupEdit () = 0;
|
||||
|
||||
/** Finishes the group editing started by a \ref startGroupEdit (call after a \ref
|
||||
* IComponentHandler::endEdit). */
|
||||
virtual tresult PLUGIN_API finishGroupEdit () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IComponentHandler2, 0xF040B4B3, 0xA36045EC, 0xABCDC045, 0xB4D5A2CC)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended host callback interface for an edit controller: Vst::IComponentHandlerBusActivation
|
||||
\ingroup vstIHost vst368
|
||||
- [host imp]
|
||||
- [extends IComponentHandler]
|
||||
- [released: 3.6.8]
|
||||
- [optional]
|
||||
|
||||
Allows the plug-in to request the host to activate or deactivate a specific bus.
|
||||
If the host accepts this request, it will call later on \ref IComponent::activateBus.
|
||||
This is particularly useful for instruments with more than 1 outputs, where the user could request
|
||||
from the plug-in UI a given output bus activation.
|
||||
|
||||
\code{.cpp}
|
||||
// somewhere in your code when you need to inform the host to enable a specific Bus.
|
||||
FUnknownPtr<IComponentHandlerBusActivation> busActivation (componentHandler);
|
||||
if (busActivation)
|
||||
{
|
||||
// here we want to activate our audio input sidechain (the 2cd input bus: index 1)
|
||||
busActivation->requestBusActivation (kAudio, kInput, 1, true);
|
||||
}
|
||||
\endcode
|
||||
\see \ref IComponentHandler
|
||||
*/
|
||||
class IComponentHandlerBusActivation : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** request the host to activate or deactivate a specific bus. */
|
||||
virtual tresult PLUGIN_API requestBusActivation (MediaType type /*in*/, BusDirection dir /*in*/,
|
||||
int32 index /*in*/, TBool state /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IComponentHandlerBusActivation, 0x067D02C1, 0x5B4E274D, 0xA92D90FD, 0x6EAF7240)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended host callback interface for an edit controller: Vst::IProgress
|
||||
\ingroup vstIHost vst370
|
||||
- [host imp]
|
||||
- [extends IComponentHandler]
|
||||
- [released: 3.7.0]
|
||||
- [optional]
|
||||
|
||||
Allows the plug-in to request the host to create a progress for some specific tasks which take
|
||||
some time. The host can visualize the progress as read-only UI elements. For example,
|
||||
after loading a project where a plug-in needs to load extra
|
||||
data (e.g. samples) in a background thread, this enables the host to get and visualize the current
|
||||
status of the loading progress and to inform the user when the loading is finished. Note: During the
|
||||
progress, the host can unload the plug-in at any time. Make sure that the plug-in supports this use
|
||||
case.
|
||||
|
||||
\section IProgressExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//--------------------------------------
|
||||
// we are in the editcontroller:
|
||||
// as member: IProgress::ID mProgressID;
|
||||
|
||||
FUnknownPtr<IProgress> progress (componentHandler);
|
||||
if (progress)
|
||||
progress->start (IProgress::ProgressType::UIBackgroundTask, STR ("Load Samples..."),
|
||||
mProgressID);
|
||||
|
||||
// ...
|
||||
myProgressValue += incProgressStep;
|
||||
FUnknownPtr<IProgress> progress (componentHandler);
|
||||
if (progress)
|
||||
progress->update (mProgressID, myProgressValue);
|
||||
|
||||
// ...
|
||||
FUnknownPtr<IProgress> progress (componentHandler);
|
||||
if (progress)
|
||||
progress->finish (mProgressID);
|
||||
\endcode
|
||||
|
||||
\see \ref IComponentHandler
|
||||
*/
|
||||
class IProgress : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
enum ProgressType : uint32
|
||||
{
|
||||
/** plug-in state is restored async (in a background Thread) */
|
||||
AsyncStateRestoration = 0,
|
||||
|
||||
/** a plug-in task triggered by a UI action */
|
||||
UIBackgroundTask
|
||||
};
|
||||
|
||||
using ID = uint64;
|
||||
|
||||
/** Start a new progress of a given type and optional Description. outID is as ID created by the
|
||||
* host to identify this newly created progress (for update and finish method) */
|
||||
virtual tresult PLUGIN_API start (ProgressType type /*in*/,
|
||||
const tchar* optionalDescription /*in*/,
|
||||
ID& outID /*out*/) = 0;
|
||||
|
||||
/** Update the progress value (normValue between [0, 1]) associated to the given id */
|
||||
virtual tresult PLUGIN_API update (ID id /*in*/, ParamValue normValue /*in*/) = 0;
|
||||
|
||||
/** Finish the progress associated to the given id */
|
||||
virtual tresult PLUGIN_API finish (ID id /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IProgress, 0x00C9DC5B, 0x9D904254, 0x91A388C8, 0xB4E91B69)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Edit controller component interface: Vst::IEditController
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
The controller part of an effect or instrument with parameter handling (export, definition,
|
||||
conversion, ...). \see \ref IComponent::getControllerClassId, \ref IMidiMapping
|
||||
*/
|
||||
class IEditController : public IPluginBase
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Receives the component state. */
|
||||
virtual tresult PLUGIN_API setComponentState (IBStream* state /*in*/) = 0;
|
||||
|
||||
/** Sets the controller state. */
|
||||
virtual tresult PLUGIN_API setState (IBStream* state /*in*/) = 0;
|
||||
|
||||
/** Gets the controller state. */
|
||||
virtual tresult PLUGIN_API getState (IBStream* state /*inout*/) = 0;
|
||||
|
||||
// parameters -------------------------
|
||||
/** Returns the number of parameters exported. */
|
||||
virtual int32 PLUGIN_API getParameterCount () = 0;
|
||||
|
||||
/** Gets for a given index the parameter information. */
|
||||
virtual tresult PLUGIN_API getParameterInfo (int32 paramIndex /*in*/,
|
||||
ParameterInfo& info /*out*/) = 0;
|
||||
|
||||
/** Gets for a given paramID and normalized value its associated string representation. */
|
||||
virtual tresult PLUGIN_API getParamStringByValue (ParamID id /*in*/,
|
||||
ParamValue valueNormalized /*in*/,
|
||||
String128 string /*out*/) = 0;
|
||||
|
||||
/** Gets for a given paramID and string its normalized value. */
|
||||
virtual tresult PLUGIN_API getParamValueByString (ParamID id /*in*/, TChar* string /*in*/,
|
||||
ParamValue& valueNormalized /*out*/) = 0;
|
||||
|
||||
/** Returns for a given paramID and a normalized value its plain representation
|
||||
* (for example -6 for -6dB - see \ref vst3AutomationIntro). */
|
||||
virtual ParamValue PLUGIN_API normalizedParamToPlain (ParamID id /*in*/,
|
||||
ParamValue valueNormalized /*in*/) = 0;
|
||||
|
||||
/** Returns for a given paramID and a plain value its normalized value. (see \ref
|
||||
* vst3AutomationIntro). */
|
||||
virtual ParamValue PLUGIN_API plainParamToNormalized (ParamID id /*in*/,
|
||||
ParamValue plainValue /*in*/) = 0;
|
||||
|
||||
/** Returns the normalized value of the parameter associated to the paramID. */
|
||||
virtual ParamValue PLUGIN_API getParamNormalized (ParamID id /*in*/) = 0;
|
||||
|
||||
/** Sets the normalized value to the parameter associated to the paramID. The controller must
|
||||
* never pass this value-change back to the host via the IComponentHandler.
|
||||
* It should update the according GUI element(s) only! */
|
||||
virtual tresult PLUGIN_API setParamNormalized (ParamID id /*in*/, ParamValue value /*in*/) = 0;
|
||||
|
||||
// handler ----------------------------
|
||||
/** Gets from host a handler which allows the Plugin-in to communicate with the host.
|
||||
* Note: This is mandatory if the host is using the IEditController! */
|
||||
virtual tresult PLUGIN_API setComponentHandler (IComponentHandler* handler /*in*/) = 0;
|
||||
|
||||
// view -------------------------------
|
||||
/** Creates the editor view of the plug-in, currently only "editor" is supported, see \ref
|
||||
* ViewType. The life time of the editor view will never exceed the life time of this controller
|
||||
* instance. */
|
||||
virtual IPlugView* PLUGIN_API createView (FIDString name /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IEditController, 0xDCD7BBE3, 0x7742448D, 0xA874AACC, 0x979C759E)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup vst3typedef VST 3 Data Types */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
/** Knob Mode Type */
|
||||
using KnobMode = int32;
|
||||
/*@}*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Knob Mode */
|
||||
enum KnobModes : KnobMode
|
||||
{
|
||||
kCircularMode = 0, ///< Circular with jump to clicked position
|
||||
kRelativCircularMode, ///< Circular without jump to clicked position
|
||||
kLinearMode ///< Linear: depending on vertical movement
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Edit controller component interface extension: Vst::IEditController2
|
||||
\ingroup vstIPlug vst310
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.1.0]
|
||||
- [optional]
|
||||
|
||||
Extension to allow the host to inform the plug-in about the host Knob Mode,
|
||||
and to open the plug-in about box or help documentation.
|
||||
|
||||
\see \ref IEditController, \ref EditController
|
||||
*/
|
||||
class IEditController2 : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Host could set the Knob Mode for the plug-in. Return kResultFalse means not supported mode.
|
||||
* \see KnobModes. */
|
||||
virtual tresult PLUGIN_API setKnobMode (KnobMode mode /*in*/) = 0;
|
||||
|
||||
/** Host could ask to open the plug-in help (could be: opening a PDF document or link to a web
|
||||
* page). The host could call it with onlyCheck set to true for testing support of open Help.
|
||||
* Return kResultFalse means not supported function. */
|
||||
virtual tresult PLUGIN_API openHelp (TBool onlyCheck /*in*/) = 0;
|
||||
|
||||
/** Host could ask to open the plug-in about box.
|
||||
* The host could call it with onlyCheck set to true for testing support of open AboutBox.
|
||||
* Return kResultFalse means not supported function. */
|
||||
virtual tresult PLUGIN_API openAboutBox (TBool onlyCheck /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IEditController2, 0x7F4EFE59, 0xF3204967, 0xAC27A3AE, 0xAFB63038)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** MIDI Mapping interface: Vst::IMidiMapping
|
||||
\ingroup vstIPlug vst301
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.0.1]
|
||||
- [optional]
|
||||
|
||||
MIDI controllers are not transmitted directly to a VST component. MIDI as hardware protocol has
|
||||
restrictions that can be avoided in software. Controller data in particular come along with unclear
|
||||
and often ignored semantics. On top of this they can interfere with regular parameter automation and
|
||||
the host is unaware of what happens in the plug-in when passing MIDI controllers directly.
|
||||
|
||||
So any functionality that is to be controlled by MIDI controllers must be exported as regular
|
||||
parameter. The host will transform incoming MIDI controller data using this interface and transmit
|
||||
them as regular parameter change. This allows the host to automate them in the same way as other
|
||||
parameters. CtrlNumber can be a typical MIDI controller value extended to some others values like
|
||||
pitchbend or aftertouch (see \ref ControllerNumbers). If the mapping has changed, the plug-in must
|
||||
call IComponentHandler::restartComponent (kMidiCCAssignmentChanged) to inform the host about this
|
||||
change.
|
||||
|
||||
\section IMidiMappingExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//--------------------------------------
|
||||
// in myeditcontroller.h
|
||||
class MyEditController: public EditControllerEx1, public IMidiMapping
|
||||
{
|
||||
//...
|
||||
//---IMidiMapping---------------------------
|
||||
tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel,
|
||||
CtrlNumber midiControllerNumber,
|
||||
ParamID& id) override;
|
||||
//---Interface---------
|
||||
OBJ_METHODS (MyEditController, EditControllerEx1)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (IMidiMapping)
|
||||
END_DEFINE_INTERFACES (MyEditController)
|
||||
REFCOUNT_METHODS (MyEditController)
|
||||
};
|
||||
|
||||
//--------------------------------------
|
||||
// in myeditcontroller.cpp
|
||||
tresult PLUGIN_API MyEditController::getMidiControllerAssignment (int32 busIndex,
|
||||
int16 midiChannel,
|
||||
CtrlNumber midiControllerNumber,
|
||||
ParamID& tag)
|
||||
{
|
||||
// for my first Event bus and for MIDI channel 0 and for MIDI CC Volume only
|
||||
if (busIndex == 0 && midiChannel == 0 && midiControllerNumber == kCtrlVolume)
|
||||
{
|
||||
tag = kGainId;
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
class IMidiMapping : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Gets an (preferred) associated ParamID for a given Input Event Bus index, channel and MIDI
|
||||
* Controller.
|
||||
* @param[in] busIndex - index of Input Event Bus
|
||||
* @param[in] channel - channel of the bus
|
||||
* @param[in] midiControllerNumber - see \ref ControllerNumbers for expected values (could be
|
||||
* bigger than 127)
|
||||
* @param[out] id - return the associated ParamID to the given midiControllerNumber
|
||||
*/
|
||||
virtual tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex /*in*/,
|
||||
int16 channel /*in*/,
|
||||
CtrlNumber midiControllerNumber /*in*/,
|
||||
ParamID& id /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IMidiMapping, 0xDF0FF9F7, 0x49B74669, 0xB63AB732, 0x7ADBF5E5)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Parameter Editing from host: Vst::IEditControllerHostEditing
|
||||
\ingroup vstIPlug vst350
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
If this interface is implemented by the edit controller, and when performing edits from outside
|
||||
the plug-in (host / remote) of a not automatable and not read-only, and not hidden flagged parameter
|
||||
(kind of helper parameter), the host will start with a beginEditFromHost before calling
|
||||
setParamNormalized and end with an endEditFromHost. Here the sequence that the host will call:
|
||||
|
||||
\section IEditControllerExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
plugEditController->beginEditFromHost (id);
|
||||
plugEditController->setParamNormalized (id, value);
|
||||
plugEditController->setParamNormalized (id, value + 0.1);
|
||||
// ...
|
||||
plugEditController->endEditFromHost (id);
|
||||
\endcode
|
||||
|
||||
\see \ref IEditController
|
||||
*/
|
||||
class IEditControllerHostEditing : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Called before a setParamNormalized sequence, a endEditFromHost will be call at the end of
|
||||
* the editing action. */
|
||||
virtual tresult PLUGIN_API beginEditFromHost (ParamID paramID /*in*/) = 0;
|
||||
|
||||
/** Called after a beginEditFromHost and a sequence of setParamNormalized. */
|
||||
virtual tresult PLUGIN_API endEditFromHost (ParamID paramID /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IEditControllerHostEditing, 0xC1271208, 0x70594098, 0xB9DD34B3, 0x6BB0195E)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IComponentHandler for an edit controller
|
||||
\ingroup vstIHost vst379
|
||||
- [host imp]
|
||||
- [extends IComponentHandler]
|
||||
- [released: 3.7.9]
|
||||
- [optional]
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class IComponentHandlerSystemTime : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** get the current systemTime (the same as the one used in ProcessContext::systemTime). */
|
||||
virtual tresult PLUGIN_API getSystemTime (int64& systemTime /*out*/) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IComponentHandlerSystemTime, 0xF9E53056, 0xD1554CD5, 0xB7695E1B, 0x7B0F7745)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstevents.h
|
||||
// Created by : Steinberg, 11/2005
|
||||
// Description : VST Events Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/ivstprocesscontext.h"
|
||||
#include "pluginterfaces/vst/ivstnoteexpression.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Reserved note identifier (noteId) range for a plug-in. Guaranteed not used by the host. */
|
||||
enum NoteIDUserRange
|
||||
{
|
||||
kNoteIDUserRangeLowerBound = -10000,
|
||||
kNoteIDUserRangeUpperBound = -1000,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Note-on event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
Pitch uses the twelve-tone equal temperament tuning (12-TET).
|
||||
*/
|
||||
struct NoteOnEvent
|
||||
{
|
||||
int16 channel; ///< channel index in event bus
|
||||
int16 pitch; ///< range [0, 127] = [C-2, G8] with A3=440Hz (12-TET: twelve-tone equal temperament)
|
||||
float tuning; ///< 1.f = +1 cent, -1.f = -1 cent
|
||||
float velocity; ///< range [0.0, 1.0]
|
||||
int32 length; ///< in sample frames (optional, Note Off has to follow in any case!)
|
||||
int32 noteId; ///< note identifier (if not available then -1)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Note-off event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
*/
|
||||
struct NoteOffEvent
|
||||
{
|
||||
int16 channel; ///< channel index in event bus
|
||||
int16 pitch; ///< range [0, 127] = [C-2, G8] with A3=440Hz (12-TET)
|
||||
float velocity; ///< range [0.0, 1.0]
|
||||
int32 noteId; ///< associated noteOn identifier (if not available then -1)
|
||||
float tuning; ///< 1.f = +1 cent, -1.f = -1 cent
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Data event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
*/
|
||||
struct DataEvent
|
||||
{
|
||||
uint32 size; ///< size in bytes of the data block bytes
|
||||
uint32 type; ///< type of this data block (see \ref DataTypes)
|
||||
const uint8* bytes; ///< pointer to the data block
|
||||
|
||||
/** Value for DataEvent::type */
|
||||
enum DataTypes
|
||||
{
|
||||
kMidiSysEx = 0 ///< for MIDI system exclusive message
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** PolyPressure event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
*/
|
||||
struct PolyPressureEvent
|
||||
{
|
||||
int16 channel; ///< channel index in event bus
|
||||
int16 pitch; ///< range [0, 127] = [C-2, G8] with A3=440Hz
|
||||
float pressure; ///< range [0.0, 1.0]
|
||||
int32 noteId; ///< event should be applied to the noteId (if not -1)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Chord event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
*/
|
||||
struct ChordEvent
|
||||
{
|
||||
int16 root; ///< range [0, 127] = [C-2, G8] with A3=440Hz
|
||||
int16 bassNote; ///< range [0, 127] = [C-2, G8] with A3=440Hz
|
||||
int16 mask; ///< root is bit 0
|
||||
uint16 textLen; ///< the number of characters (TChar) between the beginning of text and the terminating
|
||||
///< null character (without including the terminating null character itself)
|
||||
const TChar* text; ///< UTF-16, null terminated Hosts Chord Name
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Scale event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
*/
|
||||
struct ScaleEvent
|
||||
{
|
||||
int16 root; ///< range [0, 127] = root Note/Transpose Factor
|
||||
int16 mask; ///< Bit 0 = C, Bit 1 = C#, ... (0x5ab5 = Major Scale)
|
||||
uint16 textLen; ///< the number of characters (TChar) between the beginning of text and the terminating
|
||||
///< null character (without including the terminating null character itself)
|
||||
const TChar* text; ///< UTF-16, null terminated, Hosts Scale Name
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Legacy MIDI CC Out event specific data. Used in \ref Event (union)
|
||||
\ingroup vstEventGrp
|
||||
- [released: 3.6.12]
|
||||
|
||||
This kind of event is reserved for generating MIDI CC as output event for kEvent Bus during the process call.
|
||||
*/
|
||||
struct LegacyMIDICCOutEvent
|
||||
{
|
||||
uint8 controlNumber;///< see enum ControllerNumbers [0, 255]
|
||||
int8 channel; ///< channel index in event bus [0, 15]
|
||||
int8 value; ///< value of Controller [0, 127]
|
||||
int8 value2; ///< [0, 127] used for pitch bend (kPitchBend) and polyPressure (kCtrlPolyPressure)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Event
|
||||
\ingroup vstEventGrp
|
||||
Structure representing a single Event of different types associated to a specific event (\ref kEvent) bus.
|
||||
*/
|
||||
struct Event
|
||||
{
|
||||
int32 busIndex; ///< event bus index
|
||||
int32 sampleOffset; ///< sample frames related to the current block start sample position
|
||||
TQuarterNotes ppqPosition; ///< position in project
|
||||
uint16 flags; ///< combination of \ref EventFlags
|
||||
|
||||
/** Event Flags - used for Event::flags */
|
||||
enum EventFlags
|
||||
{
|
||||
kIsLive = 1 << 0, ///< indicates that the event is played live (directly from keyboard)
|
||||
|
||||
kUserReserved1 = 1 << 14, ///< reserved for user (for internal use)
|
||||
kUserReserved2 = 1 << 15 ///< reserved for user (for internal use)
|
||||
};
|
||||
|
||||
/** Event Types - used for Event::type */
|
||||
enum EventTypes
|
||||
{
|
||||
kNoteOnEvent = 0, ///< is \ref NoteOnEvent
|
||||
kNoteOffEvent = 1, ///< is \ref NoteOffEvent
|
||||
kDataEvent = 2, ///< is \ref DataEvent
|
||||
kPolyPressureEvent = 3, ///< is \ref PolyPressureEvent
|
||||
kNoteExpressionValueEvent = 4, ///< is \ref NoteExpressionValueEvent
|
||||
kNoteExpressionTextEvent = 5, ///< is \ref NoteExpressionTextEvent
|
||||
kChordEvent = 6, ///< is \ref ChordEvent
|
||||
kScaleEvent = 7, ///< is \ref ScaleEvent
|
||||
kLegacyMIDICCOutEvent = 65535 ///< is \ref LegacyMIDICCOutEvent
|
||||
};
|
||||
|
||||
uint16 type; ///< a value from \ref EventTypes
|
||||
union
|
||||
{
|
||||
NoteOnEvent noteOn; ///< type == kNoteOnEvent
|
||||
NoteOffEvent noteOff; ///< type == kNoteOffEvent
|
||||
DataEvent data; ///< type == kDataEvent
|
||||
PolyPressureEvent polyPressure; ///< type == kPolyPressureEvent
|
||||
NoteExpressionValueEvent noteExpressionValue; ///< type == kNoteExpressionValueEvent
|
||||
NoteExpressionTextEvent noteExpressionText; ///< type == kNoteExpressionTextEvent
|
||||
ChordEvent chord; ///< type == kChordEvent
|
||||
ScaleEvent scale; ///< type == kScaleEvent
|
||||
LegacyMIDICCOutEvent midiCCOut; ///< type == kLegacyMIDICCOutEvent
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** List of events to process: Vst::IEventList
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
\see ProcessData, Event
|
||||
*/
|
||||
class IEventList : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns the count of events. */
|
||||
virtual int32 PLUGIN_API getEventCount () = 0;
|
||||
|
||||
/** Gets parameter by index. */
|
||||
virtual tresult PLUGIN_API getEvent (int32 index, Event& e /*out*/) = 0;
|
||||
|
||||
/** Adds a new event. */
|
||||
virtual tresult PLUGIN_API addEvent (Event& e /*in*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IEventList, 0x3A2C4214, 0x346349FE, 0xB2C4F397, 0xB9695A44)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivsthostapplication.h
|
||||
// Created by : Steinberg, 04/2006
|
||||
// Description : VST Host Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/ivstmessage.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Basic host callback interface: Vst::IHostApplication
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [passed as 'context' in to IPluginBase::initialize () ]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
Basic VST host application interface.
|
||||
*/
|
||||
class IHostApplication : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Gets host application name. */
|
||||
virtual tresult PLUGIN_API getName (String128 name) = 0;
|
||||
|
||||
/** Creates host object (e.g. Vst::IMessage). */
|
||||
virtual tresult PLUGIN_API createInstance (TUID cid, TUID _iid, void** obj) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IHostApplication, 0x58E595CC, 0xDB2D4969, 0x8B6AAF8C, 0x36A664E5)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Helper to allocate a message */
|
||||
inline IMessage* allocateMessage (IHostApplication* host)
|
||||
{
|
||||
TUID iid;
|
||||
IMessage::iid.toTUID (iid);
|
||||
IMessage* m = nullptr;
|
||||
if (host->createInstance (iid, iid, (void**)&m) == kResultOk)
|
||||
return m;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** VST 3 to VST 2 Wrapper interface: Vst::IVst3ToVst2Wrapper
|
||||
\ingroup vstIHost vst310
|
||||
- [host imp]
|
||||
- [passed as 'context' to IPluginBase::initialize () ]
|
||||
- [released: 3.1.0]
|
||||
- [mandatory]
|
||||
|
||||
Informs the plug-in that a VST 3 to VST 2 wrapper is used between the plug-in and the real host.
|
||||
Implemented by the VST 2 Wrapper.
|
||||
*/
|
||||
class IVst3ToVst2Wrapper : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IVst3ToVst2Wrapper, 0x29633AEC, 0x1D1C47E2, 0xBB85B97B, 0xD36EAC61)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** VST 3 to AU Wrapper interface: Vst::IVst3ToAUWrapper
|
||||
\ingroup vstIHost vst310
|
||||
- [host imp]
|
||||
- [passed as 'context' to IPluginBase::initialize () ]
|
||||
- [released: 3.1.0]
|
||||
- [mandatory]
|
||||
|
||||
Informs the plug-in that a VST 3 to AU wrapper is used between the plug-in and the real host.
|
||||
Implemented by the AU Wrapper.
|
||||
*/
|
||||
class IVst3ToAUWrapper : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IVst3ToAUWrapper, 0xA3B8C6C5, 0xC0954688, 0xB0916F0B, 0xB697AA44)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** VST 3 to AAX Wrapper interface: Vst::IVst3ToAAXWrapper
|
||||
\ingroup vstIHost vst368
|
||||
- [host imp]
|
||||
- [passed as 'context' to IPluginBase::initialize () ]
|
||||
- [released: 3.6.8]
|
||||
- [mandatory]
|
||||
|
||||
Informs the plug-in that a VST 3 to AAX wrapper is used between the plug-in and the real host.
|
||||
Implemented by the AAX Wrapper.
|
||||
*/
|
||||
class IVst3ToAAXWrapper : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
DECLARE_CLASS_IID (IVst3ToAAXWrapper, 0x6D319DC6, 0x60C56242, 0xB32C951B, 0x93BEF4C6)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Wrapper MPE Support interface: Vst::IVst3WrapperMPESupport
|
||||
\ingroup vstIHost vst3612
|
||||
- [host imp]
|
||||
- [passed as 'context' to IPluginBase::initialize () ]
|
||||
- [released: 3.6.12]
|
||||
- [optional]
|
||||
|
||||
Implemented on wrappers that support MPE to Note Expression translation.
|
||||
|
||||
By default, MPE input processing is enabled, the masterChannel will be zero, the memberBeginChannel
|
||||
will be one and the memberEndChannel will be 14.
|
||||
|
||||
As MPE is a subset of the VST3 Note Expression feature, mapping from the three MPE expressions is
|
||||
handled via the INoteExpressionPhysicalUIMapping interface.
|
||||
*/
|
||||
class IVst3WrapperMPESupport : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** enable or disable MPE processing
|
||||
* @param state true to enable, false to disable MPE processing
|
||||
* @return kResultTrue on success */
|
||||
virtual tresult PLUGIN_API enableMPEInputProcessing (TBool state) = 0;
|
||||
/** setup the MPE processing
|
||||
* @param masterChannel MPE master channel (zero based)
|
||||
* @param memberBeginChannel MPE member begin channel (zero based)
|
||||
* @param memberEndChannel MPE member end channel (zero based)
|
||||
* @return kResultTrue on success */
|
||||
virtual tresult PLUGIN_API setMPEInputDeviceSettings (int32 masterChannel,
|
||||
int32 memberBeginChannel,
|
||||
int32 memberEndChannel) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IVst3WrapperMPESupport, 0x44149067, 0x42CF4BF9, 0x8800B750, 0xF7359FE3)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstinterappaudio.h
|
||||
// Created by : Steinberg, 08/2013
|
||||
// Description : VST InterAppAudio Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
struct ViewRect;
|
||||
namespace Vst {
|
||||
struct Event;
|
||||
class IInterAppAudioPresetManager;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Inter-App Audio host Interface.
|
||||
\ingroup vstIHost vst360
|
||||
- [host imp]
|
||||
- [passed as 'context' to IPluginBase::initialize () ]
|
||||
- [released: 3.6.0]
|
||||
- [optional]
|
||||
|
||||
Implemented by the InterAppAudio Wrapper.
|
||||
*/
|
||||
class IInterAppAudioHost : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** get the size of the screen
|
||||
* @param size size of the screen
|
||||
* @param scale scale of the screen
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API getScreenSize (ViewRect* size, float* scale) = 0;
|
||||
|
||||
/** get status of connection
|
||||
* @return kResultTrue if an Inter-App Audio connection is established
|
||||
*/
|
||||
virtual tresult PLUGIN_API connectedToHost () = 0;
|
||||
|
||||
/** switch to the host.
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API switchToHost () = 0;
|
||||
|
||||
/** send a remote control event to the host
|
||||
* @param event event type, see AudioUnitRemoteControlEvent in the iOS SDK documentation for possible types
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API sendRemoteControlEvent (uint32 event) = 0;
|
||||
|
||||
/** ask for the host icon.
|
||||
* @param icon pointer to a CGImageRef
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API getHostIcon (void** icon) = 0;
|
||||
|
||||
/** schedule an event from the user interface thread
|
||||
* @param event the event to schedule
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API scheduleEventFromUI (Event& event) = 0;
|
||||
|
||||
/** get the preset manager
|
||||
* @param cid class ID to use by the preset manager
|
||||
* @return the preset manager. Needs to be released by called.
|
||||
*/
|
||||
virtual IInterAppAudioPresetManager* PLUGIN_API createPresetManager (const TUID& cid) = 0;
|
||||
|
||||
/** show the settings view
|
||||
* currently includes MIDI settings and Tempo setting
|
||||
* @return kResultTrue on success
|
||||
*/
|
||||
virtual tresult PLUGIN_API showSettingsView () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IInterAppAudioHost, 0x0CE5743D, 0x68DF415E, 0xAE285BD4, 0xE2CDC8FD)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController for Inter-App Audio connection state change notifications
|
||||
\ingroup vstIPlug vst360
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.6.0]
|
||||
*/
|
||||
class IInterAppAudioConnectionNotification : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** called when the Inter-App Audio connection state changes
|
||||
* @param newState true if an Inter-App Audio connection is established, otherwise false
|
||||
*/
|
||||
virtual void PLUGIN_API onInterAppAudioConnectionStateChange (TBool newState) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IInterAppAudioConnectionNotification, 0x6020C72D, 0x5FC24AA1, 0xB0950DB5, 0xD7D6D5CF)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController for Inter-App Audio Preset Management
|
||||
\ingroup vstIPlug vst360
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.6.0]
|
||||
*/
|
||||
class IInterAppAudioPresetManager : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Open the Preset Browser in order to load a preset */
|
||||
virtual tresult PLUGIN_API runLoadPresetBrowser () = 0;
|
||||
/** Open the Preset Browser in order to save a preset */
|
||||
virtual tresult PLUGIN_API runSavePresetBrowser () = 0;
|
||||
/** Load the next available preset */
|
||||
virtual tresult PLUGIN_API loadNextPreset () = 0;
|
||||
/** Load the previous available preset */
|
||||
virtual tresult PLUGIN_API loadPreviousPreset () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IInterAppAudioPresetManager, 0xADE6FCC4, 0x46C94E1D, 0xB3B49A80, 0xC93FEFDD)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstmessage.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : VST Message Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/ivstattributes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Private plug-in message: Vst::IMessage
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [create via IHostApplication::createInstance]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
Messages are sent from a VST controller component to a VST editor component and vice versa.
|
||||
\see IAttributeList, IConnectionPoint, \ref vst3Communication
|
||||
*/
|
||||
class IMessage : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns the message ID (for example "TextMessage"). */
|
||||
virtual FIDString PLUGIN_API getMessageID () = 0;
|
||||
|
||||
/** Sets a message ID (for example "TextMessage"). */
|
||||
virtual void PLUGIN_API setMessageID (FIDString id /*in*/) = 0;
|
||||
|
||||
/** Returns the attribute list associated to the message. */
|
||||
virtual IAttributeList* PLUGIN_API getAttributes () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IMessage, 0x936F033B, 0xC6C047DB, 0xBB0882F8, 0x13C1E613)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Connect a component with another one: Vst::IConnectionPoint
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
This interface is used for the communication of separate components.
|
||||
Note that some hosts will place a proxy object between the components so that they are not directly connected.
|
||||
|
||||
\see \ref vst3Communication
|
||||
*/
|
||||
class IConnectionPoint : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Connects this instance with another connection point. */
|
||||
virtual tresult PLUGIN_API connect (IConnectionPoint* other) = 0;
|
||||
|
||||
/** Disconnects a given connection point from this. */
|
||||
virtual tresult PLUGIN_API disconnect (IConnectionPoint* other) = 0;
|
||||
|
||||
/** Called when a message has been sent from the connection point to this. */
|
||||
virtual tresult PLUGIN_API notify (IMessage* message) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IConnectionPoint, 0x70A4156F, 0x6E6E4026, 0x989148BF, 0xAA60D8D1)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstmidicontrollers.h
|
||||
// Created by : Steinberg, 02/2006
|
||||
// Description : VST MIDI Controller Enumeration
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Controller Numbers (MIDI) */
|
||||
enum ControllerNumbers
|
||||
{
|
||||
kCtrlBankSelectMSB = 0, ///< Bank Select MSB
|
||||
kCtrlModWheel = 1, ///< Modulation Wheel
|
||||
kCtrlBreath = 2, ///< Breath controller
|
||||
|
||||
kCtrlFoot = 4, ///< Foot Controller
|
||||
kCtrlPortaTime = 5, ///< Portamento Time
|
||||
kCtrlDataEntryMSB = 6, ///< Data Entry MSB
|
||||
kCtrlVolume = 7, ///< Channel Volume (formerly Main Volume)
|
||||
kCtrlBalance = 8, ///< Balance
|
||||
|
||||
kCtrlPan = 10, ///< Pan
|
||||
kCtrlExpression = 11, ///< Expression
|
||||
kCtrlEffect1 = 12, ///< Effect Control 1
|
||||
kCtrlEffect2 = 13, ///< Effect Control 2
|
||||
|
||||
//---General Purpose Controllers #1 to #4---
|
||||
kCtrlGPC1 = 16, ///< General Purpose Controller #1
|
||||
kCtrlGPC2 = 17, ///< General Purpose Controller #2
|
||||
kCtrlGPC3 = 18, ///< General Purpose Controller #3
|
||||
kCtrlGPC4 = 19, ///< General Purpose Controller #4
|
||||
|
||||
kCtrlBankSelectLSB = 32, ///< Bank Select LSB
|
||||
|
||||
kCtrlDataEntryLSB = 38, ///< Data Entry LSB
|
||||
|
||||
kCtrlSustainOnOff = 64, ///< Damper Pedal On/Off (Sustain)
|
||||
kCtrlPortaOnOff = 65, ///< Portamento On/Off
|
||||
kCtrlSustenutoOnOff = 66, ///< Sustenuto On/Off
|
||||
kCtrlSoftPedalOnOff = 67, ///< Soft Pedal On/Off
|
||||
kCtrlLegatoFootSwOnOff= 68, ///< Legato Footswitch On/Off
|
||||
kCtrlHold2OnOff = 69, ///< Hold 2 On/Off
|
||||
|
||||
//---Sound Controllers #1 to #10---
|
||||
kCtrlSoundVariation = 70, ///< Sound Variation
|
||||
kCtrlFilterCutoff = 71, ///< Filter Cutoff (Timbre/Harmonic Intensity)
|
||||
kCtrlReleaseTime = 72, ///< Release Time
|
||||
kCtrlAttackTime = 73, ///< Attack Time
|
||||
kCtrlFilterResonance= 74, ///< Filter Resonance (Brightness)
|
||||
kCtrlDecayTime = 75, ///< Decay Time
|
||||
kCtrlVibratoRate = 76, ///< Vibrato Rate
|
||||
kCtrlVibratoDepth = 77, ///< Vibrato Depth
|
||||
kCtrlVibratoDelay = 78, ///< Vibrato Delay
|
||||
kCtrlSoundCtrler10 = 79, ///< undefined
|
||||
|
||||
//---General Purpose Controllers #5 to #8---
|
||||
kCtrlGPC5 = 80, ///< General Purpose Controller #5
|
||||
kCtrlGPC6 = 81, ///< General Purpose Controller #6
|
||||
kCtrlGPC7 = 82, ///< General Purpose Controller #7
|
||||
kCtrlGPC8 = 83, ///< General Purpose Controller #8
|
||||
|
||||
kCtrlPortaControl = 84, ///< Portamento Control
|
||||
|
||||
//---Effect Controllers---
|
||||
kCtrlEff1Depth = 91, ///< Effect 1 Depth (Reverb Send Level)
|
||||
kCtrlEff2Depth = 92, ///< Effect 2 Depth (Tremolo Level)
|
||||
kCtrlEff3Depth = 93, ///< Effect 3 Depth (Chorus Send Level)
|
||||
kCtrlEff4Depth = 94, ///< Effect 4 Depth (Delay/Variation/Detune Level)
|
||||
kCtrlEff5Depth = 95, ///< Effect 5 Depth (Phaser Level)
|
||||
|
||||
kCtrlDataIncrement = 96, ///< Data Increment (+1)
|
||||
kCtrlDataDecrement = 97, ///< Data Decrement (-1)
|
||||
kCtrlNRPNSelectLSB = 98, ///< NRPN Select LSB
|
||||
kCtrlNRPNSelectMSB = 99, ///< NRPN Select MSB
|
||||
kCtrlRPNSelectLSB = 100, ///< RPN Select LSB
|
||||
kCtrlRPNSelectMSB = 101, ///< RPN Select MSB
|
||||
|
||||
//---Other Channel Mode Messages---
|
||||
kCtrlAllSoundsOff = 120, ///< All Sounds Off
|
||||
kCtrlResetAllCtrlers = 121, ///< Reset All Controllers
|
||||
kCtrlLocalCtrlOnOff = 122, ///< Local Control On/Off
|
||||
kCtrlAllNotesOff = 123, ///< All Notes Off
|
||||
kCtrlOmniModeOff = 124, ///< Omni Mode Off + All Notes Off
|
||||
kCtrlOmniModeOn = 125, ///< Omni Mode On + All Notes Off
|
||||
kCtrlPolyModeOnOff = 126, ///< Poly Mode On/Off + All Sounds Off
|
||||
kCtrlPolyModeOn = 127, ///< Poly Mode On
|
||||
|
||||
//---Extra--------------------------
|
||||
kAfterTouch = 128, ///< After Touch (associated to Channel Pressure)
|
||||
kPitchBend = 129, ///< Pitch Bend Change
|
||||
|
||||
kCountCtrlNumber, ///< Count of Controller Number
|
||||
|
||||
//---Extra for kLegacyMIDICCOutEvent-
|
||||
kCtrlProgramChange = 130, ///< Program Change (use LegacyMIDICCOutEvent.value only)
|
||||
kCtrlPolyPressure = 131, ///< Polyphonic Key Pressure (use LegacyMIDICCOutEvent.value for pitch and
|
||||
/// LegacyMIDICCOutEvent.value2 for pressure)
|
||||
kCtrlQuarterFrame = 132 ///< Quarter Frame ((use LegacyMIDICCOutEvent.value only)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstmidilearn.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : VST MIDI Learn
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** MIDI Learn interface: Vst::IMidiLearn
|
||||
\ingroup vstIPlug vst3612
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.6.12]
|
||||
- [optional]
|
||||
|
||||
If this interface is implemented by the edit controller, the host will call this method whenever
|
||||
there is live MIDI-CC input for the plug-in. This way, the plug-in can change its MIDI-CC parameter
|
||||
mapping and inform the host via the IComponentHandler::restartComponent with the
|
||||
kMidiCCAssignmentChanged flag.
|
||||
Use this if you want to implement custom MIDI-Learn functionality in your plug-in.
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------
|
||||
// in MyController class declaration
|
||||
class MyController : public Vst::EditController, public Vst::IMidiLearn
|
||||
{
|
||||
// ...
|
||||
//--- IMidiLearn ---------------------------------
|
||||
tresult PLUGIN_API onLiveMIDIControllerInput (int32 busIndex, int16 channel,
|
||||
CtrlNumber midiCC) SMTG_OVERRIDE;
|
||||
// ...
|
||||
|
||||
OBJ_METHODS (MyController, Vst::EditController)
|
||||
DEFINE_INTERFACES
|
||||
// ...
|
||||
DEF_INTERFACE (Vst::IMidiLearn)
|
||||
END_DEFINE_INTERFACES (Vst::EditController)
|
||||
//...
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// in mycontroller.cpp
|
||||
#include "pluginterfaces/vst/ivstmidilearn.h
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
DEF_CLASS_IID (IMidiLearn)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyController::onLiveMIDIControllerInput (int32 busIndex,
|
||||
int16 channel, CtrlNumber midiCC)
|
||||
{
|
||||
// if we are not in doMIDILearn (triggered by a UI button for example)
|
||||
// or wrong channel then return
|
||||
if (!doMIDILearn || busIndex != 0 || channel != 0 || midiLearnParamID == InvalidParamID)
|
||||
return kResultFalse;
|
||||
|
||||
// adapt our internal MIDICC -> parameterID mapping
|
||||
midiCCMapping[midiCC] = midiLearnParamID;
|
||||
|
||||
// new mapping then inform the host that our MIDI assignment has changed
|
||||
if (auto componentHandler = getComponentHandler ())
|
||||
{
|
||||
componentHandler->restartComponent (kMidiCCAssignmentChanged);
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class IMidiLearn : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Called on live input MIDI-CC change associated to a given bus index and MIDI channel */
|
||||
virtual tresult PLUGIN_API onLiveMIDIControllerInput (int32 busIndex, int16 channel,
|
||||
CtrlNumber midiCC) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IMidiLearn, 0x6B2449CC, 0x419740B5, 0xAB3C79DA, 0xC5FE5C86)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,255 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstnoteexpression.h
|
||||
// Created by : Steinberg, 10/2010
|
||||
// Description : VST Note Expression Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup vst3typedef VST 3 Data Types */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
/** Note Expression Types */
|
||||
typedef uint32 NoteExpressionTypeID;
|
||||
/** Note Expression Value */
|
||||
typedef double NoteExpressionValue;
|
||||
/*@}*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** NoteExpressionTypeIDs describes the type of the note expression.
|
||||
VST predefines some types like volume, pan, tuning by defining their ranges and curves.
|
||||
Used by NoteExpressionEvent::typeId and NoteExpressionTypeID::typeId
|
||||
\see NoteExpressionTypeInfo
|
||||
*/
|
||||
enum NoteExpressionTypeIDs : uint32
|
||||
{
|
||||
kVolumeTypeID = 0, ///< Volume, plain range [0 = -oo , 0.25 = 0dB, 0.5 = +6dB, 1 = +12dB]: plain = 20 * log (4 * norm)
|
||||
kPanTypeID, ///< Panning (L-R), plain range [0 = left, 0.5 = center, 1 = right]
|
||||
kTuningTypeID, ///< Tuning, plain range [0 = -120.0 (ten octaves down), 0.5 none, 1 = +120.0 (ten octaves up)]
|
||||
///< plain = 240 * (norm - 0.5) and norm = plain / 240 + 0.5
|
||||
///< oneOctave is 12.0 / 240.0; oneHalfTune = 1.0 / 240.0;
|
||||
kVibratoTypeID, ///< Vibrato
|
||||
kExpressionTypeID, ///< Expression
|
||||
kBrightnessTypeID, ///< Brightness
|
||||
kTextTypeID, ///< See NoteExpressionTextEvent
|
||||
kPhonemeTypeID, ///< TODO:
|
||||
|
||||
kCustomStart = 100000, ///< start of custom note expression type ids
|
||||
kCustomEnd = 200000, ///< end of custom note expression type ids
|
||||
|
||||
kInvalidTypeID = 0xFFFFFFFF ///< indicates an invalid note expression type
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Description of a Note Expression Type
|
||||
This structure is part of the NoteExpressionTypeInfo structure, it describes for given NoteExpressionTypeID its default value
|
||||
(for example 0.5 for a kTuningTypeID (kIsBipolar: centered)), its minimum and maximum (for predefined NoteExpressionTypeID the full range is predefined too)
|
||||
and a stepCount when the given NoteExpressionTypeID is limited to discrete values (like on/off state).
|
||||
\see NoteExpressionTypeInfo
|
||||
*/
|
||||
struct NoteExpressionValueDescription
|
||||
{
|
||||
NoteExpressionValue defaultValue; ///< default normalized value [0,1]
|
||||
NoteExpressionValue minimum; ///< minimum normalized value [0,1]
|
||||
NoteExpressionValue maximum; ///< maximum normalized value [0,1]
|
||||
int32 stepCount; ///< number of discrete steps (0: continuous, 1: toggle, discrete value otherwise - see \ref vst3ParameterIntro)
|
||||
};
|
||||
|
||||
#if SMTG_OS_WINDOWS && !SMTG_PLATFORM_64
|
||||
#include "pluginterfaces/vst/vstpshpack4.h"
|
||||
#endif
|
||||
//------------------------------------------------------------------------
|
||||
/** Note Expression Value event. Used in \ref Event (union)
|
||||
A note expression event affects one single playing note (referring its noteId).
|
||||
This kind of event is send from host to the plug-in like other events (NoteOnEvent, NoteOffEvent,...) in \ref ProcessData during the process call.
|
||||
Note expression events for a specific noteId can only occur after a NoteOnEvent. The host must take care that the event list (\ref IEventList) is properly sorted.
|
||||
Expression events are always absolute normalized values [0.0, 1.0].
|
||||
The predefined types have a predefined mapping of the normalized values (see \ref NoteExpressionTypeIDs)
|
||||
\sa INoteExpressionController
|
||||
*/
|
||||
struct NoteExpressionValueEvent
|
||||
{
|
||||
NoteExpressionTypeID typeId; ///< see \ref NoteExpressionTypeID
|
||||
int32 noteId; ///< associated note identifier to apply the change
|
||||
|
||||
NoteExpressionValue value; ///< normalized value [0.0, 1.0].
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Note Expression Text event. Used in Event (union)
|
||||
A Expression event affects one single playing note. \sa INoteExpressionController
|
||||
|
||||
\see NoteExpressionTypeInfo
|
||||
*/
|
||||
struct NoteExpressionTextEvent
|
||||
{
|
||||
NoteExpressionTypeID typeId; ///< see \ref NoteExpressionTypeID (kTextTypeID or kPhoneticTypeID)
|
||||
int32 noteId; ///< associated note identifier to apply the change
|
||||
|
||||
uint32 textLen; ///< the number of characters (TChar) between the beginning of text and the terminating
|
||||
///< null character (without including the terminating null character itself)
|
||||
|
||||
const TChar* text; ///< UTF-16, null terminated
|
||||
};
|
||||
|
||||
#if SMTG_OS_WINDOWS && !SMTG_PLATFORM_64
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** NoteExpressionTypeInfo is the structure describing a note expression supported by the plug-in.
|
||||
This structure is used by the method \ref INoteExpressionController::getNoteExpressionInfo.
|
||||
\see INoteExpressionController
|
||||
*/
|
||||
struct NoteExpressionTypeInfo
|
||||
{
|
||||
NoteExpressionTypeID typeId; ///< unique identifier of this note Expression type
|
||||
String128 title; ///< note Expression type title (e.g. "Volume")
|
||||
String128 shortTitle; ///< note Expression type short title (e.g. "Vol")
|
||||
String128 units; ///< note Expression type unit (e.g. "dB")
|
||||
int32 unitId; ///< id of unit this NoteExpression belongs to (see \ref vst3Units), in order to sort the note expression, it is possible to use unitId like for parameters. -1 means no unit used.
|
||||
NoteExpressionValueDescription valueDesc; ///< value description see \ref NoteExpressionValueDescription
|
||||
ParamID associatedParameterId; ///< optional associated parameter ID (for mapping from note expression to global (using the parameter automation for example) and back). Only used when kAssociatedParameterIDValid is set in flags.
|
||||
|
||||
int32 flags; ///< NoteExpressionTypeFlags (see below)
|
||||
enum NoteExpressionTypeFlags
|
||||
{
|
||||
kIsBipolar = 1 << 0, ///< event is bipolar (centered), otherwise unipolar
|
||||
kIsOneShot = 1 << 1, ///< event occurs only one time for its associated note (at begin of the noteOn)
|
||||
kIsAbsolute = 1 << 2, ///< This note expression will apply an absolute change to the sound (not relative (offset))
|
||||
kAssociatedParameterIDValid = 1 << 3,///< indicates that the associatedParameterID is valid and could be used
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController for note expression event support: Vst::INoteExpressionController
|
||||
\ingroup vstIPlug vst350
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
With this plug-in interface, the host can retrieve all necessary note expression information supported by the plug-in.
|
||||
Note expression information (\ref NoteExpressionTypeInfo) are specific for given channel and event bus.
|
||||
|
||||
Note that there is only one NoteExpressionTypeID per given channel of an event bus.
|
||||
|
||||
The method getNoteExpressionStringByValue allows conversion from a normalized value to a string representation
|
||||
and the getNoteExpressionValueByString method from a string to a normalized value.
|
||||
|
||||
When the note expression state changes (for example when switching presets) the plug-in needs
|
||||
to inform the host about it via \ref IComponentHandler::restartComponent (kNoteExpressionChanged).
|
||||
*/
|
||||
class INoteExpressionController : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Returns number of supported note change types for event bus index and channel. */
|
||||
virtual int32 PLUGIN_API getNoteExpressionCount (int32 busIndex, int16 channel) = 0;
|
||||
|
||||
/** Returns note change type info. */
|
||||
virtual tresult PLUGIN_API getNoteExpressionInfo (int32 busIndex, int16 channel, int32 noteExpressionIndex, NoteExpressionTypeInfo& info /*out*/) = 0;
|
||||
|
||||
/** Gets a user readable representation of the normalized note change value. */
|
||||
virtual tresult PLUGIN_API getNoteExpressionStringByValue (int32 busIndex, int16 channel, NoteExpressionTypeID id, NoteExpressionValue valueNormalized /*in*/, String128 string /*out*/) = 0;
|
||||
|
||||
/** Converts the user readable representation to the normalized note change value. */
|
||||
virtual tresult PLUGIN_API getNoteExpressionValueByString (int32 busIndex, int16 channel, NoteExpressionTypeID id, const TChar* string /*in*/, NoteExpressionValue& valueNormalized /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (INoteExpressionController, 0xB7F8F859, 0x41234872, 0x91169581, 0x4F3721A3)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
/** KeyswitchTypeIDs describes the type of a key switch
|
||||
\see KeyswitchInfo
|
||||
*/
|
||||
enum KeyswitchTypeIDs : uint32
|
||||
{
|
||||
kNoteOnKeyswitchTypeID = 0, ///< press before noteOn is played
|
||||
kOnTheFlyKeyswitchTypeID, ///< press while noteOn is played
|
||||
kOnReleaseKeyswitchTypeID, ///< press before entering release
|
||||
kKeyRangeTypeID ///< key should be maintained pressed for playing
|
||||
};
|
||||
|
||||
typedef uint32 KeyswitchTypeID;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** KeyswitchInfo is the structure describing a key switch
|
||||
This structure is used by the method \ref IKeyswitchController::getKeyswitchInfo.
|
||||
\see IKeyswitchController
|
||||
*/
|
||||
struct KeyswitchInfo
|
||||
{
|
||||
KeyswitchTypeID typeId; ///< see KeyswitchTypeID
|
||||
String128 title; ///< name of key switch (e.g. "Accentuation")
|
||||
String128 shortTitle; ///< short title (e.g. "Acc")
|
||||
|
||||
int32 keyswitchMin; ///< associated main key switch min (value between [0, 127])
|
||||
int32 keyswitchMax; ///< associated main key switch max (value between [0, 127])
|
||||
int32 keyRemapped; /** optional remapped key switch (default -1), the plug-in could provide one remapped
|
||||
key for a key switch (allowing better location on the keyboard of the key switches) */
|
||||
|
||||
int32 unitId; ///< id of unit this key switch belongs to (see \ref vst3Units), -1 means no unit used.
|
||||
|
||||
int32 flags; ///< not yet used (set to 0)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController for key switches support: Vst::IKeyswitchController
|
||||
\ingroup vstIPlug vst350
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
When a (instrument) plug-in supports such interface, the host could get from the plug-in the current set
|
||||
of used key switches (megatrig/articulation) for a given channel of a event bus and then automatically use them (like in Cubase 6) to
|
||||
create VST Expression Map (allowing to associated symbol to a given articulation / key switch).
|
||||
*/
|
||||
class IKeyswitchController : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Returns number of supported key switches for event bus index and channel. */
|
||||
virtual int32 PLUGIN_API getKeyswitchCount (int32 busIndex, int16 channel) = 0;
|
||||
|
||||
/** Returns key switch info. */
|
||||
virtual tresult PLUGIN_API getKeyswitchInfo (int32 busIndex, int16 channel, int32 keySwitchIndex, KeyswitchInfo& info /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IKeyswitchController, 0x1F2F76D3, 0xBFFB4B96, 0xB99527A5, 0x5EBCCEF4)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstparameterchanges.h
|
||||
// Created by : Steinberg, 09/2005
|
||||
// Description : VST Parameter Change Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
//----------------------------------------------------------------------
|
||||
/** Queue of changes for a specific parameter: Vst::IParamValueQueue
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
The change queue can be interpreted as segment of an automation curve. For each
|
||||
processing block, a segment with the size of the block is transmitted to the processor.
|
||||
The curve is expressed as sampling points of a linear approximation of
|
||||
the original automation curve. If the original already is a linear curve, it can
|
||||
be transmitted precisely. A non-linear curve has to be converted to a linear
|
||||
approximation by the host. Every point of the value queue defines a linear
|
||||
section of the curve as a straight line from the previous point of a block to
|
||||
the new one. So the plug-in can calculate the value of the curve for any sample
|
||||
position in the block.
|
||||
|
||||
<b>Implicit Points:</b> \n
|
||||
In each processing block, the section of the curve for each parameter is transmitted.
|
||||
In order to reduce the amount of points, the point at block position 0 can be omitted.
|
||||
- If the curve has a slope of 0 over a period of multiple blocks, only one point is
|
||||
transmitted for the block where the constant curve section starts. The queue for the following
|
||||
blocks will be empty as long as the curve slope is 0.
|
||||
- If the curve has a constant slope other than 0 over the period of several blocks, only
|
||||
the value for the last sample of the block is transmitted. In this case, the last valid point
|
||||
is at block position -1. The processor can calculate the value for each sample in the block
|
||||
by using a linear interpolation:
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
double x1 = -1; // position of last point related to current buffer
|
||||
double y1 = currentParameterValue; // last transmitted value
|
||||
|
||||
int32 pointTime = 0;
|
||||
ParamValue pointValue = 0;
|
||||
IParamValueQueue::getPoint (0, pointTime, pointValue);
|
||||
|
||||
double x2 = pointTime;
|
||||
double y2 = pointValue;
|
||||
|
||||
double slope = (y2 - y1) / (x2 - x1);
|
||||
double offset = y1 - (slope * x1);
|
||||
|
||||
double curveValue = (slope * bufferTime) + offset; // bufferTime is any position in buffer
|
||||
\endcode
|
||||
|
||||
\b Jumps:
|
||||
\n
|
||||
A jump in the automation curve has to be transmitted as two points: one with the
|
||||
old value and one with the new value at the next sample position.
|
||||
|
||||
\image html "automation.jpg"
|
||||
|
||||
See \ref IParameterChanges, \ref ProcessData
|
||||
*/
|
||||
class IParamValueQueue : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns its associated ID. */
|
||||
virtual ParamID PLUGIN_API getParameterId () = 0;
|
||||
|
||||
/** Returns count of points in the queue. */
|
||||
virtual int32 PLUGIN_API getPointCount () = 0;
|
||||
|
||||
/** Gets the value and offset at a given index. */
|
||||
virtual tresult PLUGIN_API getPoint (int32 index, int32& sampleOffset /*out*/, ParamValue& value /*out*/) = 0;
|
||||
|
||||
/** Adds a new value at the end of the queue, its index is returned. */
|
||||
virtual tresult PLUGIN_API addPoint (int32 sampleOffset, ParamValue value, int32& index /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IParamValueQueue, 0x01263A18, 0xED074F6F, 0x98C9D356, 0x4686F9BA)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** All parameter changes of a processing block: Vst::IParameterChanges
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [released: 3.0.0]
|
||||
- [mandatory]
|
||||
|
||||
This interface is used to transmit any changes to be applied to parameters
|
||||
in the current processing block. A change can be caused by GUI interaction as
|
||||
well as automation. They are transmitted as a list of queues (\ref IParamValueQueue)
|
||||
containing only queues for parameters that actually did change.
|
||||
See \ref IParamValueQueue, \ref ProcessData
|
||||
*/
|
||||
class IParameterChanges : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns count of Parameter changes in the list. */
|
||||
virtual int32 PLUGIN_API getParameterCount () = 0;
|
||||
|
||||
/** Returns the queue at a given index. */
|
||||
virtual IParamValueQueue* PLUGIN_API getParameterData (int32 index) = 0;
|
||||
|
||||
/** Adds a new parameter queue with a given ID at the end of the list,
|
||||
returns it and its index in the parameter changes list. */
|
||||
virtual IParamValueQueue* PLUGIN_API addParameterData (const ParamID& id, int32& index /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IParameterChanges, 0xA4779663, 0x0BB64A56, 0xB44384A8, 0x466FEB9D)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,151 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstparameterfunctionname.h
|
||||
// Created by : Steinberg, 03/2020
|
||||
// Description : VST Parameter Function Name Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
namespace FunctionNameType {
|
||||
//--------------------------------------------------------------------
|
||||
const CString kCompGainReduction = "Comp:GainReduction"; /** */
|
||||
const CString kCompGainReductionMax = "Comp:GainReductionMax";
|
||||
const CString kCompGainReductionPeakHold = "Comp:GainReductionPeakHold";
|
||||
const CString kCompResetGainReductionMax = "Comp:ResetGainReductionMax";
|
||||
|
||||
const CString kLowLatencyMode = "LowLatencyMode"; /** Useful for live situation where low
|
||||
latency is required:
|
||||
0 means LowLatency disable,
|
||||
1 means LowLatency enable */
|
||||
const CString kDryWetMix = "DryWetMix"; /** Allowing to mix the original (Dry) Signal with the processed one (Wet):
|
||||
0.0 means Dry Signal only,
|
||||
0.5 means 50% Dry Signal + 50% Wet Signal,
|
||||
1.0 means Wet Signal only */
|
||||
const CString kRandomize = "Randomize"; /** Allow to assign some randomized values to some
|
||||
parameters in a controlled way*/
|
||||
|
||||
/// Panner Type
|
||||
const CString kPanPosCenterX = "PanPosCenterX"; ///< Gravity point X-axis [0, 1]=>[L-R] (for stereo: middle between left and right)
|
||||
const CString kPanPosCenterY = "PanPosCenterY"; ///< Gravity point Y-axis [0, 1]=>[Front-Rear]
|
||||
const CString kPanPosCenterZ = "PanPosCenterZ"; ///< Gravity point Z-axis [0, 1]=>[Bottom-Top]
|
||||
|
||||
|
||||
} // FunctionNameType
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Edit controller component interface extension: Vst::IParameterFunctionName
|
||||
\ingroup vstIPlug vst370
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.7.0]
|
||||
- [optional]
|
||||
|
||||
This interface allows the host to get a parameter associated to a specific meaning (a functionName)
|
||||
for a given unit. The host can use this information, for example, for drawing a Gain Reduction meter
|
||||
in its own UI. In order to get the plain value of this parameter, the host should use the
|
||||
IEditController::normalizedParamToPlain. The host can automatically map parameters to dedicated UI
|
||||
controls, such as the wet-dry mix knob or Randomize button.
|
||||
|
||||
\section IParameterFunctionNameExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
// here an example of how a VST3 plug-in could support this IParameterFunctionName interface.
|
||||
// we need to define somewhere the iids:
|
||||
|
||||
in MyController class declaration
|
||||
class MyController : public Vst::EditController, public Vst::IParameterFunctionName
|
||||
{
|
||||
...
|
||||
tresult PLUGIN_API getParameterIDFromFunctionName (UnitID unitID, FIDString functionName,
|
||||
Vst::ParamID& paramID) override;
|
||||
...
|
||||
|
||||
OBJ_METHODS (MyController, Vst::EditController)
|
||||
DEFINE_INTERFACES
|
||||
...
|
||||
DEF_INTERFACE (Vst::IParameterFunctionName)
|
||||
END_DEFINE_INTERFACES (Vst::EditController)
|
||||
DELEGATE_REFCOUNT (Vst::EditController)
|
||||
...
|
||||
}
|
||||
|
||||
#include "ivstparameterfunctionname.h"
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
DEF_CLASS_IID (IParameterFunctionName)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyController::getParameterIDFromFunctionName (UnitID unitID, FIDString
|
||||
functionName, Vst::ParamID& paramID)
|
||||
{
|
||||
using namespace Vst;
|
||||
|
||||
paramID = kNoParamId;
|
||||
|
||||
if (unitID == kRootUnitId && FIDStringsEqual (functionName, kCompGainReduction))
|
||||
paramID = kMyGainReductionId;
|
||||
|
||||
return (paramID != kNoParamId) ? kResultOk : kResultFalse;
|
||||
}
|
||||
|
||||
//--- a host implementation example: --------------------
|
||||
...
|
||||
FUnknownPtr<Vst::IParameterFunctionName> functionName (mEditController->getIEditController ());
|
||||
if (functionName)
|
||||
{
|
||||
Vst::ParamID paramID;
|
||||
if (functionName->getParameterIDFromFunctionName (kRootUnitId,
|
||||
Vst::FunctionNameType::kCompGainReduction, paramID) == kResultTrue)
|
||||
{
|
||||
// paramID could be cached for performance issue
|
||||
ParamValue norm = mEditController->getIEditController ()->getParamNormalized (paramID);
|
||||
ParamValue plain = mEditController->getIEditController ()->normalizedParamToPlain (paramID, norm);
|
||||
// plain is something like -6 (-6dB)
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class IParameterFunctionName : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Gets for the given unitID the associated paramID to a function Name.
|
||||
Returns kResultFalse when no found parameter (paramID is set to kNoParamId in this case). */
|
||||
virtual tresult PLUGIN_API getParameterIDFromFunctionName (UnitID unitID, FIDString functionName, ParamID& paramID) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IParameterFunctionName, 0x6D21E1DC, 0x91199D4B, 0xA2A02FEF, 0x6C1AE55C)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstphysicalui.h
|
||||
// Created by : Steinberg, 06/2018
|
||||
// Description : VST Physical User Interface support
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/ivstnoteexpression.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup vst3typedef VST 3 Data Types */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
/** Physical UI Type */
|
||||
typedef uint32 PhysicalUITypeID;
|
||||
/*@}*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** PhysicalUITypeIDs describes the type of Physical UI (PUI) which could be associated to a note
|
||||
expression.
|
||||
\see PhysicalUIMap
|
||||
*/
|
||||
enum PhysicalUITypeIDs
|
||||
{
|
||||
/** absolute X position when touching keys of PUIs. Range [0=left, 0.5=middle, 1=right] */
|
||||
kPUIXMovement = 0,
|
||||
/** absolute Y position when touching keys of PUIs. Range [0=bottom/near, 0.5=center, 1=top/far] */
|
||||
kPUIYMovement,
|
||||
/** pressing a key down on keys of PUIs. Range [0=No Pressure, 1=Full Pressure] */
|
||||
kPUIPressure,
|
||||
|
||||
kPUITypeCount, ///< count of current defined PUIs
|
||||
|
||||
kInvalidPUITypeID = 0xFFFFFFFF ///< indicates an invalid or not initialized PUI type
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** PhysicalUIMap describes a mapping of a noteExpression Type to a Physical UI Type.
|
||||
It is used in PhysicalUIMapList.
|
||||
\see PhysicalUIMapList
|
||||
*/
|
||||
struct PhysicalUIMap
|
||||
{
|
||||
/** This represents the physical UI. /see PhysicalUITypeIDs, this is set by the caller of
|
||||
* getPhysicalUIMapping */
|
||||
PhysicalUITypeID physicalUITypeID;
|
||||
|
||||
/** This represents the associated noteExpression TypeID to the given physicalUITypeID. This
|
||||
* will be filled by the plug-in in the call getPhysicalUIMapping, set it to kInvalidTypeID if
|
||||
* no Note Expression is associated to the given PUI. */
|
||||
NoteExpressionTypeID noteExpressionTypeID;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** PhysicalUIMapList describes a list of PhysicalUIMap
|
||||
\see INoteExpressionPhysicalUIMapping
|
||||
*/
|
||||
struct PhysicalUIMapList
|
||||
{
|
||||
/** Count of entries in the map array, set by the caller of getPhysicalUIMapping. */
|
||||
uint32 count;
|
||||
|
||||
/** Pointer to a list of PhysicalUIMap containing count entries. */
|
||||
PhysicalUIMap* map;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController for note expression event support: Vst::INoteExpressionPhysicalUIMapping
|
||||
\ingroup vstIPlug vst3611
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.6.11]
|
||||
- [optional]
|
||||
|
||||
With this plug-in interface, the host can retrieve the preferred physical mapping associated to note
|
||||
expression supported by the plug-in.
|
||||
When the mapping changes (for example when switching presets) the plug-in needs
|
||||
to inform the host about it via \ref IComponentHandler::restartComponent (kNoteExpressionChanged).
|
||||
|
||||
\section INoteExpressionPhysicalUIMappingExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
// here an example of how a VST3 plug-in could support this INoteExpressionPhysicalUIMapping interface.
|
||||
// we need to define somewhere the iids:
|
||||
|
||||
//in MyController class declaration
|
||||
class MyController : public Vst::EditController, public Vst::INoteExpressionPhysicalUIMapping
|
||||
{
|
||||
// ...
|
||||
//--- INoteExpressionPhysicalUIMapping ---------------------------------
|
||||
tresult PLUGIN_API getPhysicalUIMapping (int32 busIndex, int16 channel, PhysicalUIMapList& list) SMTG_OVERRIDE;
|
||||
// ...
|
||||
|
||||
OBJ_METHODS (MyController, Vst::EditController)
|
||||
DEFINE_INTERFACES
|
||||
// ...
|
||||
DEF_INTERFACE (Vst::INoteExpressionPhysicalUIMapping)
|
||||
END_DEFINE_INTERFACES (Vst::EditController)
|
||||
//...
|
||||
}
|
||||
|
||||
// In mycontroller.cpp
|
||||
#include "pluginterfaces/vst/ivstnoteexpression.h"
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
DEF_CLASS_IID (INoteExpressionPhysicalUIMapping)
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyController::getPhysicalUIMapping (int32 busIndex, int16 channel, PhysicalUIMapList& list)
|
||||
{
|
||||
if (busIndex == 0 && channel == 0)
|
||||
{
|
||||
for (uint32 i = 0; i < list.count; ++i)
|
||||
{
|
||||
NoteExpressionTypeID type = kInvalidTypeID;
|
||||
if (kPUIXMovement == list.map[i].physicalUITypeID)
|
||||
list.map[i].noteExpressionTypeID = kCustomStart + 1;
|
||||
else if (kPUIYMovement == list.map[i].physicalUITypeID)
|
||||
list.map[i].noteExpressionTypeID = kCustomStart + 2;
|
||||
}
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class INoteExpressionPhysicalUIMapping : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Fills the list of mapped [physical UI (in) - note expression (out)] for a given bus index
|
||||
* and channel. */
|
||||
virtual tresult PLUGIN_API getPhysicalUIMapping (int32 busIndex, int16 channel,
|
||||
PhysicalUIMapList& list) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (INoteExpressionPhysicalUIMapping, 0xB03078FF, 0x94D24AC8, 0x90CCD303, 0xD4133324)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstpluginterfacesupport.h
|
||||
// Created by : Steinberg, 11/2018
|
||||
// Description : VST Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
//------------------------------------------------------------------------
|
||||
/** Host callback interface for an edit controller: Vst::IPlugInterfaceSupport
|
||||
\ingroup vstIHost vst3612
|
||||
- [host imp]
|
||||
- [released: 3.6.12]
|
||||
- [optional]
|
||||
|
||||
Allows a plug-in to ask the host if a given plug-in interface is supported/used by the host.
|
||||
It is implemented by the hostContext given when the component is initialized.
|
||||
|
||||
\section IPlugInterfaceSupportExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MyPluginController::initialize (FUnknown* context)
|
||||
{
|
||||
// ...
|
||||
FUnknownPtr<IPlugInterfaceSupport> plugInterfaceSupport (context);
|
||||
if (plugInterfaceSupport)
|
||||
{
|
||||
if (plugInterfaceSupport->isPlugInterfaceSupported (IMidiMapping::iid) == kResultTrue)
|
||||
// IMidiMapping is used by the host
|
||||
}
|
||||
// ...
|
||||
}
|
||||
\endcode
|
||||
\see IPluginBase
|
||||
*/
|
||||
class IPlugInterfaceSupport : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Returns kResultTrue if the associated interface to the given _iid is supported/used by the host. */
|
||||
virtual tresult PLUGIN_API isPlugInterfaceSupported (const TUID _iid) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPlugInterfaceSupport, 0x4FB58B9E, 0x9EAA4E0F, 0xAB361C1C, 0xCCB56FEA)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstplugview.h
|
||||
// Created by : Steinberg, 01/2009
|
||||
// Description : Plug-in User Interface Extension
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
//------------------------------------------------------------------------
|
||||
// IParameterFinder Interface
|
||||
//------------------------------------------------------------------------
|
||||
/** Extension for IPlugView to find view parameters (lookup value under mouse support): Vst::IParameterFinder
|
||||
\ingroup pluginGUI vst302
|
||||
- [plug imp]
|
||||
- [extends IPlugView]
|
||||
- [released: 3.0.2]
|
||||
- [optional]
|
||||
|
||||
It is highly recommended to implement this interface.
|
||||
A host can implement important functionality when a plug-in supports this interface.
|
||||
|
||||
For example, all Steinberg hosts require this interface in order to support the "AI Knob".
|
||||
*/
|
||||
class IParameterFinder: public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Find out which parameter in plug-in view is at given position (relative to plug-in view). */
|
||||
virtual tresult PLUGIN_API findParameter (int32 xPos, int32 yPos, ParamID& resultTag /*out*/) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IParameterFinder, 0x0F618302, 0x215D4587, 0xA512073C, 0x77B9D383)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstprefetchablesupport.h
|
||||
// Created by : Steinberg, 02/2015
|
||||
// Description : VST Prefetchable Support Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/vsttypes.h"
|
||||
#include "pluginterfaces/vst/ivstattributes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \defgroup vst3typedef VST 3 Data Types */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
/** Prefetchable Support Type */
|
||||
typedef uint32 PrefetchableSupport;
|
||||
/*@}*/
|
||||
|
||||
/** Prefetchable Support Enum */
|
||||
enum ePrefetchableSupport
|
||||
{
|
||||
kIsNeverPrefetchable = 0, ///< every instance of the plug does not support prefetch processing
|
||||
kIsYetPrefetchable, ///< in the current state the plug support prefetch processing
|
||||
kIsNotYetPrefetchable, ///< in the current state the plug does not support prefetch processing
|
||||
kNumPrefetchableSupport
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IPrefetchableSupport Interface
|
||||
//------------------------------------------------------------------------
|
||||
/** Indicates that the plug-in could or not support Prefetch (dynamically): Vst::IPrefetchableSupport
|
||||
\ingroup vstIPlug vst365
|
||||
- [plug imp]
|
||||
- [extends IComponent]
|
||||
- [released: 3.6.5]
|
||||
- [optional]
|
||||
|
||||
The plug-in should implement this interface if it needs to dynamically change between prefetchable or not.
|
||||
By default (without implementing this interface) the host decides in which mode the plug-in is processed.
|
||||
For more info about the prefetch processing mode check the ProcessModes::kPrefetch documentation.
|
||||
|
||||
\section IPrefetchableSupportExample Example
|
||||
|
||||
\code{.cpp}
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API myPlug::getPrefetchableSupport (PrefetchableSupport& prefetchable)
|
||||
{
|
||||
prefetchable = kIsNeverPrefetchable;
|
||||
|
||||
switch (myPrefetchableMode)
|
||||
{
|
||||
case 0: prefetchable = kIsNeverPrefetchable; break;
|
||||
case 1: prefetchable = kIsYetPrefetchable; break;
|
||||
case 2: prefetchable = kIsNotYetPrefetchable; break;
|
||||
}
|
||||
return kResultOk;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
class IPrefetchableSupport : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** retrieve the current prefetch support. Use IComponentHandler::restartComponent
|
||||
(kPrefetchableSupportChanged) to inform the host that this support has changed. */
|
||||
virtual tresult PLUGIN_API getPrefetchableSupport (PrefetchableSupport& prefetchable /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IPrefetchableSupport, 0x8AE54FDA, 0xE93046B9, 0xA28555BC, 0xDC98E21E)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstprocesscontext.h
|
||||
// Created by : Steinberg, 10/2005
|
||||
// Description : VST Processing Context Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
//------------------------------------------------------------------------
|
||||
/** Frame Rate
|
||||
A frame rate describes the number of image (frame) displayed per second.
|
||||
Some examples:
|
||||
- 23.976 fps is framesPerSecond: 24 and flags: kPullDownRate
|
||||
- 24 fps is framesPerSecond: 24 and flags: 0
|
||||
- 25 fps is framesPerSecond: 25 and flags: 0
|
||||
- 29.97 drop fps is framesPerSecond: 30 and flags: kDropRate|kPullDownRate
|
||||
- 29.97 fps is framesPerSecond: 30 and flags: kPullDownRate
|
||||
- 30 fps is framesPerSecond: 30 and flags: 0
|
||||
- 30 drop fps is framesPerSecond: 30 and flags: kDropRate
|
||||
- 50 fps is framesPerSecond: 50 and flags: 0
|
||||
- 59.94 fps is framesPerSecond: 60 and flags: kPullDownRate
|
||||
- 60 fps is framesPerSecond: 60 and flags: 0
|
||||
*/
|
||||
struct FrameRate
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
enum FrameRateFlags
|
||||
{
|
||||
kPullDownRate = 1 << 0,
|
||||
kDropRate = 1 << 1
|
||||
};
|
||||
|
||||
uint32 framesPerSecond; ///< frame rate
|
||||
uint32 flags; ///< flags #FrameRateFlags
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Description of a chord.
|
||||
A chord is described with a key note, a root note and the
|
||||
\copydoc chordMask
|
||||
\see ProcessContext
|
||||
*/
|
||||
struct Chord
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
uint8 keyNote; ///< key note in chord
|
||||
uint8 rootNote; ///< lowest note in chord
|
||||
|
||||
/** Bitmask of a chord. \n
|
||||
1st bit set: minor second; 2nd bit set: major second, and so on. \n
|
||||
There is \b no bit for the keynote (root of the chord) because it is inherently always present. \n
|
||||
Examples:
|
||||
- XXXX 0000 0100 1000 (= 0x0048) -> major chord
|
||||
- XXXX 0000 0100 0100 (= 0x0044) -> minor chord
|
||||
- XXXX 0010 0100 0100 (= 0x0244) -> minor chord with minor seventh */
|
||||
int16 chordMask;
|
||||
|
||||
enum Masks {
|
||||
kChordMask = 0x0FFF, ///< mask for chordMask
|
||||
kReservedMask = 0xF000 ///< reserved for future use
|
||||
};
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Audio processing context.
|
||||
For each processing block the host provides timing information and musical parameters that can
|
||||
change over time. For a host that supports jumps (like cycle) it is possible to split up a
|
||||
processing block into multiple parts in order to provide a correct project time inside of every
|
||||
block, but this behavior is not mandatory. Since the timing will be correct at the beginning of the
|
||||
next block again, a host that is dependent on a fixed processing block size can choose to neglect
|
||||
this problem.
|
||||
\see IAudioProcessor, ProcessData
|
||||
*/
|
||||
struct ProcessContext
|
||||
{
|
||||
//------------------------------------------------------------------------
|
||||
/** Transport state & other flags */
|
||||
enum StatesAndFlags
|
||||
{
|
||||
kPlaying = 1 << 1, ///< currently playing
|
||||
kCycleActive = 1 << 2, ///< cycle is active
|
||||
kRecording = 1 << 3, ///< currently recording
|
||||
|
||||
kSystemTimeValid = 1 << 8, ///< systemTime contains valid information
|
||||
kContTimeValid = 1 << 17, ///< continousTimeSamples contains valid information
|
||||
|
||||
kProjectTimeMusicValid = 1 << 9,///< projectTimeMusic contains valid information
|
||||
kBarPositionValid = 1 << 11, ///< barPositionMusic contains valid information
|
||||
kCycleValid = 1 << 12, ///< cycleStartMusic and barPositionMusic contain valid information
|
||||
|
||||
kTempoValid = 1 << 10, ///< tempo contains valid information
|
||||
kTimeSigValid = 1 << 13, ///< timeSigNumerator and timeSigDenominator contain valid information
|
||||
kChordValid = 1 << 18, ///< chord contains valid information
|
||||
|
||||
kSmpteValid = 1 << 14, ///< smpteOffset and frameRate contain valid information
|
||||
kClockValid = 1 << 15 ///< samplesToNextClock valid
|
||||
};
|
||||
|
||||
uint32 state; ///< a combination of the values from \ref StatesAndFlags
|
||||
|
||||
double sampleRate; ///< current sample rate (always valid)
|
||||
TSamples projectTimeSamples; ///< project time in samples (always valid)
|
||||
|
||||
int64 systemTime; ///< system time in nanoseconds (optional)
|
||||
TSamples continousTimeSamples; ///< project time, without loop (optional)
|
||||
|
||||
TQuarterNotes projectTimeMusic; ///< musical position in quarter notes (1.0 equals 1 quarter note) (optional)
|
||||
TQuarterNotes barPositionMusic; ///< last bar start position, in quarter notes (optional)
|
||||
TQuarterNotes cycleStartMusic; ///< cycle start in quarter notes (optional)
|
||||
TQuarterNotes cycleEndMusic; ///< cycle end in quarter notes (optional)
|
||||
|
||||
double tempo; ///< tempo in BPM (Beats Per Minute) (optional)
|
||||
int32 timeSigNumerator; ///< time signature numerator (e.g. 3 for 3/4) (optional)
|
||||
int32 timeSigDenominator; ///< time signature denominator (e.g. 4 for 3/4) (optional)
|
||||
|
||||
Chord chord; ///< musical info (optional)
|
||||
|
||||
int32 smpteOffsetSubframes; ///< SMPTE (sync) offset in subframes (1/80 of frame) (optional)
|
||||
FrameRate frameRate; ///< frame rate (optional)
|
||||
|
||||
int32 samplesToNextClock; ///< MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest) (optional)
|
||||
//------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstremapparamid.h
|
||||
// Created by : Steinberg, 02/2024
|
||||
// Description : VST Edit Controller Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended IEditController interface for a component.
|
||||
\ingroup vstIPlug vst3711
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.7.11]
|
||||
- [optional]
|
||||
|
||||
When replacing one plug-in with another, the host can ask the new plug-in for remapping paramIDs to
|
||||
new ones.
|
||||
|
||||
\n
|
||||
\see Moduleinfo
|
||||
\see \ref IPluginCompatibility
|
||||
\see IEditController
|
||||
*/
|
||||
class IRemapParamID : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Retrieve the appropriate paramID for a specific plug-in UID and paramID (or index for VST 2
|
||||
* plug-ins).
|
||||
* The retrieved paramID should match the one it replaces, maintaining the same
|
||||
* behavior during automation playback. Called in UI-Thread context.
|
||||
* @param[in] pluginToReplaceUID - TUID of plug-in (processor) that will be replaced
|
||||
* @param[in] oldParamID - paramID (or index for VST 2 plug-ins) to be replaced
|
||||
* @param[out] newParamID - contains the associated paramID to be used
|
||||
*
|
||||
* @return kResultTrue if a compatible parameter is available (newParamID has the appropriate
|
||||
* value, it could be the same than oldParamID), or kResultFalse if no compatible parameter is
|
||||
* available (newParamID is undefined)
|
||||
*/
|
||||
virtual tresult PLUGIN_API getCompatibleParamID (const TUID pluginToReplaceUID /*in*/,
|
||||
ParamID oldParamID /*in*/,
|
||||
ParamID& newParamID /*out*/) = 0;
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IRemapParamID, 0x2B88021E, 0x6286B646, 0xB49DF76A, 0x5663061C)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstrepresentation.h
|
||||
// Created by : Steinberg, 08/2010
|
||||
// Description : VST Representation Interface
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
class IBStream;
|
||||
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** RepresentationInfo is the structure describing a representation
|
||||
This structure is used in the function \see IXmlRepresentationController::getXmlRepresentationStream.
|
||||
\see IXmlRepresentationController
|
||||
*/
|
||||
struct RepresentationInfo
|
||||
{
|
||||
RepresentationInfo ()
|
||||
{
|
||||
memset (vendor, 0, kNameSize);
|
||||
memset (name, 0, kNameSize);
|
||||
memset (version, 0, kNameSize);
|
||||
memset (host, 0, kNameSize);
|
||||
}
|
||||
|
||||
RepresentationInfo (char8* _vendor, char8* _name = nullptr, char8* _version = nullptr, char8* _host = nullptr)
|
||||
{
|
||||
memset (vendor, 0, kNameSize);
|
||||
if (_vendor)
|
||||
strcpy (vendor, _vendor);
|
||||
memset (name, 0, kNameSize);
|
||||
if (_name)
|
||||
strcpy (name, _name);
|
||||
memset (version, 0, kNameSize);
|
||||
if (_version)
|
||||
strcpy (version, _version);
|
||||
memset (host, 0, kNameSize);
|
||||
if (_host)
|
||||
strcpy (host, _host);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
kNameSize = 64
|
||||
};
|
||||
char8 vendor[kNameSize]; ///< Vendor name of the associated representation (remote) (eg. "Yamaha").
|
||||
char8 name[kNameSize]; ///< Representation (remote) Name (eg. "O2").
|
||||
char8 version[kNameSize]; ///< Version of this "Remote" (eg. "1.0").
|
||||
char8 host[kNameSize]; ///< Optional: used if the representation is for a given host only (eg. "Nuendo").
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
/** Extended plug-in interface IEditController for a component: Vst::IXmlRepresentationController
|
||||
\ingroup vstIPlug vst350
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.5.0]
|
||||
- [optional]
|
||||
|
||||
A representation based on XML is a way to export, structure, and group plug-ins parameters for a specific remote (hardware or software rack (such as quick controls)).
|
||||
\n
|
||||
It allows to describe each parameter more precisely (what is the best matching to a knob, different title lengths matching limited remote display,...).\n See an \ref Example.
|
||||
\n\n
|
||||
- A representation is composed of pages (this means that to see all exported parameters, the user has to navigate through the pages).
|
||||
- A page is composed of cells (for example 8 cells per page).
|
||||
- A cell is composed of layers (for example a cell could have a knob, a display, and a button, which means 3 layers).
|
||||
- A layer is associated to a plug-in parameter using the ParameterID as identifier:
|
||||
- it could be a knob with a display for title and/or value, this display uses the same parameterId, but it could an another one.
|
||||
- switch
|
||||
- link which allows to jump directly to a subpage (another page)
|
||||
- more... See Vst::LayerType
|
||||
.
|
||||
|
||||
\n
|
||||
This representation is implemented as XML text following the Document Type Definition (DTD): http://dtd.steinberg.net/VST-Remote-1.1.dtd
|
||||
|
||||
\section Example
|
||||
Here an example of what should be passed in the stream of getXmlRepresentationStream:
|
||||
|
||||
\code
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE vstXML PUBLIC "-//Steinberg//DTD VST Remote 1.1//EN" "http://dtd.steinberg.net/VST-Remote-1.1.dtd">
|
||||
<vstXML version="1.0">
|
||||
<plugin classID="341FC5898AAA46A7A506BC0799E882AE" name="Chorus" vendor="Steinberg Media Technologies" />
|
||||
<originator>My name</originator>
|
||||
<date>2010-12-31</date>
|
||||
<comment>This is an example for 4 Cells per Page for the Remote named ProductRemote
|
||||
from company HardwareCompany.</comment>
|
||||
|
||||
<!-- ===================================== -->
|
||||
<representation name="ProductRemote" vendor="HardwareCompany" version="1.0">
|
||||
<page name="Root">
|
||||
<cell>
|
||||
<layer type="knob" parameterID="0">
|
||||
<titleDisplay>
|
||||
<name>Mix dry/wet</name>
|
||||
<name>Mix</name>
|
||||
</titleDisplay>
|
||||
</layer>
|
||||
</cell>
|
||||
<cell>
|
||||
<layer type="display"></layer>
|
||||
</cell>
|
||||
<cell>
|
||||
<layer type="knob" parameterID="3">
|
||||
<titleDisplay>
|
||||
<name>Delay</name>
|
||||
<name>Dly</name>
|
||||
</titleDisplay>
|
||||
</layer>
|
||||
</cell>
|
||||
<cell>
|
||||
<layer type="knob" parameterID="15">
|
||||
<titleDisplay>
|
||||
<name>Spatial</name>
|
||||
<name>Spat</name>
|
||||
</titleDisplay>
|
||||
</layer>
|
||||
</cell>
|
||||
</page>
|
||||
<page name="Page 2">
|
||||
<cell>
|
||||
<layer type="LED" ledStyle="spread" parameterID="2">
|
||||
<titleDisplay>
|
||||
<name>Width +</name>
|
||||
<name>Widt</name>
|
||||
</titleDisplay>
|
||||
</layer>
|
||||
<!--this is the switch for shape A/B-->
|
||||
<layer type="switch" switchStyle="pushIncLooped" parameterID="4"></layer>
|
||||
</cell>
|
||||
<cell>
|
||||
<layer type="display"></layer>
|
||||
</cell>
|
||||
<cell>
|
||||
<layer type="LED" ledStyle="singleDot" parameterID="17">
|
||||
<titleDisplay>
|
||||
<name>Sync Note +</name>
|
||||
<name>Note</name>
|
||||
</titleDisplay>
|
||||
</layer>
|
||||
<!--this is the switch for sync to tempo on /off-->
|
||||
<layer type="switch" switchStyle="pushIncLooped" parameterID="16"></layer>
|
||||
</cell>
|
||||
<cell>
|
||||
<layer type="knob" parameterID="1">
|
||||
<titleDisplay>
|
||||
<name>Rate</name>
|
||||
</titleDisplay>
|
||||
</layer>
|
||||
</cell>
|
||||
</page>
|
||||
</representation>
|
||||
</vstXML>
|
||||
\endcode
|
||||
*/
|
||||
class IXmlRepresentationController : public FUnknown
|
||||
{
|
||||
public:
|
||||
/** Retrieves a stream containing a XmlRepresentation for a wanted representation info */
|
||||
virtual tresult PLUGIN_API getXmlRepresentationStream (RepresentationInfo& info /*in*/,
|
||||
IBStream* stream /*out*/) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IXmlRepresentationController, 0xA81A0471, 0x48C34DC4, 0xAC30C9E1, 0x3C8393D5)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Defines for XML representation Tags and Attributes */
|
||||
|
||||
#define ROOTXML_TAG "vstXML"
|
||||
|
||||
#define COMMENT_TAG "comment"
|
||||
#define CELL_TAG "cell"
|
||||
#define CELLGROUP_TAG "cellGroup"
|
||||
#define CELLGROUPTEMPLATE_TAG "cellGroupTemplate"
|
||||
#define CURVE_TAG "curve"
|
||||
#define CURVETEMPLATE_TAG "curveTemplate"
|
||||
#define DATE_TAG "date"
|
||||
#define LAYER_TAG "layer"
|
||||
#define NAME_TAG "name"
|
||||
#define ORIGINATOR_TAG "originator"
|
||||
#define PAGE_TAG "page"
|
||||
#define PAGETEMPLATE_TAG "pageTemplate"
|
||||
#define PLUGIN_TAG "plugin"
|
||||
#define VALUE_TAG "value"
|
||||
#define VALUEDISPLAY_TAG "valueDisplay"
|
||||
#define VALUELIST_TAG "valueList"
|
||||
#define REPRESENTATION_TAG "representation"
|
||||
#define SEGMENT_TAG "segment"
|
||||
#define SEGMENTLIST_TAG "segmentList"
|
||||
#define TITLEDISPLAY_TAG "titleDisplay"
|
||||
|
||||
#define ATTR_CATEGORY "category"
|
||||
#define ATTR_CLASSID "classID"
|
||||
#define ATTR_ENDPOINT "endPoint"
|
||||
#define ATTR_INDEX "index"
|
||||
#define ATTR_FLAGS "flags"
|
||||
#define ATTR_FUNCTION "function"
|
||||
#define ATTR_HOST "host"
|
||||
#define ATTR_LEDSTYLE "ledStyle"
|
||||
#define ATTR_LENGTH "length"
|
||||
#define ATTR_LINKEDTO "linkedTo"
|
||||
#define ATTR_NAME "name"
|
||||
#define ATTR_ORDER "order"
|
||||
#define ATTR_PAGE "page"
|
||||
#define ATTR_PARAMID "parameterID"
|
||||
#define ATTR_STARTPOINT "startPoint"
|
||||
#define ATTR_STYLE "style"
|
||||
#define ATTR_SWITCHSTYLE "switchStyle"
|
||||
#define ATTR_TEMPLATE "template"
|
||||
#define ATTR_TURNSPERFULLRANGE "turnsPerFullRange"
|
||||
#define ATTR_TYPE "type"
|
||||
#define ATTR_UNITID "unitID"
|
||||
#define ATTR_VARIABLES "variables"
|
||||
#define ATTR_VENDOR "vendor"
|
||||
#define ATTR_VERSION "version"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Defines some predefined Representation Remote Names */
|
||||
#define GENERIC "Generic"
|
||||
#define GENERIC_4_CELLS "Generic 4 Cells"
|
||||
#define GENERIC_8_CELLS "Generic 8 Cells"
|
||||
#define GENERIC_12_CELLS "Generic 12 Cells"
|
||||
#define GENERIC_24_CELLS "Generic 24 Cells"
|
||||
#define GENERIC_N_CELLS "Generic %d Cells"
|
||||
#define QUICK_CONTROL_8_CELLS "Quick Controls 8 Cells"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Layer Types used in a VST XML Representation */
|
||||
namespace LayerType
|
||||
{
|
||||
enum
|
||||
{
|
||||
kKnob = 0, ///< a knob (encoder or not)
|
||||
kPressedKnob, ///< a knob which is used by pressing and turning
|
||||
kSwitchKnob, ///< knob could be pressed to simulate a switch
|
||||
kSwitch, ///< a "on/off" button
|
||||
kLED, ///< LED like VU-meter or display around a knob
|
||||
kLink, ///< indicates that this layer is a folder linked to an another INode (page)
|
||||
kDisplay, ///< only for text display (not really a control)
|
||||
kFader, ///< a fader
|
||||
kEndOfLayerType
|
||||
};
|
||||
|
||||
/** FIDString variant of the LayerType */
|
||||
static const FIDString layerTypeFIDString[] = {
|
||||
"knob"
|
||||
,"pressedKnob"
|
||||
,"switchKnob"
|
||||
,"switch"
|
||||
,"LED"
|
||||
,"link"
|
||||
,"display"
|
||||
,"fader"
|
||||
,nullptr
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Curve Types used in a VST XML Representation */
|
||||
namespace CurveType
|
||||
{
|
||||
const CString kSegment = "segment"; ///<
|
||||
const CString kValueList = "valueList"; ///<
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Attributes used to defined a Layer in a VST XML Representation */
|
||||
namespace Attributes
|
||||
{
|
||||
const CString kStyle = ATTR_STYLE; ///< string attribute : See AttributesStyle for available string value
|
||||
const CString kLEDStyle = ATTR_LEDSTYLE; ///< string attribute : See AttributesStyle for available string value
|
||||
const CString kSwitchStyle = ATTR_SWITCHSTYLE; ///< string attribute : See AttributesStyle for available string value
|
||||
const CString kKnobTurnsPerFullRange = ATTR_TURNSPERFULLRANGE; ///< float attribute
|
||||
const CString kFunction = ATTR_FUNCTION; ///< string attribute : See AttributesFunction for available string value
|
||||
const CString kFlags = ATTR_FLAGS; ///< string attribute : See AttributesFlags for available string value
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Attributes Function used to defined the function of a Layer in a VST XML Representation */
|
||||
namespace AttributesFunction
|
||||
{
|
||||
/// Global Style
|
||||
const CString kPanPosCenterXFunc = "PanPosCenterX"; ///< Gravity point X-axis (L-R) (for stereo: middle between left and right)
|
||||
const CString kPanPosCenterYFunc = "PanPosCenterY"; ///< Gravity point Y-axis (Front-Rear)
|
||||
const CString kPanPosFrontLeftXFunc = "PanPosFrontLeftX"; ///< Left channel Position in X-axis
|
||||
const CString kPanPosFrontLeftYFunc = "PanPosFrontLeftY"; ///< Left channel Position in Y-axis
|
||||
const CString kPanPosFrontRightXFunc = "PanPosFrontRightX"; ///< Right channel Position in X-axis
|
||||
const CString kPanPosFrontRightYFunc = "PanPosFrontRightY"; ///< Right channel Position in Y-axis
|
||||
const CString kPanRotationFunc = "PanRotation"; ///< Rotation around the Center (gravity point)
|
||||
const CString kPanLawFunc = "PanLaw"; ///< Panning Law
|
||||
const CString kPanMirrorModeFunc = "PanMirrorMode"; ///< Panning Mirror Mode
|
||||
const CString kPanLfeGainFunc = "PanLfeGain"; ///< Panning LFE Gain
|
||||
const CString kGainReductionFunc = "GainReduction"; ///< Gain Reduction for compressor
|
||||
const CString kSoloFunc = "Solo"; ///< Solo
|
||||
const CString kMuteFunc = "Mute"; ///< Mute
|
||||
const CString kVolumeFunc = "Volume"; ///< Volume
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Attributes Style associated a specific Layer Type in a VST XML Representation */
|
||||
namespace AttributesStyle
|
||||
{
|
||||
/// Global Style
|
||||
const CString kInverseStyle = "inverse"; ///< the associated layer should use the inverse value of parameter (1 - x).
|
||||
|
||||
/// LED Style
|
||||
const CString kLEDWrapLeftStyle = "wrapLeft"; ///< |======>----- (the default one if not specified)
|
||||
const CString kLEDWrapRightStyle = "wrapRight"; ///< -------<====|
|
||||
const CString kLEDSpreadStyle = "spread"; ///< ---<==|==>---
|
||||
const CString kLEDBoostCutStyle = "boostCut"; ///< ------|===>--
|
||||
const CString kLEDSingleDotStyle = "singleDot"; ///< --------|----
|
||||
|
||||
/// Switch Style
|
||||
const CString kSwitchPushStyle = "push"; ///< Apply only when pressed, unpressed will reset the value to min.
|
||||
const CString kSwitchPushIncLoopedStyle = "pushIncLooped"; ///< Push will increment the value. When the max is reached it will restart with min.
|
||||
///< The default one if not specified (with 2 states values it is a OnOff switch).
|
||||
const CString kSwitchPushDecLoopedStyle = "pushDecLooped"; ///< Push will decrement the value. When the min is reached it will restart with max.
|
||||
const CString kSwitchPushIncStyle = "pushInc"; ///< Increment after each press (delta depends of the curve).
|
||||
const CString kSwitchPushDecStyle = "pushDec"; ///< Decrement after each press (delta depends of the curve).
|
||||
const CString kSwitchLatchStyle = "latch"; ///< Each push-release will change the value between min and max.
|
||||
///< A timeout between push and release could be used to simulate a push style (if timeout is reached).
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Attributes Flags defining a Layer in a VST XML Representation */
|
||||
namespace AttributesFlags
|
||||
{
|
||||
const CString kHideableFlag = "hideable"; ///< the associated layer marked as hideable allows a remote to hide or make it not usable a parameter when the associated value is inactive
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Validator
|
||||
// Filename : public.sdk/source/vst/testsuite/iplugprovider.h
|
||||
// Created by : Steinberg, 04/2005
|
||||
// Description : VST Test Suite
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2022, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/istringresult.h"
|
||||
#include "pluginterfaces/vst/ivstcomponent.h"
|
||||
#include "pluginterfaces/vst/ivsteditcontroller.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Test Helper.
|
||||
* \ingroup TestClass
|
||||
*
|
||||
* This class provides access to the component and the controller of a plug-in when running a unit
|
||||
* test (see ITest).
|
||||
* You get this interface as the context argument in the ITestFactory::createTests method.
|
||||
*/
|
||||
//------------------------------------------------------------------------
|
||||
class ITestPlugProvider : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** get the component of the plug-in.
|
||||
*
|
||||
* The reference count of the component is increased in this function and you need to call
|
||||
* releasePlugIn when done with the component.
|
||||
*/
|
||||
virtual IComponent* PLUGIN_API getComponent () = 0;
|
||||
/** get the controller of the plug-in.
|
||||
*
|
||||
* The reference count of the controller is increased in this function and you need to call
|
||||
* releasePlugIn when done with the controller.
|
||||
*/
|
||||
virtual IEditController* PLUGIN_API getController () = 0;
|
||||
/** release the component and/or controller */
|
||||
virtual tresult PLUGIN_API releasePlugIn (IComponent* component,
|
||||
IEditController* controller) = 0;
|
||||
/** get the sub categories of the plug-in */
|
||||
virtual tresult PLUGIN_API getSubCategories (IStringResult& result) const = 0;
|
||||
/** get the component UID of the plug-in */
|
||||
virtual tresult PLUGIN_API getComponentUID (FUID& uid) const = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (ITestPlugProvider, 0x86BE70EE, 0x4E99430F, 0x978F1E6E, 0xD68FB5BA)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Test Helper extension.
|
||||
* \ingroup TestClass
|
||||
*/
|
||||
class ITestPlugProvider2 : public ITestPlugProvider
|
||||
{
|
||||
public:
|
||||
/** get the plugin factory.
|
||||
*
|
||||
* The reference count of the returned factory object is not increased when calling this
|
||||
* function.
|
||||
*/
|
||||
virtual IPluginFactory* PLUGIN_API getPluginFactory () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (ITestPlugProvider2, 0xC7C75364, 0x7B8343AC, 0xA4495B0A, 0x3E5A46C7)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/ivstunits.h
|
||||
// Created by : Steinberg, 2005
|
||||
// Description : VST Units Interfaces
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/funknown.h"
|
||||
#include "pluginterfaces/vst/vsttypes.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpush.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
class IBStream;
|
||||
//------------------------------------------------------------------------
|
||||
namespace Vst {
|
||||
//------------------------------------------------------------------------
|
||||
/** Special UnitIDs for UnitInfo */
|
||||
static const UnitID kRootUnitId = 0; ///< identifier for the top level unit (root)
|
||||
static const UnitID kNoParentUnitId = -1; ///< used for the root unit which does not have a parent.
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Special ProgramListIDs for UnitInfo */
|
||||
static const ProgramListID kNoProgramListId = -1; ///< no programs are used in the unit.
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Basic Unit Description.
|
||||
\see IUnitInfo
|
||||
*/
|
||||
struct UnitInfo
|
||||
{
|
||||
UnitID id; ///< unit identifier
|
||||
UnitID parentUnitId; ///< identifier of parent unit (kNoParentUnitId: does not apply, this unit is the root)
|
||||
String128 name; ///< name, optional for the root component, required otherwise
|
||||
ProgramListID programListId; ///< id of program list used in unit (kNoProgramListId = no programs used in this unit)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Basic Program List Description.
|
||||
\see IUnitInfo
|
||||
*/
|
||||
struct ProgramListInfo
|
||||
{
|
||||
ProgramListID id; ///< program list identifier
|
||||
String128 name; ///< name of program list
|
||||
int32 programCount; ///< number of programs in this list
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Special programIndex value for IUnitHandler::notifyProgramListChange */
|
||||
static const int32 kAllProgramInvalid = -1; ///< all program information is invalid
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Host callback for unit support: Vst::IUnitHandler
|
||||
\ingroup vstIHost vst300
|
||||
- [host imp]
|
||||
- [extends IComponentHandler]
|
||||
- [released: 3.0.0]
|
||||
- [optional]
|
||||
|
||||
Host callback interface, used with IUnitInfo.
|
||||
Retrieve via queryInterface from IComponentHandler.
|
||||
|
||||
\see \ref vst3Units, IUnitInfo
|
||||
*/
|
||||
class IUnitHandler : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Notify host when a module is selected in plug-in GUI. */
|
||||
virtual tresult PLUGIN_API notifyUnitSelection (UnitID unitId) = 0;
|
||||
|
||||
/** Tell host that the plug-in controller changed a program list (rename, load, PitchName changes).
|
||||
\param listId is the specified program list ID to inform.
|
||||
\param programIndex : when kAllProgramInvalid, all program information is invalid, otherwise only the program of given index. */
|
||||
virtual tresult PLUGIN_API notifyProgramListChange (ProgramListID listId, int32 programIndex) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IUnitHandler, 0x4B5147F8, 0x4654486B, 0x8DAB30BA, 0x163A3C56)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Host callback for extended unit support: Vst::IUnitHandler2
|
||||
\ingroup vstIHost vst365
|
||||
- [host imp]
|
||||
- [extends IUnitHandler]
|
||||
- [released: 3.6.5]
|
||||
- [optional]
|
||||
|
||||
Host callback interface, used with IUnitInfo.
|
||||
Retrieve via queryInterface from IComponentHandler.
|
||||
|
||||
The plug-in has the possibility to inform the host with notifyUnitByBusChange that something has
|
||||
changed in the bus - unit assignment, the host then has to recall IUnitInfo::getUnitByBus in order
|
||||
to get the new relations between busses and unit.
|
||||
|
||||
\see \ref vst3Units, IUnitHandler
|
||||
*/
|
||||
class IUnitHandler2 : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Tell host that assignment Unit-Bus defined by IUnitInfo::getUnitByBus has changed. */
|
||||
virtual tresult PLUGIN_API notifyUnitByBusChange () = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IUnitHandler2, 0xF89F8CDF, 0x699E4BA5, 0x96AAC9A4, 0x81452B01)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Edit controller extension to describe the plug-in structure: Vst::IUnitInfo
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [extends IEditController]
|
||||
- [released: 3.0.0]
|
||||
- [optional]
|
||||
|
||||
IUnitInfo describes the internal structure of the plug-in.
|
||||
- The root unit is the component itself, so getUnitCount must return 1 at least.
|
||||
- The root unit id has to be 0 (kRootUnitId).
|
||||
- Each unit can reference one program list - this reference must not change.
|
||||
- Each unit, using a program list, references one program of the list.
|
||||
|
||||
\see \ref vst3Units, IUnitHandler
|
||||
*/
|
||||
class IUnitInfo : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns the flat count of units. */
|
||||
virtual int32 PLUGIN_API getUnitCount () = 0;
|
||||
|
||||
/** Gets UnitInfo for a given index in the flat list of unit. */
|
||||
virtual tresult PLUGIN_API getUnitInfo (int32 unitIndex, UnitInfo& info /*out*/) = 0;
|
||||
|
||||
/** Component intern program structure. */
|
||||
/** Gets the count of Program List. */
|
||||
virtual int32 PLUGIN_API getProgramListCount () = 0;
|
||||
|
||||
/** Gets for a given index the Program List Info. */
|
||||
virtual tresult PLUGIN_API getProgramListInfo (int32 listIndex, ProgramListInfo& info /*out*/) = 0;
|
||||
|
||||
/** Gets for a given program list ID and program index its program name. */
|
||||
virtual tresult PLUGIN_API getProgramName (ProgramListID listId, int32 programIndex, String128 name /*out*/) = 0;
|
||||
|
||||
/** Gets for a given program list ID, program index and attributeId the associated attribute value. */
|
||||
virtual tresult PLUGIN_API getProgramInfo (ProgramListID listId, int32 programIndex,
|
||||
CString attributeId /*in*/, String128 attributeValue /*out*/) = 0;
|
||||
|
||||
/** Returns kResultTrue if the given program index of a given program list ID supports PitchNames. */
|
||||
virtual tresult PLUGIN_API hasProgramPitchNames (ProgramListID listId, int32 programIndex) = 0;
|
||||
|
||||
/** Gets the PitchName for a given program list ID, program index and pitch.
|
||||
If PitchNames are changed the plug-in should inform the host with IUnitHandler::notifyProgramListChange. */
|
||||
virtual tresult PLUGIN_API getProgramPitchName (ProgramListID listId, int32 programIndex,
|
||||
int16 midiPitch, String128 name /*out*/) = 0;
|
||||
|
||||
// units selection --------------------
|
||||
/** Gets the current selected unit. */
|
||||
virtual UnitID PLUGIN_API getSelectedUnit () = 0;
|
||||
|
||||
/** Sets a new selected unit. */
|
||||
virtual tresult PLUGIN_API selectUnit (UnitID unitId) = 0;
|
||||
|
||||
/** Gets the according unit if there is an unambiguous relation between a channel or a bus and a unit.
|
||||
This method mainly is intended to find out which unit is related to a given MIDI input channel. */
|
||||
virtual tresult PLUGIN_API getUnitByBus (MediaType type, BusDirection dir, int32 busIndex,
|
||||
int32 channel, UnitID& unitId /*out*/) = 0;
|
||||
|
||||
/** Receives a preset data stream.
|
||||
- If the component supports program list data (IProgramListData), the destination of the data
|
||||
stream is the program specified by list-Id and program index (first and second parameter)
|
||||
- If the component supports unit data (IUnitData), the destination is the unit specified by the first
|
||||
parameter - in this case parameter programIndex is < 0). */
|
||||
virtual tresult PLUGIN_API setUnitProgramData (int32 listOrUnitId, int32 programIndex, IBStream* data) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IUnitInfo, 0x3D4BD6B5, 0x913A4FD2, 0xA886E768, 0xA5EB92C1)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Component extension to access program list data: Vst::IProgramListData
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [extends IComponent]
|
||||
- [released: 3.0.0]
|
||||
- [optional]
|
||||
|
||||
A component can support program list data via this interface or/and
|
||||
unit preset data (IUnitData).
|
||||
|
||||
\see IUnitData, \ref vst3MultitimbralPrograms
|
||||
*/
|
||||
class IProgramListData : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns kResultTrue if the given Program List ID supports Program Data. */
|
||||
virtual tresult PLUGIN_API programDataSupported (ProgramListID listId) = 0;
|
||||
|
||||
/** Gets for a given program list ID and program index the program Data. */
|
||||
virtual tresult PLUGIN_API getProgramData (ProgramListID listId, int32 programIndex, IBStream* data) = 0;
|
||||
|
||||
/** Sets for a given program list ID and program index a program Data. */
|
||||
virtual tresult PLUGIN_API setProgramData (ProgramListID listId, int32 programIndex, IBStream* data) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IProgramListData, 0x8683B01F, 0x7B354F70, 0xA2651DEC, 0x353AF4FF)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Component extension to access unit data: Vst::IUnitData
|
||||
\ingroup vstIPlug vst300
|
||||
- [plug imp]
|
||||
- [extends IComponent]
|
||||
- [released: 3.0.0]
|
||||
- [optional]
|
||||
|
||||
A component can support unit preset data via this interface or
|
||||
program list data (IProgramListData).
|
||||
|
||||
\see \ref vst3ProgramLists
|
||||
*/
|
||||
class IUnitData : public FUnknown
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
/** Returns kResultTrue if the specified unit supports export and import of preset data. */
|
||||
virtual tresult PLUGIN_API unitDataSupported (UnitID unitID) = 0;
|
||||
|
||||
/** Gets the preset data for the specified unit. */
|
||||
virtual tresult PLUGIN_API getUnitData (UnitID unitId, IBStream* data) = 0;
|
||||
|
||||
/** Sets the preset data for the specified unit. */
|
||||
virtual tresult PLUGIN_API setUnitData (UnitID unitId, IBStream* data) = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const FUID iid;
|
||||
};
|
||||
|
||||
DECLARE_CLASS_IID (IUnitData, 0x6C389611, 0xD391455D, 0xB870B833, 0x94A0EFDD)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#include "pluginterfaces/base/falignpop.h"
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/vstpshpack4.h
|
||||
// Created by : Steinberg, 05/2010
|
||||
// Description : This file turns 4 Bytes packing of structures on. The file
|
||||
// pluginterfaces/base/falignpop.h is the complement to this file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
#if defined __BORLANDC__
|
||||
#pragma -a4
|
||||
#else
|
||||
#if (_MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
|
||||
#pragma warning(disable:4103)
|
||||
#endif
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,159 +0,0 @@
|
|||
//------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Interfaces
|
||||
// Filename : pluginterfaces/vst/vsttypes.h
|
||||
// Created by : Steinberg, 12/2005
|
||||
// Description : Common Defines
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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/base/fstrdefs.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
//------------------------------------------------------------------------
|
||||
/** VST 3 SDK Version */
|
||||
#ifndef kVstVersionString
|
||||
#define kVstVersionString "VST 3.7.12" ///< SDK version for PClassInfo2
|
||||
#endif
|
||||
|
||||
#define kVstVersionMajor 3
|
||||
#define kVstVersionMinor 7
|
||||
#define kVstVersionSub 12
|
||||
|
||||
#define VST_VERSION ((kVstVersionMajor << 16) | (kVstVersionMinor << 8) | kVstVersionSub)
|
||||
|
||||
// Versions History which allows to write such code:
|
||||
// #if VST_VERSION >= VST_3_6_5_VERSION
|
||||
#define VST_3_7_12_VERSION 0x03070C
|
||||
#define VST_3_7_11_VERSION 0x03070B
|
||||
#define VST_3_7_10_VERSION 0x03070A
|
||||
#define VST_3_7_9_VERSION 0x030709
|
||||
#define VST_3_7_8_VERSION 0x030708
|
||||
#define VST_3_7_7_VERSION 0x030707
|
||||
#define VST_3_7_6_VERSION 0x030706
|
||||
#define VST_3_7_5_VERSION 0x030705
|
||||
#define VST_3_7_4_VERSION 0x030704
|
||||
#define VST_3_7_3_VERSION 0x030703
|
||||
#define VST_3_7_2_VERSION 0x030702
|
||||
#define VST_3_7_1_VERSION 0x030701
|
||||
#define VST_3_7_0_VERSION 0x030700
|
||||
#define VST_3_6_14_VERSION 0x03060E
|
||||
#define VST_3_6_13_VERSION 0x03060D
|
||||
#define VST_3_6_12_VERSION 0x03060C
|
||||
#define VST_3_6_11_VERSION 0x03060B
|
||||
#define VST_3_6_10_VERSION 0x03060A
|
||||
#define VST_3_6_9_VERSION 0x030609
|
||||
#define VST_3_6_8_VERSION 0x030608
|
||||
#define VST_3_6_7_VERSION 0x030607
|
||||
#define VST_3_6_6_VERSION 0x030606
|
||||
#define VST_3_6_5_VERSION 0x030605
|
||||
#define VST_3_6_0_VERSION 0x030600
|
||||
#define VST_3_5_0_VERSION 0x030500
|
||||
#define VST_3_1_0_VERSION 0x030100
|
||||
#define VST_3_0_0_VERSION 0x030000
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** \defgroup vst3typedef VST 3 Data Types */
|
||||
/*@{*/
|
||||
//------------------------------------------------------------------------
|
||||
// String Types
|
||||
//------------------------------------------------------------------------
|
||||
typedef char16 TChar; ///< UTF-16 character
|
||||
typedef TChar String128[128]; ///< 128 character UTF-16 string
|
||||
typedef const char8* CString; ///< C-String
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// General
|
||||
//------------------------------------------------------------------------
|
||||
typedef int32 MediaType; ///< media type (audio/event)
|
||||
typedef int32 BusDirection; ///< bus direction (in/out)
|
||||
typedef int32 BusType; ///< bus type (main/aux)
|
||||
typedef int32 IoMode; ///< I/O mode (see \ref vst3IoMode)
|
||||
typedef int32 UnitID; ///< unit identifier
|
||||
|
||||
typedef double ParamValue; ///< parameter value type: normalized value => [0.0, 1.0]
|
||||
typedef uint32 ParamID; ///< parameter identifier: value in range [0, 0x7FFFFFFF].
|
||||
/// The range [0x80000000, 0xFFFFFFFF], is reserved for host application.
|
||||
|
||||
typedef int32 ProgramListID; ///< program list identifier
|
||||
typedef int16 CtrlNumber; ///< MIDI controller number (see \ref ControllerNumbers for allowed values)
|
||||
|
||||
typedef double TQuarterNotes; ///< time expressed in quarter notes
|
||||
typedef int64 TSamples; ///< time expressed in audio samples
|
||||
|
||||
typedef uint32 ColorSpec; ///< color defining by 4 component ARGB value (Alpha/Red/Green/Blue)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const ParamID kNoParamId = 0xFFFFFFFF; ///< default for uninitialized parameter ID
|
||||
static const ParamID kMinParamId = 0; ///< value min for a parameter ID
|
||||
static const ParamID kMaxParamId = 0x7FFFFFFF; ///< value max for a parameter ID
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Audio Types
|
||||
//------------------------------------------------------------------------
|
||||
typedef float Sample32; ///< 32-bit precision audio sample
|
||||
typedef double Sample64; ///< 64-bit precision audio sample
|
||||
typedef double SampleRate; ///< sample rate
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Speaker Arrangements Types
|
||||
//------------------------------------------------------------------------
|
||||
typedef uint64 SpeakerArrangement; ///< Bitset of speakers
|
||||
typedef uint64 Speaker; ///< Bit for one speaker
|
||||
|
||||
/*@}*/
|
||||
|
||||
static SMTG_CONSTEXPR const FIDString SDKVersionString = kVstVersionString;
|
||||
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersionMajor = kVstVersionMajor;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersionMinor = kVstVersionMinor;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersionSub = kVstVersionSub;
|
||||
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion =
|
||||
((SDKVersionMajor << 16) | (SDKVersionMinor << 8) | SDKVersionSub);
|
||||
|
||||
// Versions History which allows to write such code:
|
||||
// if constexpr (SDKVersion >= SDKVersion_3_6_5) { ... }
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_12 = VST_3_7_12_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_11 = VST_3_7_11_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_10 = VST_3_7_10_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_9 = VST_3_7_9_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_8 = VST_3_7_8_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_7 = VST_3_7_7_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_6 = VST_3_7_6_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_5 = VST_3_7_5_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_4 = VST_3_7_4_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_3 = VST_3_7_3_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_2 = VST_3_7_2_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_1 = VST_3_7_1_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_0 = VST_3_7_0_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_14 = VST_3_6_14_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_13 = VST_3_6_13_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_12 = VST_3_6_12_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_11 = VST_3_6_11_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_10 = VST_3_6_10_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_9 = VST_3_6_9_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_8 = VST_3_6_8_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_7 = VST_3_6_7_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_6 = VST_3_6_6_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_5 = VST_3_6_5_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_6_0 = VST_3_6_0_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_5_0 = VST_3_5_0_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_1_0 = VST_3_1_0_VERSION;
|
||||
static SMTG_CONSTEXPR const uint32 SDKVersion_3_0_0 = VST_3_0_0_VERSION;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Welcome to VST 3 SDK public_sdk
|
||||
|
||||
Here are located:
|
||||
|
||||
- helper classes implementing **VST 3** Interfaces
|
||||
- samples of **VST 3** Hosting and **VST 3** plug-ins
|
||||
- **AAX** Wrapper
|
||||
- **AU** Wrapper
|
||||
- **AUv3** Wrapper
|
||||
- InterAppAudio
|
||||
|
||||
## License & Usage guidelines
|
||||
|
||||
More details are found at [VST 3 SDK public_sdk License](https://forums.steinberg.net/t/vst-3-sdk-public-sdk-license/695592)
|
||||
|
||||
----
|
||||
Return to [VST 3 SDK](https://github.com/steinbergmedia/vst3sdk)
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/common/commonstringconvert.cpp
|
||||
// Created by : Steinberg, 07/2024
|
||||
// Description : c++11 unicode string convert functions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "commonstringconvert.h"
|
||||
|
||||
#include <codecvt>
|
||||
#include <istream>
|
||||
#include <locale>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace StringConvert {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
#define USE_WCHAR_AS_UTF16TYPE
|
||||
using UTF16Type = wchar_t;
|
||||
#else
|
||||
using UTF16Type = char16_t;
|
||||
#endif
|
||||
|
||||
using Converter = std::wstring_convert<std::codecvt_utf8_utf16<UTF16Type>, UTF16Type>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Converter& converter ()
|
||||
{
|
||||
static Converter conv;
|
||||
return conv;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // anonymous
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::u16string convert (const std::string& utf8Str)
|
||||
{
|
||||
#if defined(USE_WCHAR_AS_UTF16TYPE)
|
||||
auto wstr = converter ().from_bytes (utf8Str);
|
||||
return {wstr.data (), wstr.data () + wstr.size ()};
|
||||
#else
|
||||
return converter ().from_bytes (utf8Str);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string convert (const std::u16string& str)
|
||||
{
|
||||
return converter ().to_bytes (reinterpret_cast<const UTF16Type*> (str.data ()),
|
||||
reinterpret_cast<const UTF16Type*> (str.data () + str.size ()));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string convert (const char* str, uint32_t max)
|
||||
{
|
||||
std::string result;
|
||||
if (str)
|
||||
{
|
||||
result.reserve (max);
|
||||
for (uint32_t i = 0; i < max; ++i, ++str)
|
||||
{
|
||||
if (*str == 0)
|
||||
break;
|
||||
result += *str;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // StringConvert
|
||||
} // Steinberg
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : stringconvert
|
||||
// Filename : public.sdk/source/common/commonstringconvert.h
|
||||
// Created by : Steinberg, 07/2024
|
||||
// Description : read file routine
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace StringConvert {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* convert an UTF-8 string to an UTF-16 string
|
||||
*
|
||||
* @param utf8Str UTF-8 string
|
||||
*
|
||||
* @return UTF-16 string
|
||||
*/
|
||||
std::u16string convert (const std::string& utf8Str);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* convert an UTF-16 string to an UTF-8 string
|
||||
*
|
||||
* @param str UTF-16 string
|
||||
*
|
||||
* @return UTF-8 string
|
||||
*/
|
||||
std::string convert (const std::u16string& str);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* convert a ASCII string buffer to an UTF-8 string
|
||||
*
|
||||
* @param str ASCII string buffer
|
||||
* @param max maximum characters in str
|
||||
*
|
||||
* @return UTF-8 string
|
||||
*/
|
||||
std::string convert (const char* str, uint32_t max);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/**
|
||||
* convert a number to an UTF-16 string
|
||||
*
|
||||
* @param value number
|
||||
*
|
||||
* @return UTF-16 string
|
||||
*/
|
||||
template <typename NumberT>
|
||||
std::u16string toString (NumberT value)
|
||||
{
|
||||
auto u8str = std::to_string (value);
|
||||
return StringConvert::convert (u8str);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace StringConvert
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : Common Classes
|
||||
// Filename : public.sdk/source/common/memorystream.cpp
|
||||
// Created by : Steinberg, 03/2008
|
||||
// Description : IBStream Implementation for memory blocks
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "memorystream.h"
|
||||
#include "pluginterfaces/base/futils.h"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_FUNKNOWN_METHODS (MemoryStream, IBStream, IBStream::iid)
|
||||
static const TSize kMemGrowAmount = 4096;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryStream::MemoryStream (void* data, TSize length)
|
||||
: memory ((char*)data)
|
||||
, memorySize (length)
|
||||
, size (length)
|
||||
, cursor (0)
|
||||
, ownMemory (false)
|
||||
, allocationError (false)
|
||||
{
|
||||
FUNKNOWN_CTOR
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryStream::MemoryStream ()
|
||||
: memory (nullptr)
|
||||
, memorySize (0)
|
||||
, size (0)
|
||||
, cursor (0)
|
||||
, ownMemory (true)
|
||||
, allocationError (false)
|
||||
{
|
||||
FUNKNOWN_CTOR
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
MemoryStream::~MemoryStream ()
|
||||
{
|
||||
if (ownMemory && memory)
|
||||
::free (memory);
|
||||
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MemoryStream::read (void* data, int32 numBytes, int32* numBytesRead)
|
||||
{
|
||||
if (memory == nullptr)
|
||||
{
|
||||
if (allocationError)
|
||||
return kOutOfMemory;
|
||||
numBytes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Does read exceed size ?
|
||||
if (cursor + numBytes > size)
|
||||
{
|
||||
int32 maxBytes = int32 (size - cursor);
|
||||
|
||||
// Has length become zero or negative ?
|
||||
if (maxBytes <= 0)
|
||||
{
|
||||
cursor = size;
|
||||
numBytes = 0;
|
||||
}
|
||||
else
|
||||
numBytes = maxBytes;
|
||||
}
|
||||
|
||||
if (numBytes)
|
||||
{
|
||||
memcpy (data, &memory[cursor], static_cast<size_t> (numBytes));
|
||||
cursor += numBytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (numBytesRead)
|
||||
*numBytesRead = numBytes;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MemoryStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
|
||||
{
|
||||
if (allocationError)
|
||||
return kOutOfMemory;
|
||||
if (buffer == nullptr)
|
||||
return kInvalidArgument;
|
||||
|
||||
// Does write exceed size ?
|
||||
TSize requiredSize = cursor + numBytes;
|
||||
if (requiredSize > size)
|
||||
{
|
||||
if (requiredSize > memorySize)
|
||||
setSize (requiredSize);
|
||||
else
|
||||
size = requiredSize;
|
||||
}
|
||||
|
||||
// Copy data
|
||||
if (memory && cursor >= 0 && numBytes > 0)
|
||||
{
|
||||
memcpy (&memory[cursor], buffer, static_cast<size_t> (numBytes));
|
||||
// Update cursor
|
||||
cursor += numBytes;
|
||||
}
|
||||
else
|
||||
numBytes = 0;
|
||||
|
||||
if (numBytesWritten)
|
||||
*numBytesWritten = numBytes;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MemoryStream::seek (int64 pos, int32 mode, int64* result)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case kIBSeekSet:
|
||||
cursor = pos;
|
||||
break;
|
||||
case kIBSeekCur:
|
||||
cursor = cursor + pos;
|
||||
break;
|
||||
case kIBSeekEnd:
|
||||
cursor = size + pos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ownMemory == false)
|
||||
if (cursor > memorySize)
|
||||
cursor = memorySize;
|
||||
|
||||
if (result)
|
||||
*result = cursor;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API MemoryStream::tell (int64* pos)
|
||||
{
|
||||
if (!pos)
|
||||
return kInvalidArgument;
|
||||
|
||||
*pos = cursor;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
TSize MemoryStream::getSize () const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void MemoryStream::setSize (TSize s)
|
||||
{
|
||||
if (s <= 0)
|
||||
{
|
||||
if (ownMemory && memory)
|
||||
free (memory);
|
||||
|
||||
memory = nullptr;
|
||||
memorySize = 0;
|
||||
size = 0;
|
||||
cursor = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
TSize newMemorySize = (((Max (memorySize, s) - 1) / kMemGrowAmount) + 1) * kMemGrowAmount;
|
||||
if (newMemorySize == memorySize)
|
||||
{
|
||||
size = s;
|
||||
return;
|
||||
}
|
||||
|
||||
if (memory && ownMemory == false)
|
||||
{
|
||||
allocationError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ownMemory = true;
|
||||
char* newMemory = nullptr;
|
||||
|
||||
if (memory)
|
||||
{
|
||||
newMemory = (char*)realloc (memory, (size_t)newMemorySize);
|
||||
if (newMemory == nullptr && newMemorySize > 0)
|
||||
{
|
||||
newMemory = (char*)malloc ((size_t)newMemorySize);
|
||||
if (newMemory)
|
||||
{
|
||||
memcpy (newMemory, memory, (size_t)Min (newMemorySize, memorySize));
|
||||
free (memory);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
newMemory = (char*)malloc ((size_t)newMemorySize);
|
||||
|
||||
if (newMemory == nullptr)
|
||||
{
|
||||
if (newMemorySize > 0)
|
||||
allocationError = true;
|
||||
|
||||
memory = nullptr;
|
||||
memorySize = 0;
|
||||
size = 0;
|
||||
cursor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory = newMemory;
|
||||
memorySize = newMemorySize;
|
||||
size = s;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
char* MemoryStream::getData () const
|
||||
{
|
||||
return memory;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
char* MemoryStream::detachData ()
|
||||
{
|
||||
if (ownMemory)
|
||||
{
|
||||
char* result = memory;
|
||||
memory = nullptr;
|
||||
memorySize = 0;
|
||||
size = 0;
|
||||
cursor = 0;
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool MemoryStream::truncate ()
|
||||
{
|
||||
if (ownMemory == false)
|
||||
return false;
|
||||
|
||||
if (memorySize == size)
|
||||
return true;
|
||||
|
||||
memorySize = size;
|
||||
|
||||
if (memorySize == 0)
|
||||
{
|
||||
if (memory)
|
||||
{
|
||||
free (memory);
|
||||
memory = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memory)
|
||||
{
|
||||
char* newMemory = (char*)realloc (memory, (size_t)memorySize);
|
||||
if (newMemory)
|
||||
memory = newMemory;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool MemoryStream::truncateToCursor ()
|
||||
{
|
||||
size = cursor;
|
||||
return truncate ();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : Common Classes
|
||||
// Filename : public.sdk/source/common/memorystream.h
|
||||
// Created by : Steinberg, 03/2008
|
||||
// Description : IBStream Implementation for memory blocks
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/base/ibstream.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Memory based Stream for IBStream implementation (using malloc).
|
||||
\ingroup sdkBase
|
||||
*/
|
||||
class MemoryStream : public IBStream
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
MemoryStream ();
|
||||
MemoryStream (void* memory, TSize memorySize); ///< reuse a given memory without getting ownership
|
||||
virtual ~MemoryStream ();
|
||||
|
||||
//---IBStream---------------------------------------
|
||||
tresult PLUGIN_API read (void* buffer, int32 numBytes, int32* numBytesRead) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API seek (int64 pos, int32 mode, int64* result) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API tell (int64* pos) SMTG_OVERRIDE;
|
||||
|
||||
TSize getSize () const; ///< returns the current memory size
|
||||
void setSize (TSize size); ///< set the memory size, a realloc will occur if memory already used
|
||||
char* getData () const; ///< returns the memory pointer
|
||||
char* detachData (); ///< returns the memory pointer and give up ownership
|
||||
bool truncate (); ///< realloc to the current use memory size if needed
|
||||
bool truncateToCursor (); ///< truncate memory at current cursor position
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
protected:
|
||||
char* memory; // memory block
|
||||
TSize memorySize; // size of the memory block
|
||||
TSize size; // size of the stream
|
||||
int64 cursor; // stream pointer
|
||||
bool ownMemory; // stream has allocated memory itself
|
||||
bool allocationError; // stream invalid
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : Common Base Classes
|
||||
// Filename : public.sdk/source/common/pluginview.cpp
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Plug-In View Implementation
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "pluginview.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// CPluginView implementation
|
||||
//------------------------------------------------------------------------
|
||||
CPluginView::CPluginView (const ViewRect* _rect)
|
||||
: rect (0, 0, 0, 0)
|
||||
{
|
||||
if (_rect)
|
||||
rect = *_rect;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CPluginView::~CPluginView ()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API CPluginView::isPlatformTypeSupported (FIDString /*type*/)
|
||||
{
|
||||
return kNotImplemented;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API CPluginView::attached (void* parent, FIDString /*type*/)
|
||||
{
|
||||
systemWindow = parent;
|
||||
|
||||
attachedToParent ();
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API CPluginView::removed ()
|
||||
{
|
||||
systemWindow = nullptr;
|
||||
|
||||
removedFromParent ();
|
||||
return kResultOk;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API CPluginView::onSize (ViewRect* newSize)
|
||||
{
|
||||
if (newSize)
|
||||
rect = *newSize;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
tresult PLUGIN_API CPluginView::getSize (ViewRect* size)
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
*size = rect;
|
||||
return kResultTrue;
|
||||
}
|
||||
return kInvalidArgument;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : SDK Core
|
||||
//
|
||||
// Category : Common Base Classes
|
||||
// Filename : public.sdk/source/common/pluginview.h
|
||||
// Created by : Steinberg, 01/2004
|
||||
// Description : Plug-In View Implementation
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/gui/iplugview.h"
|
||||
#include "base/source/fobject.h"
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Plug-In view default implementation.
|
||||
\ingroup sdkBase
|
||||
Can be used as base class for an IPlugView implementation.
|
||||
*/
|
||||
class CPluginView : public FObject, public IPlugView
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
CPluginView (const ViewRect* rect = nullptr);
|
||||
~CPluginView () SMTG_OVERRIDE;
|
||||
|
||||
/** Returns its current frame rectangle. */
|
||||
const ViewRect& getRect () const { return rect; }
|
||||
|
||||
/** Sets a new frame rectangle. */
|
||||
void setRect (const ViewRect& r) { rect = r; }
|
||||
|
||||
/** Checks if this view is attached to its parent view. */
|
||||
bool isAttached () const { return systemWindow != nullptr; }
|
||||
|
||||
/** Calls when this view will be attached to its parent view. */
|
||||
virtual void attachedToParent () {}
|
||||
|
||||
/** Calls when this view will be removed from its parent view. */
|
||||
virtual void removedFromParent () {}
|
||||
|
||||
//---from IPlugView-------
|
||||
tresult PLUGIN_API isPlatformTypeSupported (FIDString type) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API attached (void* parent, FIDString type) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API removed () SMTG_OVERRIDE;
|
||||
|
||||
tresult PLUGIN_API onWheel (float /*distance*/) SMTG_OVERRIDE { return kResultFalse; }
|
||||
tresult PLUGIN_API onKeyDown (char16 /*key*/, int16 /*keyMsg*/,
|
||||
int16 /*modifiers*/) SMTG_OVERRIDE
|
||||
{
|
||||
return kResultFalse;
|
||||
}
|
||||
tresult PLUGIN_API onKeyUp (char16 /*key*/, int16 /*keyMsg*/, int16 /*modifiers*/) SMTG_OVERRIDE
|
||||
{
|
||||
return kResultFalse;
|
||||
}
|
||||
tresult PLUGIN_API getSize (ViewRect* size) SMTG_OVERRIDE;
|
||||
tresult PLUGIN_API onSize (ViewRect* newSize) SMTG_OVERRIDE;
|
||||
|
||||
tresult PLUGIN_API onFocus (TBool /*state*/) SMTG_OVERRIDE { return kResultFalse; }
|
||||
tresult PLUGIN_API setFrame (IPlugFrame* frame) SMTG_OVERRIDE
|
||||
{
|
||||
plugFrame = frame;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API canResize () SMTG_OVERRIDE { return kResultFalse; }
|
||||
tresult PLUGIN_API checkSizeConstraint (ViewRect* /*rect*/) SMTG_OVERRIDE
|
||||
{
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//---Interface------
|
||||
OBJ_METHODS (CPluginView, FObject)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (IPlugView)
|
||||
END_DEFINE_INTERFACES (FObject)
|
||||
REFCOUNT_METHODS (FObject)
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
ViewRect rect;
|
||||
void* systemWindow {nullptr};
|
||||
IPtr<IPlugFrame> plugFrame;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
// Flags : clang-format SMTGSequencer
|
||||
//
|
||||
// Category : readfile
|
||||
// Filename : public.sdk/source/common/readfile.cpp
|
||||
// Created by : Steinberg, 3/2023
|
||||
// Description : read file routine
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "readfile.h"
|
||||
|
||||
#include "pluginterfaces/base/fplatform.h"
|
||||
|
||||
#if SMTG_OS_WINDOWS
|
||||
#include "commonstringconvert.h"
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#if !SMTG_CPP17
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string readFile (const std::string& path)
|
||||
{
|
||||
#if SMTG_OS_WINDOWS
|
||||
auto u16Path = StringConvert::convert (path);
|
||||
std::ifstream file (reinterpret_cast<const wchar_t*> (u16Path.data ()),
|
||||
std::ios_base::in | std::ios_base::binary);
|
||||
#else
|
||||
std::ifstream file (path, std::ios_base::in | std::ios_base::binary);
|
||||
#endif
|
||||
if (!file.is_open ())
|
||||
return {};
|
||||
|
||||
#if SMTG_CPP17
|
||||
auto size = file.seekg (0, std::ios_base::end).tellg ();
|
||||
file.seekg (0, std::ios_base::beg);
|
||||
std::string data;
|
||||
data.resize (size);
|
||||
file.read (data.data (), data.size ());
|
||||
if (file.bad ())
|
||||
return {};
|
||||
return data;
|
||||
#else
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf ();
|
||||
return buffer.str ();
|
||||
#endif // SMTG_CPP17
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Flags : clang-format SMTGSequencer
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : readfile
|
||||
// Filename : public.sdk/source/common/readfile.h
|
||||
// Created by : Steinberg, 3/2023
|
||||
// Description : read file routine
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Steinberg {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Reads entire file content
|
||||
\ingroup sdkBase
|
||||
|
||||
Returns entire file content at the given path
|
||||
\endcode
|
||||
*/
|
||||
std::string readFile (const std::string& path);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,342 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/hostclasses.cpp
|
||||
// Created by : Steinberg, 03/05/2008.
|
||||
// Description : VST 3 hostclasses, example impl. for IHostApplication, IAttributeList and IMessage
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "hostclasses.h"
|
||||
#include "public.sdk/source/vst/utility/stringconvert.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HostApplication::HostApplication ()
|
||||
{
|
||||
FUNKNOWN_CTOR
|
||||
|
||||
mPlugInterfaceSupport = owned (new PlugInterfaceSupport);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostApplication::getName (String128 name)
|
||||
{
|
||||
return StringConvert::convert ("My VST3 HostApplication", name) ? kResultTrue :
|
||||
kInternalError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostApplication::createInstance (TUID cid, TUID _iid, void** obj)
|
||||
{
|
||||
if (FUnknownPrivate::iidEqual (cid, IMessage::iid) &&
|
||||
FUnknownPrivate::iidEqual (_iid, IMessage::iid))
|
||||
{
|
||||
*obj = new HostMessage;
|
||||
return kResultTrue;
|
||||
}
|
||||
if (FUnknownPrivate::iidEqual (cid, IAttributeList::iid) &&
|
||||
FUnknownPrivate::iidEqual (_iid, IAttributeList::iid))
|
||||
{
|
||||
if (auto al = HostAttributeList::make ())
|
||||
{
|
||||
*obj = al.take ();
|
||||
return kResultTrue;
|
||||
}
|
||||
return kOutOfMemory;
|
||||
}
|
||||
*obj = nullptr;
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostApplication::queryInterface (const char* _iid, void** obj)
|
||||
{
|
||||
QUERY_INTERFACE (_iid, obj, FUnknown::iid, IHostApplication)
|
||||
QUERY_INTERFACE (_iid, obj, IHostApplication::iid, IHostApplication)
|
||||
|
||||
if (mPlugInterfaceSupport && mPlugInterfaceSupport->queryInterface (iid, obj) == kResultTrue)
|
||||
return kResultOk;
|
||||
|
||||
*obj = nullptr;
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32 PLUGIN_API HostApplication::addRef ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32 PLUGIN_API HostApplication::release ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_FUNKNOWN_METHODS (HostMessage, IMessage, IMessage::iid)
|
||||
//-----------------------------------------------------------------------------
|
||||
HostMessage::HostMessage () {FUNKNOWN_CTOR}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HostMessage::~HostMessage () noexcept
|
||||
{
|
||||
setMessageID (nullptr);
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* PLUGIN_API HostMessage::getMessageID ()
|
||||
{
|
||||
return messageId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PLUGIN_API HostMessage::setMessageID (const char* mid)
|
||||
{
|
||||
if (messageId)
|
||||
delete[] messageId;
|
||||
messageId = nullptr;
|
||||
if (mid)
|
||||
{
|
||||
size_t len = strlen (mid) + 1;
|
||||
messageId = new char[len];
|
||||
strcpy (messageId, mid);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IAttributeList* PLUGIN_API HostMessage::getAttributes ()
|
||||
{
|
||||
if (!attributeList)
|
||||
attributeList = HostAttributeList::make ();
|
||||
return attributeList;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
struct HostAttributeList::Attribute
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
kUninitialized,
|
||||
kInteger,
|
||||
kFloat,
|
||||
kString,
|
||||
kBinary
|
||||
};
|
||||
Attribute () = default;
|
||||
|
||||
Attribute (int64 value) : type (Type::kInteger) { v.intValue = value; }
|
||||
Attribute (double value) : type (Type::kFloat) { v.floatValue = value; }
|
||||
/* size is in code unit (count of TChar) */
|
||||
Attribute (const TChar* value, uint32 sizeInCodeUnit)
|
||||
: size (sizeInCodeUnit), type (Type::kString)
|
||||
{
|
||||
v.stringValue = new TChar[sizeInCodeUnit];
|
||||
memcpy (v.stringValue, value, sizeInCodeUnit * sizeof (TChar));
|
||||
}
|
||||
Attribute (const void* value, uint32 sizeInBytes) : size (sizeInBytes), type (Type::kBinary)
|
||||
{
|
||||
v.binaryValue = new char[sizeInBytes];
|
||||
memcpy (v.binaryValue, value, sizeInBytes);
|
||||
}
|
||||
Attribute (Attribute&& o) { *this = std::move (o); }
|
||||
Attribute& operator= (Attribute&& o)
|
||||
{
|
||||
v = o.v;
|
||||
size = o.size;
|
||||
type = o.type;
|
||||
o.size = 0;
|
||||
o.type = Type::kUninitialized;
|
||||
o.v = {};
|
||||
return *this;
|
||||
}
|
||||
~Attribute () noexcept
|
||||
{
|
||||
if (size)
|
||||
delete[] v.binaryValue;
|
||||
}
|
||||
|
||||
int64 intValue () const { return v.intValue; }
|
||||
double floatValue () const { return v.floatValue; }
|
||||
/* sizeInCodeUnit is in code unit (count of TChar) */
|
||||
const TChar* stringValue (uint32& sizeInCodeUnit)
|
||||
{
|
||||
sizeInCodeUnit = size;
|
||||
return v.stringValue;
|
||||
}
|
||||
const void* binaryValue (uint32& sizeInBytes)
|
||||
{
|
||||
sizeInBytes = size;
|
||||
return v.binaryValue;
|
||||
}
|
||||
|
||||
Type getType () const { return type; }
|
||||
|
||||
private:
|
||||
union v
|
||||
{
|
||||
int64 intValue;
|
||||
double floatValue;
|
||||
TChar* stringValue;
|
||||
char* binaryValue;
|
||||
} v;
|
||||
uint32 size {0};
|
||||
Type type {Type::kUninitialized};
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_FUNKNOWN_METHODS (HostAttributeList, IAttributeList, IAttributeList::iid)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IPtr<IAttributeList> HostAttributeList::make ()
|
||||
{
|
||||
return owned (new HostAttributeList);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HostAttributeList::HostAttributeList () {FUNKNOWN_CTOR}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HostAttributeList::~HostAttributeList () noexcept
|
||||
{
|
||||
FUNKNOWN_DTOR
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::setInt (AttrID aid, int64 value)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
list[aid] = Attribute (value);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::getInt (AttrID aid, int64& value)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
auto it = list.find (aid);
|
||||
if (it != list.end () && it->second.getType () == Attribute::Type::kInteger)
|
||||
{
|
||||
value = it->second.intValue ();
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::setFloat (AttrID aid, double value)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
list[aid] = Attribute (value);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::getFloat (AttrID aid, double& value)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
auto it = list.find (aid);
|
||||
if (it != list.end () && it->second.getType () == Attribute::Type::kFloat)
|
||||
{
|
||||
value = it->second.floatValue ();
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::setString (AttrID aid, const TChar* string)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
// + 1 for the null-terminate
|
||||
auto length = tstrlen (string) + 1;
|
||||
list[aid] = Attribute (string, length);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::getString (AttrID aid, TChar* string, uint32 sizeInBytes)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
auto it = list.find (aid);
|
||||
if (it != list.end () && it->second.getType () == Attribute::Type::kString)
|
||||
{
|
||||
uint32 sizeInCodeUnit = 0;
|
||||
const TChar* _string = it->second.stringValue (sizeInCodeUnit);
|
||||
memcpy (string, _string, std::min<uint32> (sizeInCodeUnit * sizeof (TChar), sizeInBytes));
|
||||
return kResultTrue;
|
||||
}
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::setBinary (AttrID aid, const void* data, uint32 sizeInBytes)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
list[aid] = Attribute (data, sizeInBytes);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API HostAttributeList::getBinary (AttrID aid, const void*& data, uint32& sizeInBytes)
|
||||
{
|
||||
if (!aid)
|
||||
return kInvalidArgument;
|
||||
auto it = list.find (aid);
|
||||
if (it != list.end () && it->second.getType () == Attribute::Type::kBinary)
|
||||
{
|
||||
data = it->second.binaryValue (sizeInBytes);
|
||||
return kResultTrue;
|
||||
}
|
||||
sizeInBytes = 0;
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/hostclasses.h
|
||||
// Created by : Steinberg, 03/05/2008.
|
||||
// Description : VST 3 hostclasses, example impl. for IHostApplication, IAttributeList and IMessage
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "public.sdk/source/vst/hosting/pluginterfacesupport.h"
|
||||
#include "pluginterfaces/vst/ivsthostapplication.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Implementation's example of IHostApplication.
|
||||
\ingroup hostingBase
|
||||
*/
|
||||
class HostApplication : public IHostApplication
|
||||
{
|
||||
public:
|
||||
HostApplication ();
|
||||
virtual ~HostApplication () noexcept {FUNKNOWN_DTOR}
|
||||
|
||||
//--- IHostApplication ---------------
|
||||
tresult PLUGIN_API getName (String128 name) override;
|
||||
tresult PLUGIN_API createInstance (TUID cid, TUID _iid, void** obj) override;
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
PlugInterfaceSupport* getPlugInterfaceSupport () const { return mPlugInterfaceSupport; }
|
||||
|
||||
private:
|
||||
IPtr<PlugInterfaceSupport> mPlugInterfaceSupport;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Example, ready to use implementation of IAttributeList.
|
||||
\ingroup hostingBase
|
||||
*/
|
||||
class HostAttributeList final : public IAttributeList
|
||||
{
|
||||
public:
|
||||
/** make a new attribute list instance */
|
||||
static IPtr<IAttributeList> make ();
|
||||
|
||||
tresult PLUGIN_API setInt (AttrID aid, int64 value) override;
|
||||
tresult PLUGIN_API getInt (AttrID aid, int64& value) override;
|
||||
tresult PLUGIN_API setFloat (AttrID aid, double value) override;
|
||||
tresult PLUGIN_API getFloat (AttrID aid, double& value) override;
|
||||
tresult PLUGIN_API setString (AttrID aid, const TChar* string) override;
|
||||
tresult PLUGIN_API getString (AttrID aid, TChar* string, uint32 sizeInBytes) override;
|
||||
tresult PLUGIN_API setBinary (AttrID aid, const void* data, uint32 sizeInBytes) override;
|
||||
tresult PLUGIN_API getBinary (AttrID aid, const void*& data, uint32& sizeInBytes) override;
|
||||
|
||||
virtual ~HostAttributeList () noexcept;
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
private:
|
||||
HostAttributeList ();
|
||||
|
||||
struct Attribute;
|
||||
std::map<std::string, Attribute> list;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Example implementation of IMessage.
|
||||
\ingroup hostingBase
|
||||
*/
|
||||
class HostMessage final : public IMessage
|
||||
{
|
||||
public:
|
||||
HostMessage ();
|
||||
virtual ~HostMessage () noexcept;
|
||||
|
||||
const char* PLUGIN_API getMessageID () override;
|
||||
void PLUGIN_API setMessageID (const char* messageID) override;
|
||||
IAttributeList* PLUGIN_API getAttributes () override;
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
private:
|
||||
char* messageId {nullptr};
|
||||
IPtr<IAttributeList> attributeList;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
|
|
@ -1,347 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/module.cpp
|
||||
// Created by : Steinberg, 08/2016
|
||||
// Description : hosting module classes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "module.h"
|
||||
#include "public.sdk/source/vst/utility/stringconvert.h"
|
||||
#include "public.sdk/source/vst/utility/optional.h"
|
||||
#include "pluginterfaces/base/funknownimpl.h"
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VST3 {
|
||||
namespace Hosting {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FactoryInfo::FactoryInfo (PFactoryInfo&& other) noexcept
|
||||
{
|
||||
*this = std::move (other);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FactoryInfo& FactoryInfo::operator= (FactoryInfo&& other) noexcept
|
||||
{
|
||||
info = std::move (other.info);
|
||||
other.info = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FactoryInfo& FactoryInfo::operator= (PFactoryInfo&& other) noexcept
|
||||
{
|
||||
info = std::move (other);
|
||||
other = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string FactoryInfo::vendor () const noexcept
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
return StringConvert::convert (info.vendor, PFactoryInfo::kNameSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string FactoryInfo::url () const noexcept
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
return StringConvert::convert (info.url, PFactoryInfo::kURLSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string FactoryInfo::email () const noexcept
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
return StringConvert::convert (info.email, PFactoryInfo::kEmailSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Steinberg::int32 FactoryInfo::flags () const noexcept
|
||||
{
|
||||
return info.flags;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FactoryInfo::classesDiscardable () const noexcept
|
||||
{
|
||||
return (info.flags & PFactoryInfo::kClassesDiscardable) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FactoryInfo::licenseCheck () const noexcept
|
||||
{
|
||||
return (info.flags & PFactoryInfo::kLicenseCheck) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool FactoryInfo::componentNonDiscardable () const noexcept
|
||||
{
|
||||
return (info.flags & PFactoryInfo::kComponentNonDiscardable) != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
PluginFactory::PluginFactory (const PluginFactoryPtr& factory) noexcept : factory (factory)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void PluginFactory::setHostContext (Steinberg::FUnknown* context) const noexcept
|
||||
{
|
||||
if (auto f = Steinberg::FUnknownPtr<Steinberg::IPluginFactory3> (factory))
|
||||
f->setHostContext (context);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
FactoryInfo PluginFactory::info () const noexcept
|
||||
{
|
||||
Steinberg::PFactoryInfo i;
|
||||
factory->getFactoryInfo (&i);
|
||||
return FactoryInfo (std::move (i));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
uint32_t PluginFactory::classCount () const noexcept
|
||||
{
|
||||
auto count = factory->countClasses ();
|
||||
assert (count >= 0);
|
||||
return static_cast<uint32_t> (count);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
PluginFactory::ClassInfos PluginFactory::classInfos () const noexcept
|
||||
{
|
||||
auto count = classCount ();
|
||||
Optional<FactoryInfo> factoryInfo;
|
||||
ClassInfos classes;
|
||||
classes.reserve (count);
|
||||
auto f3 = Steinberg::U::cast<Steinberg::IPluginFactory3> (factory);
|
||||
auto f2 = Steinberg::U::cast<Steinberg::IPluginFactory2> (factory);
|
||||
Steinberg::PClassInfo ci;
|
||||
Steinberg::PClassInfo2 ci2;
|
||||
Steinberg::PClassInfoW ci3;
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (f3 && f3->getClassInfoUnicode (i, &ci3) == Steinberg::kResultTrue)
|
||||
classes.emplace_back (ci3);
|
||||
else if (f2 && f2->getClassInfo2 (i, &ci2) == Steinberg::kResultTrue)
|
||||
classes.emplace_back (ci2);
|
||||
else if (factory->getClassInfo (i, &ci) == Steinberg::kResultTrue)
|
||||
classes.emplace_back (ci);
|
||||
auto& classInfo = classes.back ();
|
||||
if (classInfo.vendor ().empty ())
|
||||
{
|
||||
if (!factoryInfo)
|
||||
factoryInfo = Optional<FactoryInfo> (info ());
|
||||
classInfo.get ().vendor = factoryInfo->vendor ();
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
const UID& ClassInfo::ID () const noexcept
|
||||
{
|
||||
return data.classID;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int32_t ClassInfo::cardinality () const noexcept
|
||||
{
|
||||
return data.cardinality;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const std::string& ClassInfo::category () const noexcept
|
||||
{
|
||||
return data.category;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const std::string& ClassInfo::name () const noexcept
|
||||
{
|
||||
return data.name;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const std::string& ClassInfo::vendor () const noexcept
|
||||
{
|
||||
return data.vendor;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const std::string& ClassInfo::version () const noexcept
|
||||
{
|
||||
return data.version;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const std::string& ClassInfo::sdkVersion () const noexcept
|
||||
{
|
||||
return data.sdkVersion;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const ClassInfo::SubCategories& ClassInfo::subCategories () const noexcept
|
||||
{
|
||||
return data.subCategories;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Steinberg::uint32 ClassInfo::classFlags () const noexcept
|
||||
{
|
||||
return data.classFlags;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ClassInfo::ClassInfo (const PClassInfo& info) noexcept
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
data.classID = info.cid;
|
||||
data.cardinality = info.cardinality;
|
||||
data.category = StringConvert::convert (info.category, PClassInfo::kCategorySize);
|
||||
data.name = StringConvert::convert (info.name, PClassInfo::kNameSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ClassInfo::ClassInfo (const PClassInfo2& info) noexcept
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
data.classID = info.cid;
|
||||
data.cardinality = info.cardinality;
|
||||
data.category = StringConvert::convert (info.category, PClassInfo::kCategorySize);
|
||||
data.name = StringConvert::convert (info.name, PClassInfo::kNameSize);
|
||||
data.vendor = StringConvert::convert (info.vendor, PClassInfo2::kVendorSize);
|
||||
data.version = StringConvert::convert (info.version, PClassInfo2::kVersionSize);
|
||||
data.sdkVersion = StringConvert::convert (info.sdkVersion, PClassInfo2::kVersionSize);
|
||||
parseSubCategories (
|
||||
StringConvert::convert (info.subCategories, PClassInfo2::kSubCategoriesSize));
|
||||
data.classFlags = info.classFlags;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ClassInfo::ClassInfo (const PClassInfoW& info) noexcept
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
data.classID = info.cid;
|
||||
data.cardinality = info.cardinality;
|
||||
data.category = StringConvert::convert (info.category, PClassInfo::kCategorySize);
|
||||
data.name = StringConvert::convert (info.name, PClassInfo::kNameSize);
|
||||
data.vendor = StringConvert::convert (info.vendor, PClassInfo2::kVendorSize);
|
||||
data.version = StringConvert::convert (info.version, PClassInfo2::kVersionSize);
|
||||
data.sdkVersion = StringConvert::convert (info.sdkVersion, PClassInfo2::kVersionSize);
|
||||
parseSubCategories (
|
||||
StringConvert::convert (info.subCategories, PClassInfo2::kSubCategoriesSize));
|
||||
data.classFlags = info.classFlags;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void ClassInfo::parseSubCategories (const std::string& str) noexcept
|
||||
{
|
||||
std::stringstream stream (str);
|
||||
std::string item;
|
||||
while (std::getline (stream, item, '|'))
|
||||
data.subCategories.emplace_back (std::move (item));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::string ClassInfo::subCategoriesString () const noexcept
|
||||
{
|
||||
std::string result;
|
||||
if (data.subCategories.empty ())
|
||||
return result;
|
||||
result = data.subCategories[0];
|
||||
for (auto index = 1u; index < data.subCategories.size (); ++index)
|
||||
result += "|" + data.subCategories[index];
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
std::pair<size_t, size_t> rangeOfScaleFactor (const std::string& name)
|
||||
{
|
||||
auto result = std::make_pair (std::string::npos, std::string::npos);
|
||||
size_t xIndex = name.find_last_of ('x');
|
||||
if (xIndex == std::string::npos)
|
||||
return result;
|
||||
|
||||
size_t indicatorIndex = name.find_last_of ('_');
|
||||
if (indicatorIndex == std::string::npos)
|
||||
return result;
|
||||
if (xIndex < indicatorIndex)
|
||||
return result;
|
||||
result.first = indicatorIndex + 1;
|
||||
result.second = xIndex;
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // anonymous
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<double> Module::Snapshot::decodeScaleFactor (const std::string& name)
|
||||
{
|
||||
auto range = rangeOfScaleFactor (name);
|
||||
if (range.first == std::string::npos || range.second == std::string::npos)
|
||||
return {};
|
||||
std::string tmp (name.data () + range.first, range.second - range.first);
|
||||
std::istringstream sstream (tmp);
|
||||
sstream.imbue (std::locale::classic ());
|
||||
sstream.precision (static_cast<std::streamsize> (3));
|
||||
double result;
|
||||
sstream >> result;
|
||||
return Optional<double> (result);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<UID> Module::Snapshot::decodeUID (const std::string& filename)
|
||||
{
|
||||
if (filename.size () < 45)
|
||||
return {};
|
||||
if (filename.find ("_snapshot") != 32)
|
||||
return {};
|
||||
auto uidStr = filename.substr (0, 32);
|
||||
return UID::fromString (uidStr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Hosting
|
||||
} // VST3
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/module.h
|
||||
// Created by : Steinberg, 08/2016
|
||||
// Description : hosting module classes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../utility/uid.h"
|
||||
#include "pluginterfaces/base/ipluginbase.h"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VST3 {
|
||||
namespace Hosting {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class FactoryInfo
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
using PFactoryInfo = Steinberg::PFactoryInfo;
|
||||
|
||||
FactoryInfo () noexcept {}
|
||||
~FactoryInfo () noexcept {}
|
||||
FactoryInfo (const FactoryInfo&) noexcept = default;
|
||||
FactoryInfo (PFactoryInfo&&) noexcept;
|
||||
FactoryInfo (FactoryInfo&&) noexcept = default;
|
||||
FactoryInfo& operator= (const FactoryInfo&) noexcept = default;
|
||||
FactoryInfo& operator= (FactoryInfo&&) noexcept;
|
||||
FactoryInfo& operator= (PFactoryInfo&&) noexcept;
|
||||
|
||||
std::string vendor () const noexcept;
|
||||
std::string url () const noexcept;
|
||||
std::string email () const noexcept;
|
||||
Steinberg::int32 flags () const noexcept;
|
||||
bool classesDiscardable () const noexcept;
|
||||
bool licenseCheck () const noexcept;
|
||||
bool componentNonDiscardable () const noexcept;
|
||||
|
||||
PFactoryInfo& get () noexcept { return info; }
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
PFactoryInfo info {};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class ClassInfo
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
using SubCategories = std::vector<std::string>;
|
||||
using PClassInfo = Steinberg::PClassInfo;
|
||||
using PClassInfo2 = Steinberg::PClassInfo2;
|
||||
using PClassInfoW = Steinberg::PClassInfoW;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
ClassInfo () noexcept {}
|
||||
explicit ClassInfo (const PClassInfo& info) noexcept;
|
||||
explicit ClassInfo (const PClassInfo2& info) noexcept;
|
||||
explicit ClassInfo (const PClassInfoW& info) noexcept;
|
||||
ClassInfo (const ClassInfo&) = default;
|
||||
ClassInfo& operator= (const ClassInfo&) = default;
|
||||
ClassInfo (ClassInfo&&) = default;
|
||||
ClassInfo& operator= (ClassInfo&&) = default;
|
||||
|
||||
const UID& ID () const noexcept;
|
||||
int32_t cardinality () const noexcept;
|
||||
const std::string& category () const noexcept;
|
||||
const std::string& name () const noexcept;
|
||||
const std::string& vendor () const noexcept;
|
||||
const std::string& version () const noexcept;
|
||||
const std::string& sdkVersion () const noexcept;
|
||||
const SubCategories& subCategories () const noexcept;
|
||||
std::string subCategoriesString () const noexcept;
|
||||
Steinberg::uint32 classFlags () const noexcept;
|
||||
|
||||
struct Data
|
||||
{
|
||||
UID classID;
|
||||
int32_t cardinality;
|
||||
std::string category;
|
||||
std::string name;
|
||||
std::string vendor;
|
||||
std::string version;
|
||||
std::string sdkVersion;
|
||||
SubCategories subCategories;
|
||||
Steinberg::uint32 classFlags = 0;
|
||||
};
|
||||
|
||||
Data& get () noexcept { return data; }
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
void parseSubCategories (const std::string& str) noexcept;
|
||||
Data data {};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class PluginFactory
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
using ClassInfos = std::vector<ClassInfo>;
|
||||
using PluginFactoryPtr = Steinberg::IPtr<Steinberg::IPluginFactory>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
explicit PluginFactory (const PluginFactoryPtr& factory) noexcept;
|
||||
|
||||
void setHostContext (Steinberg::FUnknown* context) const noexcept;
|
||||
|
||||
FactoryInfo info () const noexcept;
|
||||
uint32_t classCount () const noexcept;
|
||||
ClassInfos classInfos () const noexcept;
|
||||
|
||||
template <typename T>
|
||||
Steinberg::IPtr<T> createInstance (const UID& classID) const noexcept;
|
||||
|
||||
const PluginFactoryPtr& get () const noexcept { return factory; }
|
||||
//------------------------------------------------------------------------
|
||||
private:
|
||||
PluginFactoryPtr factory;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
class Module
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
struct Snapshot
|
||||
{
|
||||
struct ImageDesc
|
||||
{
|
||||
double scaleFactor {1.};
|
||||
std::string path;
|
||||
};
|
||||
UID uid;
|
||||
std::vector<ImageDesc> images;
|
||||
|
||||
static Optional<double> decodeScaleFactor (const std::string& path);
|
||||
static Optional<UID> decodeUID (const std::string& filename);
|
||||
};
|
||||
|
||||
using Ptr = std::shared_ptr<Module>;
|
||||
using PathList = std::vector<std::string>;
|
||||
using SnapshotList = std::vector<Snapshot>;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static Ptr create (const std::string& path, std::string& errorDescription);
|
||||
static PathList getModulePaths ();
|
||||
static SnapshotList getSnapshots (const std::string& modulePath);
|
||||
/** get the path to the module info json file if it exists */
|
||||
static Optional<std::string> getModuleInfoPath (const std::string& modulePath);
|
||||
|
||||
const std::string& getName () const noexcept { return name; }
|
||||
const std::string& getPath () const noexcept { return path; }
|
||||
const PluginFactory& getFactory () const noexcept { return factory; }
|
||||
bool isBundle () const noexcept { return hasBundleStructure; }
|
||||
//------------------------------------------------------------------------
|
||||
protected:
|
||||
virtual ~Module () noexcept = default;
|
||||
virtual bool load (const std::string& path, std::string& errorDescription) = 0;
|
||||
|
||||
PluginFactory factory {nullptr};
|
||||
std::string name;
|
||||
std::string path;
|
||||
bool hasBundleStructure {true};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline Steinberg::IPtr<T> PluginFactory::createInstance (const UID& classID) const noexcept
|
||||
{
|
||||
T* obj = nullptr;
|
||||
if (factory->createInstance (classID.data (), T::iid, reinterpret_cast<void**> (&obj)) ==
|
||||
Steinberg::kResultTrue)
|
||||
return Steinberg::owned (obj);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Hosting
|
||||
} // VST3
|
||||
|
|
@ -1,372 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/module_linux.cpp
|
||||
// Created by : Steinberg, 08/2016
|
||||
// Description : hosting module classes (linux implementation)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "module.h"
|
||||
#include "public.sdk/source/vst/utility/optional.h"
|
||||
#include "public.sdk/source/vst/utility/stringconvert.h"
|
||||
|
||||
#include "pluginterfaces/base/funknownimpl.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if SMTG_CPP17
|
||||
|
||||
#if __has_include(<filesystem>)
|
||||
#define USE_EXPERIMENTAL_FS 0
|
||||
#elif __has_include(<experimental/filesystem>)
|
||||
#define USE_EXPERIMENTAL_FS 1
|
||||
#endif
|
||||
|
||||
#else // !SMTG_CPP17
|
||||
|
||||
#define USE_EXPERIMENTAL_FS 1
|
||||
|
||||
#endif // SMTG_CPP17
|
||||
|
||||
#if USE_EXPERIMENTAL_FS == 1
|
||||
|
||||
#include <experimental/filesystem>
|
||||
namespace filesystem = std::experimental::filesystem;
|
||||
|
||||
#else // USE_EXPERIMENTAL_FS == 0
|
||||
|
||||
#include <filesystem>
|
||||
namespace filesystem = std::filesystem;
|
||||
|
||||
#endif // USE_EXPERIMENTAL_FS
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
extern "C" {
|
||||
using ModuleEntryFunc = bool (PLUGIN_API*) (void*);
|
||||
using ModuleExitFunc = bool (PLUGIN_API*) ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VST3 {
|
||||
namespace Hosting {
|
||||
|
||||
using Path = filesystem::path;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<std::string> getCurrentMachineName ()
|
||||
{
|
||||
struct utsname unameData;
|
||||
|
||||
int res = uname (&unameData);
|
||||
if (res != 0)
|
||||
return {};
|
||||
|
||||
return {unameData.machine};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<Path> getApplicationPath ()
|
||||
{
|
||||
std::string appPath = "";
|
||||
|
||||
pid_t pid = getpid ();
|
||||
char buf[10];
|
||||
sprintf (buf, "%d", pid);
|
||||
std::string _link = "/proc/";
|
||||
_link.append (buf);
|
||||
_link.append ("/exe");
|
||||
char proc[1024];
|
||||
int ch = readlink (_link.c_str (), proc, 1024);
|
||||
if (ch == -1)
|
||||
return {};
|
||||
|
||||
proc[ch] = 0;
|
||||
appPath = proc;
|
||||
std::string::size_type t = appPath.find_last_of ("/");
|
||||
appPath = appPath.substr (0, t);
|
||||
|
||||
return Path {appPath};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class LinuxModule : public Module
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
T getFunctionPointer (const char* name)
|
||||
{
|
||||
return reinterpret_cast<T> (dlsym (mModule, name));
|
||||
}
|
||||
|
||||
~LinuxModule () override
|
||||
{
|
||||
factory = PluginFactory (nullptr);
|
||||
|
||||
if (mModule)
|
||||
{
|
||||
if (auto moduleExit = getFunctionPointer<ModuleExitFunc> ("ModuleExit"))
|
||||
moduleExit ();
|
||||
|
||||
dlclose (mModule);
|
||||
}
|
||||
}
|
||||
|
||||
static Optional<Path> getSOPath (const std::string& inPath)
|
||||
{
|
||||
Path modulePath {inPath};
|
||||
if (!filesystem::is_directory (modulePath))
|
||||
return {};
|
||||
|
||||
auto stem = modulePath.stem ();
|
||||
|
||||
modulePath /= "Contents";
|
||||
if (!filesystem::is_directory (modulePath))
|
||||
return {};
|
||||
|
||||
// use the Machine Hardware Name (from uname cmd-line) as prefix for "-linux"
|
||||
auto machine = getCurrentMachineName ();
|
||||
if (!machine)
|
||||
return {};
|
||||
|
||||
modulePath /= *machine + "-linux";
|
||||
if (!filesystem::is_directory (modulePath))
|
||||
return {};
|
||||
|
||||
stem.replace_extension (".so");
|
||||
modulePath /= stem;
|
||||
return Optional<Path> (std::move (modulePath));
|
||||
}
|
||||
|
||||
bool load (const std::string& inPath, std::string& errorDescription) override
|
||||
{
|
||||
auto modulePath = getSOPath (inPath);
|
||||
if (!modulePath)
|
||||
{
|
||||
errorDescription = inPath + " is not a module directory.";
|
||||
return false;
|
||||
}
|
||||
|
||||
mModule = dlopen (reinterpret_cast<const char*> (modulePath->generic_string ().data ()),
|
||||
RTLD_LAZY);
|
||||
if (!mModule)
|
||||
{
|
||||
errorDescription = "dlopen failed.\n";
|
||||
errorDescription += dlerror ();
|
||||
return false;
|
||||
}
|
||||
// ModuleEntry is mandatory
|
||||
auto moduleEntry = getFunctionPointer<ModuleEntryFunc> ("ModuleEntry");
|
||||
if (!moduleEntry)
|
||||
{
|
||||
errorDescription =
|
||||
"The shared library does not export the required 'ModuleEntry' function";
|
||||
return false;
|
||||
}
|
||||
// ModuleExit is mandatory
|
||||
auto moduleExit = getFunctionPointer<ModuleExitFunc> ("ModuleExit");
|
||||
if (!moduleExit)
|
||||
{
|
||||
errorDescription =
|
||||
"The shared library does not export the required 'ModuleExit' function";
|
||||
return false;
|
||||
}
|
||||
auto factoryProc = getFunctionPointer<GetFactoryProc> ("GetPluginFactory");
|
||||
if (!factoryProc)
|
||||
{
|
||||
errorDescription =
|
||||
"The shared library does not export the required 'GetPluginFactory' function";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!moduleEntry (mModule))
|
||||
{
|
||||
errorDescription = "Calling 'ModuleEntry' failed";
|
||||
return false;
|
||||
}
|
||||
auto f = Steinberg::U::cast<Steinberg::IPluginFactory> (owned (factoryProc ()));
|
||||
if (!f)
|
||||
{
|
||||
errorDescription = "Calling 'GetPluginFactory' returned nullptr";
|
||||
return false;
|
||||
}
|
||||
factory = PluginFactory (f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* mModule {nullptr};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void findFilesWithExt (const std::string& path, const std::string& ext, Module::PathList& pathList,
|
||||
bool recursive = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (auto& p : filesystem::directory_iterator (path))
|
||||
{
|
||||
if (p.path ().extension () == ext)
|
||||
{
|
||||
pathList.push_back (p.path ().generic_string ());
|
||||
}
|
||||
else if (recursive && p.status ().type () == filesystem::file_type::directory)
|
||||
{
|
||||
findFilesWithExt (p.path (), ext, pathList);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void findModules (const std::string& path, Module::PathList& pathList)
|
||||
{
|
||||
findFilesWithExt (path, ".vst3", pathList);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // anonymous
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::Ptr Module::create (const std::string& path, std::string& errorDescription)
|
||||
{
|
||||
auto _module = std::make_shared<LinuxModule> ();
|
||||
if (_module->load (path, errorDescription))
|
||||
{
|
||||
_module->path = path;
|
||||
auto it = std::find_if (path.rbegin (), path.rend (),
|
||||
[] (const std::string::value_type& c) { return c == '/'; });
|
||||
if (it != path.rend ())
|
||||
_module->name = {it.base (), path.end ()};
|
||||
return _module;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::PathList Module::getModulePaths ()
|
||||
{
|
||||
/* VST3 component locations on linux :
|
||||
* User privately installed : $HOME/.vst3/
|
||||
* Distribution installed : /usr/lib/vst3/
|
||||
* Locally installed : /usr/local/lib/vst3/
|
||||
* Application : /$APPFOLDER/vst3/
|
||||
*/
|
||||
|
||||
const auto systemPaths = {"/usr/lib/vst3/", "/usr/local/lib/vst3/"};
|
||||
|
||||
PathList list;
|
||||
if (auto homeDir = getenv ("HOME"))
|
||||
{
|
||||
filesystem::path homePath (homeDir);
|
||||
homePath /= ".vst3";
|
||||
findModules (homePath.generic_string (), list);
|
||||
}
|
||||
for (auto path : systemPaths)
|
||||
findModules (path, list);
|
||||
|
||||
// application level
|
||||
auto appPath = getApplicationPath ();
|
||||
if (appPath)
|
||||
{
|
||||
*appPath /= "vst3";
|
||||
findModules (appPath->generic_string (), list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::SnapshotList Module::getSnapshots (const std::string& modulePath)
|
||||
{
|
||||
SnapshotList result;
|
||||
filesystem::path path (modulePath);
|
||||
path /= "Contents";
|
||||
path /= "Resources";
|
||||
path /= "Snapshots";
|
||||
PathList pngList;
|
||||
findFilesWithExt (path, ".png", pngList, false);
|
||||
for (auto& png : pngList)
|
||||
{
|
||||
filesystem::path p (png);
|
||||
auto filename = p.filename ().generic_string ();
|
||||
auto uid = Snapshot::decodeUID (filename);
|
||||
if (!uid)
|
||||
continue;
|
||||
auto scaleFactor = 1.;
|
||||
if (auto decodedScaleFactor = Snapshot::decodeScaleFactor (filename))
|
||||
scaleFactor = *decodedScaleFactor;
|
||||
|
||||
Module::Snapshot::ImageDesc desc;
|
||||
desc.scaleFactor = scaleFactor;
|
||||
desc.path = std::move (png);
|
||||
bool found = false;
|
||||
for (auto& entry : result)
|
||||
{
|
||||
if (entry.uid != *uid)
|
||||
continue;
|
||||
found = true;
|
||||
entry.images.emplace_back (std::move (desc));
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
Module::Snapshot snapshot;
|
||||
snapshot.uid = *uid;
|
||||
snapshot.images.emplace_back (std::move (desc));
|
||||
result.emplace_back (std::move (snapshot));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<std::string> Module::getModuleInfoPath (const std::string& modulePath)
|
||||
{
|
||||
filesystem::path path (modulePath);
|
||||
path /= "Contents";
|
||||
path /= "Resources";
|
||||
path /= "moduleinfo.json";
|
||||
if (filesystem::exists (path))
|
||||
return {path.generic_string ()};
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Hosting
|
||||
} // VST3
|
||||
|
|
@ -1,395 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/module_mac.mm
|
||||
// Created by : Steinberg, 08/2016
|
||||
// Description : hosting module classes (macOS implementation)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#import "module.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error this file needs to be compiled with automatic reference counting enabled
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
extern "C" {
|
||||
typedef bool (*BundleEntryFunc) (CFBundleRef);
|
||||
typedef bool (*BundleExitFunc) ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VST3 {
|
||||
namespace Hosting {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
class CFPtr
|
||||
{
|
||||
public:
|
||||
inline CFPtr (const T& obj = nullptr) : obj (obj) {}
|
||||
inline CFPtr (CFPtr&& other) { *this = other; }
|
||||
inline ~CFPtr ()
|
||||
{
|
||||
if (obj)
|
||||
CFRelease (obj);
|
||||
}
|
||||
|
||||
inline CFPtr& operator= (CFPtr&& other)
|
||||
{
|
||||
obj = other.obj;
|
||||
other.obj = nullptr;
|
||||
return *this;
|
||||
}
|
||||
inline CFPtr& operator= (const T& o)
|
||||
{
|
||||
if (obj)
|
||||
CFRelease (obj);
|
||||
obj = o;
|
||||
return *this;
|
||||
}
|
||||
inline operator T () const { return obj; } // act as T
|
||||
private:
|
||||
CFPtr (const CFPtr& other) = delete;
|
||||
CFPtr& operator= (const CFPtr& other) = delete;
|
||||
|
||||
T obj = nullptr;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class MacModule : public Module
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
T getFunctionPointer (const char* name)
|
||||
{
|
||||
assert (bundle);
|
||||
CFPtr<CFStringRef> functionName (
|
||||
CFStringCreateWithCString (kCFAllocatorDefault, name, kCFStringEncodingASCII));
|
||||
return reinterpret_cast<T> (CFBundleGetFunctionPointerForName (bundle, functionName));
|
||||
}
|
||||
|
||||
bool loadInternal (const std::string& path, std::string& errorDescription)
|
||||
{
|
||||
CFPtr<CFURLRef> url (CFURLCreateFromFileSystemRepresentation (
|
||||
kCFAllocatorDefault, reinterpret_cast<const UInt8*> (path.data ()), path.length (),
|
||||
true));
|
||||
if (!url)
|
||||
return false;
|
||||
bundle = CFBundleCreate (kCFAllocatorDefault, url);
|
||||
CFErrorRef error = nullptr;
|
||||
if (!bundle || !CFBundleLoadExecutableAndReturnError (bundle, &error))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
CFPtr<CFStringRef> errorString (CFErrorCopyDescription (error));
|
||||
if (errorString)
|
||||
{
|
||||
auto stringLength = CFStringGetLength (errorString);
|
||||
auto maxSize =
|
||||
CFStringGetMaximumSizeForEncoding (stringLength, kCFStringEncodingUTF8);
|
||||
auto buffer = std::make_unique<char[]> (maxSize);
|
||||
if (CFStringGetCString (errorString, buffer.get (), maxSize,
|
||||
kCFStringEncodingUTF8))
|
||||
errorDescription = buffer.get ();
|
||||
CFRelease (error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorDescription = "Could not create Bundle for path: " + path;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// bundleEntry is mandatory
|
||||
auto bundleEntry = getFunctionPointer<BundleEntryFunc> ("bundleEntry");
|
||||
if (!bundleEntry)
|
||||
{
|
||||
errorDescription = "Bundle does not export the required 'bundleEntry' function";
|
||||
return false;
|
||||
}
|
||||
// bundleExit is mandatory
|
||||
auto bundleExit = getFunctionPointer<BundleExitFunc> ("bundleExit");
|
||||
if (!bundleExit)
|
||||
{
|
||||
errorDescription = "Bundle does not export the required 'bundleExit' function";
|
||||
return false;
|
||||
}
|
||||
auto factoryProc = getFunctionPointer<GetFactoryProc> ("GetPluginFactory");
|
||||
if (!factoryProc)
|
||||
{
|
||||
errorDescription = "Bundle does not export the required 'GetPluginFactory' function";
|
||||
return false;
|
||||
}
|
||||
if (!bundleEntry (bundle))
|
||||
{
|
||||
errorDescription = "Calling 'bundleEntry' failed";
|
||||
return false;
|
||||
}
|
||||
auto f = owned (factoryProc ());
|
||||
if (!f)
|
||||
{
|
||||
errorDescription = "Calling 'GetPluginFactory' returned nullptr";
|
||||
return false;
|
||||
}
|
||||
factory = PluginFactory (f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load (const std::string& path, std::string& errorDescription) override
|
||||
{
|
||||
if (!path.empty () && path[0] != '/')
|
||||
{
|
||||
auto buffer = std::make_unique<char[]> (PATH_MAX);
|
||||
auto workDir = getcwd (buffer.get (), PATH_MAX);
|
||||
if (workDir)
|
||||
{
|
||||
std::string wd (workDir);
|
||||
wd += "/";
|
||||
if (loadInternal (wd + path, errorDescription))
|
||||
{
|
||||
name = path;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return loadInternal (path, errorDescription);
|
||||
}
|
||||
|
||||
~MacModule () override
|
||||
{
|
||||
factory = PluginFactory (nullptr);
|
||||
|
||||
if (bundle)
|
||||
{
|
||||
if (auto bundleExit = getFunctionPointer<BundleExitFunc> ("bundleExit"))
|
||||
bundleExit ();
|
||||
}
|
||||
}
|
||||
|
||||
CFPtr<CFBundleRef> bundle;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void findModulesInDirectory (NSURL* dirUrl, Module::PathList& result)
|
||||
{
|
||||
dirUrl = [dirUrl URLByResolvingSymlinksInPath];
|
||||
if (!dirUrl)
|
||||
return;
|
||||
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager]
|
||||
enumeratorAtURL: dirUrl
|
||||
includingPropertiesForKeys:nil
|
||||
options:NSDirectoryEnumerationSkipsPackageDescendants
|
||||
errorHandler:nil];
|
||||
for (NSURL* url in enumerator)
|
||||
{
|
||||
if ([[[url lastPathComponent] pathExtension] isEqualToString:@"vst3"])
|
||||
{
|
||||
CFPtr<CFArrayRef> archs (
|
||||
CFBundleCopyExecutableArchitecturesForURL (static_cast<CFURLRef> (url)));
|
||||
if (archs)
|
||||
result.emplace_back ([url.path UTF8String]);
|
||||
}
|
||||
else
|
||||
{
|
||||
id resValue;
|
||||
if (![url getResourceValue:&resValue forKey:NSURLIsSymbolicLinkKey error:nil])
|
||||
continue;
|
||||
if (!static_cast<NSNumber*> (resValue).boolValue)
|
||||
continue;
|
||||
auto resolvedUrl = [url URLByResolvingSymlinksInPath];
|
||||
if (![resolvedUrl getResourceValue:&resValue forKey:NSURLIsDirectoryKey error:nil])
|
||||
continue;
|
||||
if (!static_cast<NSNumber*> (resValue).boolValue)
|
||||
continue;
|
||||
findModulesInDirectory (resolvedUrl, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void getModules (NSSearchPathDomainMask domain, Module::PathList& result)
|
||||
{
|
||||
NSURL* libraryUrl = [[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory
|
||||
inDomain:domain
|
||||
appropriateForURL:nil
|
||||
create:NO
|
||||
error:nil];
|
||||
if (libraryUrl == nil)
|
||||
return;
|
||||
NSURL* audioUrl = [libraryUrl URLByAppendingPathComponent:@"Audio"];
|
||||
if (audioUrl == nil)
|
||||
return;
|
||||
NSURL* plugInsUrl = [audioUrl URLByAppendingPathComponent:@"Plug-Ins"];
|
||||
if (plugInsUrl == nil)
|
||||
return;
|
||||
NSURL* vst3Url =
|
||||
[[plugInsUrl URLByAppendingPathComponent:@"VST3"] URLByResolvingSymlinksInPath];
|
||||
if (vst3Url == nil)
|
||||
return;
|
||||
findModulesInDirectory (vst3Url, result);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void getApplicationModules (Module::PathList& result)
|
||||
{
|
||||
auto bundle = CFBundleGetMainBundle ();
|
||||
if (!bundle)
|
||||
return;
|
||||
auto bundleUrl = static_cast<NSURL*> (CFBridgingRelease (CFBundleCopyBundleURL (bundle)));
|
||||
if (!bundleUrl)
|
||||
return;
|
||||
auto resUrl = [bundleUrl URLByAppendingPathComponent:@"Contents"];
|
||||
if (!resUrl)
|
||||
return;
|
||||
auto vst3Url = [resUrl URLByAppendingPathComponent:@"VST3"];
|
||||
if (!vst3Url)
|
||||
return;
|
||||
findModulesInDirectory (vst3Url, result);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void getModuleSnapshots (const std::string& path, Module::SnapshotList& result)
|
||||
{
|
||||
auto* nsString = [NSString stringWithUTF8String:path.data ()];
|
||||
if (!nsString)
|
||||
return;
|
||||
auto bundleUrl = [NSURL fileURLWithPath:nsString];
|
||||
if (!bundleUrl)
|
||||
return;
|
||||
auto urls = [NSBundle URLsForResourcesWithExtension:@"png"
|
||||
subdirectory:@"Snapshots"
|
||||
inBundleWithURL:bundleUrl];
|
||||
if (!urls || [urls count] == 0)
|
||||
return;
|
||||
|
||||
for (NSURL* url in urls)
|
||||
{
|
||||
std::string fullpath ([[url path] UTF8String]);
|
||||
std::string filename ([[[url path] lastPathComponent] UTF8String]);
|
||||
auto uid = Module::Snapshot::decodeUID (filename);
|
||||
if (!uid)
|
||||
continue;
|
||||
|
||||
auto scaleFactor = 1.;
|
||||
if (auto decodedScaleFactor = Module::Snapshot::decodeScaleFactor (filename))
|
||||
scaleFactor = *decodedScaleFactor;
|
||||
|
||||
Module::Snapshot::ImageDesc desc;
|
||||
desc.scaleFactor = scaleFactor;
|
||||
desc.path = std::move (fullpath);
|
||||
bool found = false;
|
||||
for (auto& entry : result)
|
||||
{
|
||||
if (entry.uid != *uid)
|
||||
continue;
|
||||
found = true;
|
||||
entry.images.emplace_back (std::move (desc));
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
Module::Snapshot snapshot;
|
||||
snapshot.uid = *uid;
|
||||
snapshot.images.emplace_back (std::move (desc));
|
||||
result.emplace_back (std::move (snapshot));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // anonymous
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::Ptr Module::create (const std::string& path, std::string& errorDescription)
|
||||
{
|
||||
auto module = std::make_shared<MacModule> ();
|
||||
if (module->load (path, errorDescription))
|
||||
{
|
||||
module->path = path;
|
||||
auto it = std::find_if (path.rbegin (), path.rend (),
|
||||
[] (const std::string::value_type& c) { return c == '/'; });
|
||||
if (it != path.rend ())
|
||||
module->name = {it.base (), path.end ()};
|
||||
return std::move (module);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::PathList Module::getModulePaths ()
|
||||
{
|
||||
PathList list;
|
||||
getModules (NSUserDomainMask, list);
|
||||
getModules (NSLocalDomainMask, list);
|
||||
// TODO getModules (NSNetworkDomainMask, list);
|
||||
getApplicationModules (list);
|
||||
return list;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::SnapshotList Module::getSnapshots (const std::string& modulePath)
|
||||
{
|
||||
SnapshotList list;
|
||||
getModuleSnapshots (modulePath, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<std::string> Module::getModuleInfoPath (const std::string& modulePath)
|
||||
{
|
||||
auto* nsString = [NSString stringWithUTF8String:modulePath.data ()];
|
||||
if (!nsString)
|
||||
return {};
|
||||
auto bundleUrl = [NSURL fileURLWithPath:nsString];
|
||||
if (!bundleUrl)
|
||||
return {};
|
||||
auto moduleInfoUrl = [NSBundle URLForResource:@"moduleinfo"
|
||||
withExtension:@"json"
|
||||
subdirectory:nullptr
|
||||
inBundleWithURL:bundleUrl];
|
||||
if (!moduleInfoUrl)
|
||||
return {};
|
||||
NSError* error = nil;
|
||||
if ([moduleInfoUrl checkResourceIsReachableAndReturnError:&error])
|
||||
return {std::string (moduleInfoUrl.fileSystemRepresentation)};
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Hosting
|
||||
} // VST3
|
||||
|
|
@ -1,668 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/module_win32.cpp
|
||||
// Created by : Steinberg, 08/2016
|
||||
// Description : hosting module classes (win32 implementation)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "module.h"
|
||||
#include "public.sdk/source/vst/utility/optional.h"
|
||||
#include "public.sdk/source/vst/utility/stringconvert.h"
|
||||
|
||||
#include "pluginterfaces/base/funknownimpl.h"
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#if SMTG_CPP17
|
||||
|
||||
#if __has_include(<filesystem>)
|
||||
#define USE_FILESYSTEM 1
|
||||
#elif __has_include(<experimental/filesystem>)
|
||||
#define USE_FILESYSTEM 0
|
||||
#endif
|
||||
|
||||
#else // !SMTG_CPP17
|
||||
|
||||
#define USE_FILESYSTEM 0
|
||||
|
||||
#endif // SMTG_CPP17
|
||||
|
||||
#if USE_FILESYSTEM == 1
|
||||
|
||||
#include <filesystem>
|
||||
namespace filesystem = std::filesystem;
|
||||
|
||||
#else // USE_FILESYSTEM == 0
|
||||
|
||||
// The <experimental/filesystem> header is deprecated. It is superseded by the C++17 <filesystem>
|
||||
// header. You can define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING to silence the
|
||||
// warning, otherwise the build will fail in VS2019 16.3.0
|
||||
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
|
||||
#include <experimental/filesystem>
|
||||
namespace filesystem = std::experimental::filesystem;
|
||||
|
||||
#endif // USE_FILESYSTEM
|
||||
|
||||
#pragma comment(lib, "Shell32")
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
extern "C" {
|
||||
using InitModuleFunc = bool (PLUGIN_API*) ();
|
||||
using ExitModuleFunc = bool (PLUGIN_API*) ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VST3 {
|
||||
namespace Hosting {
|
||||
|
||||
constexpr unsigned long kIPPathNameMax = 1024;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
#define USE_OLE !USE_FILESYSTEM
|
||||
|
||||
// for testing only
|
||||
#if 0 // DEVELOPMENT
|
||||
#define LOG_ENABLE 1
|
||||
#else
|
||||
#define LOG_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if SMTG_PLATFORM_64
|
||||
|
||||
#if SMTG_OS_WINDOWS_ARM
|
||||
|
||||
#if SMTG_CPU_ARM_64EC
|
||||
constexpr auto architectureString = "arm64ec-win";
|
||||
constexpr auto architectureX64String = "x86_64-win";
|
||||
#else // !SMTG_CPU_ARM_64EC
|
||||
constexpr auto architectureString = "arm64-win";
|
||||
#endif // SMTG_CPU_ARM_64EC
|
||||
|
||||
constexpr auto architectureArm64XString = "arm64x-win";
|
||||
|
||||
#else // !SMTG_OS_WINDOWS_ARM
|
||||
constexpr auto architectureString = "x86_64-win";
|
||||
#endif // SMTG_OS_WINDOWS_ARM
|
||||
|
||||
#else // !SMTG_PLATFORM_64
|
||||
|
||||
#if SMTG_OS_WINDOWS_ARM
|
||||
constexpr auto architectureString = "arm-win";
|
||||
#else // !SMTG_OS_WINDOWS_ARM
|
||||
constexpr auto architectureString = "x86-win";
|
||||
#endif // SMTG_OS_WINDOWS_ARM
|
||||
|
||||
#endif // SMTG_PLATFORM_64
|
||||
|
||||
#if USE_OLE
|
||||
//------------------------------------------------------------------------
|
||||
struct Ole
|
||||
{
|
||||
static Ole& instance ()
|
||||
{
|
||||
static Ole gInstance;
|
||||
return gInstance;
|
||||
}
|
||||
|
||||
private:
|
||||
Ole () { OleInitialize (nullptr); }
|
||||
~Ole () { OleUninitialize (); }
|
||||
};
|
||||
#endif // USE_OLE
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
class Win32Module : public Module
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
T getFunctionPointer (const char* name)
|
||||
{
|
||||
return reinterpret_cast<T> (GetProcAddress (mModule, name));
|
||||
}
|
||||
|
||||
~Win32Module () override
|
||||
{
|
||||
factory = PluginFactory (nullptr);
|
||||
|
||||
if (mModule)
|
||||
{
|
||||
// ExitDll is optional
|
||||
if (auto dllExit = getFunctionPointer<ExitModuleFunc> ("ExitDll"))
|
||||
dllExit ();
|
||||
|
||||
FreeLibrary ((HMODULE)mModule);
|
||||
}
|
||||
}
|
||||
|
||||
//--- -----------------------------------------------------------------------
|
||||
HINSTANCE loadAsPackage (const std::string& inPath, std::string& errorDescription,
|
||||
const char* archString = architectureString)
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
|
||||
filesystem::path p (inPath);
|
||||
auto filename = p.filename ();
|
||||
p /= "Contents";
|
||||
p /= archString;
|
||||
p /= filename;
|
||||
auto wideStr = StringConvert::convert (p.string ());
|
||||
HINSTANCE instance = LoadLibraryW (reinterpret_cast<LPCWSTR> (wideStr.data ()));
|
||||
#if SMTG_CPU_ARM_64EC
|
||||
if (instance == nullptr)
|
||||
instance = loadAsPackage (inPath, errorDescription, architectureArm64XString);
|
||||
if (instance == nullptr)
|
||||
instance = loadAsPackage (inPath, errorDescription, architectureX64String);
|
||||
#endif
|
||||
if (instance == nullptr)
|
||||
getLastError (p.string (), errorDescription);
|
||||
return instance;
|
||||
}
|
||||
|
||||
//--- -----------------------------------------------------------------------
|
||||
HINSTANCE loadAsDll (const std::string& inPath, std::string& errorDescription)
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
|
||||
auto wideStr = StringConvert::convert (inPath);
|
||||
HINSTANCE instance = LoadLibraryW (reinterpret_cast<LPCWSTR> (wideStr.data ()));
|
||||
if (instance == nullptr)
|
||||
{
|
||||
getLastError (inPath, errorDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasBundleStructure = false;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
//--- -----------------------------------------------------------------------
|
||||
bool load (const std::string& inPath, std::string& errorDescription) override
|
||||
{
|
||||
// filesystem::u8path is deprecated in C++20
|
||||
#if SMTG_CPP20
|
||||
const filesystem::path tmp (inPath);
|
||||
#else
|
||||
const filesystem::path tmp = filesystem::u8path (inPath);
|
||||
#endif
|
||||
if (filesystem::is_directory (tmp))
|
||||
{
|
||||
// try as package (bundle)
|
||||
mModule = loadAsPackage (inPath, errorDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
// try old definition without package
|
||||
mModule = loadAsDll (inPath, errorDescription);
|
||||
}
|
||||
if (mModule == nullptr)
|
||||
return false;
|
||||
|
||||
auto factoryProc = getFunctionPointer<GetFactoryProc> ("GetPluginFactory");
|
||||
if (!factoryProc)
|
||||
{
|
||||
errorDescription = "The dll does not export the required 'GetPluginFactory' function";
|
||||
return false;
|
||||
}
|
||||
// InitDll is optional
|
||||
auto dllEntry = getFunctionPointer<InitModuleFunc> ("InitDll");
|
||||
if (dllEntry && !dllEntry ())
|
||||
{
|
||||
errorDescription = "Calling 'InitDll' failed";
|
||||
return false;
|
||||
}
|
||||
auto f = Steinberg::U::cast<Steinberg::IPluginFactory> (owned (factoryProc ()));
|
||||
if (!f)
|
||||
{
|
||||
errorDescription = "Calling 'GetPluginFactory' returned nullptr";
|
||||
return false;
|
||||
}
|
||||
factory = PluginFactory (f);
|
||||
return true;
|
||||
}
|
||||
|
||||
HINSTANCE mModule {nullptr};
|
||||
|
||||
private:
|
||||
//--- -----------------------------------------------------------------------
|
||||
void getLastError (const std::string& inPath, std::string& errorDescription)
|
||||
{
|
||||
auto lastError = GetLastError ();
|
||||
LPVOID lpMessageBuffer {nullptr};
|
||||
if (FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
|
||||
lastError, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMessageBuffer, 0, nullptr) > 0)
|
||||
{
|
||||
errorDescription = "LoadLibraryW failed for path " + inPath + ": " +
|
||||
std::string ((char*)lpMessageBuffer);
|
||||
LocalFree (lpMessageBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorDescription = "LoadLibraryW failed with error number: " +
|
||||
std::to_string (lastError) + " for path " + inPath;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool openVST3Package (const filesystem::path& p, const char* archString,
|
||||
filesystem::path* result = nullptr)
|
||||
{
|
||||
auto path = p;
|
||||
path /= "Contents";
|
||||
path /= archString;
|
||||
path /= p.filename ();
|
||||
auto hFile = CreateFileW (reinterpret_cast<LPCWSTR> (path.c_str ()), GENERIC_READ,
|
||||
FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle (hFile);
|
||||
if (result)
|
||||
*result = path;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool checkVST3Package (const filesystem::path& p, filesystem::path* result = nullptr,
|
||||
const char* archString = architectureString)
|
||||
{
|
||||
if (openVST3Package (p, archString, result))
|
||||
return true;
|
||||
|
||||
#if SMTG_CPU_ARM_64EC
|
||||
if (openVST3Package (p, architectureArm64XString, result))
|
||||
return true;
|
||||
if (openVST3Package (p, architectureX64String, result))
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
bool isFolderSymbolicLink (const filesystem::path& p)
|
||||
{
|
||||
#if USE_FILESYSTEM
|
||||
if (/*filesystem::exists (p) &&*/ filesystem::is_symlink (p))
|
||||
return true;
|
||||
#else
|
||||
std::wstring wString = p.generic_wstring ();
|
||||
auto attrib = GetFileAttributesW (reinterpret_cast<LPCWSTR> (wString.c_str ()));
|
||||
if (attrib & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
{
|
||||
auto hFile = CreateFileW (reinterpret_cast<LPCWSTR> (wString.c_str ()), GENERIC_READ,
|
||||
FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
CloseHandle (hFile);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<std::string> getKnownFolder (REFKNOWNFOLDERID folderID)
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
|
||||
PWSTR wideStr {};
|
||||
if (FAILED (SHGetKnownFolderPath (folderID, 0, nullptr, &wideStr)))
|
||||
return {};
|
||||
return StringConvert::convert (Steinberg::wscast (wideStr));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
VST3::Optional<filesystem::path> resolveShellLink (const filesystem::path& p)
|
||||
{
|
||||
#if USE_FILESYSTEM
|
||||
return {filesystem::read_symlink (p).lexically_normal ()};
|
||||
#elif USE_OLE
|
||||
Ole::instance ();
|
||||
|
||||
IShellLink* shellLink = nullptr;
|
||||
if (!SUCCEEDED (CoCreateInstance (CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_IShellLink, reinterpret_cast<LPVOID*> (&shellLink))))
|
||||
return {};
|
||||
|
||||
IPersistFile* persistFile = nullptr;
|
||||
if (!SUCCEEDED (
|
||||
shellLink->QueryInterface (IID_IPersistFile, reinterpret_cast<void**> (&persistFile))))
|
||||
return {};
|
||||
|
||||
if (!SUCCEEDED (persistFile->Load (p.wstring ().data (), STGM_READ)))
|
||||
return {};
|
||||
|
||||
if (!SUCCEEDED (shellLink->Resolve (nullptr, MAKELONG (SLR_NO_UI, 500))))
|
||||
return {};
|
||||
|
||||
WCHAR resolvedPath[kIPPathNameMax];
|
||||
if (!SUCCEEDED (shellLink->GetPath (resolvedPath, kIPPathNameMax, nullptr, SLGP_SHORTPATH)))
|
||||
return {};
|
||||
|
||||
std::wstring longPath;
|
||||
longPath.resize (kIPPathNameMax);
|
||||
auto numChars =
|
||||
GetLongPathNameW (resolvedPath, const_cast<wchar_t*> (longPath.data ()), kIPPathNameMax);
|
||||
if (!numChars)
|
||||
return {};
|
||||
longPath.resize (numChars);
|
||||
|
||||
persistFile->Release ();
|
||||
shellLink->Release ();
|
||||
|
||||
return {filesystem::path (longPath)};
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void addToPathList (Module::PathList& pathList, const std::string& toAdd)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
std::cout << "=> add: " << toAdd << "\n";
|
||||
#endif
|
||||
|
||||
pathList.push_back (toAdd);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void findFilesWithExt (const filesystem::path& path, const std::string& ext,
|
||||
Module::PathList& pathList, bool recursive = true)
|
||||
{
|
||||
for (auto& p : filesystem::directory_iterator (path))
|
||||
{
|
||||
#if USE_FILESYSTEM
|
||||
filesystem::path finalPath (p);
|
||||
if (isFolderSymbolicLink (p))
|
||||
{
|
||||
if (auto res = resolveShellLink (p))
|
||||
{
|
||||
finalPath = *res;
|
||||
if (!filesystem::exists (finalPath))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
const auto& cpExt = finalPath.extension ();
|
||||
if (cpExt == ext)
|
||||
{
|
||||
filesystem::path result;
|
||||
if (checkVST3Package (finalPath, &result))
|
||||
{
|
||||
addToPathList (pathList, result.generic_string ());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (filesystem::is_directory (finalPath))
|
||||
{
|
||||
if (recursive)
|
||||
findFilesWithExt (finalPath, ext, pathList, recursive);
|
||||
}
|
||||
else if (cpExt == ext)
|
||||
addToPathList (pathList, finalPath.generic_string ());
|
||||
#else
|
||||
const auto& cp = p.path ();
|
||||
const auto& cpExt = cp.extension ();
|
||||
if (cpExt == ext)
|
||||
{
|
||||
if ((p.status ().type () == filesystem::file_type::directory) ||
|
||||
isFolderSymbolicLink (p))
|
||||
{
|
||||
filesystem::path result;
|
||||
if (checkVST3Package (p, &result))
|
||||
{
|
||||
addToPathList (pathList, result.generic_u8string ());
|
||||
continue;
|
||||
}
|
||||
findFilesWithExt (cp, ext, pathList, recursive);
|
||||
}
|
||||
else
|
||||
addToPathList (pathList, cp.generic_u8string ());
|
||||
}
|
||||
else if (recursive)
|
||||
{
|
||||
if (p.status ().type () == filesystem::file_type::directory)
|
||||
{
|
||||
findFilesWithExt (cp, ext, pathList, recursive);
|
||||
}
|
||||
else if (cpExt == ".lnk")
|
||||
{
|
||||
if (auto resolvedLink = resolveShellLink (cp))
|
||||
{
|
||||
if (resolvedLink->extension () == ext)
|
||||
{
|
||||
if (filesystem::is_directory (*resolvedLink) ||
|
||||
isFolderSymbolicLink (*resolvedLink))
|
||||
{
|
||||
filesystem::path result;
|
||||
if (checkVST3Package (*resolvedLink, &result))
|
||||
{
|
||||
addToPathList (pathList, result.generic_u8string ());
|
||||
continue;
|
||||
}
|
||||
findFilesWithExt (*resolvedLink, ext, pathList, recursive);
|
||||
}
|
||||
else
|
||||
addToPathList (pathList, resolvedLink->generic_u8string ());
|
||||
}
|
||||
else if (filesystem::is_directory (*resolvedLink))
|
||||
{
|
||||
const auto& str = resolvedLink->generic_u8string ();
|
||||
if (cp.generic_u8string ().compare (0, str.size (), str.data (),
|
||||
str.size ()) != 0)
|
||||
findFilesWithExt (*resolvedLink, ext, pathList, recursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void findModules (const filesystem::path& path, Module::PathList& pathList)
|
||||
{
|
||||
if (filesystem::exists (path))
|
||||
findFilesWithExt (path, ".vst3", pathList);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<filesystem::path> getContentsDirectoryFromModuleExecutablePath (
|
||||
const std::string& modulePath)
|
||||
{
|
||||
filesystem::path path (modulePath);
|
||||
|
||||
path = path.parent_path ();
|
||||
if (path.filename () != architectureString)
|
||||
return {};
|
||||
path = path.parent_path ();
|
||||
if (path.filename () != "Contents")
|
||||
return {};
|
||||
|
||||
return Optional<filesystem::path> {std::move (path)};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // anonymous
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::Ptr Module::create (const std::string& path, std::string& errorDescription)
|
||||
{
|
||||
auto _module = std::make_shared<Win32Module> ();
|
||||
if (_module->load (path, errorDescription))
|
||||
{
|
||||
_module->path = path;
|
||||
auto it = std::find_if (path.rbegin (), path.rend (),
|
||||
[] (const std::string::value_type& c) { return c == '/'; });
|
||||
if (it != path.rend ())
|
||||
_module->name = {it.base (), path.end ()};
|
||||
return _module;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::PathList Module::getModulePaths ()
|
||||
{
|
||||
namespace StringConvert = Steinberg::Vst::StringConvert;
|
||||
|
||||
// find plug-ins located in common/VST3
|
||||
PathList list;
|
||||
if (auto knownFolder = getKnownFolder (FOLDERID_UserProgramFilesCommon))
|
||||
{
|
||||
filesystem::path path (*knownFolder);
|
||||
path.append ("VST3");
|
||||
#if LOG_ENABLE
|
||||
std::cout << "Check folder: " << path << "\n";
|
||||
#endif
|
||||
findModules (path, list);
|
||||
}
|
||||
|
||||
if (auto knownFolder = getKnownFolder (FOLDERID_ProgramFilesCommon))
|
||||
{
|
||||
filesystem::path path (*knownFolder);
|
||||
path.append ("VST3");
|
||||
#if LOG_ENABLE
|
||||
std::cout << "Check folder: " << path << "\n";
|
||||
#endif
|
||||
findModules (path, list);
|
||||
}
|
||||
|
||||
// find plug-ins located in VST3 (application folder)
|
||||
WCHAR modulePath[kIPPathNameMax];
|
||||
GetModuleFileNameW (nullptr, modulePath, kIPPathNameMax);
|
||||
auto appPath = StringConvert::convert (Steinberg::wscast (modulePath));
|
||||
filesystem::path path (appPath);
|
||||
path = path.parent_path ();
|
||||
path = path.append ("VST3");
|
||||
#if LOG_ENABLE
|
||||
std::cout << "Check folder: " << path << "\n";
|
||||
#endif
|
||||
findModules (path, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Optional<std::string> Module::getModuleInfoPath (const std::string& modulePath)
|
||||
{
|
||||
auto path = getContentsDirectoryFromModuleExecutablePath (modulePath);
|
||||
if (!path)
|
||||
{
|
||||
filesystem::path p;
|
||||
if (!checkVST3Package ({modulePath}, &p))
|
||||
return {};
|
||||
p = p.parent_path ();
|
||||
p = p.parent_path ();
|
||||
path = Optional<filesystem::path> {p};
|
||||
}
|
||||
|
||||
*path /= "Resources";
|
||||
*path /= "moduleinfo.json";
|
||||
|
||||
if (filesystem::exists (*path))
|
||||
{
|
||||
return {path->generic_string ()};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
Module::SnapshotList Module::getSnapshots (const std::string& modulePath)
|
||||
{
|
||||
SnapshotList result;
|
||||
auto path = getContentsDirectoryFromModuleExecutablePath (modulePath);
|
||||
if (!path)
|
||||
{
|
||||
filesystem::path p;
|
||||
if (!checkVST3Package ({modulePath}, &p))
|
||||
return result;
|
||||
p = p.parent_path ();
|
||||
p = p.parent_path ();
|
||||
path = Optional<filesystem::path> (p);
|
||||
}
|
||||
|
||||
*path /= "Resources";
|
||||
*path /= "Snapshots";
|
||||
|
||||
if (filesystem::exists (*path) == false)
|
||||
return result;
|
||||
|
||||
PathList pngList;
|
||||
findFilesWithExt (*path, ".png", pngList, false);
|
||||
for (auto& png : pngList)
|
||||
{
|
||||
filesystem::path p (png);
|
||||
auto filename = p.filename ().generic_string ();
|
||||
auto uid = Snapshot::decodeUID (filename);
|
||||
if (!uid)
|
||||
continue;
|
||||
auto scaleFactor = 1.;
|
||||
if (auto decodedScaleFactor = Snapshot::decodeScaleFactor (filename))
|
||||
scaleFactor = *decodedScaleFactor;
|
||||
|
||||
Module::Snapshot::ImageDesc desc;
|
||||
desc.scaleFactor = scaleFactor;
|
||||
desc.path = std::move (png);
|
||||
bool found = false;
|
||||
for (auto& entry : result)
|
||||
{
|
||||
if (entry.uid != *uid)
|
||||
continue;
|
||||
found = true;
|
||||
entry.images.emplace_back (std::move (desc));
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
Module::Snapshot snapshot;
|
||||
snapshot.uid = *uid;
|
||||
snapshot.images.emplace_back (std::move (desc));
|
||||
result.emplace_back (std::move (snapshot));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // Hosting
|
||||
} // VST3
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/pluginterfacesupport.cpp
|
||||
// Created by : Steinberg, 11/2018.
|
||||
// Description : VST 3 hostclasses, example implementations for IPlugInterfaceSupport
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "pluginterfacesupport.h"
|
||||
|
||||
#include "pluginterfaces/vst/ivstaudioprocessor.h"
|
||||
#include "pluginterfaces/vst/ivsteditcontroller.h"
|
||||
#include "pluginterfaces/vst/ivstunits.h"
|
||||
#include "pluginterfaces/vst/ivstmessage.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PlugInterfaceSupport::PlugInterfaceSupport ()
|
||||
{
|
||||
FUNKNOWN_CTOR
|
||||
// add minimum set
|
||||
|
||||
//---VST 3.0.0--------------------------------
|
||||
addPlugInterfaceSupported (IComponent::iid);
|
||||
addPlugInterfaceSupported (IAudioProcessor::iid);
|
||||
addPlugInterfaceSupported (IEditController::iid);
|
||||
addPlugInterfaceSupported (IConnectionPoint::iid);
|
||||
|
||||
addPlugInterfaceSupported (IUnitInfo::iid);
|
||||
addPlugInterfaceSupported (IUnitData::iid);
|
||||
addPlugInterfaceSupported (IProgramListData::iid);
|
||||
|
||||
//---VST 3.0.1--------------------------------
|
||||
addPlugInterfaceSupported (IMidiMapping::iid);
|
||||
|
||||
//---VST 3.1----------------------------------
|
||||
addPlugInterfaceSupported (IEditController2::iid);
|
||||
|
||||
/*
|
||||
//---VST 3.0.2--------------------------------
|
||||
addPlugInterfaceSupported (IParameterFinder::iid);
|
||||
|
||||
//---VST 3.1----------------------------------
|
||||
addPlugInterfaceSupported (IAudioPresentationLatency::iid);
|
||||
|
||||
//---VST 3.5----------------------------------
|
||||
addPlugInterfaceSupported (IKeyswitchController::iid);
|
||||
addPlugInterfaceSupported (IContextMenuTarget::iid);
|
||||
addPlugInterfaceSupported (IEditControllerHostEditing::iid);
|
||||
addPlugInterfaceSupported (IXmlRepresentationController::iid);
|
||||
addPlugInterfaceSupported (INoteExpressionController::iid);
|
||||
|
||||
//---VST 3.6.5--------------------------------
|
||||
addPlugInterfaceSupported (ChannelContext::IInfoListener::iid);
|
||||
addPlugInterfaceSupported (IPrefetchableSupport::iid);
|
||||
addPlugInterfaceSupported (IAutomationState::iid);
|
||||
|
||||
//---VST 3.6.11--------------------------------
|
||||
addPlugInterfaceSupported (INoteExpressionPhysicalUIMapping::iid);
|
||||
|
||||
//---VST 3.6.12--------------------------------
|
||||
addPlugInterfaceSupported (IMidiLearn::iid);
|
||||
|
||||
//---VST 3.7-----------------------------------
|
||||
addPlugInterfaceSupported (IProcessContextRequirements::iid);
|
||||
addPlugInterfaceSupported (IParameterFunctionName::iid);
|
||||
addPlugInterfaceSupported (IProgress::iid);
|
||||
*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
tresult PLUGIN_API PlugInterfaceSupport::isPlugInterfaceSupported (const TUID _iid)
|
||||
{
|
||||
auto uid = FUID::fromTUID (_iid);
|
||||
if (std::find (mFUIDArray.begin (), mFUIDArray.end (), uid) != mFUIDArray.end ())
|
||||
return kResultTrue;
|
||||
return kResultFalse;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlugInterfaceSupport::addPlugInterfaceSupported (const TUID _iid)
|
||||
{
|
||||
mFUIDArray.push_back (FUID::fromTUID (_iid));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool PlugInterfaceSupport::removePlugInterfaceSupported (const TUID _iid)
|
||||
{
|
||||
auto uid = FUID::fromTUID (_iid);
|
||||
auto it = std::find (mFUIDArray.begin (), mFUIDArray.end (), uid);
|
||||
if (it == mFUIDArray.end ())
|
||||
return false;
|
||||
mFUIDArray.erase (it);
|
||||
return true;
|
||||
}
|
||||
|
||||
IMPLEMENT_FUNKNOWN_METHODS (PlugInterfaceSupport, IPlugInterfaceSupport, IPlugInterfaceSupport::iid)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
} // Vst
|
||||
} // Steinberg
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Project : VST SDK
|
||||
//
|
||||
// Category : Helpers
|
||||
// Filename : public.sdk/source/vst/hosting/pluginterfacesupport.h
|
||||
// Created by : Steinberg, 11/20018.
|
||||
// Description : VST 3 hostclasses, example implementations for IPlugInterfaceSupport
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// LICENSE
|
||||
// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pluginterfaces/vst/ivstpluginterfacesupport.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Steinberg {
|
||||
namespace Vst {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/** Example implementation of IPlugInterfaceSupport.
|
||||
\ingroup hostingBase
|
||||
*/
|
||||
class PlugInterfaceSupport : public IPlugInterfaceSupport
|
||||
{
|
||||
public:
|
||||
PlugInterfaceSupport ();
|
||||
virtual ~PlugInterfaceSupport () = default;
|
||||
|
||||
//--- IPlugInterfaceSupport ---------
|
||||
tresult PLUGIN_API isPlugInterfaceSupported (const TUID _iid) SMTG_OVERRIDE;
|
||||
|
||||
void addPlugInterfaceSupported (const TUID _iid);
|
||||
bool removePlugInterfaceSupported (const TUID _iid);
|
||||
|
||||
DECLARE_FUNKNOWN_METHODS
|
||||
|
||||
private:
|
||||
std::vector<FUID> mFUIDArray;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // namespace Vst
|
||||
} // namespace Steinberg
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue