Signed-off-by: falkTX <falktx@gmail.com>tags/v2.1-alpha1-winvst
@@ -0,0 +1,74 @@ | |||||
set(base_sources | |||||
source/baseiids.cpp | |||||
source/classfactoryhelpers.h | |||||
source/fbuffer.cpp | |||||
source/fbuffer.h | |||||
source/fcleanup.h | |||||
source/fcommandline.h | |||||
source/fdebug.cpp | |||||
source/fdebug.h | |||||
source/fdynlib.cpp | |||||
source/fdynlib.h | |||||
source/fobject.cpp | |||||
source/fobject.h | |||||
source/flock.cpp | |||||
source/flock.h | |||||
source/fstreamer.cpp | |||||
source/fstreamer.h | |||||
source/fstring.cpp | |||||
source/fstring.h | |||||
source/timer.cpp | |||||
source/timer.h | |||||
source/updatehandler.cpp | |||||
source/updatehandler.h | |||||
) | |||||
set(base_sources_ext | |||||
source/basefwd.h | |||||
source/classfactory.cpp | |||||
source/classfactory.h | |||||
source/fatomic.cpp | |||||
source/fatomic.h | |||||
source/fbitset.cpp | |||||
source/fbitset.h | |||||
source/fcontainer.h | |||||
source/fcpu.cpp | |||||
source/fcpu.h | |||||
source/fcriticalperformance.cpp | |||||
source/fcriticalperformance.h | |||||
source/finitializer.cpp | |||||
source/finitializer.h | |||||
source/fmemory.cpp | |||||
source/fmemory.h | |||||
source/fpoint.cpp | |||||
source/fpoint.h | |||||
source/frect.cpp | |||||
source/frect.h | |||||
source/fregion.cpp | |||||
source/fregion.h | |||||
source/frwlock_generic.h | |||||
source/frwlock_macosx.h | |||||
source/frwlock_windows.h | |||||
source/fstdmethods.h | |||||
source/fstringmethods.h | |||||
source/fstringstream.h | |||||
source/fthread.cpp | |||||
source/fthread.h | |||||
source/funknownfactory.h | |||||
source/hexbinary.h | |||||
source/istreamwrapper.cpp | |||||
source/istreamwrapper.h | |||||
source/tringbuffer.h | |||||
) | |||||
if (VST_SDK) | |||||
add_library(base STATIC ${base_sources}) | |||||
else() | |||||
add_library(base STATIC ${base_sources} ${base_sources_ext}) | |||||
endif() | |||||
# iOS target | |||||
if(MAC AND XCODE AND IOS_DEVELOPMENT_TEAM) | |||||
add_library(base_ios STATIC ${base_sources}) | |||||
smtg_set_platform_ios(base_ios) | |||||
endif() |
@@ -0,0 +1,27 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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. | |||||
//----------------------------------------------------------------------------- |
@@ -0,0 +1,61 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/baseidds.cpp | |||||
// Created by : Steinberg, 01/2008 | |||||
// Description : Basic Interface | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/iupdatehandler.h" | |||||
#include "pluginterfaces/base/ipersistent.h" | |||||
#include "pluginterfaces/base/icloneable.h" | |||||
#include "pluginterfaces/base/ibstream.h" | |||||
namespace Steinberg { | |||||
DEF_CLASS_IID (FUnknown) | |||||
DEF_CLASS_IID (IString) | |||||
DEF_CLASS_IID (IStringResult) | |||||
DEF_CLASS_IID (IDependent) | |||||
DEF_CLASS_IID (IUpdateHandler) | |||||
DEF_CLASS_IID (IPersistent) | |||||
DEF_CLASS_IID (IAttributes) | |||||
DEF_CLASS_IID (IAttributes2) | |||||
DEF_CLASS_IID (ICloneable) | |||||
DEF_CLASS_IID (ISizeableStream) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,87 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/classfactoryhelpers.h | |||||
// Created by : Steinberg, 03/2017 | |||||
// Description : Class factory | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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) |
@@ -0,0 +1,644 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fbuffer.cpp | |||||
// Created by : Steinberg, 2008 | |||||
// Description : | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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 <stdlib.h> | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------------------- | |||||
Buffer::Buffer () | |||||
: buffer (0) | |||||
, memSize (0) | |||||
, fillSize (0) | |||||
, delta (defaultDelta) | |||||
{} | |||||
//------------------------------------------------------------------------------------- | |||||
Buffer::Buffer (uint32 s, uint8 initVal) | |||||
: buffer (0) | |||||
, 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 (0) | |||||
, 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 (0) | |||||
, 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 (0) | |||||
, 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 = 0; | |||||
} | |||||
//------------------------------------------------------------------------------------- | |||||
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 == 0 || bytes == 0) | |||||
return false; | |||||
char8* stringBuffer = (char8*)malloc ((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 == 0) | |||||
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] = 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 == 0) | |||||
{ | |||||
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 = 0; | |||||
} | |||||
} | |||||
else | |||||
buffer = newBuffer; | |||||
} | |||||
else | |||||
{ | |||||
::free (buffer); | |||||
buffer = 0; | |||||
} | |||||
} | |||||
else | |||||
buffer = (int8*)::malloc (newSize); | |||||
if (newSize > 0 && !buffer) | |||||
memSize = 0; | |||||
else | |||||
memSize = newSize; | |||||
if (fillSize > memSize) | |||||
fillSize = memSize; | |||||
} | |||||
return (newSize > 0) == (buffer != 0); | |||||
} | |||||
//------------------------------------------------------------------------------------- | |||||
void Buffer::fillup (uint8 value) | |||||
{ | |||||
if (getFree () > 0) | |||||
memset (buffer + fillSize, value, getFree ()); | |||||
} | |||||
//------------------------------------------------------------------------------------- | |||||
int8* Buffer::operator + (uint32 i) | |||||
{ | |||||
if (i < memSize) | |||||
return buffer + i; | |||||
else | |||||
{ | |||||
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 = 0; | |||||
from.memSize = 0; | |||||
from.fillSize = 0; | |||||
} | |||||
//------------------------------------------------------------------------------------- | |||||
int8* Buffer::pass () | |||||
{ | |||||
int8* res = buffer; | |||||
buffer = 0; | |||||
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 (), buffer, 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 |
@@ -0,0 +1,306 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fbuffer.h | |||||
// Created by : Steinberg, 2008 | |||||
// Description : | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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. | |||||
*/ | |||||
~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 == 0; } | |||||
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 |
@@ -0,0 +1,322 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fcleanup.h | |||||
// Created by : Steinberg, 2008 | |||||
// Description : Template classes for automatic resource cleanup | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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 <stdlib.h> | |||||
namespace Steinberg { | |||||
/** Template definition for classes that help guarding against memory leaks. | |||||
A stack allocated object of this type automatically deletes an at construction time passed | |||||
dynamically allocated single object when it reaches the end of its scope. \n\n | |||||
Intended usage: | |||||
\code | |||||
{ | |||||
int* pointerToInt = new int; | |||||
Steinberg::FDeleter<int> deleter (pointerToInt); | |||||
// Do something with the variable behind pointerToInt. | |||||
} // No memory leak here, destructor of deleter cleans up the integer. | |||||
\endcode | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
template <class T> | |||||
struct FDeleter | |||||
{ | |||||
/// Constructor. _toDelete is a pointer to the dynamically allocated object that is to be | |||||
/// deleted when this FDeleter object's destructor is executed. | |||||
FDeleter (T* _toDelete) : toDelete (_toDelete) {} | |||||
/// Destructor. Calls delete on the at construction time passed pointer. | |||||
~FDeleter () | |||||
{ | |||||
if (toDelete) | |||||
delete toDelete; | |||||
} | |||||
T* toDelete; ///< Remembers the object that is to be deleted during destruction. | |||||
}; | |||||
/** Template definition for classes that help guarding against memory leaks. | |||||
A stack allocated object of this type automatically deletes an at construction time passed | |||||
dynamically allocated array of objects when it reaches the end of its scope. \n\n | |||||
Intended usage: | |||||
\code | |||||
{ | |||||
int* pointerToIntArray = new int[10]; | |||||
Steinberg::FArrayDeleter<int> deleter (pointerToIntArray); | |||||
// Do something with the array behind pointerToIntArray. | |||||
} // No memory leak here, destructor of deleter cleans up the integer array. | |||||
\endcode | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
template <class T> | |||||
struct FArrayDeleter | |||||
{ | |||||
/// Constructor. _arrayToDelete is a pointer to the dynamically allocated array of objects that | |||||
/// is to be deleted when this FArrayDeleter object's destructor is executed. | |||||
FArrayDeleter (T* _arrayToDelete) : arrayToDelete (_arrayToDelete) {} | |||||
/// Destructor. Calls delete[] on the at construction time passed pointer. | |||||
~FArrayDeleter () | |||||
{ | |||||
if (arrayToDelete) | |||||
delete[] arrayToDelete; | |||||
} | |||||
T* arrayToDelete; ///< Remembers the array of objects that is to be deleted during destruction. | |||||
}; | |||||
/** Template definition for classes that help guarding against dangling pointers. | |||||
A stack allocated object of this type automatically resets an at construction time passed | |||||
pointer to null when it reaches the end of its scope. \n\n | |||||
Intended usage: | |||||
\code | |||||
int* pointerToInt = 0; | |||||
{ | |||||
int i = 1; | |||||
pointerToInt = &i; | |||||
Steinberg::FPtrNuller<int> ptrNuller (pointerToInt); | |||||
// Do something with pointerToInt. | |||||
} // No dangling pointer here, pointerToInt is reset to 0 by destructor of ptrNuller. | |||||
\endcode | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
template <class T> | |||||
struct FPtrNuller | |||||
{ | |||||
/// Constructor. _toNull is a reference to the pointer that is to be reset to NULL when this | |||||
/// FPtrNuller object's destructor is executed. | |||||
FPtrNuller (T*& _toNull) : toNull (_toNull) {} | |||||
/// Destructor. Calls delete[] on the at construction time passed pointer. | |||||
~FPtrNuller () { toNull = 0; } | |||||
T*& toNull; ///< Remembers the pointer that is to be set to NULL during destruction. | |||||
}; | |||||
/** Template definition for classes that help resetting an object's value. | |||||
A stack allocated object of this type automatically resets the value of an at construction time | |||||
passed object to null when it reaches the end of its scope. \n\n Intended usage: \code int theObject | |||||
= 0; | |||||
{ | |||||
Steinberg::FNuller<int> theNuller (theObject); | |||||
theObject = 1; | |||||
} // Here the destructor of theNuller resets the value of theObject to 0. | |||||
\endcode | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
template <class T> | |||||
struct FNuller | |||||
{ | |||||
/// Constructor. _toNull is a reference to the object that is to be assigned 0 when this FNuller | |||||
/// object's destructor is executed. | |||||
FNuller (T& _toNull) : toNull (_toNull) {} | |||||
/// Destructor. Assigns 0 to the at construction time passed object reference. | |||||
~FNuller () { toNull = 0; } | |||||
T& toNull; ///< Remembers the object that is to be assigned 0 during destruction. | |||||
}; | |||||
/** Class definition for objects that help resetting boolean variables. | |||||
A stack allocated object of this type automatically sets an at construction time passed | |||||
boolean variable immediately to TRUE and resets the same variable to FALSE when it | |||||
reaches the end of its own scope. \n\n | |||||
Intended usage: | |||||
\code | |||||
bool theBoolean = false; | |||||
{ | |||||
Steinberg::FBoolSetter theBoolSetter (theBoolean); | |||||
// Here the constructor of theBoolSetter sets theBoolean to TRUE. | |||||
// Do something. | |||||
} // Here the destructor of theBoolSetter resets theBoolean to FALSE. | |||||
\endcode | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
template <class T> | |||||
struct FBooleanSetter | |||||
{ | |||||
/// Constructor. _toSet is a reference to the boolean that is set to TRUE immediately in this | |||||
/// constructor call and gets reset to FALSE when this FBoolSetter object's destructor is | |||||
/// executed. | |||||
FBooleanSetter (T& _toSet) : toSet (_toSet) { toSet = true; } | |||||
/// Destructor. Resets the at construction time passed boolean to FALSE. | |||||
~FBooleanSetter () { toSet = false; } | |||||
T& toSet; ///< Remembers the boolean that is to be reset during destruction. | |||||
}; | |||||
typedef FBooleanSetter<bool> FBoolSetter; | |||||
/** Class definition for objects that help setting boolean variables. | |||||
A stack allocated object of this type automatically sets an at construction time passed | |||||
boolean variable to TRUE if the given condition is met. At the end of its own scope the | |||||
stack object will reset the same boolean variable to FALSE, if it wasn't set so already. \n\n | |||||
Intended usage: | |||||
\code | |||||
bool theBoolean = false; | |||||
{ | |||||
bool creativityFirst = true; | |||||
Steinberg::FConditionalBoolSetter theCBSetter (theBoolean, creativityFirst); | |||||
// Here the constructor of theCBSetter sets theBoolean to the value of creativityFirst. | |||||
// Do something. | |||||
} // Here the destructor of theCBSetter resets theBoolean to FALSE. | |||||
\endcode | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
struct FConditionalBoolSetter | |||||
{ | |||||
/// Constructor. _toSet is a reference to the boolean that is to be set. If the in the second | |||||
/// parameter given condition is TRUE then also _toSet is set to TRUE immediately. | |||||
FConditionalBoolSetter (bool& _toSet, bool condition) : toSet (_toSet) | |||||
{ | |||||
if (condition) | |||||
toSet = true; | |||||
} | |||||
/// Destructor. Resets the at construction time passed boolean to FALSE. | |||||
~FConditionalBoolSetter () { toSet = false; } | |||||
bool& toSet; ///< Remembers the boolean that is to be reset during destruction. | |||||
}; | |||||
/** Template definition for classes that help closing resources. | |||||
A stack allocated object of this type automatically calls the close method of an at | |||||
construction time passed object when it reaches the end of its scope. | |||||
It goes without saying that the given type needs to have a close method. \n\n | |||||
Intended usage: | |||||
\code | |||||
struct CloseableObject | |||||
{ | |||||
void close() {}; | |||||
}; | |||||
{ | |||||
CloseableObject theObject; | |||||
Steinberg::FCloser<CloseableObject> theCloser (&theObject); | |||||
// Do something. | |||||
} // Here the destructor of theCloser calls the close method of theObject. | |||||
\endcode | |||||
*/ | |||||
template <class T> | |||||
struct FCloser | |||||
{ | |||||
/// Constructor. _obj is the pointer on which close is to be called when this FCloser object's | |||||
/// destructor is executed. | |||||
FCloser (T* _obj) : obj (_obj) {} | |||||
/// Destructor. Calls the close function on the at construction time passed pointer. | |||||
~FCloser () | |||||
{ | |||||
if (obj) | |||||
obj->close (); | |||||
} | |||||
T* obj; ///< Remembers the pointer on which close is to be called during destruction. | |||||
}; | |||||
/** Class definition for objects that help guarding against memory leaks. | |||||
A stack allocated object of this type automatically frees the "malloced" memory behind an at | |||||
construction time passed pointer when it reaches the end of its scope. | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
/*! \class FMallocReleaser | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class FMallocReleaser | |||||
{ | |||||
public: | |||||
/// Constructor. _data is the pointer to the memory on which free is to be called when this | |||||
/// FMallocReleaser object's destructor is executed. | |||||
FMallocReleaser (void* _data) : data (_data) {} | |||||
/// Destructor. Calls the free function on the at construction time passed pointer. | |||||
~FMallocReleaser () | |||||
{ | |||||
if (data) | |||||
free (data); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
protected: | |||||
void* data; ///< Remembers the pointer on which free is to be called during destruction. | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg | |||||
#if MAC | |||||
typedef const void* CFTypeRef; | |||||
extern "C" { | |||||
extern void CFRelease (CFTypeRef cf); | |||||
} | |||||
namespace Steinberg { | |||||
/** Class definition for objects that helps releasing CoreFoundation objects. | |||||
A stack allocated object of this type automatically releases an at construction time | |||||
passed CoreFoundation object when it reaches the end of its scope. | |||||
Only available on Macintosh platform. | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
/*! \class CFReleaser | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class CFReleaser | |||||
{ | |||||
public: | |||||
/// Constructor. _obj is the reference to an CoreFoundation object which is to be released when this CFReleaser object's destructor is executed. | |||||
CFReleaser (CFTypeRef _obj) : obj (_obj) {} | |||||
/// Destructor. Releases the at construction time passed object. | |||||
~CFReleaser () { if (obj) CFRelease (obj); } | |||||
protected: | |||||
CFTypeRef obj; ///< Remembers the object which is to be released during destruction. | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg | |||||
#endif // MAC |
@@ -0,0 +1,344 @@ | |||||
//------------------------------------------------------------------------ | |||||
// 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) 2017, 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 <deque> | |||||
#include <map> | |||||
#include <vector> | |||||
#include <algorithm> | |||||
#include <sstream> | |||||
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; | |||||
using namespace Steinberg; | |||||
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; | |||||
typedef std::map<std::string, std::string> VariablesMapContainer; | |||||
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. | |||||
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; ///< Retrieve the value of option @c k. | |||||
VariablesMapContainer::size_type count (const VariablesMapContainer::key_type k) const; ///< Returns @c != @c 0 if command-line contains option @c k. | |||||
}; | |||||
//! type of the list of elements on the command line that are not handled by options parsing | |||||
typedef std::vector<std::string> FilesVector; | |||||
//------------------------------------------------------------------------ | |||||
/** 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: | |||||
Description (const std::string& name, const std::string& help, const std::string& valueType ); ///< Construct a Description | |||||
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 | |||||
{ | |||||
typedef std::deque<Description> DescriptionsList; | |||||
DescriptionsList mDescriptions; | |||||
std::string mCaption; | |||||
public: | |||||
Descriptions& addOptions (const std::string& caption = ""); ///< Sets the command-line tool caption and starts adding Descriptions. | |||||
bool parse (int ac, char* av[], VariablesMap& result, FilesVector* files = 0) const; ///< Parse the command-line. | |||||
void print (std::ostream& os) const; ///< Print a brief description for the command-line tool into the stream @c os. | |||||
Descriptions& operator() (const std::string& name, const std::string& help); ///< Add a new switch. Only | |||||
template <typename Type> Descriptions& operator() (const std::string& name, const Type& inType, std::string help); ///< Add a new option of type @c inType. Currently only std::string is supported. | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
// 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.push_back (Description (name, help, inType)); | |||||
return *this; | |||||
} | |||||
bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, FilesVector* files = 0); ///< Parse the command-line. | |||||
std::ostream& operator<< (std::ostream& os, const Descriptions& desc); ///< Make Descriptions stream able. | |||||
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 reverence 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 reverence to *this. | |||||
*/ | |||||
Descriptions& Descriptions::operator() (const std::string& name, const std::string& help) | |||||
{ | |||||
mDescriptions.push_back (Description (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. | |||||
@param[in] caption the caption of the command-line tool. | |||||
@return a reverense to *this. | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
Descriptions& Descriptions::addOptions (const std::string& caption) | |||||
{ | |||||
mCaption = caption; | |||||
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; | |||||
int i; | |||||
for (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"; | |||||
unsigned int i; | |||||
for (i = 0; i < mDescriptions.size (); ++i) | |||||
{ | |||||
const Description& opt = mDescriptions[i]; | |||||
os << "-" << opt << ":\t" << 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 |
@@ -0,0 +1,270 @@ | |||||
//------------------------------------------------------------------------ | |||||
// 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) 2017, 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 DEVELOPMENT | |||||
#include <cstdio> | |||||
#include <cstdarg> | |||||
#if WINDOWS | |||||
#ifndef _WIN32_WINNT | |||||
#define _WIN32_WINNT 0x0400 | |||||
#endif | |||||
#include <windows.h> | |||||
#include <intrin.h> | |||||
#define vsnprintf _vsnprintf | |||||
#elif MAC | |||||
#include <mach/mach_time.h> | |||||
#include <mach/mach_init.h> | |||||
#include <errno.h> | |||||
#include <new> | |||||
#include <stdbool.h> | |||||
#include <sys/types.h> | |||||
#include <unistd.h> | |||||
#include <sys/sysctl.h> | |||||
#include <signal.h> | |||||
static bool AmIBeingDebugged (void); | |||||
#define THREAD_ALLOC_WATCH 0 // check allocations on specific threads | |||||
#if THREAD_ALLOC_WATCH | |||||
mach_port_t watchThreadID = 0; | |||||
#endif | |||||
#endif | |||||
AssertionHandler gAssertionHandler = 0; | |||||
//-------------------------------------------------------------------------- | |||||
static const int kDebugPrintfBufferSize = 10000; | |||||
static bool neverDebugger = false; // so I can switch it off in the debugger... | |||||
//-------------------------------------------------------------------------- | |||||
static void printDebugString (const char* string) | |||||
{ | |||||
if (!string) | |||||
return; | |||||
#if MAC | |||||
fprintf (stderr, "%s", string); | |||||
#elif 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); | |||||
} | |||||
#if WINDOWS | |||||
#define AmIBeingDebugged IsDebuggerPresent | |||||
#endif | |||||
#if LINUX | |||||
#include <sys/types.h> | |||||
#include <unistd.h> | |||||
#include <signal.h> | |||||
//-------------------------------------------------------------------------- | |||||
static inline bool AmIBeingDebugged () | |||||
{ | |||||
// TODO: check if GDB or LLDB is attached | |||||
return true; | |||||
} | |||||
#endif | |||||
//-------------------------------------------------------------------------- | |||||
// 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); | |||||
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 WINDOWS | |||||
__debugbreak (); // intrinsic version of DebugBreak() | |||||
#elif __ppc64__ || __ppc__ || __arm__ | |||||
kill (getpid (), SIGINT); | |||||
#elif __i386__ || __x86_64__ | |||||
{ __asm__ volatile ("int3"); } | |||||
#endif | |||||
} | |||||
} | |||||
} | |||||
//-------------------------------------------------------------------------- | |||||
void FPrintLastError (const char* file, int line) | |||||
{ | |||||
#if WINDOWS | |||||
LPVOID lpMessageBuffer; | |||||
FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | |||||
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |||||
(LPSTR) &lpMessageBuffer, 0, NULL); | |||||
FDebugPrint ("%s(%d) : %s\n", file, line, lpMessageBuffer); | |||||
LocalFree (lpMessageBuffer); | |||||
#endif | |||||
#if MAC | |||||
#if !__MACH__ | |||||
extern int errno; | |||||
#endif | |||||
FDebugPrint ("%s(%d) : Errno %d\n", file, line, errno); | |||||
#endif | |||||
} | |||||
#if MAC | |||||
//------------------------------------------------------------------------ | |||||
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) | |||||
{ | |||||
::operator delete (p); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void operator delete[](void* p, int, const char *file, int line) | |||||
{ | |||||
::operator delete[] (p); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
// from Technical Q&A QA1361 (http://developer.apple.com/qa/qa2004/qa1361.html) | |||||
//------------------------------------------------------------------------ | |||||
bool AmIBeingDebugged(void) | |||||
// 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 // MAC | |||||
#endif // DEVELOPMENT |
@@ -0,0 +1,206 @@ | |||||
//------------------------------------------------------------------------ | |||||
// 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) 2017, 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 <string.h> | |||||
#if MAC | |||||
#include <new> | |||||
#endif | |||||
//----------------------------------------------------------------------------- | |||||
// 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 WINDOWS | |||||
#undef ASSERT | |||||
/** 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 // 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. 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 ASSERT(f) if (!(f)) FDebugBreak ("%s(%d) : Assert failed: %s\n", __FILE__, __LINE__, #f); | |||||
/** Send "comment" string to the debugger for display. */ | |||||
#define WARNING(comment) FDebugPrint ("%s(%d) : %s\n", __FILE__, __LINE__, comment); | |||||
/** Send the last error string to the debugger for display. */ | |||||
#define 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 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: VERIFY (isValid ()) */ | |||||
#define VERIFY(f) 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: VERIFY_IS (callMethod (), kResultOK) */ | |||||
#define 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: VERIFY_NOT (callMethod (), kResultError) */ | |||||
#define 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 DBPRT0(a) FDebugPrint(a); | |||||
#define DBPRT1(a,b) FDebugPrint(a,b); | |||||
#define DBPRT2(a,b,c) FDebugPrint(a,b,c); | |||||
#define DBPRT3(a,b,c,d) FDebugPrint(a,b,c,d); | |||||
#define DBPRT4(a,b,c,d,e) FDebugPrint(a,b,c,d,e); | |||||
#define 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 | |||||
*/ | |||||
///@{ | |||||
typedef bool (*AssertionHandler)(const char* message); | |||||
extern AssertionHandler gAssertionHandler; | |||||
///@} | |||||
/** Definition of memory allocation macros: | |||||
Use "NEW" to allocate storage for individual objects. | |||||
Use "NEWVEC" to allocate storage for an array of objects. */ | |||||
#if MAC | |||||
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 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 ASSERT(f) | |||||
#define WARNING(s) | |||||
#define PRINTSYSERROR | |||||
#define DEBUGSTR(s) | |||||
#define VERIFY(f) f; | |||||
#define VERIFY_IS(f,r) f; | |||||
#define VERIFY_NOT(f,r) f; | |||||
#define DBPRT0(a) | |||||
#define DBPRT1(a,b) | |||||
#define DBPRT2(a,b,c) | |||||
#define DBPRT3(a,b,c,d) | |||||
#define DBPRT4(a,b,c,d,e) | |||||
#define DBPRT5(a,b,c,d,e,f) | |||||
#ifndef NEW | |||||
#define NEW new | |||||
#define NEWVEC new | |||||
#endif | |||||
#endif | |||||
#if SMTG_CPPUNIT_TESTING | |||||
#define SMTG_IS_TEST true | |||||
#else | |||||
#define SMTG_IS_TEST false | |||||
#endif |
@@ -0,0 +1,264 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fdynlib.cpp | |||||
// Created by : Steinberg, 1998 | |||||
// Description : Dynamic library loading | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/fdynlib.h" | |||||
#include "pluginterfaces/base/fstrdefs.h" | |||||
#include "base/source/fstring.h" | |||||
#if WINDOWS | |||||
#include <windows.h> | |||||
#elif MAC | |||||
#include <mach-o/dyld.h> | |||||
#include <CoreFoundation/CoreFoundation.h> | |||||
#if !TARGET_OS_IPHONE | |||||
static const Steinberg::tchar kUnixDelimiter = STR ('/'); | |||||
#endif | |||||
#endif | |||||
namespace Steinberg { | |||||
#if MAC | |||||
#include <dlfcn.h> | |||||
// we ignore for the moment that the NSAddImage functions are deprecated | |||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |||||
static bool CopyProcessPath (Steinberg::String& name) | |||||
{ | |||||
Dl_info info; | |||||
if (dladdr ((const void*)CopyProcessPath, &info)) | |||||
{ | |||||
if (info.dli_fname) | |||||
{ | |||||
name.assign (info.dli_fname); | |||||
#ifdef UNICODE | |||||
name.toWideString (); | |||||
#endif | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
// FDynLibrary | |||||
//------------------------------------------------------------------------ | |||||
FDynLibrary::FDynLibrary (const tchar* n, bool addExtension) | |||||
: isloaded (false) | |||||
, instance (0) | |||||
{ | |||||
if (n) | |||||
init (n, addExtension); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
FDynLibrary::~FDynLibrary () | |||||
{ | |||||
unload (); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
bool FDynLibrary::init (const tchar* n, bool addExtension) | |||||
{ | |||||
if (isLoaded ()) | |||||
return true; | |||||
Steinberg::String name (n); | |||||
#if WINDOWS | |||||
if (addExtension) | |||||
name.append (STR (".dll")); | |||||
instance = LoadLibrary (name); | |||||
if (instance) | |||||
isloaded = true; | |||||
#elif MAC | |||||
isBundle = false; | |||||
// first check if it is a bundle | |||||
if (addExtension) | |||||
name.append (STR (".bundle")); | |||||
if (name.getChar16 (0) != STR('/')) // no absoltue path | |||||
{ | |||||
Steinberg::String p; | |||||
if (CopyProcessPath (p)) | |||||
{ | |||||
Steinberg::int32 index = p.findLast (STR ('/')); | |||||
p.remove (index+1); | |||||
name = p + name; | |||||
} | |||||
} | |||||
CFStringRef fsString = (CFStringRef)name.toCFStringRef (); | |||||
CFURLRef url = CFURLCreateWithFileSystemPath (NULL, fsString, kCFURLPOSIXPathStyle, true); | |||||
if (url) | |||||
{ | |||||
CFBundleRef bundle = CFBundleCreate (NULL, url); | |||||
if (bundle) | |||||
{ | |||||
if (CFBundleLoadExecutable (bundle)) | |||||
{ | |||||
isBundle = true; | |||||
instance = (void*)bundle; | |||||
} | |||||
else | |||||
CFRelease (bundle); | |||||
} | |||||
CFRelease (url); | |||||
} | |||||
CFRelease (fsString); | |||||
name.assign (n); | |||||
#if !TARGET_OS_IPHONE | |||||
if (!isBundle) | |||||
{ | |||||
// now we check for a dynamic library | |||||
firstSymbol = NULL; | |||||
if (addExtension) | |||||
{ | |||||
name.append (STR (".dylib")); | |||||
} | |||||
// Only if name is a relative path we use the Process Path as root: | |||||
if (name[0] != kUnixDelimiter) | |||||
{ | |||||
Steinberg::String p; | |||||
if (CopyProcessPath (p)) | |||||
{ | |||||
Steinberg::int32 index = p.findLast (STR ("/")); | |||||
p.remove (index+1); | |||||
p.append (name); | |||||
p.toMultiByte (Steinberg::kCP_Utf8); | |||||
instance = (void*) NSAddImage (p, NSADDIMAGE_OPTION_RETURN_ON_ERROR); | |||||
} | |||||
} | |||||
// Last but not least let the system search for it | |||||
// | |||||
if (instance == 0) | |||||
{ | |||||
name.toMultiByte (Steinberg::kCP_Utf8); | |||||
instance = (void*) NSAddImage (name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); | |||||
} | |||||
} | |||||
#endif // !TARGET_OS_IPHONE | |||||
if (instance) | |||||
isloaded = true; | |||||
#endif | |||||
return isloaded; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
bool FDynLibrary::unload () | |||||
{ | |||||
if (!isLoaded ()) | |||||
return false; | |||||
#if WINDOWS | |||||
FreeLibrary ((HINSTANCE)instance); | |||||
#elif MAC | |||||
if (isBundle) | |||||
{ | |||||
if (CFGetRetainCount ((CFTypeRef)instance) == 1) | |||||
CFBundleUnloadExecutable ((CFBundleRef)instance); | |||||
CFRelease ((CFBundleRef)instance); | |||||
} | |||||
else | |||||
{ | |||||
// we don't use this anymore as the darwin dyld can't unload dynamic libraries yet and may crash | |||||
/* if (firstSymbol) | |||||
{ | |||||
NSModule module = NSModuleForSymbol ((NSSymbol)firstSymbol); | |||||
if (module) | |||||
NSUnLinkModule (module, NSUNLINKMODULE_OPTION_NONE); | |||||
}*/ | |||||
} | |||||
#endif | |||||
instance = 0; | |||||
isloaded = false; | |||||
return true; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void* FDynLibrary::getProcAddress (const char* name) | |||||
{ | |||||
if (!isloaded) | |||||
return 0; | |||||
#if WINDOWS | |||||
return (void*)GetProcAddress ((HINSTANCE)instance, name); | |||||
#elif MAC | |||||
if (isBundle) | |||||
{ | |||||
CFStringRef functionName = CFStringCreateWithCString (NULL, name, kCFStringEncodingASCII); | |||||
void* result = CFBundleGetFunctionPointerForName ((CFBundleRef)instance, functionName); | |||||
CFRelease (functionName); | |||||
return result; | |||||
} | |||||
#if !TARGET_OS_IPHONE | |||||
else | |||||
{ | |||||
char* symbolName = (char*) malloc (strlen (name) + 2); | |||||
strcpy (symbolName, "_"); | |||||
strcat (symbolName, name); | |||||
NSSymbol symbol; | |||||
symbol = NSLookupSymbolInImage ((const struct mach_header*)instance, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | |||||
free (symbolName); | |||||
if (symbol) | |||||
{ | |||||
if (firstSymbol == NULL) | |||||
firstSymbol = symbol; | |||||
return NSAddressOfSymbol (symbol); | |||||
} | |||||
} | |||||
#endif // !TARGET_OS_IPHONE | |||||
#endif | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,112 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fdynlib.h | |||||
// Created by : Steinberg, 1998 | |||||
// Description : Dynamic library loading | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/fdynlib.h | |||||
Platform independent dynamic library loading. */ | |||||
//------------------------------------------------------------------------ | |||||
#pragma once | |||||
#include "pluginterfaces/base/ftypes.h" | |||||
#include "base/source/fobject.h" | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------ | |||||
/** Platform independent dynamic library loader. */ | |||||
//------------------------------------------------------------------------ | |||||
class FDynLibrary : public FObject | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
/** Constructor. | |||||
Loads the specified dynamic library. | |||||
@param[in] name the path of the library to load. | |||||
@param[in] addExtension if @c true append the platform dependent default extension to @c name. | |||||
@remarks | |||||
- If @c name specifies a full path, the FDynLibrary searches only that path for the library. | |||||
- If @c name specifies a relative path or a name without path, | |||||
FDynLibrary uses a standard search strategy of the current platform to find the library; | |||||
- If @c name is @c NULL the library is not loaded. | |||||
- Use init() to load the library. */ | |||||
FDynLibrary (const tchar* name = 0, bool addExtension = true); | |||||
/** Destructor. | |||||
The destructor unloads the library.*/ | |||||
~FDynLibrary (); | |||||
/** Loads the library if not already loaded. | |||||
This function is normally called by FDynLibrary(). | |||||
@remarks If the library is already loaded, this call has no effect. */ | |||||
bool init (const tchar* name, bool addExtension = true); | |||||
/** Returns the address of the procedure @c name */ | |||||
void* getProcAddress (const char* name); | |||||
/** Returns true when the library was successfully loaded. */ | |||||
bool isLoaded () {return isloaded;} | |||||
/** Unloads the library if it is loaded. | |||||
This function is called by ~FDynLibrary (). */ | |||||
bool unload (); | |||||
/** Returns the platform dependent representation of the library instance. */ | |||||
void* getPlatformInstance () const { return instance; } | |||||
#if MAC | |||||
/** Returns @c true if the library is a bundle (Mac only). */ | |||||
bool isBundleLib () const {return isBundle;} | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
OBJ_METHODS(FDynLibrary, FObject) | |||||
protected: | |||||
bool isloaded; | |||||
void* instance; | |||||
#if MAC | |||||
void* firstSymbol; | |||||
bool isBundle; | |||||
#endif | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,142 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/flock.cpp | |||||
// Created by : Steinberg, 1995 | |||||
// Description : Locks | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/source/flock.h" | |||||
#include "base/source/fdebug.h" | |||||
//------------------------------------------------------------------------ | |||||
#if 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 | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------ | |||||
// FLock implementation | |||||
//------------------------------------------------------------------------ | |||||
FLock::FLock (const char8* name) | |||||
{ | |||||
#if PTHREADS | |||||
pthread_mutexattr_t mutexAttr; | |||||
pthread_mutexattr_init (&mutexAttr); | |||||
pthread_mutexattr_settype (&mutexAttr, PTHREAD_MUTEX_RECURSIVE); | |||||
if (pthread_mutex_init (&mutex, &mutexAttr) != 0) | |||||
{WARNING("mutex_init failed")} | |||||
pthread_mutexattr_destroy (&mutexAttr); | |||||
#elif WINDOWS | |||||
INIT_CS (section) | |||||
#else | |||||
#warning implement FLock! | |||||
#endif | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
FLock::~FLock () | |||||
{ | |||||
#if PTHREADS | |||||
pthread_mutex_destroy (&mutex); | |||||
#elif WINDOWS | |||||
DeleteCriticalSection ((LPCRITICAL_SECTION)§ion); | |||||
#endif | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void FLock::lock () | |||||
{ | |||||
#if DEBUG_LOCK | |||||
FDebugPrint ("FLock::lock () %x\n", this); | |||||
#endif | |||||
#if PTHREADS | |||||
pthread_mutex_lock (&mutex); | |||||
#elif WINDOWS | |||||
EnterCriticalSection ((LPCRITICAL_SECTION)§ion); | |||||
#endif | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void FLock::unlock () | |||||
{ | |||||
#if DEBUG_LOCK | |||||
FDebugPrint ("FLock::unlock () %x\n", this); | |||||
#endif | |||||
#if PTHREADS | |||||
pthread_mutex_unlock (&mutex); | |||||
#elif WINDOWS | |||||
LeaveCriticalSection ((LPCRITICAL_SECTION)§ion); | |||||
#endif | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
bool FLock::trylock () | |||||
{ | |||||
#if PTHREADS | |||||
return pthread_mutex_trylock (&mutex) == 0; | |||||
#elif WINDOWS | |||||
return TryEnterCriticalSection ((LPCRITICAL_SECTION)§ion) != 0 ? true : false; | |||||
#else | |||||
return false; | |||||
#endif | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,183 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/flock.h | |||||
// Created by : Steinberg, 1995 | |||||
// Description : locks | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/flock.h | |||||
Locks. */ | |||||
/** @defgroup baseLocks Locks */ | |||||
//---------------------------------------------------------------------------------- | |||||
#pragma once | |||||
#include "fobject.h" | |||||
#include "pluginterfaces/base/ftypes.h" | |||||
#if PTHREADS | |||||
#include <pthread.h> | |||||
#elif 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 { | |||||
//------------------------------------------------------------------------ | |||||
/** 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 (); | |||||
//-- ILock ----------------------------------------------------------- | |||||
virtual void lock () SMTG_OVERRIDE; | |||||
virtual void unlock () SMTG_OVERRIDE; | |||||
virtual bool trylock () SMTG_OVERRIDE; | |||||
//-------------------------------------------------------------------- | |||||
//------------------------------------------------------------------------ | |||||
protected: | |||||
#if PTHREADS | |||||
pthread_mutex_t mutex; ///< Mutex object | |||||
#elif 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 Steinberg |
@@ -0,0 +1,183 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fobject.cpp | |||||
// Created by : Steinberg, 2008 | |||||
// Description : Basic Object implementing FUnknown | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/source/flock.h" | |||||
#include <vector> | |||||
namespace Steinberg { | |||||
IUpdateHandler* FObject::gUpdateHandler = 0; | |||||
//------------------------------------------------------------------------ | |||||
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; | |||||
//------------------------------------------------------------------------ | |||||
uint32 PLUGIN_API FObject::addRef () | |||||
{ | |||||
return FUnknownPrivate::atomicAdd (refCount, 1); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
uint32 PLUGIN_API FObject::release () | |||||
{ | |||||
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 = 0; | |||||
return kNoInterface; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void FObject::addDependent (IDependent* dep) | |||||
{ | |||||
if (gUpdateHandler) | |||||
gUpdateHandler->addDependent (unknownCast (), dep); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void FObject::removeDependent (IDependent* dep) | |||||
{ | |||||
if (gUpdateHandler) | |||||
gUpdateHandler->removeDependent (unknownCast (), dep); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
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 | |||||
{ | |||||
typedef std::vector<FObject**> ObjectVector; | |||||
ObjectVector* singletonInstances = 0; | |||||
bool singletonsTerminated = false; | |||||
FLock* singletonsLock; | |||||
bool isTerminated () {return singletonsTerminated;} | |||||
void lockRegister () | |||||
{ | |||||
if (!singletonsLock) // assume first call not from multiple threads | |||||
singletonsLock = NEW FLock; | |||||
singletonsLock->lock (); | |||||
} | |||||
void unlockRegister () | |||||
{ | |||||
singletonsLock->unlock (); | |||||
} | |||||
void registerInstance (FObject** o) | |||||
{ | |||||
ASSERT (singletonsTerminated == false) | |||||
if (singletonsTerminated == false) | |||||
{ | |||||
if (singletonInstances == 0) | |||||
singletonInstances = NEW std::vector<FObject**>; | |||||
singletonInstances->push_back (o); | |||||
} | |||||
} | |||||
struct Deleter | |||||
{ | |||||
~Deleter () | |||||
{ | |||||
singletonsTerminated = true; | |||||
if (singletonInstances) | |||||
{ | |||||
for (ObjectVector::iterator it = singletonInstances->begin (), | |||||
end = singletonInstances->end (); | |||||
it != end; ++it) | |||||
{ | |||||
FObject** obj = (*it); | |||||
(*obj)->release (); | |||||
obj = 0; | |||||
} | |||||
delete singletonInstances; | |||||
singletonInstances = 0; | |||||
} | |||||
delete singletonsLock; | |||||
singletonsLock = 0; | |||||
} | |||||
} deleter; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,518 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fobject.h | |||||
// Created by : Steinberg, 2008 | |||||
// Description : Basic Object implementing FUnknown | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/basefwd.h" | |||||
#include "base/source/fdebug.h" // NEW | |||||
namespace Steinberg { | |||||
//---------------------------------- | |||||
typedef FIDString FClassID; | |||||
//------------------------------------------------------------------------ | |||||
// 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 () : refCount (1) {} ///< default constructor... | |||||
FObject (const FObject&) : refCount (1) {} ///< overloaded constructor... | |||||
virtual ~FObject () {} ///< destructor... | |||||
FObject& operator = (const FObject&) { return *this; } ///< overloads operator "=" as the reference assignment | |||||
// 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 | |||||
virtual tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE; ///< please refer to FUnknown::queryInterface () | |||||
virtual uint32 PLUGIN_API addRef () SMTG_OVERRIDE; ///< please refer to FUnknown::addref () | |||||
virtual uint32 PLUGIN_API release () SMTG_OVERRIDE; ///< please refer to FUnknown::release () | |||||
// IDependent | |||||
virtual 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 (IDependent* d) {return static_cast<IDependent*> (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 | |||||
/** Special UID that is used to cast an FUnknown pointer to a FObject */ | |||||
static const FUID iid; | |||||
//------------------------------------------------------------------------ | |||||
protected: | |||||
int32 refCount; ///< COM-model local reference count | |||||
static IUpdateHandler* gUpdateHandler; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
// conversion from FUnknown to FObject | |||||
//------------------------------------------------------------------------ | |||||
inline FObject* FObject::unknownToObject (FUnknown* unknown) | |||||
{ | |||||
FObject* object = 0; | |||||
if (unknown) | |||||
{ | |||||
unknown->queryInterface (FObject::iid, (void**)&object); | |||||
if (object) | |||||
object->release (); // queryInterface has added ref | |||||
} | |||||
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 0; | |||||
} | |||||
//----------------------------------------------------------------------- | |||||
/** FCast overload 2 - FUnknown to FObject */ | |||||
//----------------------------------------------------------------------- | |||||
template <class C> | |||||
inline C* FCast (FUnknown* unknown) | |||||
{ | |||||
FObject* object = FObject::unknownToObject (unknown); | |||||
return FCast<C> (object); | |||||
} | |||||
//----------------------------------------------------------------------- | |||||
/** FUCast - casting from FUnknown to Interface */ | |||||
//----------------------------------------------------------------------- | |||||
template <class C> | |||||
inline C* FUCast (FObject* object) | |||||
{ | |||||
return FUnknownPtr<C> (object ? object->unknownCast () : 0); | |||||
} | |||||
template <class C> | |||||
inline C* FUCast (FUnknown* object) | |||||
{ | |||||
return FUnknownPtr<C> (object); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** @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 (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 |
@@ -0,0 +1,202 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fstdmethods.h | |||||
// Created by : Steinberg, 2007 | |||||
// Description : Convenient macros to create setter and getter methods. | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/fstdmethods.h | |||||
Convenient macros to create setter and getter methods. */ | |||||
//------------------------------------------------------------------------ | |||||
#pragma once | |||||
//---------------------------------------------------------------------------------- | |||||
/** @name Methods for flags. | |||||
Macros to create setter and getter methods for flags. | |||||
Usage example with DEFINE_STATE: | |||||
\code | |||||
class MyClass | |||||
{ | |||||
public: | |||||
MyClass () : flags (0) {} | |||||
DEFINE_FLAG (flags, isFlagged, 1<<0) | |||||
DEFINE_FLAG (flags, isMine, 1<<1) | |||||
private: | |||||
uint32 flags; | |||||
}; | |||||
void someFunction () | |||||
{ | |||||
MyClass c; | |||||
if (c.isFlagged ()) // check the flag | |||||
c.isFlagged (false); // set the flag | |||||
} | |||||
\endcode | |||||
*/ | |||||
//---------------------------------------------------------------------------------- | |||||
///@{ | |||||
/** Create Methods with @c get and @c set prefix. */ | |||||
#define DEFINE_STATE(flagVar,methodName,value)\ | |||||
void set##methodName (bool state) { if (state) flagVar |= (value); else flagVar &= ~(value); }\ | |||||
bool get##methodName ()const { return (flagVar & (value)) != 0; } | |||||
/** Create Methods with @c get prefix. | |||||
There is only a 'get' method. */ | |||||
#define DEFINE_GETSTATE(flagVar,methodName,value)\ | |||||
bool get##methodName ()const { return (flagVar & (value)) != 0; } | |||||
/** Create Methods. | |||||
Same name for the getter and setter. */ | |||||
#define DEFINE_FLAG(flagVar,methodName,value)\ | |||||
void methodName (bool state) { if (state) flagVar |= (value); else flagVar &= ~(value); }\ | |||||
bool methodName ()const { return (flagVar & (value)) != 0; } | |||||
/** Create Methods. | |||||
There is only a 'get' method. */ | |||||
#define DEFINE_GETFLAG(flagVar,methodName,value)\ | |||||
bool methodName ()const { return (flagVar & (value)) != 0; } | |||||
/** Create @c static Methods. | |||||
Same name for the getter and setter. */ | |||||
#define DEFINE_FLAG_STATIC(flagVar,methodName,value)\ | |||||
static void methodName (bool __state) { if (__state) flagVar |= (value); else flagVar &= ~(value); }\ | |||||
static bool methodName () { return (flagVar & (value)) != 0; } | |||||
///@} | |||||
//---------------------------------------------------------------------------------- | |||||
/** @name Methods for data members. | |||||
Macros to create setter and getter methods for class members. | |||||
<b>Examples:</b> | |||||
\code | |||||
class MyClass | |||||
{ | |||||
public: | |||||
DATA_MEMBER (double, distance, Distance) | |||||
STRING_MEMBER (Steinberg::String, name, Name) | |||||
SHARED_MEMBER (FUnknown, userData, UserData) | |||||
CLASS_MEMBER (Steinberg::Buffer, bufferData, BufferData) | |||||
POINTER_MEMBER (Steinberg::FObject, refOnly, RefOnly) | |||||
}; | |||||
\endcode | |||||
*/ | |||||
//-------------------------------------------------------------------------------------- | |||||
///@{ | |||||
/** Build-in member (pass by value). */ | |||||
#define DATA_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (type v) { varName = v;}\ | |||||
type get##methodName ()const { return varName; }\ | |||||
protected: type varName; public: | |||||
//** Object member (pass by reference). */ | |||||
#define CLASS_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (const type& v){ varName = v;}\ | |||||
const type& get##methodName () const { return varName; }\ | |||||
protected: type varName; public: | |||||
//** Simple pointer. */ | |||||
#define POINTER_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (type* ptr){ varName = ptr;}\ | |||||
type* get##methodName ()const { return varName; }\ | |||||
private: type* varName; public: | |||||
//** Shared member - FUnknown / FObject / etc */ | |||||
#define SHARED_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (type* v){ varName = v;}\ | |||||
type* get##methodName ()const { return varName; }\ | |||||
private: IPtr<type> varName; public: | |||||
//** Owned member - FUnknown / FObject / CmObject etc */ | |||||
#define OWNED_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (type* v){ varName = v;}\ | |||||
type* get##methodName ()const { return varName; }\ | |||||
private: OPtr<type> varName; public: | |||||
//** tchar* / String class member - set by const tchar*, return by reference */ | |||||
#define STRING_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (const tchar* v){ varName = v;}\ | |||||
const type& get##methodName () const { return varName; }\ | |||||
protected: type varName; public: | |||||
//** char8* / String class member - set by const char8*, return by reference */ | |||||
#define STRING8_MEMBER(type,varName,methodName)\ | |||||
public:void set##methodName (const char8* v){ varName = v;}\ | |||||
const type& get##methodName () const { return varName; }\ | |||||
protected: type varName; public: | |||||
//** Standard String Member Steinberg::String */ | |||||
#define STRING_MEMBER_STD(varName,methodName) STRING_MEMBER(Steinberg::String,varName,methodName) | |||||
#define STRING8_MEMBER_STD(varName,methodName) STRING8_MEMBER(Steinberg::String,varName,methodName) | |||||
///@} | |||||
// obsolete names | |||||
#define DEFINE_VARIABLE(type,varName,methodName) DATA_MEMBER(type,varName,methodName) | |||||
#define DEFINE_POINTER(type,varName,methodName) POINTER_MEMBER(type,varName,methodName) | |||||
#define DEFINE_MEMBER(type,varName,methodName) CLASS_MEMBER(type,varName,methodName) | |||||
//------------------------------------------------------------------------ | |||||
// for implementing comparison operators using a class member or a compare method: | |||||
//------------------------------------------------------------------------ | |||||
#define COMPARE_BY_MEMBER_METHODS(className,memberName) \ | |||||
bool operator == (const className& other) const {return (memberName == other.memberName);} \ | |||||
bool operator != (const className& other) const {return (memberName != other.memberName);} \ | |||||
bool operator < (const className& other) const {return (memberName < other.memberName);} \ | |||||
bool operator > (const className& other) const {return (memberName > other.memberName);} \ | |||||
bool operator <= (const className& other) const {return (memberName <= other.memberName);} \ | |||||
bool operator >= (const className& other) const {return (memberName >= other.memberName);} | |||||
#define COMPARE_BY_MEMORY_METHODS(className) \ | |||||
bool operator == (const className& other) const {return memcmp (this, &other, sizeof (className)) == 0;} \ | |||||
bool operator != (const className& other) const {return memcmp (this, &other, sizeof (className)) != 0;} \ | |||||
bool operator < (const className& other) const {return memcmp (this, &other, sizeof (className)) < 0;} \ | |||||
bool operator > (const className& other) const {return memcmp (this, &other, sizeof (className)) > 0;} \ | |||||
bool operator <= (const className& other) const {return memcmp (this, &other, sizeof (className)) <= 0;} \ | |||||
bool operator >= (const className& other) const {return memcmp (this, &other, sizeof (className)) >= 0;} | |||||
#define COMPARE_BY_COMPARE_METHOD(className,methodName) \ | |||||
bool operator == (const className& other) const {return methodName (other) == 0;} \ | |||||
bool operator != (const className& other) const {return methodName (other) != 0;} \ | |||||
bool operator < (const className& other) const {return methodName (other) < 0;} \ | |||||
bool operator > (const className& other) const {return methodName (other) > 0;} \ | |||||
bool operator <= (const className& other) const {return methodName (other) <= 0; } \ | |||||
bool operator >= (const className& other) const {return methodName (other) >= 0; } |
@@ -0,0 +1,726 @@ | |||||
//------------------------------------------------------------------------ | |||||
// 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) 2017, 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; | |||||
} | |||||
// 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) | |||||
{ | |||||
TSize i = 0; | |||||
char8 c = 0; | |||||
while (i < size) | |||||
{ | |||||
if (readRaw ((void*)&c, sizeof (char)) != sizeof (char)) | |||||
break; | |||||
ptr[i] = c; | |||||
i++; | |||||
if (c == '\n' || c == '\0') | |||||
break; | |||||
} | |||||
if (c == '\n' && ptr[i - 2] == '\r') | |||||
ptr[i - 2] = 0; | |||||
if (i < size) | |||||
ptr[i] = 0; | |||||
else | |||||
ptr[size - 1] = 0; | |||||
return strlen (ptr); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
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.int8Ptr (); | |||||
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) == 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 0; | |||||
// check corruption | |||||
if (length > 262144) | |||||
return 0; | |||||
char8* s = (length > 0) ? NEWVEC char8[length] : 0; | |||||
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 |
@@ -0,0 +1,242 @@ | |||||
//------------------------------------------------------------------------ | |||||
// 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) 2017, 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 () { 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){return writeChar8 (c);} | |||||
bool readInt8 (int8& c){return readChar8 (c);} | |||||
bool writeInt8u (uint8 c){return writeUChar8 (c);} | |||||
bool readInt8u (uint8& c){return readUChar8 (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 |
@@ -0,0 +1,747 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/fstring.h | |||||
// Created by : Steinberg, 2008 | |||||
// Description : String class | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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 <stdarg.h> | |||||
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 len;} ///< Return length of string | |||||
inline bool isEmpty () const {return buffer == 0 || len == 0;} ///< Return true if sting 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 (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 (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 MAC | |||||
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. | |||||
\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 (); | |||||
#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) | |||||
virtual const char8* text8 () const SMTG_OVERRIDE; | |||||
virtual const char16* text16 () const SMTG_OVERRIDE; | |||||
virtual char8 getChar8 (uint32 index) const SMTG_OVERRIDE; | |||||
virtual 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); | |||||
String& printFloat (double value); | |||||
/** 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 MAC | |||||
virtual bool fromCFStringRef (const void*, uint32 encoding = 0xFFFF); ///< CFString conversion | |||||
#endif | |||||
//------------------------------------------------------------------------- | |||||
//----------------------------------------------------------------------------- | |||||
protected: | |||||
bool resize (uint32 newSize, bool wide, bool fill = false); | |||||
private: | |||||
void tryFreeBuffer (); | |||||
bool checkToMultiByte (uint32 destCodePage = kCP_Default) const; // to remove debug code from inline - const_cast inside!!! | |||||
}; | |||||
// 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 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 ---------------------------------------------------------- | |||||
virtual void PLUGIN_API setText (const char8* text) SMTG_OVERRIDE; | |||||
//------------------------------------------------------------------------- | |||||
// IString----------------------------------------------------------------- | |||||
virtual void PLUGIN_API setText8 (const char8* text) SMTG_OVERRIDE; | |||||
virtual void PLUGIN_API setText16 (const char16* text) SMTG_OVERRIDE; | |||||
virtual const char8* PLUGIN_API getText8 () SMTG_OVERRIDE; | |||||
virtual const char16* PLUGIN_API getText16 () SMTG_OVERRIDE; | |||||
virtual void PLUGIN_API take (void* s, bool _isWide) SMTG_OVERRIDE; | |||||
virtual bool PLUGIN_API isWideString () const SMTG_OVERRIDE; | |||||
//------------------------------------------------------------------------- | |||||
OBJ_METHODS (StringObject, FObject) | |||||
FUNKNOWN_METHODS2 (IStringResult, IString, FObject) | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,130 @@ | |||||
//------------------------------------------------------------------------------------- | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/hexbinary.h | |||||
// Created by : Steinberg, 1/2012 | |||||
// Description : HexBinary encoding and decoding | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/hexbinary.h | |||||
HexBinary encoding and decoding. */ | |||||
//---------------------------------------------------------------------------------- | |||||
#pragma once | |||||
#include "base/source/fbuffer.h" | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------------ | |||||
namespace HexBinary | |||||
{ | |||||
//------------------------------------------------------------------------------ | |||||
/** convert the HexBinary input buffer to binary. Note that it is appended to the result buffer. */ | |||||
//------------------------------------------------------------------------------ | |||||
inline bool decode (const void* input, int32 inputSize, Buffer& result) | |||||
{ | |||||
if ((inputSize & 1) == 1) | |||||
return false; | |||||
result.grow (result.getSize () + inputSize / 2); | |||||
const char8* ptr = (const char8*)input; | |||||
uint8 current = 0; | |||||
for (int32 i = 0; i < inputSize; i++, ptr++) | |||||
{ | |||||
current *= 16; | |||||
if (*ptr >= 48 && *ptr <= 57) // 0, 1, 2, .., 9 | |||||
{ | |||||
current += *ptr - 48; | |||||
} | |||||
else if (*ptr >= 65 && *ptr <= 70) // A, B, .., F | |||||
{ | |||||
current += *ptr - 55; | |||||
} | |||||
else if (*ptr >= 97 && *ptr <= 102) // a, b, .., f | |||||
{ | |||||
current += *ptr - 87; | |||||
} | |||||
else | |||||
{ | |||||
// malformed | |||||
return false; | |||||
} | |||||
if (i % 2) | |||||
{ | |||||
if (result.put (current) == false) | |||||
return false; | |||||
current = 0; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** convert the binary input buffer to HexBinary. Note that it is appended to the result buffer. */ | |||||
//------------------------------------------------------------------------------ | |||||
inline bool encode (const void* input, int32 inputSize, Buffer& result) | |||||
{ | |||||
result.grow (result.getSize () + inputSize * 2); | |||||
const char8* ptr = (const char8*)input; | |||||
for (int32 i = 0; i < inputSize; i++, ptr++) | |||||
{ | |||||
char8 high = (*ptr & 0xF0) >> 4; | |||||
char8 low = (*ptr & 0x0F); | |||||
if (high > 9) | |||||
{ | |||||
if (result.put ((char8)(high + 55)) == false) | |||||
return false; | |||||
} | |||||
else | |||||
{ | |||||
if (result.put ((char8)(high + 48)) == false) | |||||
return false; | |||||
} | |||||
if (low > 9) | |||||
{ | |||||
if (result.put ((char8)(low + 55)) == false) | |||||
return false; | |||||
} | |||||
else | |||||
{ | |||||
if (result.put ((char8)(low + 48)) == false) | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace HexBinary | |||||
} // namespace Steinberg |
@@ -0,0 +1,329 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/timer.cpp | |||||
// Created by : Steinberg, 05/2006 | |||||
// Description : Timer class for receiving triggers at regular intervals | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/timer.h" | |||||
namespace Steinberg { | |||||
static bool timersEnabled = true; | |||||
//------------------------------------------------------------------------ | |||||
DisableDispatchingTimers::DisableDispatchingTimers () | |||||
{ | |||||
oldState = timersEnabled; | |||||
timersEnabled = false; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
DisableDispatchingTimers::~DisableDispatchingTimers () | |||||
{ | |||||
timersEnabled = oldState; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
namespace SystemTime { | |||||
//------------------------------------------------------------------------ | |||||
struct ZeroStartTicks | |||||
{ | |||||
static const uint64 startTicks; | |||||
static int32 getTicks32 () | |||||
{ | |||||
return static_cast<int32> (SystemTime::getTicks64 () - startTicks); | |||||
} | |||||
}; | |||||
const uint64 ZeroStartTicks::startTicks = SystemTime::getTicks64 (); | |||||
//------------------------------------------------------------------------ | |||||
int32 getTicks () | |||||
{ | |||||
return ZeroStartTicks::getTicks32 (); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace SystemTime | |||||
} // namespace Steinberg | |||||
#if MAC | |||||
#include <CoreFoundation/CoreFoundation.h> | |||||
#include <mach/mach_time.h> | |||||
#ifdef verify | |||||
#undef verify | |||||
#endif | |||||
namespace Steinberg { | |||||
namespace SystemTime { | |||||
struct MachTimeBase { | |||||
private: | |||||
struct mach_timebase_info timebaseInfo; | |||||
MachTimeBase () | |||||
{ | |||||
mach_timebase_info (&timebaseInfo); | |||||
} | |||||
static const MachTimeBase& instance () | |||||
{ | |||||
static MachTimeBase gInstance; | |||||
return gInstance; | |||||
} | |||||
public: | |||||
static double getTimeNanos () | |||||
{ | |||||
const MachTimeBase& timeBase = instance (); | |||||
double absTime = static_cast<double> (mach_absolute_time ()); | |||||
double d = (absTime / timeBase.timebaseInfo.denom) * timeBase.timebaseInfo.numer; // nano seconds | |||||
return d; | |||||
} | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
uint64 getTicks64 () | |||||
{ | |||||
return static_cast<uint64> (MachTimeBase::getTimeNanos () / 1000000.); | |||||
} | |||||
} // namespace SystemTime | |||||
//------------------------------------------------------------------------ | |||||
class MacPlatformTimer : public Timer | |||||
{ | |||||
public: | |||||
MacPlatformTimer (ITimerCallback* callback, uint32 milliseconds); | |||||
~MacPlatformTimer (); | |||||
void stop (); | |||||
bool verify () const { return platformTimer != 0; } | |||||
static void timerCallback (CFRunLoopTimerRef timer, void *info); | |||||
protected: | |||||
CFRunLoopTimerRef platformTimer; | |||||
ITimerCallback* callback; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
MacPlatformTimer::MacPlatformTimer (ITimerCallback* callback, uint32 milliseconds) | |||||
: platformTimer (0) | |||||
, callback (callback) | |||||
{ | |||||
if (callback) | |||||
{ | |||||
CFRunLoopTimerContext timerContext = {0}; | |||||
timerContext.info = this; | |||||
platformTimer = CFRunLoopTimerCreate (kCFAllocatorDefault, CFAbsoluteTimeGetCurrent () + milliseconds * 0.001, milliseconds * 0.001f, 0, 0, timerCallback, &timerContext); | |||||
if (platformTimer) | |||||
CFRunLoopAddTimer (CFRunLoopGetMain (), platformTimer, kCFRunLoopCommonModes); | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
MacPlatformTimer::~MacPlatformTimer () | |||||
{ | |||||
stop (); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void MacPlatformTimer::stop () | |||||
{ | |||||
if (platformTimer) | |||||
{ | |||||
CFRunLoopRemoveTimer (CFRunLoopGetMain (), platformTimer, kCFRunLoopCommonModes); | |||||
CFRelease (platformTimer); | |||||
platformTimer = 0; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void MacPlatformTimer::timerCallback (CFRunLoopTimerRef , void *info) | |||||
{ | |||||
if (timersEnabled) | |||||
{ | |||||
MacPlatformTimer* timer = (MacPlatformTimer*)info; | |||||
if (timer) | |||||
{ | |||||
timer->callback->onTimer (timer); | |||||
} | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
Timer* Timer::create (ITimerCallback* callback, uint32 milliseconds) | |||||
{ | |||||
MacPlatformTimer* timer = NEW MacPlatformTimer (callback, milliseconds); | |||||
if (timer->verify ()) | |||||
return timer; | |||||
timer->release (); | |||||
return 0; | |||||
} | |||||
} | |||||
#elif WINDOWS | |||||
#include <windows.h> | |||||
#include <list> | |||||
#include <algorithm> | |||||
namespace Steinberg { | |||||
namespace SystemTime { | |||||
/* | |||||
@return the current system time in milliseconds | |||||
*/ | |||||
uint64 getTicks64 () | |||||
{ | |||||
return GetTickCount64 (); | |||||
} | |||||
} | |||||
class WinPlatformTimer; | |||||
typedef std::list<WinPlatformTimer*> WinPlatformTimerList; | |||||
//------------------------------------------------------------------------ | |||||
// WinPlatformTimer | |||||
//------------------------------------------------------------------------ | |||||
class WinPlatformTimer : public Timer | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
WinPlatformTimer (ITimerCallback* callback, uint32 milliseconds); | |||||
~WinPlatformTimer (); | |||||
void stop (); | |||||
bool verify () const {return id != 0;} | |||||
//------------------------------------------------------------------------ | |||||
private: | |||||
UINT_PTR id; | |||||
ITimerCallback* callback; | |||||
static void addTimer (WinPlatformTimer* t); | |||||
static void removeTimer (WinPlatformTimer* t); | |||||
static void CALLBACK TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); | |||||
static WinPlatformTimerList* timers; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
WinPlatformTimerList* WinPlatformTimer::timers = 0; | |||||
//------------------------------------------------------------------------ | |||||
WinPlatformTimer::WinPlatformTimer (ITimerCallback* callback, uint32 milliseconds) | |||||
: callback (callback) | |||||
{ | |||||
id = SetTimer (0, 0, milliseconds, TimerProc); | |||||
if (id) | |||||
addTimer (this); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
WinPlatformTimer::~WinPlatformTimer () | |||||
{ | |||||
stop (); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void WinPlatformTimer::addTimer (WinPlatformTimer* t) | |||||
{ | |||||
if (timers == 0) | |||||
timers = NEW WinPlatformTimerList; | |||||
timers->push_back (t); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void WinPlatformTimer::removeTimer (WinPlatformTimer* t) | |||||
{ | |||||
if (!timers) | |||||
return; | |||||
WinPlatformTimerList::iterator it = std::find (timers->begin (), timers->end (), t); | |||||
if (it != timers->end ()) | |||||
timers->erase (it); | |||||
if (timers->empty ()) | |||||
{ | |||||
delete timers; | |||||
timers = 0; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void WinPlatformTimer::stop () | |||||
{ | |||||
if (!id) | |||||
return; | |||||
KillTimer (0, id); | |||||
removeTimer (this); | |||||
id = 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void CALLBACK WinPlatformTimer::TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) | |||||
{ | |||||
if (timersEnabled && timers) | |||||
{ | |||||
WinPlatformTimerList::const_iterator it = timers->cbegin (); | |||||
while (it != timers->cend ()) | |||||
{ | |||||
WinPlatformTimer* timer = *it; | |||||
if (timer->id == idEvent) | |||||
{ | |||||
if (timer->callback) | |||||
timer->callback->onTimer (timer); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
Timer* Timer::create (ITimerCallback* callback, uint32 milliseconds) | |||||
{ | |||||
WinPlatformTimer* platformTimer = NEW WinPlatformTimer (callback, milliseconds); | |||||
if (platformTimer->verify ()) | |||||
return platformTimer; | |||||
platformTimer->release (); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg | |||||
#elif LINUX | |||||
#warning DEPRECATED No Linux implementation | |||||
#endif |
@@ -0,0 +1,165 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/timer.h | |||||
// Created by : Steinberg, 05/2006 | |||||
// Description : Timer class for receiving tiggers at regular intervals | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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 "fobject.h" | |||||
#include <limits> | |||||
namespace Steinberg { | |||||
class Timer; | |||||
//------------------------------------------------------------------------ | |||||
namespace SystemTime { | |||||
uint64 getTicks64 (); | |||||
inline uint64 getTicksDuration (uint64 old, uint64 now) | |||||
{ | |||||
if (old > now) | |||||
return (std::numeric_limits<uint64>::max) () - old + now; | |||||
return now - old; | |||||
} | |||||
int32 getTicks (); ///< deprecated, use getTicks64 () | |||||
//------------------------------------------------------------------------ | |||||
} // SystemTime | |||||
//------------------------------------------------------------------------ | |||||
/** @class ITimerCallback | |||||
Implement this callback interface to receive triggers from a timer. | |||||
Note: This interface is intended as a mix-in class and therefore does not provide refcounting. | |||||
@see Timer */ | |||||
//------------------------------------------------------------------------ | |||||
class ITimerCallback | |||||
{ | |||||
public: | |||||
virtual ~ITimerCallback () {} | |||||
/** This method is called at the end of each interval. | |||||
\param timer The timer which calls. | |||||
*/ | |||||
virtual void onTimer (Timer* timer) = 0; | |||||
}; | |||||
template <typename Call> | |||||
ITimerCallback* newTimerCallback (const Call& call) | |||||
{ | |||||
struct Callback : public ITimerCallback | |||||
{ | |||||
Callback (const Call& call) : call (call) {} | |||||
void onTimer (Timer* timer) SMTG_OVERRIDE { call (timer); } | |||||
Call call; | |||||
}; | |||||
return NEW Callback (call); | |||||
} | |||||
// ----------------------------------------------------------------- | |||||
/** @class Timer | |||||
Timer is a class that allows you to receive triggers at regular intervals. | |||||
Note: The timer class is an abstract base class with (hidden) platform specific subclasses. | |||||
Usage: | |||||
@code | |||||
class TimerReceiver : public FObject, public ITimerCallback | |||||
{ | |||||
... | |||||
virtual void onTimer (Timer* timer) | |||||
{ | |||||
// do stuff | |||||
} | |||||
... | |||||
}; | |||||
TimerReceiver* receiver = new TimerReceiver (); | |||||
Timer* myTimer = Timer::create (receiver, 100); // interval: every 100ms | |||||
... | |||||
... | |||||
if (myTimer) | |||||
myTimer->release (); | |||||
if (receiver) | |||||
receiver->release (); | |||||
@endcode | |||||
@see ITimerCallback | |||||
*/ | |||||
// ----------------------------------------------------------------- | |||||
class Timer : public FObject | |||||
{ | |||||
public: | |||||
/** Create a timer with a given interval | |||||
\param callback The receiver of the timer calls. | |||||
\param intervalMilliseconds The timer interval in milliseconds. | |||||
\return The created timer if any, callers owns the timer. The timer starts immediately. | |||||
*/ | |||||
static Timer* create (ITimerCallback* callback, uint32 intervalMilliseconds); | |||||
virtual void stop () = 0; ///< Stop the timer. | |||||
}; | |||||
// ----------------------------------------------------------------- | |||||
/** @class DisableDispatchingTimers | |||||
Disables dispatching of timers for the live time of this object | |||||
*/ | |||||
// ----------------------------------------------------------------- | |||||
class DisableDispatchingTimers | |||||
{ | |||||
public: | |||||
DisableDispatchingTimers (); | |||||
~DisableDispatchingTimers (); | |||||
private: | |||||
bool oldState; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,667 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/updatehandler.cpp | |||||
// Created by : Steinberg, 2008 | |||||
// Description : | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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" | |||||
#include <list> | |||||
#include <map> | |||||
#include <algorithm> | |||||
#define NON_EXISTING_DEPENDENCY_CHECK 0 // not now, mm | |||||
#define CLASS_NAME_TRACKED DEVELOPMENT | |||||
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 = 0; | |||||
if (unknown) | |||||
unknown->queryInterface (FUnknown::iid, (void**)&result); | |||||
return owned (result); | |||||
} | |||||
#if CLASS_NAME_TRACKED | |||||
//------------------------------------------------------------------------ | |||||
struct Dependency | |||||
{ | |||||
Dependency (FUnknown* o = 0, IDependent* d = 0) : obj (o), dep (d), objClass (0), depClass (0) | |||||
{ | |||||
} | |||||
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 = 0, 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 = 0, IDependent** d = 0, uint32 c = 0) | |||||
: 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; | |||||
} | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
typedef std::list<DeferedChange> DeferedChangeList; | |||||
typedef DeferedChangeList::const_iterator DeferedChangeListIterConst; | |||||
typedef std::list<UpdateData> UpdateDataList; | |||||
typedef UpdateDataList::const_iterator UpdateDataListIterConst; | |||||
#if CLASS_NAME_TRACKED | |||||
typedef std::list<Dependency> DependentList; | |||||
#else | |||||
typedef std::list<IDependent*> DependentList; | |||||
#endif | |||||
typedef DependentList::iterator DependentListIter; | |||||
typedef DependentList::const_iterator DependentListIterConst; | |||||
typedef std::map<const FUnknown*, DependentList> DependentMap; | |||||
typedef DependentMap::iterator DependentMapIter; | |||||
typedef DependentMap::const_iterator DependentMapIterConst; | |||||
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); | |||||
} | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
SINGLE_CREATE_FUNC (UpdateHandler) | |||||
//------------------------------------------------------------------------ | |||||
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 (0) | |||||
{ | |||||
table = NEW Update::Table; | |||||
if (FObject::getUpdateHandler () == 0) | |||||
FObject::setUpdateHandler (this); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
UpdateHandler::~UpdateHandler () | |||||
{ | |||||
if (FObject::getUpdateHandler () == this) | |||||
FObject::setUpdateHandler (0); | |||||
delete table; | |||||
table = 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
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[u] = list; | |||||
} | |||||
else | |||||
{ | |||||
(*it).second.push_back (dependent); | |||||
} | |||||
return kResultTrue; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* dependent) | |||||
{ | |||||
IPtr<FUnknown> unknown = Update::getUnknownBase (u); | |||||
if (unknown == 0 && dependent == 0) | |||||
return kResultFalse; | |||||
FGuard guard (lock); | |||||
Update::UpdateDataListIterConst iter = table->updateData.begin (); | |||||
while (iter != table->updateData.end ()) | |||||
{ | |||||
if ((*iter).obj == unknown || unknown == 0) | |||||
{ | |||||
for (uint32 count = 0; count < (*iter).count; count++) | |||||
{ | |||||
if ((*iter).dependents[count] == dependent) | |||||
(*iter).dependents[count] = 0; | |||||
} | |||||
} | |||||
++iter; | |||||
} | |||||
// Remove all objects for the given dependent | |||||
if (unknown == 0) | |||||
{ | |||||
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 (); | |||||
while (iterList != list.end ()) | |||||
{ | |||||
if ((*iterList) == dependent) | |||||
list.erase (iterList++); | |||||
else | |||||
++iterList; | |||||
} | |||||
++iterMap; | |||||
} | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
bool mustFlush = true; | |||||
Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)]; | |||||
Update::DependentMapIter iterList = map.find (unknown); | |||||
#if NON_EXISTING_DEPENDENCY_CHECK | |||||
ASSERT (iterList != map.end () && "ERROR: Trying to remove a non existing dependency!") | |||||
#endif | |||||
if (iterList != map.end ()) | |||||
{ | |||||
if (dependent == 0) // Remove all dependents of object | |||||
{ | |||||
map.erase (iterList); | |||||
} | |||||
else // Remove one dependent | |||||
{ | |||||
int32 eraseCount = 0; | |||||
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 | |||||
{ | |||||
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 | |||||
{ | |||||
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::DeferedChangeListIterConst it = | |||||
std::find (table->defered.begin (), table->defered.end (), tmp); | |||||
if (it == table->defered.end ()) | |||||
{ | |||||
lock.unlock (); | |||||
return kResultTrue; | |||||
} | |||||
if ((*it).obj != 0) | |||||
{ | |||||
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); | |||||
table->defered.remove (change); | |||||
return kResultTrue; | |||||
} | |||||
#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 | |||||
} | |||||
++iterList; | |||||
} | |||||
} | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,131 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// Version : 1.0 | |||||
// | |||||
// Category : Helpers | |||||
// Filename : base/source/updatehandler.h | |||||
// Created by : Steinberg, 2008 | |||||
// Description : | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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/source/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 = 0) = 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 (); | |||||
// IUpdateHandler | |||||
/** register \param dependent to get messages from \param object */ | |||||
virtual tresult PLUGIN_API addDependent (FUnknown* object, IDependent* dependent) SMTG_OVERRIDE; | |||||
/** unregister \param dependent to get no messages from \param object */ | |||||
virtual tresult PLUGIN_API removeDependent (FUnknown* object, | |||||
IDependent* dependent) SMTG_OVERRIDE; | |||||
/** send \param message to all dependents of \param object immediately */ | |||||
virtual tresult PLUGIN_API triggerUpdates (FUnknown* object, int32 message) SMTG_OVERRIDE; | |||||
/** send \param message to all dependents of \param object when idle */ | |||||
virtual 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 */ | |||||
virtual tresult PLUGIN_API cancelUpdates (FUnknown* object) SMTG_OVERRIDE; | |||||
/** send pending messages send by \param object or by any if object is 0 */ | |||||
virtual tresult PLUGIN_API triggerDeferedUpdates (FUnknown* object = 0) SMTG_OVERRIDE; | |||||
/// @cond ignore | |||||
// obsolete functions kept for compatibility | |||||
void checkUpdates (FObject* object = 0) { triggerDeferedUpdates (object->unknownCast ()); } | |||||
void flushUpdates (FObject* object) { cancelUpdates (object->unknownCast ()); } | |||||
void deferUpdate (FObject* object, int32 message) | |||||
{ | |||||
deferUpdates (object->unknownCast (), message); | |||||
} | |||||
void signalChange (FObject* object, int32 message, bool suppressUpdateDone = false) | |||||
{ | |||||
doTriggerUpdates (object->unknownCast (), message, suppressUpdateDone); | |||||
} | |||||
#if DEVELOPMENT | |||||
bool checkDeferred (FUnknown* object); | |||||
bool hasDependencies (FUnknown* object); | |||||
void printForObject (FObject* object) const; | |||||
#endif | |||||
/// @endcond | |||||
OBJ_METHODS (UpdateHandler, FObject) | |||||
FUNKNOWN_METHODS2 (IUpdateHandler, IUpdateManager, FObject) | |||||
SINGLETON (UpdateHandler) | |||||
//------------------------------------------------------------------------------ | |||||
private: | |||||
tresult doTriggerUpdates (FUnknown* object, int32 message, bool suppressUpdateDone); | |||||
FLock lock; | |||||
Update::Table* table; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,41 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// LICENSE | |||||
// (c) 2017, 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 | |||||
//---------------------------------------------------------------------------------- |
@@ -0,0 +1,106 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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; | |||||
} | |||||
//---------------------------------------------------------------------------- | |||||
const 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 |
@@ -0,0 +1,45 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 */ | |||||
const char16 getString (const char8 str) const; | |||||
protected: | |||||
ConstStringTable (); | |||||
~ConstStringTable (); | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg | |||||
@@ -0,0 +1,29 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 TARGET_API_MAC_CARBON | |||||
#if PLATFORM_64 | |||||
#pragma pack(pop) | |||||
#else | |||||
#pragma options align=reset | |||||
#endif | |||||
#elif defined __BORLANDC__ | |||||
#pragma -a- | |||||
#elif WINDOWS | |||||
#pragma pack(pop) | |||||
#endif | |||||
//--------------------------------------------------------------------------------------------------- |
@@ -0,0 +1,34 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 TARGET_API_MAC_CARBON | |||||
#if PLATFORM_64 | |||||
#pragma pack(push, 16) | |||||
#else | |||||
#pragma options align=mac68k | |||||
#endif | |||||
#elif defined __BORLANDC__ | |||||
#pragma -a8 | |||||
#elif WINDOWS | |||||
#pragma pack(push) | |||||
#if PLATFORM_64 | |||||
#pragma pack(16) | |||||
#else | |||||
#pragma pack(8) | |||||
#endif | |||||
#endif | |||||
//---------------------------------------------------------------------------------------------- |
@@ -0,0 +1,147 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 | |||||
#define kLittleEndian 0 | |||||
#define kBigEndian 1 | |||||
#undef PLUGIN_API | |||||
#undef WINDOWS | |||||
#undef MAC | |||||
//----------------------------------------------------------------------------- | |||||
// WIN32 AND WIN64 | |||||
#if defined (_WIN32) | |||||
#define WINDOWS 1 | |||||
#define BYTEORDER kLittleEndian | |||||
#define COM_COMPATIBLE 1 | |||||
#define PLUGIN_API __stdcall | |||||
#ifndef _CRT_SECURE_NO_WARNINGS | |||||
#define _CRT_SECURE_NO_WARNINGS | |||||
#endif | |||||
#pragma warning (disable : 4244) // Conversion from 'type1' to 'type2', possible loss of data. | |||||
#pragma warning (disable : 4250) // Inheritance via dominance is allowed | |||||
#pragma warning (disable : 4996) // deprecated functions | |||||
#pragma warning (3 : 4189) // local variable is initialized but not referenced | |||||
#pragma warning (3 : 4238) // nonstandard extension used : class rvalue used as lvalue | |||||
#if defined (_WIN64) // WIN64 only | |||||
#define PLATFORM_64 1 | |||||
#endif | |||||
#ifndef WIN32 | |||||
#define WIN32 1 | |||||
#endif | |||||
#ifdef __cplusplus | |||||
#define SMTG_CPP11 __cplusplus >= 201103L || _MSC_VER > 1600 || __INTEL_CXX11_MODE__ | |||||
#define SMTG_CPP11_STDLIBSUPPORT SMTG_CPP11 | |||||
#endif | |||||
//----------------------------------------------------------------------------- | |||||
// LINUX | |||||
#elif __gnu_linux__ | |||||
#define LINUX 1 | |||||
#include <endian.h> | |||||
#if __BYTE_ORDER == __LITTLE_ENDIAN | |||||
#define BYTEORDER kLittleEndian | |||||
#else | |||||
#define BYTEORDER kBigEndian | |||||
#endif | |||||
#define COM_COMPATIBLE 0 | |||||
#define PLUGIN_API | |||||
#define PTHREADS 1 | |||||
#if __LP64__ | |||||
#define PLATFORM_64 1 | |||||
#endif | |||||
#ifdef __cplusplus | |||||
#include <cstddef> | |||||
#define SMTG_CPP11 (__cplusplus >= 201103L) | |||||
#ifndef SMTG_CPP11 | |||||
#error unsupported compiler | |||||
#endif | |||||
#define SMTG_CPP11_STDLIBSUPPORT 1 | |||||
#endif | |||||
//----------------------------------------------------------------------------- | |||||
// Mac and iOS | |||||
#elif __APPLE__ | |||||
#include <TargetConditionals.h> | |||||
#define MAC 1 | |||||
#define PTHREADS 1 | |||||
#if !TARGET_OS_IPHONE | |||||
#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 PLATFORM_64 1 | |||||
#endif | |||||
#if defined (__BIG_ENDIAN__) | |||||
#define BYTEORDER kBigEndian | |||||
#else | |||||
#define BYTEORDER kLittleEndian | |||||
#endif | |||||
#define COM_COMPATIBLE 0 | |||||
#define PLUGIN_API | |||||
#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 || __INTEL_CXX11_MODE__) | |||||
#if defined (_LIBCPP_VERSION) && SMTG_CPP11 | |||||
#define SMTG_CPP11_STDLIBSUPPORT 1 | |||||
#else | |||||
#define SMTG_CPP11_STDLIBSUPPORT 0 | |||||
#endif | |||||
#endif | |||||
#else | |||||
#pragma error unknown platform | |||||
#endif | |||||
//----------------------------------------------------------------------------- | |||||
//----------------------------------------------------------------------------- | |||||
#if SMTG_CPP11 | |||||
#define SMTG_OVERRIDE override | |||||
#else | |||||
#define SMTG_OVERRIDE | |||||
#endif |
@@ -0,0 +1,291 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 | |||||
#if WINDOWS | |||||
#define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(L,x) | |||||
#else | |||||
#define STR16(x) SMTG_CPP11_CAT_PRIVATE_DONT_USE(u,x) | |||||
#endif | |||||
#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 WINDOWS | |||||
#define FORMAT_INT64A "I64d" | |||||
#define FORMAT_UINT64A "I64u" | |||||
#elif MAC || 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 WINDOWS | |||||
#define ENDLINE_A "\r\n" | |||||
#define ENDLINE_W STR ("\r\n") | |||||
#elif MAC | |||||
#define ENDLINE_A "\r" | |||||
#define ENDLINE_W STR ("\r") | |||||
#elif LINUX | |||||
#define ENDLINE_A "\n" | |||||
#define ENDLINE_W STR ("\n") | |||||
#endif | |||||
#ifdef UNICODE | |||||
#define ENDLINE ENDLINE_W | |||||
#else | |||||
#define ENDLINE ENDLINE_A | |||||
#endif | |||||
#if WINDOWS && !defined(__GNUC__) && defined(_MSC_VER) && (_MSC_VER < 1900) | |||||
#define stricmp _stricmp | |||||
#define strnicmp _strnicmp | |||||
#define snprintf _snprintf | |||||
#endif | |||||
namespace Steinberg { | |||||
//---------------------------------------------------------------------------- | |||||
static const tchar kEmptyString[] = { 0 }; | |||||
static const char8 kEmptyString8[] = { 0 }; | |||||
static const char16 kEmptyString16[] = { 0 }; | |||||
#ifdef UNICODE | |||||
static const tchar kInfiniteSymbol[] = { 0x221E, 0 }; | |||||
#else | |||||
static const tchar* const kInfiniteSymbol = STR ("oo"); | |||||
#endif | |||||
//---------------------------------------------------------------------------- | |||||
template <class T> | |||||
inline int32 _tstrlen (const T* wcs) | |||||
{ | |||||
const T* eos = wcs; | |||||
while (*eos++) | |||||
; | |||||
return (int32) (eos - wcs - 1); | |||||
} | |||||
inline int32 tstrlen (const tchar* str) {return _tstrlen (str);} | |||||
inline int32 strlen8 (const char8* str) {return _tstrlen (str);} | |||||
inline int32 strlen16 (const char16* str) {return _tstrlen (str);} | |||||
//---------------------------------------------------------------------------- | |||||
template <class T> | |||||
inline int32 _tstrcmp (const T* src, const T* dst) | |||||
{ | |||||
while (*src == *dst && *dst) | |||||
{ | |||||
src++; | |||||
dst++; | |||||
} | |||||
if (*src == 0 && *dst == 0) | |||||
return 0; | |||||
else if (*src == 0) | |||||
return -1; | |||||
else if (*dst == 0) | |||||
return 1; | |||||
else | |||||
return (int32) (*src - *dst); | |||||
} | |||||
inline int32 tstrcmp (const tchar* src, const tchar* dst) {return _tstrcmp (src, dst);} | |||||
inline int32 strcmp8 (const char8* src, const char8* dst) {return _tstrcmp (src, dst);} | |||||
inline int32 strcmp16 (const char16* src, const char16* dst) {return _tstrcmp (src, dst);} | |||||
template <typename T> | |||||
inline int32 strcmpT (const T* first, const T* last); | |||||
template <> | |||||
inline int32 strcmpT<char8> (const char8* first, const char8* last) { return _tstrcmp (first, last); } | |||||
template <> | |||||
inline int32 strcmpT<char16> (const char16* first, const char16* last) { return _tstrcmp (first, last); } | |||||
//---------------------------------------------------------------------------- | |||||
template <class T> | |||||
inline 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; | |||||
else if (*first == 0) | |||||
return -1; | |||||
else if (*last == 0) | |||||
return 1; | |||||
else | |||||
return (int32) (*first - *last); | |||||
} | |||||
inline int32 tstrncmp (const tchar* first, const tchar* last, uint32 count) {return _tstrncmp (first, last, count);} | |||||
inline int32 strncmp8 (const char8* first, const char8* last, uint32 count) {return _tstrncmp (first, last, count);} | |||||
inline int32 strncmp16 (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count);} | |||||
template <typename T> | |||||
inline int32 strncmpT (const T* first, const T* last, uint32 count); | |||||
template <> | |||||
inline int32 strncmpT<char8> (const char8* first, const char8* last, uint32 count) { return _tstrncmp (first, last, count); } | |||||
template <> | |||||
inline int32 strncmpT<char16> (const char16* first, const char16* last, uint32 count) {return _tstrncmp (first, last, count); } | |||||
//---------------------------------------------------------------------------- | |||||
template <class T> | |||||
inline T* _tstrcpy (T* dst, const T* src) | |||||
{ | |||||
T* cp = dst; | |||||
while ((*cp++ = *src++) != 0) // copy string | |||||
; | |||||
return dst; | |||||
} | |||||
inline tchar* tstrcpy (tchar* dst, const tchar* src) {return _tstrcpy (dst, src);} | |||||
inline char8* strcpy8 (char8* dst, const char8* src) {return _tstrcpy (dst, src);} | |||||
inline char16* strcpy16 (char16* dst, const char16* src) {return _tstrcpy (dst, src);} | |||||
//---------------------------------------------------------------------------- | |||||
template <class T> | |||||
inline 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 tchar* tstrncpy (tchar* dest, const tchar* source, uint32 count) {return _tstrncpy (dest, source, count);} | |||||
inline char8* strncpy8 (char8* dest, const char8* source, uint32 count) {return _tstrncpy (dest, source, count);} | |||||
inline char16* strncpy16 (char16* dest, const char16* source, uint32 count) {return _tstrncpy (dest, source, count);} | |||||
//---------------------------------------------------------------------------- | |||||
template <class T> | |||||
inline 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 tchar* tstrcat (tchar* dst, const tchar* src) {return _tstrcat (dst, src); } | |||||
inline char8* strcat8 (char8* dst, const char8* src) {return _tstrcat (dst, src); } | |||||
inline char16* strcat16 (char16* dst, const char16* src) {return _tstrcat (dst, src); } | |||||
//---------------------------------------------------------------------------- | |||||
inline void str8ToStr16 (char16* dst, const char8* src, int32 n = -1) | |||||
{ | |||||
int32 i = 0; | |||||
for (;;) | |||||
{ | |||||
if (i == n) | |||||
{ | |||||
dst[i] = 0; | |||||
return; | |||||
} | |||||
#if BYTEORDER == kBigEndian | |||||
char8* pChr = (char8*)&dst[i]; | |||||
pChr[0] = 0; | |||||
pChr[1] = src[i]; | |||||
#else | |||||
dst[i] = src[i]; | |||||
#endif | |||||
if (src[i] == 0) | |||||
break; | |||||
i++; | |||||
} | |||||
while (n > i) | |||||
{ | |||||
dst[i] = 0; | |||||
i++; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
inline bool FIDStringsEqual (FIDString id1, FIDString id2) | |||||
{ | |||||
return (id1 && id2) ? (strcmp8 (id1, id2) == 0) : false; | |||||
} | |||||
static const uint32 kPrintfBufferSize = 4096; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,192 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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" | |||||
//#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 unsigned char uint8; | |||||
typedef unsigned char uchar; | |||||
typedef short int16; | |||||
typedef unsigned short uint16; | |||||
#if WINDOWS && !defined(__GNUC__) | |||||
typedef long int32; | |||||
typedef unsigned long uint32; | |||||
#else | |||||
typedef int int32; | |||||
typedef unsigned int uint32; | |||||
#endif | |||||
static const int32 kMaxLong = 0x7fffffff; | |||||
static const int32 kMinLong = (-0x7fffffff - 1); | |||||
static const int32 kMaxInt32 = kMaxLong; | |||||
static const int32 kMinInt32 = kMinLong; | |||||
static const uint32 kMaxInt32u = 0xffffffff; | |||||
#if WINDOWS && !defined(__GNUC__) | |||||
typedef __int64 int64; | |||||
typedef unsigned __int64 uint64; | |||||
static const int64 kMaxInt64 = 9223372036854775807i64; | |||||
static const int64 kMinInt64 = (-9223372036854775807i64 - 1); | |||||
#else | |||||
typedef long long int64; | |||||
typedef unsigned long long uint64; | |||||
static const int64 kMaxInt64 = 0x7fffffffffffffffLL; | |||||
static const int64 kMinInt64 = (-0x7fffffffffffffffLL-1); | |||||
#endif | |||||
static const uint64 kMaxInt64u = uint64 (0xffffffff) | (uint64 (0xffffffff) << 32); | |||||
//----------------------------------------------------------------- | |||||
// 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 PLATFORM_64 | |||||
typedef uint64 TPtrInt; | |||||
#else | |||||
typedef uint32 TPtrInt; | |||||
#endif | |||||
//------------------------------------------------------------------ | |||||
// Boolean | |||||
typedef uint8 TBool; | |||||
//------------------------------------------------------------------ | |||||
// Char / Strings | |||||
typedef char char8; | |||||
#ifdef _NATIVE_WCHAR_T_DEFINED | |||||
typedef __wchar_t char16; | |||||
#elif SMTG_CPP11 | |||||
typedef char16_t char16; | |||||
#else | |||||
typedef int16 char16; | |||||
#endif | |||||
#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 WINDOWS | |||||
const FIDString kPlatformString = kPlatformStringWin; | |||||
#elif TARGET_OS_IPHONE | |||||
const FIDString kPlatformString = kPlatformStringIOS; | |||||
#elif MAC | |||||
const FIDString kPlatformString = kPlatformStringMac; | |||||
#elif 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 MAC || LINUX | |||||
#define SMTG_ALWAYS_INLINE __inline__ __attribute__((__always_inline__)) | |||||
#define SMTG_NEVER_INLINE __attribute__((noinline)) | |||||
#elif 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 |
@@ -0,0 +1,475 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 <stdio.h> | |||||
#if WINDOWS | |||||
#include <objbase.h> | |||||
#endif | |||||
#if MAC | |||||
#include <CoreFoundation/CoreFoundation.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 | |||||
#if LINUX | |||||
#include <ext/atomicity.h> | |||||
#endif | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------ | |||||
#if COM_COMPATIBLE | |||||
#if 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 WINDOWS | |||||
return _InterlockedExchangeAdd ((__LONG32 volatile *)&var, d) + d; | |||||
#elif MAC | |||||
return OSAtomicAdd32Barrier (d, (int32_t*)&var); | |||||
#elif LINUX | |||||
__gnu_cxx::__atomic_add (&var, d); | |||||
return var; | |||||
#else | |||||
#warning implement me! | |||||
var += d; | |||||
return var; | |||||
#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 WINDOWS | |||||
GUID guid; | |||||
HRESULT hr = CoCreateGuid (&guid); | |||||
switch (hr) | |||||
{ | |||||
case RPC_S_OK: | |||||
memcpy (data, (char*)&guid, sizeof (TUID)); | |||||
return true; | |||||
case RPC_S_UUID_LOCAL_ONLY: | |||||
default: | |||||
return false; | |||||
} | |||||
#elif MAC | |||||
CFUUIDRef uuid = CFUUIDCreate (kCFAllocatorDefault); | |||||
if (uuid) | |||||
{ | |||||
CFUUIDBytes bytes = CFUUIDGetUUIDBytes (uuid); | |||||
memcpy (data, (char*)&bytes, sizeof (TUID)); | |||||
CFRelease (uuid); | |||||
return true; | |||||
} | |||||
return false; | |||||
#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; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
FUID& FUID::operator = (FIDString uid) | |||||
{ | |||||
memcpy (data, uid, sizeof (TUID)); | |||||
return *this; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
FUID& FUID::operator = (TUID uid) | |||||
{ | |||||
memcpy (data, uid, 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 | |||||
GuidStruct* 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 | |||||
GuidStruct* 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); | |||||
sprintf (string, "{%s-%s-%s-%s-%s}", s1, s2, s3, s4, s5); | |||||
#endif | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void FUID::print (char8* string, int32 style) const | |||||
{ | |||||
if (!string) // no string: debug output | |||||
{ | |||||
char8 str [128]; | |||||
print (str, style); | |||||
#if 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: | |||||
sprintf (string, "INLINE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); | |||||
break; | |||||
case kDECLARE_UID: | |||||
sprintf (string, "DECLARE_UID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); | |||||
break; | |||||
case kFUID: | |||||
sprintf (string, "FUID (0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); | |||||
break; | |||||
case kCLASS_UID: | |||||
default: | |||||
sprintf (string, "DECLARE_CLASS_IID (Interface, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", l1, l2, l3, l4); | |||||
break; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
void FUID::toTUID (TUID result) const | |||||
{ | |||||
memcpy (result, data, sizeof (TUID)); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
// 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]; | |||||
sprintf (s, "%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 |
@@ -0,0 +1,456 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 <string.h> | |||||
//------------------------------------------------------------------------ | |||||
/*! \defgroup pluginBase Basic Interfaces | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
//------------------------------------------------------------------------ | |||||
// Unique Identifier macros | |||||
//------------------------------------------------------------------------ | |||||
#if COM_COMPATIBLE | |||||
#define INLINE_UID(l1, l2, l3, l4) \ | |||||
{ \ | |||||
(::Steinberg::int8)((l1 & 0x000000FF) ), (::Steinberg::int8)((l1 & 0x0000FF00) >> 8), \ | |||||
(::Steinberg::int8)((l1 & 0x00FF0000) >> 16), (::Steinberg::int8)((l1 & 0xFF000000) >> 24), \ | |||||
(::Steinberg::int8)((l2 & 0x00FF0000) >> 16), (::Steinberg::int8)((l2 & 0xFF000000) >> 24), \ | |||||
(::Steinberg::int8)((l2 & 0x000000FF) ), (::Steinberg::int8)((l2 & 0x0000FF00) >> 8), \ | |||||
(::Steinberg::int8)((l3 & 0xFF000000) >> 24), (::Steinberg::int8)((l3 & 0x00FF0000) >> 16), \ | |||||
(::Steinberg::int8)((l3 & 0x0000FF00) >> 8), (::Steinberg::int8)((l3 & 0x000000FF) ), \ | |||||
(::Steinberg::int8)((l4 & 0xFF000000) >> 24), (::Steinberg::int8)((l4 & 0x00FF0000) >> 16), \ | |||||
(::Steinberg::int8)((l4 & 0x0000FF00) >> 8), (::Steinberg::int8)((l4 & 0x000000FF) ) \ | |||||
} | |||||
#else | |||||
#define INLINE_UID(l1, l2, l3, l4) \ | |||||
{ \ | |||||
(::Steinberg::int8)((l1 & 0xFF000000) >> 24), (::Steinberg::int8)((l1 & 0x00FF0000) >> 16), \ | |||||
(::Steinberg::int8)((l1 & 0x0000FF00) >> 8), (::Steinberg::int8)((l1 & 0x000000FF) ), \ | |||||
(::Steinberg::int8)((l2 & 0xFF000000) >> 24), (::Steinberg::int8)((l2 & 0x00FF0000) >> 16), \ | |||||
(::Steinberg::int8)((l2 & 0x0000FF00) >> 8), (::Steinberg::int8)((l2 & 0x000000FF) ), \ | |||||
(::Steinberg::int8)((l3 & 0xFF000000) >> 24), (::Steinberg::int8)((l3 & 0x00FF0000) >> 16), \ | |||||
(::Steinberg::int8)((l3 & 0x0000FF00) >> 8), (::Steinberg::int8)((l3 & 0x000000FF) ), \ | |||||
(::Steinberg::int8)((l4 & 0xFF000000) >> 24), (::Steinberg::int8)((l4 & 0x00FF0000) >> 16), \ | |||||
(::Steinberg::int8)((l4 & 0x0000FF00) >> 8), (::Steinberg::int8)((l4 & 0x000000FF) ) \ | |||||
} | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
#define DECLARE_UID(name, l1, l2, l3, l4) \ | |||||
::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 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 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; } | |||||
#define FUNKNOWN_DTOR | |||||
//------------------------------------------------------------------------ | |||||
#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 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 int8 TUID[16]; ///< plain UID type | |||||
//------------------------------------------------------------------------ | |||||
/* 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 Globaly Unique Identifiers. | |||||
\ingroup pluginBase | |||||
Each interface declares its identifier as static member inside the interface | |||||
namespace (e.g. FUnknown::iid). | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class FUID | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
FUID (); | |||||
inline FUID (const TUID uid); | |||||
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); | |||||
FUID& operator = (FIDString uid); | |||||
FUID& operator = (TUID uid); | |||||
bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); } | |||||
bool operator == (FIDString uid) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, uid); } | |||||
bool operator == (TUID uid) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, uid); } | |||||
bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; } | |||||
bool operator < (FIDString uid) const { return memcmp (data, uid, sizeof (TUID)) < 0; } | |||||
bool operator < (TUID uid) const { return memcmp (data, uid, sizeof (TUID)) < 0; } | |||||
bool operator != (const FUID& f) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); } | |||||
bool operator != (FIDString uid) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, uid); } | |||||
bool operator != (TUID uid) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, uid); } | |||||
operator FIDString () const { return data; } | |||||
operator char* () { return 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 [64]; | |||||
/** Converts UID to a string. | |||||
The string will be 32 characters long, representing the hexadecimal values | |||||
of each data byte (e.g. "9127BE30160E4BB69966670AA6087880"). */ | |||||
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® OLE format. | |||||
(e.g. "{c200e360-38c5-11ce-ae62-08002b2b79ef}") */ | |||||
void toRegistryString (char8* string) const; | |||||
/** Sets the UID data from a string in Microsoft® 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 string is the output string if not NULL. | |||||
\param style can be chosen from the FUID::UIDPrintStyle enumeration. */ | |||||
void print (char8* string = 0, int32 style = kINLINE_UID) const; | |||||
void toTUID (TUID result) const; | |||||
inline const TUID& toTUID () const | |||||
{ | |||||
return data; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
protected: | |||||
TUID data; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
inline FUID::FUID (const TUID uid) | |||||
{ | |||||
memset (data, 0, sizeof (TUID)); | |||||
if (uid) | |||||
memcpy (data, uid, sizeof (TUID)); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
// 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 return 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 return 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 | |||||
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; } | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
template <class I> | |||||
inline FUnknownPtr<I>::FUnknownPtr (FUnknown* unknown) | |||||
{ | |||||
if (unknown && unknown->queryInterface (I::iid, (void**)&this->ptr) != kResultOk) | |||||
this->ptr = 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
template <class I> | |||||
inline I* FUnknownPtr<I>::operator=(FUnknown* unknown) | |||||
{ | |||||
I* newPtr = 0; | |||||
if (unknown && unknown->queryInterface (I::iid, (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 | |||||
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 | |||||
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 |
@@ -0,0 +1,92 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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; | |||||
else 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))); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,206 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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" | |||||
//------------------------------------------------------------------------ | |||||
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 (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 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; | |||||
} | |||||
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 : 0; } | |||||
inline const char16* getString16 () const { return (type & kString16) ? string16 : 0; } | |||||
inline FUnknown* getObject () const { return (type & kObject) ? object : 0; } | |||||
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 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 | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
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) | |||||
delete[] string8; | |||||
else if ((type & kString16) && string16) | |||||
delete[] string16; | |||||
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 = new char8[strlen (variant.string8) + 1]; | |||||
strcpy (const_cast<char8*> (string8), variant.string8); | |||||
type |= kOwner; | |||||
} | |||||
else if ((type & kString16) && variant.string16) | |||||
{ | |||||
int32 len = strlen16 (variant.string16); | |||||
string16 = new char16[len + 1]; | |||||
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 |
@@ -0,0 +1,96 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// Project : SDK Core | |||||
// | |||||
// Category : SDK Core Interfaces | |||||
// Filename : pluginterfaces/base/geoconstants.h | |||||
// Created by : Steinberg, 11/2014 | |||||
// Description : Defines orientations and directions as also used by fpoint.h and frect.h | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// 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 { | |||||
//------------------------------------------------------------------------ | |||||
enum Direction | |||||
{ | |||||
kNorth, | |||||
kNorthEast, | |||||
kEast, | |||||
kSouthEast, | |||||
kSouth, | |||||
kSouthWest, | |||||
kWest, | |||||
kNorthWest, | |||||
kNoDirection, //same position or center point of a geometry | |||||
kNumberOfDirections | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
enum Orientation | |||||
{ | |||||
kHorizontal, | |||||
kVertical, | |||||
kNumberOfOrientations | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
namespace GeoConstants { | |||||
//------------------------------------------------------------------------ | |||||
inline Direction toOpposite (Direction dir) | |||||
{ | |||||
switch (dir) | |||||
{ | |||||
case kNorth : return kSouth; | |||||
case kNorthEast : return kSouthWest; | |||||
case kEast : return kWest; | |||||
case kSouthEast : return kNorthWest; | |||||
case kSouth : return kNorth; | |||||
case kSouthWest : return kNorthEast; | |||||
case kWest : return kEast; | |||||
case kNorthWest : return kSouthEast; | |||||
case kNoDirection : return kNoDirection; | |||||
default: | |||||
return kNumberOfDirections; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
inline Orientation toOrientation (Direction dir) | |||||
{ | |||||
switch (dir) | |||||
{ | |||||
case kNorth : return kVertical; | |||||
case kEast : return kHorizontal; | |||||
case kSouth : return kVertical; | |||||
case kWest : return kHorizontal; | |||||
default: | |||||
return kNumberOfOrientations; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
inline Orientation toOrthogonalOrientation (Orientation dir) | |||||
{ | |||||
switch (dir) | |||||
{ | |||||
case kVertical : return kHorizontal; | |||||
case kHorizontal : return kVertical; | |||||
default: | |||||
return kNumberOfOrientations; | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // namespace GeoConstants | |||||
} // namespace Steinberg |
@@ -0,0 +1,89 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 = 0) = 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 = 0) = 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 = 0) = 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 |
@@ -0,0 +1,42 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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] \n | |||||
[released: N4.12] \n | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
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 |
@@ -0,0 +1,47 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// Project : SDK Core | |||||
// | |||||
// Category : SDK Core Interfaces | |||||
// Filename : pluginterfaces/base/ierrorcontext.h | |||||
// Created by : Steinberg, 02/2008 | |||||
// Description : Error Context 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 { | |||||
class IString; | |||||
//------------------------------------------------------------------------ | |||||
/** Interface for error handling. | |||||
[plug imp] \n | |||||
[released: Sequel 2] */ | |||||
//------------------------------------------------------------------------ | |||||
class IErrorContext : public FUnknown | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
/** Tells the plug-in to not show any UI elements on errors. */ | |||||
virtual void PLUGIN_API disableErrorUI (bool state) = 0; | |||||
/** If an error happens and disableErrorUI was not set this should return kResultTrue if the plug-in already showed a message to the user what happened. */ | |||||
virtual tresult PLUGIN_API errorMessageShown () = 0; | |||||
/** Fill message with error string. The host may show this to the user. */ | |||||
virtual tresult PLUGIN_API getErrorMessage (IString* message) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IErrorContext, 0x12BCD07B, 0x7C694336, 0xB7DA77C3, 0x444A0CD0) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,161 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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] \n | |||||
- 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] \n | |||||
[released] C7/N6 \n | |||||
\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 |
@@ -0,0 +1,398 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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. | |||||
\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. | |||||
@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 | |||||
{ | |||||
kNoFlags = 0, ///< Nothing | |||||
kClassesDiscardable = 1 << 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. | |||||
kLicenseCheck = 1 << 1, ///< Class IDs of components are interpreted as Syncrosoft-License (LICENCE_UID). Loaded in a Steinberg host, the module will not be loaded when the license is not valid | |||||
kComponentNonDiscardable = 1 << 3, ///< Component won't be unloaded until process exit | |||||
kUnicode = 1 << 4 ///< Components have entirely unicode encoded strings. (True for VST 3 Plug-ins so far) | |||||
}; | |||||
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 above) | |||||
//------------------------------------------------------------------------ | |||||
PFactoryInfo (const char8* _vendor, const char8* _url, const char8* _email, int32 _flags) | |||||
{ | |||||
strncpy8 (vendor, _vendor, kNameSize); | |||||
strncpy8 (url, _url, kURLSize); | |||||
strncpy8 (email, _email, kEmailSize); | |||||
flags = _flags; | |||||
#ifdef UNICODE | |||||
flags |= kUnicode; | |||||
#endif | |||||
} | |||||
PFactoryInfo () { memset (this, 0, sizeof (PFactoryInfo)); } | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Basic Information about a class provided by the Plug-in. | |||||
\ingroup pluginBase | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
struct PClassInfo | |||||
{ | |||||
//------------------------------------------------------------------------ | |||||
enum ClassCardinality | |||||
{ | |||||
kManyInstances = 0x7FFFFFFF | |||||
}; | |||||
enum | |||||
{ | |||||
kCategorySize = 32, | |||||
kNameSize = 64 | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
TUID cid; ///< Class ID 16 Byte class GUID | |||||
int32 cardinality; ///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality) | |||||
char8 category[kCategorySize]; ///< class category, host uses this to categorize interfaces | |||||
char8 name[kNameSize]; ///< class name, visible to the user | |||||
//------------------------------------------------------------------------ | |||||
PClassInfo (TUID _cid, int32 _cardinality, const char8* _category, const char8* _name) | |||||
{ | |||||
memset (this, 0, sizeof (PClassInfo)); | |||||
memcpy (cid, _cid, sizeof (TUID)); | |||||
if (_category) | |||||
strncpy8 (category, _category, kCategorySize); | |||||
if (_name) | |||||
strncpy8 (name, _name, kNameSize); | |||||
cardinality = _cardinality; | |||||
} | |||||
PClassInfo () { memset (this, 0, sizeof (PClassInfo)); } | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
// IPluginFactory interface declaration | |||||
//------------------------------------------------------------------------ | |||||
/** Class factory that any Plug-in defines for creating class instances. | |||||
\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 | |||||
{ | |||||
//------------------------------------------------------------------------ | |||||
TUID cid; ///< Class ID 16 Byte class GUID | |||||
int32 cardinality; ///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality) | |||||
char8 category[PClassInfo::kCategorySize]; ///< class category, host uses this to categorize interfaces | |||||
char8 name[PClassInfo::kNameSize]; ///< class name, visible to the user | |||||
enum { | |||||
kVendorSize = 64, | |||||
kVersionSize = 64, | |||||
kSubCategoriesSize = 128 | |||||
}; | |||||
uint32 classFlags; ///< flags used for a specific category, must be defined where category is defined | |||||
char8 subCategories[kSubCategoriesSize]; ///< module specific subcategories, can be more than one, logically added by the \c OR operator | |||||
char8 vendor[kVendorSize]; ///< overwrite vendor information from factory info | |||||
char8 version[kVersionSize]; ///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) | |||||
char8 sdkVersion[kVersionSize]; ///< SDK version used to build this class (e.g. "VST 3.0") | |||||
//------------------------------------------------------------------------ | |||||
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) | |||||
{ | |||||
memset (this, 0, sizeof (PClassInfo2)); | |||||
memcpy (cid, _cid, sizeof (TUID)); | |||||
cardinality = _cardinality; | |||||
if (_category) | |||||
strncpy8 (category, _category, PClassInfo::kCategorySize); | |||||
if (_name) | |||||
strncpy8 (name, _name, PClassInfo::kNameSize); | |||||
classFlags = _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); | |||||
} | |||||
PClassInfo2 () { memset (this, 0, sizeof (PClassInfo2)); } | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
// IPluginFactory2 interface declaration | |||||
//------------------------------------------------------------------------ | |||||
/** Version 2 of class factory supporting PClassInfo2. | |||||
\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 | |||||
}; | |||||
uint32 classFlags; ///< flags used for a specific category, must be defined where category is defined | |||||
char8 subCategories[kSubCategoriesSize];///< module specific subcategories, can be more than one, logically added by the \c OR operator | |||||
char16 vendor[kVendorSize]; ///< overwrite vendor information from factory info | |||||
char16 version[kVersionSize]; ///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) | |||||
char16 sdkVersion[kVersionSize]; ///< SDK version used to build this class (e.g. "VST 3.0") | |||||
//------------------------------------------------------------------------ | |||||
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) | |||||
{ | |||||
memset (this, 0, sizeof (PClassInfoW)); | |||||
memcpy (cid, _cid, sizeof (TUID)); | |||||
cardinality = _cardinality; | |||||
if (_category) | |||||
strncpy8 (category, _category, PClassInfo::kCategorySize); | |||||
if (_name) | |||||
strncpy16 (name, _name, PClassInfo::kNameSize); | |||||
classFlags = _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); | |||||
} | |||||
PClassInfoW () { memset (this, 0, sizeof (PClassInfoW)); } | |||||
void fromAscii (const PClassInfo2& ci2) | |||||
{ | |||||
memcpy (cid, ci2.cid, sizeof (TUID)); | |||||
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. | |||||
\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 | |||||
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" | |||||
{ | |||||
Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory (); | |||||
typedef Steinberg::IPluginFactory* (PLUGIN_API *GetFactoryProc) (); | |||||
} |
@@ -0,0 +1,80 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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] \n | |||||
[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] \n | |||||
[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 |
@@ -0,0 +1,100 @@ | |||||
//------------------------------------------------------------------------ | |||||
// 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] \n | |||||
[get this interface from IHostClasses] \n | |||||
[released N3.1] \n | |||||
- 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 |
@@ -0,0 +1,161 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// Project : SDK Core | |||||
// | |||||
// Category : SDK Core Interfaces | |||||
// Filename : pluginterfaces/base/keycodes.h | |||||
// Created by : Steinberg, 01/2004 | |||||
// Description : Key Code Definitions | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// 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 { | |||||
//------------------------------------------------------------------------------ | |||||
/** Virtual Key Codes. | |||||
OS-independent enumeration of virtual keycodes. | |||||
*/ | |||||
//------------------------------------------------------------------------------ | |||||
enum VirtualKeyCodes | |||||
{ | |||||
KEY_BACK = 1, | |||||
KEY_TAB, | |||||
KEY_CLEAR, | |||||
KEY_RETURN, | |||||
KEY_PAUSE, | |||||
KEY_ESCAPE, | |||||
KEY_SPACE, | |||||
KEY_NEXT, | |||||
KEY_END, | |||||
KEY_HOME, | |||||
KEY_LEFT, | |||||
KEY_UP, | |||||
KEY_RIGHT, | |||||
KEY_DOWN, | |||||
KEY_PAGEUP, | |||||
KEY_PAGEDOWN, | |||||
KEY_SELECT, | |||||
KEY_PRINT, | |||||
KEY_ENTER, | |||||
KEY_SNAPSHOT, | |||||
KEY_INSERT, | |||||
KEY_DELETE, | |||||
KEY_HELP, | |||||
KEY_NUMPAD0, | |||||
KEY_NUMPAD1, | |||||
KEY_NUMPAD2, | |||||
KEY_NUMPAD3, | |||||
KEY_NUMPAD4, | |||||
KEY_NUMPAD5, | |||||
KEY_NUMPAD6, | |||||
KEY_NUMPAD7, | |||||
KEY_NUMPAD8, | |||||
KEY_NUMPAD9, | |||||
KEY_MULTIPLY, | |||||
KEY_ADD, | |||||
KEY_SEPARATOR, | |||||
KEY_SUBTRACT, | |||||
KEY_DECIMAL, | |||||
KEY_DIVIDE, | |||||
KEY_F1, | |||||
KEY_F2, | |||||
KEY_F3, | |||||
KEY_F4, | |||||
KEY_F5, | |||||
KEY_F6, | |||||
KEY_F7, | |||||
KEY_F8, | |||||
KEY_F9, | |||||
KEY_F10, | |||||
KEY_F11, | |||||
KEY_F12, | |||||
KEY_NUMLOCK, | |||||
KEY_SCROLL, | |||||
KEY_SHIFT, | |||||
KEY_CONTROL, | |||||
KEY_ALT, | |||||
KEY_EQUALS, // only occurs on a Mac | |||||
KEY_CONTEXTMENU, // Windows only | |||||
// multimedia keys | |||||
KEY_MEDIA_PLAY, | |||||
KEY_MEDIA_STOP, | |||||
KEY_MEDIA_PREV, | |||||
KEY_MEDIA_NEXT, | |||||
KEY_VOLUME_UP, | |||||
KEY_VOLUME_DOWN, | |||||
KEY_F13, | |||||
KEY_F14, | |||||
KEY_F15, | |||||
KEY_F16, | |||||
KEY_F17, | |||||
KEY_F18, | |||||
KEY_F19, | |||||
VKEY_FIRST_CODE = KEY_BACK, | |||||
VKEY_LAST_CODE = KEY_F19, | |||||
VKEY_FIRST_ASCII = 128 | |||||
/* | |||||
KEY_0 - KEY_9 are the same as ASCII '0' - '9' (0x30 - 0x39) + FIRST_ASCII | |||||
KEY_A - KEY_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) + FIRST_ASCII | |||||
*/ | |||||
}; | |||||
//------------------------------------------------------------------------------ | |||||
inline tchar VirtualKeyCodeToChar (uint8 vKey) | |||||
{ | |||||
if (vKey >= VKEY_FIRST_ASCII) | |||||
return (tchar)(vKey - VKEY_FIRST_ASCII + 0x30); | |||||
else if (vKey == KEY_SPACE) | |||||
return ' '; | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
inline uint8 CharToVirtualKeyCode (tchar character) | |||||
{ | |||||
if ((character >= 0x30 && character <= 0x39) || (character >= 0x41 && character <= 0x5A)) | |||||
return (uint8)(character - 0x30 + VKEY_FIRST_ASCII); | |||||
if (character == ' ') | |||||
return (uint8)KEY_SPACE; | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
enum KeyModifier | |||||
{ | |||||
kShiftKey = 1 << 0, ///< same on both PC and Mac | |||||
kAlternateKey = 1 << 1, ///< same on both PC and Mac | |||||
kCommandKey = 1 << 2, ///< windows ctrl key; mac cmd key (apple button) | |||||
kControlKey = 1 << 3 ///< windows: not assigned, mac: ctrl key | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
struct KeyCode | |||||
{ | |||||
tchar character; | |||||
uint8 virt; | |||||
uint8 modifier; | |||||
explicit KeyCode (tchar character = 0, uint8 virt = 0, uint8 modifier = 0) | |||||
: character (character), virt (virt), modifier (modifier) | |||||
{ | |||||
} | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,32 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : SDK Base | |||||
// | |||||
// Category : SDK Core Interfaces | |||||
// Filename : pluginterfaces/base/pluginbasefwd.h | |||||
// Created by : Steinberg, 10/2014 | |||||
// Description : Forward declarations for pluginterfaces base module | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// 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 { | |||||
class FUnknown; | |||||
class FUID; | |||||
template <typename T> class IPtr; | |||||
class ICloneable; | |||||
class IDependent; | |||||
class IUpdateHandler; | |||||
class IBStream; | |||||
} // Steinberg |
@@ -0,0 +1,351 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 <memory> | |||||
#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) : ptr (nullptr) { *this = std::move (movePtr); } | |||||
inline IPtr& operator= (IPtr<I>&& movePtr) | |||||
{ | |||||
if (ptr) | |||||
ptr->release (); | |||||
ptr = movePtr.ptr; | |||||
movePtr.ptr = nullptr; | |||||
return *this; | |||||
} | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
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 (); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
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 | |||||
} // Steinberg |
@@ -0,0 +1,64 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// Project : SDK Core | |||||
// | |||||
// Category : SDK Core Interfaces | |||||
// Filename : pluginterfaces/base/ucolorspec.h | |||||
// Created by : Steinberg, 02/2006 (Host: S4.1) | |||||
// Description : GUI 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 "pluginterfaces/base/ftypes.h" | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------ | |||||
// Colors | |||||
typedef uint32 ColorSpec; | |||||
typedef uint8 ColorComponent; | |||||
typedef ColorSpec UColorSpec; // legacy support | |||||
typedef ColorComponent UColorComponent; // legacy support | |||||
/** Create color specifier with RGB values (alpha is opaque) */ | |||||
inline ColorSpec MakeColorSpec (ColorComponent r, ColorComponent g, ColorComponent b) | |||||
{ | |||||
return 0xFF000000 | ((ColorSpec)r) << 16 | ((ColorSpec)g) << 8 | (ColorSpec)b; | |||||
} | |||||
/** Create color specifier with RGBA values */ | |||||
inline ColorSpec MakeColorSpec (ColorComponent r, ColorComponent g, ColorComponent b, ColorComponent a) | |||||
{ | |||||
return ((ColorSpec)a) << 24 | ((ColorSpec)r) << 16 | ((ColorSpec)g) << 8 | (uint32)b; | |||||
} | |||||
inline ColorComponent GetBlue (ColorSpec cs) { return (ColorComponent)(cs & 0x000000FF); } | |||||
inline ColorComponent GetGreen (ColorSpec cs) { return (ColorComponent)((cs >> 8) & 0x000000FF); } | |||||
inline ColorComponent GetRed (ColorSpec cs) { return (ColorComponent)((cs >> 16) & 0x000000FF); } | |||||
inline ColorComponent GetAlpha (ColorSpec cs) { return (ColorComponent)((cs >> 24) & 0x000000FF); } | |||||
inline void SetBlue (ColorSpec& argb, ColorComponent b) { argb = (argb & 0xFFFFFF00) | (ColorSpec)(b); } | |||||
inline void SetGreen (ColorSpec& argb, ColorComponent g) { argb = (argb & 0xFFFF00FF) | (((ColorSpec)g) << 8); } | |||||
inline void SetRed (ColorSpec& argb, ColorComponent r) { argb = (argb & 0xFF00FFFF) | (((ColorSpec)r) << 16); } | |||||
inline void SetAlpha (ColorSpec& argb, ColorComponent a) { argb = (argb & 0x00FFFFFF) | (((ColorSpec)a) << 24); } | |||||
/** Normalized color components*/ | |||||
/** { */ | |||||
inline double NormalizeColorComponent (ColorComponent c) { return c / 255.0; } | |||||
inline ColorComponent DenormalizeColorComponent (double c) { return static_cast<ColorComponent> (c * 255.0); } | |||||
inline void SetAlphaNorm (ColorSpec& argb, double a) { SetAlpha (argb, DenormalizeColorComponent (a)); } | |||||
inline double GetAlphaNorm (ColorSpec cs) { return (NormalizeColorComponent (GetAlpha (cs))); } | |||||
inline double NormalizeAlpha (uint8 alpha) {return NormalizeColorComponent (alpha);} | |||||
inline ColorComponent DenormalizeAlpha (double alphaNorm) { return DenormalizeColorComponent (alphaNorm); } | |||||
/** } */ | |||||
inline ColorSpec StripAlpha (ColorSpec argb) { return (argb & 0x00FFFFFF); } | |||||
} |
@@ -0,0 +1,272 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 WINDOWS | |||||
#include <stdio.h> | |||||
#pragma warning (disable : 4996) | |||||
#elif MAC | |||||
#include <CoreFoundation/CoreFoundation.h> | |||||
#elif LINUX | |||||
#include <cstring> | |||||
#include <string> | |||||
#include <codecvt> | |||||
#include <sstream> | |||||
#include <locale> | |||||
#include <wctype.h> | |||||
#include <wchar.h> | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
//------------------------------------------------------------------------ | |||||
#if LINUX | |||||
//------------------------------------------------------------------------ | |||||
namespace { | |||||
using Converter = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>; | |||||
//------------------------------------------------------------------------ | |||||
Converter& converter () | |||||
{ | |||||
static Converter instance; | |||||
return instance; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
} // anonymous | |||||
//------------------------------------------------------------------------ | |||||
#endif // 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. */ | |||||
//------------------------------------------------------------------------ | |||||
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 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 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 WINDOWS | |||||
return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1; | |||||
#elif MAC | |||||
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 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 WINDOWS | |||||
return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1; | |||||
#elif MAC | |||||
CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false); | |||||
if (cfStr) | |||||
{ | |||||
value = CFStringGetIntValue (cfStr); | |||||
CFRelease (cfStr); | |||||
return true; | |||||
} | |||||
return false; | |||||
#elif 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 WINDOWS | |||||
return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1; | |||||
#elif MAC | |||||
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 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 |
@@ -0,0 +1,110 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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. */ | |||||
//------------------------------------------------------------------------ | |||||
class UString | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
UString (char16* buffer, int32 size) | |||||
: thisBuffer (buffer), | |||||
thisSize (size) | |||||
{} | |||||
int32 getSize () const { return thisSize; } ///< returns buffer size | |||||
operator const char16* () const { return thisBuffer; } ///< cast to char16* | |||||
/** Returns length of string (in code units). */ | |||||
int32 getLength () const; | |||||
/** Copy from UTF-16 buffer. */ | |||||
UString& assign (const char16* src, int32 srcSize = -1); | |||||
/** Append UTF-16 buffer. */ | |||||
UString& append (const char16* src, int32 srcSize = -1); | |||||
/** Copy to UTF-16 buffer. */ | |||||
const UString& copyTo (char16* dst, int32 dstSize) const; | |||||
/** Copy from ASCII string. */ | |||||
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; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** 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)) | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,238 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 "../base/funknown.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; } | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** \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. */ | |||||
const FIDString kPlatformTypeX11EmbedWindowID = "X11EmbedWindowID"; ///< X11 Window ID. (X11) | |||||
/*@}*/ | |||||
//------------------------------------------------------------------------ | |||||
//------------------------------------------------------------------------ | |||||
/** Plug-in definition of a view. | |||||
\ingroup pluginGUI | |||||
- [plug imp] | |||||
\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 </b> : If IPlugView::canResize () returns kResultTrue the host will setup 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 rect. The host then resizes the | |||||
window to this rect and has to call IPlugView::onSize (). | |||||
\n | |||||
\n | |||||
- <b> Plug-in </b> : The Plug-in can call IPlugFrame::resizeView () and cause the host to resize the | |||||
window. | |||||
Afterwards 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!! | |||||
Here the calling sequence: | |||||
* plug-in->host: IPlugFrame::resizeView (newSize) | |||||
* host->plug-in (optional): IPlugView::getSize () returns the currentSize (not the wanted | |||||
newSize)! | |||||
* host->plug-in: if newSize is different than its actual current size: IPlugView::onSize | |||||
(newSize) | |||||
* host->plug-in (optional): IPlugView::getSize () returns the newSize | |||||
\n | |||||
Please only resize the platform representation of the view when IPlugView::onSize () is called. | |||||
\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 | |||||
- [host imp] | |||||
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) | |||||
//------------------------------------------------------------------------ | |||||
class IPlugViewIdleHandler : public FUnknown | |||||
{ | |||||
public: | |||||
virtual void PLUGIN_API onPlugViewIdle () = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IPlugViewIdleHandler, 0x35BD6C3A, 0x9C1F4073, 0x89C7DA88, 0xBF6595D3) | |||||
//------------------------------------------------------------------------ | |||||
/** Extension to IPlugFrame | |||||
\ingroup pluginGUI | |||||
- [host impl] | |||||
Enables a Plug-in to add an idle handler to the main event loop (Linux only) | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class IPlugFrameIdle : public FUnknown | |||||
{ | |||||
public: | |||||
virtual tresult PLUGIN_API addIdleHandler (IPlugViewIdleHandler* handler) = 0; | |||||
virtual tresult PLUGIN_API removeIdleHandler (IPlugViewIdleHandler* handler) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IPlugFrameIdle, 0x31DE26C9, 0x36654639, 0x9F858E64, 0xE211817A) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,61 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// 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 | |||||
- [plug impl] | |||||
- [extends IPlugView] | |||||
- [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 after the plug view was attached and when the scale | |||||
factor changes (system change or window moved to another screen with different scaling settings) | |||||
When a plug-in handles this, it needs to scale the width and height of its view by the scale factor | |||||
and inform the host via a IPlugView::resizeView(). | |||||
*/ | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,151 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// Project : SDK Core | |||||
// Version : 1.0 | |||||
// | |||||
// Category : SDK Core Interfaces | |||||
// Filename : pluginterfaces/test/itest.h | |||||
// Created by : Steinberg, 01/2005 | |||||
// Description : Test Interface - Availability Depends on HOST | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// 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" | |||||
#ifndef kTestClass | |||||
#define kTestClass "Test Class" ///< A class for automated tests | |||||
#endif | |||||
namespace Steinberg { | |||||
class ITestResult; | |||||
//------------------------------------------------------------------------ | |||||
// ITest interface declaration | |||||
//------------------------------------------------------------------------ | |||||
class ITest : public FUnknown | |||||
{ | |||||
public: | |||||
//--- --------------------------------------------------------------------- | |||||
/** called immediately before the test is actually run. | |||||
Usually this will be used to setup the test environment. | |||||
\return true upon success */ | |||||
virtual bool PLUGIN_API setup () = 0; | |||||
/** execute the test. | |||||
\param testResult : points to a test result where the test can | |||||
(optionally) add an error message. | |||||
\return true upon success | |||||
\sa ITestResult */ | |||||
virtual bool PLUGIN_API run (ITestResult* testResult) = 0; | |||||
/** called after the test has run. This method shall be used to | |||||
deconstruct a test environment that has been setup with ITest::setup (). | |||||
\return true upon success */ | |||||
virtual bool PLUGIN_API teardown () = 0; | |||||
/** This function is used to provide information about the performed | |||||
testcase. What is done, what is validated and what has to be prepared | |||||
before executing the test (in case of half-automated tests). | |||||
\return null terminated string upon success, zero otherwise */ | |||||
virtual const tchar* PLUGIN_API getDescription () {return 0;} | |||||
//--- --------------------------------------------------------------------- | |||||
static const FUID iid; | |||||
}; | |||||
#ifdef UNICODE | |||||
DECLARE_CLASS_IID (ITest, 0xFE64FC19, 0x95684F53, 0xAAA78DC8, 0x7228338E) | |||||
#else | |||||
DECLARE_CLASS_IID (ITest, 0x9E2E608B, 0x64C64CF8, 0x839059BD, 0xA194032D) | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
// ITestResult interface declaration | |||||
//------------------------------------------------------------------------ | |||||
/** Test Result message logger | |||||
[host imp] | |||||
when a test is called, a pointer to an ITestResult is passed in, so the | |||||
test class can output error messages | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class ITestResult : public FUnknown | |||||
{ | |||||
public: | |||||
//--- --------------------------------------------------------------------- | |||||
/** add an error message */ | |||||
virtual void PLUGIN_API addErrorMessage (const tchar* msg) = 0; | |||||
virtual void PLUGIN_API addMessage (const tchar* msg) = 0; | |||||
//--- --------------------------------------------------------------------- | |||||
static const FUID iid; | |||||
}; | |||||
#ifdef UNICODE | |||||
DECLARE_CLASS_IID (ITestResult, 0x69796279, 0xF651418B, 0xB24D79B7, 0xD7C527F4) | |||||
#else | |||||
DECLARE_CLASS_IID (ITestResult, 0xCE13B461, 0x5334451D, 0xB3943E99, 0x7446885B) | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
// ITestSuite interface declaration | |||||
//------------------------------------------------------------------------ | |||||
/** A collection of tests supporting a hierarchical ordering | |||||
[host imp] | |||||
[create via hostclasses]*/ | |||||
//------------------------------------------------------------------------ | |||||
class ITestSuite : public FUnknown | |||||
{ | |||||
public: | |||||
//--- --------------------------------------------------------------------- | |||||
/** append a new test */ | |||||
virtual tresult PLUGIN_API addTest (FIDString name, ITest* test) = 0; | |||||
/** append an entire test suite as a child suite */ | |||||
virtual tresult PLUGIN_API addTestSuite (FIDString name, ITestSuite* testSuite) = 0; | |||||
virtual tresult PLUGIN_API setEnvironment (ITest* environment) = 0; | |||||
//--- --------------------------------------------------------------------- | |||||
static const FUID iid; | |||||
}; | |||||
#ifdef UNICODE | |||||
DECLARE_CLASS_IID (ITestSuite, 0x5CA7106F, 0x98784AA5, 0xB4D30D71, 0x2F5F1498) | |||||
#else | |||||
DECLARE_CLASS_IID (ITestSuite, 0x81724C94, 0xE9F64F65, 0xACB104E9, 0xCC702253) | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
// ITestFactory interface declaration | |||||
//------------------------------------------------------------------------ | |||||
/** Class factory that any testable module defines for creating tests | |||||
that will be executed from the host | |||||
[plug imp] \n | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class ITestFactory : public FUnknown | |||||
{ | |||||
public: | |||||
//--- --------------------------------------------------------------------- | |||||
/** create the tests that this module provides. | |||||
\param parentSuite : the test suite that the newly created tests | |||||
shall register with. */ | |||||
virtual tresult PLUGIN_API createTests (FUnknown* context, ITestSuite* parentSuite) = 0; | |||||
//--- --------------------------------------------------------------------- | |||||
static const FUID iid; | |||||
}; | |||||
#ifdef UNICODE | |||||
DECLARE_CLASS_IID (ITestFactory, 0xAB483D3A, 0x15264650, 0xBF86EEF6, 0x9A327A93) | |||||
#else | |||||
DECLARE_CLASS_IID (ITestFactory, 0xE77EA913, 0x58AA4838, 0x986A4620, 0x53579080) | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Steinberg |
@@ -0,0 +1,146 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [released: 3.0.0] | |||||
An attribute list associates values with a key (id: some predefined keys could 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). */ | |||||
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 size) = 0; | |||||
/** Sets binary data. */ | |||||
virtual tresult PLUGIN_API setBinary (AttrID id, const void* data, uint32 size) = 0; | |||||
/** Gets binary data. */ | |||||
virtual tresult PLUGIN_API getBinary (AttrID id, const void*& data, uint32& size) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IAttributeList, 0x1E5F0AEB, 0xCC7F4533, 0xA2544011, 0x38AD5EE4) | |||||
//------------------------------------------------------------------------ | |||||
/** Meta attributes of a stream. | |||||
\ingroup vstIHost vst360 | |||||
- [host imp] | |||||
- [extends IBStream] | |||||
- [released: 3.6.0] | |||||
\code | |||||
... | |||||
#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))) | |||||
{ | |||||
// 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 | |||||
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 this 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). */ | |||||
//------------------------------------------------------------------------ | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,348 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "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 */ | |||||
/*@{*/ | |||||
//------------------------------------------------------------------------ | |||||
const CString kFxAnalyzer = "Fx|Analyzer"; ///< Scope, FFT-Display, Loudness Processing... | |||||
const CString kFxDelay = "Fx|Delay"; ///< Delay, Multi-tap Delay, Ping-Pong Delay... | |||||
const CString kFxDistortion = "Fx|Distortion"; ///< Amp Simulator, Sub-Harmonic, SoftClipper... | |||||
const CString kFxDynamics = "Fx|Dynamics"; ///< Compressor, Expander, Gate, Limiter, Maximizer, Tape Simulator, EnvelopeShaper... | |||||
const CString kFxEQ = "Fx|EQ"; ///< Equalization, Graphical EQ... | |||||
const CString kFxFilter = "Fx|Filter"; ///< WahWah, ToneBooster, Specific Filter,... | |||||
const CString kFx = "Fx"; ///< others type (not categorized) | |||||
const CString kFxInstrument = "Fx|Instrument"; ///< Fx which could be loaded as Instrument too | |||||
const CString kFxInstrumentExternal = "Fx|Instrument|External"; ///< Fx which could be loaded as Instrument too and is external (wrapped Hardware) | |||||
const CString kFxSpatial = "Fx|Spatial"; ///< MonoToStereo, StereoEnhancer,... | |||||
const CString kFxGenerator = "Fx|Generator"; ///< Tone Generator, Noise Generator... | |||||
const CString kFxMastering = "Fx|Mastering"; ///< Dither, Noise Shaping,... | |||||
const CString kFxModulation = "Fx|Modulation"; ///< Phaser, Flanger, Chorus, Tremolo, Vibrato, AutoPan, Rotary, Cloner... | |||||
const CString kFxPitchShift = "Fx|Pitch Shift"; ///< Pitch Processing, Pitch Correction, Vocal Tuning... | |||||
const CString kFxRestoration = "Fx|Restoration"; ///< Denoiser, Declicker,... | |||||
const CString kFxReverb = "Fx|Reverb"; ///< Reverberation, Room Simulation, Convolution Reverb... | |||||
const CString kFxSurround = "Fx|Surround"; ///< dedicated to surround processing: LFE Splitter, Bass Manager... | |||||
const CString kFxTools = "Fx|Tools"; ///< Volume, Mixer, Tuner... | |||||
const CString kFxNetwork = "Fx|Network"; ///< using Network | |||||
const CString kInstrument = "Instrument"; ///< Effect used as instrument (sound generator), not as insert | |||||
const CString kInstrumentDrum = "Instrument|Drum"; ///< Instrument for Drum sounds | |||||
const CString kInstrumentSampler = "Instrument|Sampler"; ///< Instrument based on Samples | |||||
const CString kInstrumentSynth = "Instrument|Synth"; ///< Instrument based on Synthesis | |||||
const CString kInstrumentSynthSampler = "Instrument|Synth|Sampler"; ///< Instrument based on Synthesis and Samples | |||||
const CString kInstrumentExternal = "Instrument|External";///< External Instrument (wrapped Hardware) | |||||
const CString kSpatial = "Spatial"; ///< used for SurroundPanner | |||||
const CString kSpatialFx = "Spatial|Fx"; ///< used for SurroundPanner and as insert effect | |||||
const CString kOnlyRealTime = "OnlyRT"; ///< indicates that it supports only realtime process call, no processing faster than realtime | |||||
const CString kOnlyOfflineProcess = "OnlyOfflineProcess"; ///< used for Plug-in offline processing (will not work as normal insert Plug-in) | |||||
const CString kNoOfflineProcess = "NoOfflineProcess"; ///< will be NOT used for Plug-in offline processing (will work as normal insert Plug-in) | |||||
const CString kUpDownMix = "Up-Downmix"; ///< used for Mixconverter/Up-Mixer/Down-Mixer | |||||
const CString kAnalyzer = "Analyzer"; ///< Meter, Scope, FFT-Display, not selectable as insert plugin | |||||
const CString kMono = "Mono"; ///< used for Mono only Plug-in [optional] | |||||
const CString kStereo = "Stereo"; ///< used for Stereo only Plug-in [optional] | |||||
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 (0) {} | |||||
//------------------------------------------------------------------------ | |||||
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 */ | |||||
//------------------------------------------------------------------------ | |||||
struct ProcessData | |||||
{ | |||||
ProcessData () | |||||
: processMode (0), symbolicSampleSize (kSample32), numSamples (0), numInputs (0) | |||||
, numOutputs (0), inputs (0), outputs (0), inputParameterChanges (0), outputParameterChanges (0) | |||||
, inputEvents (0), outputEvents (0), processContext (0) {} | |||||
//------------------------------------------------------------------------ | |||||
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 buses | |||||
int32 numOutputs; ///< number of audio output buses | |||||
AudioBusBuffers* inputs; ///< buffers of input buses | |||||
AudioBusBuffers* outputs; ///< buffers of output buses | |||||
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. | |||||
\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 (from host) a predefined arrangement for inputs and outputs. | |||||
The host should always deliver the same number of input and output buses than the Plug-in needs | |||||
(see \ref IComponent::getBusCount). | |||||
The Plug-in returns kResultFalse if wanted arrangements are not supported. | |||||
If the Plug-in accepts these arrangements, it should modify its buses to match the new arrangements | |||||
(asked by the host with IComponent::getInfo () or IAudioProcessor::getBusArrangement ()) and then return kResultTrue. | |||||
If the Plug-in does not accept these arrangements, but can adapt its current arrangements (according to the wanted ones), | |||||
it should modify its buses arrangements and return 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::getInfo () and IAudioProcessor::getBusArrangement () should be always return the same | |||||
information about the buses 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 (not active) before 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. | |||||
In this call the Plug-in should do only light operation (no memory allocation or big setup reconfiguration), | |||||
this could be used to reset some buffers (like Delay line or Reverb). */ | |||||
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. | |||||
\ingroup vstIPlug vst310 | |||||
- [plug imp] | |||||
- [extends IAudioProcessor] | |||||
- [released: 3.1.0] | |||||
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 a Audio Device, then this initial input latency will be 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 a Audio Device then this initial output latency will be the output | |||||
latency of the Audio Device itself. | |||||
A value of zero means either 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. | |||||
\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) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpop.h" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,68 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 IComponent interface for a component. | |||||
\ingroup vstIPlug vst365 | |||||
- [plug imp] | |||||
- [extends IComponent] | |||||
- [released: 3.6.5] | |||||
- [optional] | |||||
Hosts could 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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,227 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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. | |||||
\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 could 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 | |||||
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 | |||||
typedef uint32 ColorSpec; ///< ARGB (Alpha-Red-Green-Blue) | |||||
typedef uint8 ColorComponent; | |||||
inline ColorComponent GetBlue (ColorSpec cs) {return (ColorComponent)(cs & 0x000000FF); } | |||||
inline ColorComponent GetGreen (ColorSpec cs) {return (ColorComponent)((cs >> 8) & 0x000000FF); } | |||||
inline ColorComponent GetRed (ColorSpec cs) {return (ColorComponent)((cs >> 16) & 0x000000FF); } | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,198 @@ | |||||
//----------------------------------------------------------------------------- | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "vsttypes.h" | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpush.h" | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
class IBStream; | |||||
//------------------------------------------------------------------------ | |||||
/** All VST specific interfaces are located in Vst namespace */ | |||||
//------------------------------------------------------------------------ | |||||
namespace Vst { | |||||
const int32 kDefaultFactoryFlags = PFactoryInfo::kUnicode; ///< Standard value for PFactoryInfo::flags | |||||
#define BEGIN_FACTORY_DEF(vendor,url,email) using namespace Steinberg; \ | |||||
EXPORT_FACTORY IPluginFactory* PLUGIN_API GetPluginFactory () { \ | |||||
if (!gPluginFactory) \ | |||||
{ static PFactoryInfo factoryInfo (vendor,url,email,Vst::kDefaultFactoryFlags); \ | |||||
gPluginFactory = new CPluginFactory (factoryInfo); | |||||
//------------------------------------------------------------------------ | |||||
/** \defgroup vstBus VST Buses | |||||
@{*/ | |||||
//------------------------------------------------------------------------ | |||||
/** 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) | |||||
//------------------------------------------------------------------------ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** 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 buses, but this number must \b never change. | |||||
Dynamic usage of buses is handled in the host by activating and deactivating buses. | |||||
The component has to define the maximum number of supported buses and it has to | |||||
define which of them are active by default. A host that can handle multiple buses, | |||||
allows the user to activate buses that were initially inactive. | |||||
See also: IComponent::getBusInfo , IComponent::activateBus | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
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 | |||||
{ | |||||
kDefaultActive = 1 << 0 ///< bus active per default | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
}; | |||||
/*@}*/ | |||||
//------------------------------------------------------------------------ | |||||
/** 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 buses, a host may want to know how the | |||||
buses 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 | |||||
\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. | |||||
*/ | |||||
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 buses are not activated */ | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,213 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "vsttypes.h" | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpush.h" | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
class IPlugView; | |||||
namespace Vst { | |||||
class IContextMenu; | |||||
//------------------------------------------------------------------------ | |||||
/** Extended Host callback interface IComponentHandler3 for an edit controller. | |||||
\ingroup vstIHost vst350 | |||||
- [host imp] | |||||
- [extends IComponentHandler] | |||||
- [released: 3.5.0] | |||||
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 pop-up it. See the \ref IContextMenuExample. | |||||
- extract the host menu items and add them to its own created context menu | |||||
\b Note: You can and should use this even if you don't add your own items to the menu as this is considered to be a big user value. | |||||
\sa IContextMenu | |||||
\sa IContextMenuTarget | |||||
\section IContextMenuExample Example | |||||
Adding Plug-in specific items to the context menu | |||||
\code | |||||
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 won't 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. | |||||
\ingroup vstIHost vstIPlug vst350 | |||||
- [host imp] | |||||
- [plug imp] | |||||
- [released: 3.5.0] | |||||
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. | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
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) | |||||
//------------------------------------------------------------------------ | |||||
/** Context Menu Interface. | |||||
\ingroup vstIHost vst350 | |||||
- [host imp] | |||||
- [create with IComponentHandler3::createContextMenu(..)] | |||||
- [released: 3.5.0] | |||||
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. | |||||
*/ | |||||
//------------------------------------------------------------------------ | |||||
class IContextMenu : public FUnknown | |||||
{ | |||||
public: | |||||
/** Item is a entry element of the context menu. */ | |||||
struct Item | |||||
{ | |||||
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 | |||||
}; | |||||
}; | |||||
/** 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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,400 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "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. */ | |||||
//------------------------------------------------------------------------ | |||||
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 a min = 0 and a 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 vst3UnitsIntro) | |||||
int32 flags; ///< ParameterFlags (see below) | |||||
enum ParameterFlags | |||||
{ | |||||
kCanAutomate = 1 << 0, ///< parameter can be automated | |||||
kIsReadOnly = 1 << 1, ///< parameter cannot be changed from outside (implies that kCanAutomate is false) | |||||
kIsWrapAround = 1 << 2, ///< attempts to set the parameter value out of the limits will result in a wrap around [SDK 3.0.2] | |||||
kIsList = 1 << 3, ///< parameter should be displayed as list in generic editor or automation editing [SDK 3.1.0] | |||||
kIsProgramChange = 1 << 15, ///< parameter is a program change (unitId gives info about associated unit | |||||
///< - see \ref vst3UnitPrograms) | |||||
kIsBypass = 1 << 16 ///< special bypass parameter (only one allowed): Plug-in can handle bypass | |||||
///< (highly recommended to export a bypass parameter for effect Plug-in) | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** View Types used for IEditController::createView */ | |||||
//------------------------------------------------------------------------ | |||||
namespace ViewType { | |||||
const CString kEditor = "editor"; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Flags used for IComponentHandler::restartComponent */ | |||||
//------------------------------------------------------------------------ | |||||
enum RestartFlags | |||||
{ | |||||
kReloadComponent = 1 << 0, ///< The Component should be reloaded [SDK 3.0.0] | |||||
kIoChanged = 1 << 1, ///< Input and/or Output Bus configuration has changed [SDK 3.0.0] | |||||
kParamValuesChanged = 1 << 2, ///< Multiple parameter values have changed | |||||
///< (as result of a program change for example) [SDK 3.0.0] | |||||
kLatencyChanged = 1 << 3, ///< Latency has changed (IAudioProcessor.getLatencySamples) [SDK 3.0.0] | |||||
kParamTitlesChanged = 1 << 4, ///< Parameter titles or default values or flags have changed [SDK 3.0.0] | |||||
kMidiCCAssignmentChanged = 1 << 5, ///< MIDI Controller Assignments have changed [SDK 3.0.1] | |||||
kNoteExpressionChanged = 1 << 6, ///< Note Expression has changed (info, count...) [SDK 3.5.0] | |||||
kIoTitlesChanged = 1 << 7, ///< Input and/or Output bus titles have changed [SDK 3.5.0] | |||||
kPrefetchableSupportChanged = 1 << 8, ///< Prefetch support has changed (\see IPrefetchableSupport) [SDK 3.6.1] | |||||
kRoutingInfoChanged = 1 << 9 ///< RoutingInfo has changed (\see IComponent) [SDK 3.6.6] | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Host callback interface for an edit controller. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [released: 3.0.0] | |||||
Allow transfer of parameter editing to component (processor) via host and support automation. | |||||
Cause the host to react on configuration changes (restartComponent) | |||||
\see IEditController */ | |||||
//------------------------------------------------------------------------ | |||||
class IComponentHandler: public FUnknown | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
/** To be called before calling a performEdit (e.g. on mouse-click-down event). */ | |||||
virtual tresult PLUGIN_API beginEdit (ParamID id) = 0; | |||||
/** Called between beginEdit and endEdit to inform the handler that a given parameter has a new value. */ | |||||
virtual tresult PLUGIN_API performEdit (ParamID id, ParamValue valueNormalized) = 0; | |||||
/** To be called after calling a performEdit (e.g. on mouse-click-up event). */ | |||||
virtual tresult PLUGIN_API endEdit (ParamID id) = 0; | |||||
/** Instructs host to restart the component. This should be called in the UI-Thread context! | |||||
\param flags is a combination of RestartFlags */ | |||||
virtual tresult PLUGIN_API restartComponent (int32 flags) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IComponentHandler, 0x93A0BEA3, 0x0BD045DB, 0x8E890B0C, 0xC1E46AC6) | |||||
//------------------------------------------------------------------------ | |||||
/** Extended Host callback interface IComponentHandler2 for an edit controller | |||||
\ingroup vstIHost vst310 | |||||
- [host imp] | |||||
- [extends IComponentHandler] | |||||
- [released: 3.1.0] | |||||
One part handles: | |||||
- Setting dirty state of Plug-in | |||||
- requesting the host to open the editor | |||||
The other part handles parameter group editing from Plug-in UI. It wraps a set of \ref IComponentHandler::beginEdit / | |||||
\ref IComponentHandler::performEdit / \ref IComponentHandler::endEdit functions (see \ref IComponentHandler) | |||||
which should use the same timestamp in the host when writing automation. | |||||
This allows for better synchronizing multiple parameter changes at once. | |||||
\section IComponentHandler2Example Examples of different use cases | |||||
\code | |||||
//-------------------------------------- | |||||
// 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 IComponentHandler | |||||
\see 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) = 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) | |||||
//------------------------------------------------------------------------ | |||||
/** Edit controller component interface. | |||||
\ingroup vstIPlug vst300 | |||||
- [plug imp] | |||||
- [released: 3.0.0] | |||||
The Controller part of an effect or instrument with parameter handling (export, definition, conversion...). | |||||
\see IComponent::getControllerClassId, IMidiMapping */ | |||||
//------------------------------------------------------------------------ | |||||
class IEditController: public IPluginBase | |||||
{ | |||||
public: | |||||
//------------------------------------------------------------------------ | |||||
/** Receives the component state. */ | |||||
virtual tresult PLUGIN_API setComponentState (IBStream* state) = 0; | |||||
/** Sets the controller state. */ | |||||
virtual tresult PLUGIN_API setState (IBStream* state) = 0; | |||||
/** Gets the controller state. */ | |||||
virtual tresult PLUGIN_API getState (IBStream* state) = 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, ParameterInfo& info /*out*/) = 0; | |||||
/** Gets for a given paramID and normalized value its associated string representation. */ | |||||
virtual tresult PLUGIN_API getParamStringByValue (ParamID id, ParamValue valueNormalized /*in*/, String128 string /*out*/) = 0; | |||||
/** Gets for a given paramID and string its normalized value. */ | |||||
virtual tresult PLUGIN_API getParamValueByString (ParamID id, TChar* string /*in*/, ParamValue& valueNormalized /*out*/) = 0; | |||||
/** Returns for a given paramID and a normalized value its plain representation | |||||
(for example 90 for 90db - see \ref vst3AutomationIntro). */ | |||||
virtual ParamValue PLUGIN_API normalizedParamToPlain (ParamID id, ParamValue valueNormalized) = 0; | |||||
/** Returns for a given paramID and a plain value its normalized value. (see \ref vst3AutomationIntro) */ | |||||
virtual ParamValue PLUGIN_API plainParamToNormalized (ParamID id, ParamValue plainValue) = 0; | |||||
/** Returns the normalized value of the parameter associated to the paramID. */ | |||||
virtual ParamValue PLUGIN_API getParamNormalized (ParamID id) = 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, ParamValue value) = 0; | |||||
// handler ---------------------------- | |||||
/** Gets from host a handler. */ | |||||
virtual tresult PLUGIN_API setComponentHandler (IComponentHandler* handler) = 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) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IEditController, 0xDCD7BBE3, 0x7742448D, 0xA874AACC, 0x979C759E) | |||||
//------------------------------------------------------------------------ | |||||
/** Knob Mode */ | |||||
//------------------------------------------------------------------------ | |||||
enum KnobModes | |||||
{ | |||||
kCircularMode = 0, ///< Circular with jump to clicked position | |||||
kRelativCircularMode, ///< Circular without jump to clicked position | |||||
kLinearMode ///< Linear: depending on vertical movement | |||||
}; | |||||
typedef int32 KnobMode; ///< Knob Mode | |||||
//------------------------------------------------------------------------ | |||||
/** Edit controller component interface extension. | |||||
\ingroup vstIPlug vst310 | |||||
- [plug imp] | |||||
- [extends IEditController] | |||||
- [released: 3.1.0] | |||||
Extension to inform the Plug-in about the host Knob Mode, | |||||
and to open the Plug-in about box or help documentation. | |||||
\see IEditController*/ | |||||
//------------------------------------------------------------------------ | |||||
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) = 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) = 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) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IEditController2, 0x7F4EFE59, 0xF3204967, 0xAC27A3AE, 0xAFB63038) | |||||
//------------------------------------------------------------------------ | |||||
/** MIDI Mapping Interface. | |||||
\ingroup vstIPlug vst301 | |||||
- [plug imp] | |||||
- [extends IEditController] | |||||
- [released: 3.0.1] | |||||
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 normal | |||||
parameter change. This allows the host to automate them in the same way as other parameters. | |||||
CtrlNumber could be typical MIDI controller value extended to some others values like pitch bend or | |||||
after touch (see \ref ControllerNumbers). | |||||
If the mapping has changed, the Plug-in should call IComponentHandler::restartComponent (kMidiCCAssignmentChanged) | |||||
to inform the host about this change. */ | |||||
//------------------------------------------------------------------------ | |||||
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[in] id - return the associated ParamID to the given midiControllerNumber | |||||
*/ | |||||
virtual tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel, | |||||
CtrlNumber midiControllerNumber, ParamID& id/*out*/) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IMidiMapping, 0xDF0FF9F7, 0x49B74669, 0xB63AB732, 0x7ADBF5E5) | |||||
//------------------------------------------------------------------------ | |||||
/** Parameter Editing from Host. | |||||
\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 flagged parameter (kind of helper parameter), | |||||
the host will start with a beginEditFromHost before calling setParamNormalized and end with an endEditFromHost. | |||||
Here the sequencing, the host will call: | |||||
- beginEditFromHost () | |||||
- setParamNormalized () | |||||
- setParamNormalized () | |||||
- ... | |||||
- endEditFromHost () | |||||
\see 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) = 0; | |||||
/** Called after a beginEditFromHost and a sequence of setParamNormalized. */ | |||||
virtual tresult PLUGIN_API endEditFromHost (ParamID paramID) = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IEditControllerHostEditing, 0xC1271208, 0x70594098, 0xB9DD34B3, 0x6BB0195E) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpop.h" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,180 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// Category : Interfaces | |||||
// Filename : pluginterfaces/vst/ivstevents.h | |||||
// Created by : Steinberg, 11/2005 | |||||
// Description : VST Events (MIDI) 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 { | |||||
//------------------------------------------------------------------------ | |||||
/** Note-on event specific data. Used in \ref Event (union)*/ | |||||
struct NoteOnEvent | |||||
{ | |||||
int16 channel; ///< channel index in event bus | |||||
int16 pitch; ///< range [0, 127] = [C-2, G8] with A3=440Hz | |||||
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)*/ | |||||
struct NoteOffEvent | |||||
{ | |||||
int16 channel; ///< channel index in event bus | |||||
int16 pitch; ///< range [0, 127] = [C-2, G8] with A3=440Hz | |||||
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)*/ | |||||
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)*/ | |||||
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)*/ | |||||
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)*/ | |||||
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 | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Event */ | |||||
//------------------------------------------------------------------------ | |||||
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, ///< is \ref NoteOffEvent | |||||
kDataEvent, ///< is \ref DataEvent | |||||
kPolyPressureEvent, ///< is \ref PolyPressureEvent | |||||
kNoteExpressionValueEvent, ///< is \ref NoteExpressionValueEvent | |||||
kNoteExpressionTextEvent, ///< is \ref NoteExpressionTextEvent | |||||
kChordEvent, ///< is \ref ChordEvent | |||||
kScaleEvent ///< is \ref ScaleEvent | |||||
}; | |||||
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 | |||||
}; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** List of events to process. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [released: 3.0.0] | |||||
\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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,98 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [passed as 'context' in to IPluginBase::initialize () ] | |||||
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) | |||||
//------------------------------------------------------------------------ | |||||
inline IMessage* allocateMessage (IHostApplication* host) | |||||
{ | |||||
TUID iid; | |||||
IMessage::iid.toTUID (iid); | |||||
IMessage* m = 0; | |||||
if (host->createInstance (iid, iid, (void**)&m) == kResultOk) | |||||
return m; | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** VST 3 to VST 2 Wrapper Interface. | |||||
\ingroup vstIHost vst310 | |||||
- [host imp] | |||||
- [passed as 'context' to IPluginBase::initialize () ] | |||||
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. | |||||
\ingroup vstIHost vst310 | |||||
- [host imp] | |||||
- [passed as 'context' to IPluginBase::initialize () ] | |||||
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) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg |
@@ -0,0 +1,144 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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] | |||||
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: | |||||
/** TODO */ | |||||
virtual tresult PLUGIN_API runLoadPresetBrowser () = 0; | |||||
/** TODO */ | |||||
virtual tresult PLUGIN_API runSavePresetBrowser () = 0; | |||||
/** TODO */ | |||||
virtual tresult PLUGIN_API loadNextPreset () = 0; | |||||
/** TODO */ | |||||
virtual tresult PLUGIN_API loadPreviousPreset () = 0; | |||||
//------------------------------------------------------------------------ | |||||
static const FUID iid; | |||||
}; | |||||
DECLARE_CLASS_IID (IInterAppAudioPresetManager, 0xADE6FCC4, 0x46C94E1D, 0xB3B49A80, 0xC93FEFDD) | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg |
@@ -0,0 +1,95 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [create via IHostApplication::createInstance] | |||||
- [released: 3.0.0] | |||||
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. | |||||
\ingroup vstIPlug vst300 | |||||
- [plug imp] | |||||
- [host imp] | |||||
- [released: 3.0.0] | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,113 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 | |||||
kCtrlEff3Depth = 93, ///< Effect 3 Depth (Chorus Send Level) | |||||
kCtrlEff4Depth = 94, ///< Effect 4 Depth (Delay/Variation Level) | |||||
kCtrlEff5Depth = 95, ///< Effect 5 Depth | |||||
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 | |||||
kPitchBend, ///< Pitch Bend | |||||
kCountCtrlNumber ///< Count of Controller Number | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg |
@@ -0,0 +1,249 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "vsttypes.h" | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpush.h" | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
namespace Vst { | |||||
typedef uint32 NoteExpressionTypeID; | |||||
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 | |||||
{ | |||||
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, ///< TODO: | |||||
kPhonemeTypeID, ///< TODO: | |||||
kCustomStart = 100000 ///< custom note change type ids must start from here | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** 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 WINDOWS && !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 WINDOWS && !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 vst3UnitsIntro), 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 | |||||
\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 (per 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 | |||||
{ | |||||
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 vst3UnitsIntro), -1 means no unit used. | |||||
int32 flags; ///< not yet used (set to 0) | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Extended Plug-in interface IEditController for key switches support | |||||
\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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,141 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "vsttypes.h" | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpush.h" | |||||
//------------------------------------------------------------------------ | |||||
//---------------------------------------------------------------------- | |||||
namespace Steinberg { | |||||
namespace Vst { | |||||
//---------------------------------------------------------------------- | |||||
/** Queue of changes for a specific parameter. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [released: 3.0.0] | |||||
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 | |||||
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:</b> \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 IParameterChanges, 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. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [released: 3.0.0] | |||||
This interface is used to transmit any changes that shall be applied to paramaters | |||||
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 (IParamValueQueue) | |||||
containing only queues for paramaters that actually did change. | |||||
\see IParamValueQueue, 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 Vst::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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,62 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "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) | |||||
\ingroup pluginGUI vst302 | |||||
- [plug imp] | |||||
- [extends IPlugView] | |||||
- [released: 3.0.2] | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,88 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 { | |||||
typedef uint32 PrefetchableSupport; | |||||
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). | |||||
\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 will decide in which mode the Plug-in will be process. | |||||
For more info about Prefetch processing mode check ProcessModes::kPrefetch documentation. | |||||
\section IPrefetchableSupportExample Example | |||||
\code | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,143 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "vsttypes.h" | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpush.h" | |||||
//------------------------------------------------------------------------ | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
namespace Vst { | |||||
//------------------------------------------------------------------------ | |||||
/** Frame Rate */ | |||||
//------------------------------------------------------------------------ | |||||
struct FrameRate | |||||
{ | |||||
//------------------------------------------------------------------------ | |||||
enum FrameRateFlags | |||||
{ | |||||
kPullDownRate = 1 << 0, ///< for ex. HDTV: 23.976 fps with 24 as frame rate | |||||
kDropRate = 1 << 1 ///< for ex. 29.97 fps drop with 30 as frame rate | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
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. | |||||
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\n | |||||
- XXXX 0000 0100 0100 (= 0x0044) -> minor chord\n | |||||
- 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 behaviour | |||||
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) | |||||
TQuarterNotes barPositionMusic; ///< last bar start position, in quarter notes | |||||
TQuarterNotes cycleStartMusic; ///< cycle start in quarter notes | |||||
TQuarterNotes cycleEndMusic; ///< cycle end in quarter notes | |||||
double tempo; ///< tempo in BPM (Beats Per Minute) | |||||
int32 timeSigNumerator; ///< time signature numerator (e.g. 3 for 3/4) | |||||
int32 timeSigDenominator; ///< time signature denominator (e.g. 4 for 3/4) | |||||
Chord chord; ///< musical info | |||||
int32 smpteOffsetSubframes; ///< SMPTE (sync) offset in subframes (1/80 of frame) | |||||
FrameRate frameRate; ///< frame rate | |||||
int32 samplesToNextClock; ///< MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest) | |||||
//------------------------------------------------------------------------ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg | |||||
//------------------------------------------------------------------------ | |||||
#include "pluginterfaces/base/falignpop.h" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,373 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 = 0, char8* _version = 0, char8* _host = 0) | |||||
{ | |||||
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. | |||||
\ingroup vstIPlug vst350 | |||||
- [plug imp] | |||||
- [extends IEditController] | |||||
- [released: 3.5.0] | |||||
- [optional] | |||||
A Representation based on XML is a way to export and structure, group Plug-ins parameters for a specific remote (could be hardware or software rack (like quickcontrols)). | |||||
\n | |||||
It allows to describe more precisely each parameter (what is the best matching to a knob, different titles 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 are 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 (an 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" | |||||
,0 | |||||
}; | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** 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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,265 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 "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 doesn't 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. | |||||
\ingroup vstIHost vst300 | |||||
- [host imp] | |||||
- [extends IComponentHandler] | |||||
- [released: 3.0.0] | |||||
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. | |||||
\ingroup vstIHost vst365 | |||||
- [host imp] | |||||
- [extends IUnitHandler] | |||||
- [released: 3.6.5] | |||||
Host callback interface, used with IUnitInfo. | |||||
Retrieve via queryInterface from IComponentHandler. | |||||
\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. | |||||
\ingroup vstIPlug vst300 | |||||
- [plug imp] | |||||
- [extends IEditController] | |||||
- [released: 3.0.0] | |||||
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. | |||||
\ingroup vstIPlug vst300 | |||||
- [plug imp] | |||||
- [extends IComponent] | |||||
- [released: 3.0.0] | |||||
A component can either support program list data via this interface or | |||||
unit preset data (IUnitData), but not both! | |||||
\see \ref vst3UnitPrograms */ | |||||
//------------------------------------------------------------------------ | |||||
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. | |||||
\ingroup vstIPlug vst300 | |||||
- [plug imp] | |||||
- [extends IComponent] | |||||
- [released: 3.0.0] | |||||
A component can either support unit preset data via this interface or | |||||
program list data (IProgramListData), but not both! | |||||
\see \ref vst3UnitPrograms */ | |||||
//------------------------------------------------------------------------ | |||||
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" | |||||
//------------------------------------------------------------------------ |
@@ -0,0 +1,430 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// Category : Interfaces | |||||
// Filename : pluginterfaces/vst/vstpresetkeys.h | |||||
// Created by : Steinberg, 2006 | |||||
// Description : VST Preset Keys | |||||
// | |||||
//----------------------------------------------------------------------------- | |||||
// 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 "vsttypes.h" | |||||
//------------------------------------------------------------------------ | |||||
namespace Steinberg { | |||||
namespace Vst { | |||||
//------------------------------------------------------------------------ | |||||
/** Predefined Preset Attributes */ | |||||
//------------------------------------------------------------------------ | |||||
namespace PresetAttributes | |||||
{ | |||||
/** | |||||
\defgroup presetAttributes Predefined Preset Attributes*/ | |||||
/*@{*/ | |||||
const CString kPlugInName = "PlugInName"; ///< Plug-in name | |||||
const CString kPlugInCategory = "PlugInCategory"; ///< eg. "Fx|Dynamics", "Instrument", "Instrument|Synth" | |||||
const CString kInstrument = "MusicalInstrument";///< eg. instrument group (like 'Piano' or 'Piano|A. Piano') | |||||
const CString kStyle = "MusicalStyle"; ///< eg. 'Pop', 'Jazz', 'Classic' | |||||
const CString kCharacter = "MusicalCharacter"; ///< eg. instrument nature (like 'Soft' 'Dry' 'Acoustic') | |||||
const CString kStateType = "StateType"; ///< Type of the given state see \ref StateType : Project / Default Preset or Normal Preset | |||||
const CString kFilePathStringType = "FilePathString"; ///< Full file path string (if available) where the preset comes from (be sure to use a bigger string when asking for it (with 1024 characters)) | |||||
/*@}*/ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Predefined StateType used for Key kStateType */ | |||||
//------------------------------------------------------------------------ | |||||
namespace StateType { | |||||
/** | |||||
\defgroup stateType Context of State Restoration */ | |||||
/*@{*/ | |||||
//------------------------------------------------------------------------ | |||||
const CString kProject = "Project"; ///< the state is restored from a project loading or it is saved in a project | |||||
const CString kDefault = "Default"; ///< the state is restored from a preset (marked as default) or the host wants to store a default state of the plug-in | |||||
//------------------------------------------------------------------------ | |||||
/*@}*/ | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Predefined Musical Instrument */ | |||||
//------------------------------------------------------------------------ | |||||
namespace MusicalInstrument | |||||
{ | |||||
/** | |||||
\defgroup musicalInstrument Predefined Musical Instrument */ | |||||
/*@{*/ | |||||
const CString kAccordion = "Accordion"; | |||||
const CString kAccordionAccordion = "Accordion|Accordion"; | |||||
const CString kAccordionHarmonica = "Accordion|Harmonica"; | |||||
const CString kAccordionOther = "Accordion|Other"; | |||||
const CString kBass = "Bass"; | |||||
const CString kBassABass = "Bass|A. Bass"; | |||||
const CString kBassEBass = "Bass|E. Bass"; | |||||
const CString kBassSynthBass = "Bass|Synth Bass"; | |||||
const CString kBassOther = "Bass|Other"; | |||||
const CString kBrass = "Brass"; | |||||
const CString kBrassFrenchHorn = "Brass|French Horn"; | |||||
const CString kBrassTrumpet = "Brass|Trumpet"; | |||||
const CString kBrassTrombone = "Brass|Trombone"; | |||||
const CString kBrassTuba = "Brass|Tuba"; | |||||
const CString kBrassSection = "Brass|Section"; | |||||
const CString kBrassSynth = "Brass|Synth"; | |||||
const CString kBrassOther = "Brass|Other"; | |||||
const CString kChromaticPerc = "Chromatic Perc"; | |||||
const CString kChromaticPercBell = "Chromatic Perc|Bell"; | |||||
const CString kChromaticPercMallett = "Chromatic Perc|Mallett"; | |||||
const CString kChromaticPercWood = "Chromatic Perc|Wood"; | |||||
const CString kChromaticPercPercussion = "Chromatic Perc|Percussion"; | |||||
const CString kChromaticPercTimpani = "Chromatic Perc|Timpani"; | |||||
const CString kChromaticPercOther = "Chromatic Perc|Other"; | |||||
const CString kDrumPerc = "Drum&Perc"; | |||||
const CString kDrumPercDrumsetGM = "Drum&Perc|Drumset GM"; | |||||
const CString kDrumPercDrumset = "Drum&Perc|Drumset"; | |||||
const CString kDrumPercDrumMenues = "Drum&Perc|Drum Menues"; | |||||
const CString kDrumPercBeats = "Drum&Perc|Beats"; | |||||
const CString kDrumPercPercussion = "Drum&Perc|Percussion"; | |||||
const CString kDrumPercKickDrum = "Drum&Perc|Kick Drum"; | |||||
const CString kDrumPercSnareDrum = "Drum&Perc|Snare Drum"; | |||||
const CString kDrumPercToms = "Drum&Perc|Toms"; | |||||
const CString kDrumPercHiHats = "Drum&Perc|HiHats"; | |||||
const CString kDrumPercCymbals = "Drum&Perc|Cymbals"; | |||||
const CString kDrumPercOther = "Drum&Perc|Other"; | |||||
const CString kEthnic = "Ethnic"; | |||||
const CString kEthnicAsian = "Ethnic|Asian"; | |||||
const CString kEthnicAfrican = "Ethnic|African"; | |||||
const CString kEthnicEuropean = "Ethnic|European"; | |||||
const CString kEthnicLatin = "Ethnic|Latin"; | |||||
const CString kEthnicAmerican = "Ethnic|American"; | |||||
const CString kEthnicAlien = "Ethnic|Alien"; | |||||
const CString kEthnicOther = "Ethnic|Other"; | |||||
const CString kGuitar = "Guitar/Plucked"; | |||||
const CString kGuitarAGuitar = "Guitar/Plucked|A. Guitar"; | |||||
const CString kGuitarEGuitar = "Guitar/Plucked|E. Guitar"; | |||||
const CString kGuitarHarp = "Guitar/Plucked|Harp"; | |||||
const CString kGuitarEthnic = "Guitar/Plucked|Ethnic"; | |||||
const CString kGuitarOther = "Guitar/Plucked|Other"; | |||||
const CString kKeyboard = "Keyboard"; | |||||
const CString kKeyboardClavi = "Keyboard|Clavi"; | |||||
const CString kKeyboardEPiano = "Keyboard|E. Piano"; | |||||
const CString kKeyboardHarpsichord = "Keyboard|Harpsichord"; | |||||
const CString kKeyboardOther = "Keyboard|Other"; | |||||
const CString kMusicalFX = "Musical FX"; | |||||
const CString kMusicalFXHitsStabs = "Musical FX|Hits&Stabs"; | |||||
const CString kMusicalFXMotion = "Musical FX|Motion"; | |||||
const CString kMusicalFXSweeps = "Musical FX|Sweeps"; | |||||
const CString kMusicalFXBeepsBlips = "Musical FX|Beeps&Blips"; | |||||
const CString kMusicalFXScratches = "Musical FX|Scratches"; | |||||
const CString kMusicalFXOther = "Musical FX|Other"; | |||||
const CString kOrgan = "Organ"; | |||||
const CString kOrganElectric = "Organ|Electric"; | |||||
const CString kOrganPipe = "Organ|Pipe"; | |||||
const CString kOrganOther = "Organ|Other"; | |||||
const CString kPiano = "Piano"; | |||||
const CString kPianoAPiano = "Piano|A. Piano"; | |||||
const CString kPianoEGrand = "Piano|E. Grand"; | |||||
const CString kPianoOther = "Piano|Other"; | |||||
const CString kSoundFX = "Sound FX"; | |||||
const CString kSoundFXNature = "Sound FX|Nature"; | |||||
const CString kSoundFXMechanical = "Sound FX|Mechanical"; | |||||
const CString kSoundFXSynthetic = "Sound FX|Synthetic"; | |||||
const CString kSoundFXOther = "Sound FX|Other"; | |||||
const CString kStrings = "Strings"; | |||||
const CString kStringsViolin = "Strings|Violin"; | |||||
const CString kStringsViola = "Strings|Viola"; | |||||
const CString kStringsCello = "Strings|Cello"; | |||||
const CString kStringsBass = "Strings|Bass"; | |||||
const CString kStringsSection = "Strings|Section"; | |||||
const CString kStringsSynth = "Strings|Synth"; | |||||
const CString kStringsOther = "Strings|Other"; | |||||
const CString kSynthLead = "Synth Lead"; | |||||
const CString kSynthLeadAnalog = "Synth Lead|Analog"; | |||||
const CString kSynthLeadDigital = "Synth Lead|Digital"; | |||||
const CString kSynthLeadArpeggio = "Synth Lead|Arpeggio"; | |||||
const CString kSynthLeadOther = "Synth Lead|Other"; | |||||
const CString kSynthPad = "Synth Pad"; | |||||
const CString kSynthPadSynthChoir = "Synth Pad|Synth Choir"; | |||||
const CString kSynthPadAnalog = "Synth Pad|Analog"; | |||||
const CString kSynthPadDigital = "Synth Pad|Digital"; | |||||
const CString kSynthPadMotion = "Synth Pad|Motion"; | |||||
const CString kSynthPadOther = "Synth Pad|Other"; | |||||
const CString kSynthComp = "Synth Comp"; | |||||
const CString kSynthCompAnalog = "Synth Comp|Analog"; | |||||
const CString kSynthCompDigital = "Synth Comp|Digital"; | |||||
const CString kSynthCompOther = "Synth Comp|Other"; | |||||
const CString kVocal = "Vocal"; | |||||
const CString kVocalLeadVocal = "Vocal|Lead Vocal"; | |||||
const CString kVocalAdlibs = "Vocal|Adlibs"; | |||||
const CString kVocalChoir = "Vocal|Choir"; | |||||
const CString kVocalSolo = "Vocal|Solo"; | |||||
const CString kVocalFX = "Vocal|FX"; | |||||
const CString kVocalSpoken = "Vocal|Spoken"; | |||||
const CString kVocalOther = "Vocal|Other"; | |||||
const CString kWoodwinds = "Woodwinds"; | |||||
const CString kWoodwindsEthnic = "Woodwinds|Ethnic"; | |||||
const CString kWoodwindsFlute = "Woodwinds|Flute"; | |||||
const CString kWoodwindsOboe = "Woodwinds|Oboe"; | |||||
const CString kWoodwindsEnglHorn = "Woodwinds|Engl. Horn"; | |||||
const CString kWoodwindsClarinet = "Woodwinds|Clarinet"; | |||||
const CString kWoodwindsSaxophone = "Woodwinds|Saxophone"; | |||||
const CString kWoodwindsBassoon = "Woodwinds|Bassoon"; | |||||
const CString kWoodwindsOther = "Woodwinds|Other"; | |||||
/*@}*/ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Predefined Musical Style */ | |||||
//------------------------------------------------------------------------ | |||||
namespace MusicalStyle | |||||
{ | |||||
/** | |||||
\defgroup musicalStyle Predefined Musical Style */ | |||||
/*@{*/ | |||||
const CString kAlternativeIndie = "Alternative/Indie"; | |||||
const CString kAlternativeIndieGothRock = "Alternative/Indie|Goth Rock"; | |||||
const CString kAlternativeIndieGrunge = "Alternative/Indie|Grunge"; | |||||
const CString kAlternativeIndieNewWave = "Alternative/Indie|New Wave"; | |||||
const CString kAlternativeIndiePunk = "Alternative/Indie|Punk"; | |||||
const CString kAlternativeIndieCollegeRock = "Alternative/Indie|College Rock"; | |||||
const CString kAlternativeIndieDarkWave = "Alternative/Indie|Dark Wave"; | |||||
const CString kAlternativeIndieHardcore = "Alternative/Indie|Hardcore"; | |||||
const CString kAmbientChillOut = "Ambient/ChillOut"; | |||||
const CString kAmbientChillOutNewAgeMeditation = "Ambient/ChillOut|New Age/Meditation"; | |||||
const CString kAmbientChillOutDarkAmbient = "Ambient/ChillOut|Dark Ambient"; | |||||
const CString kAmbientChillOutDowntempo = "Ambient/ChillOut|Downtempo"; | |||||
const CString kAmbientChillOutLounge = "Ambient/ChillOut|Lounge"; | |||||
const CString kBlues = "Blues"; | |||||
const CString kBluesAcousticBlues = "Blues|Acoustic Blues"; | |||||
const CString kBluesCountryBlues = "Blues|Country Blues"; | |||||
const CString kBluesElectricBlues = "Blues|Electric Blues"; | |||||
const CString kBluesChicagoBlues = "Blues|Chicago Blues"; | |||||
const CString kClassical = "Classical"; | |||||
const CString kClassicalBaroque = "Classical|Baroque"; | |||||
const CString kClassicalChamberMusic = "Classical|Chamber Music"; | |||||
const CString kClassicalMedieval = "Classical|Medieval"; | |||||
const CString kClassicalModernComposition = "Classical|Modern Composition"; | |||||
const CString kClassicalOpera = "Classical|Opera"; | |||||
const CString kClassicalGregorian = "Classical|Gregorian"; | |||||
const CString kClassicalRenaissance = "Classical|Renaissance"; | |||||
const CString kClassicalClassic = "Classical|Classic"; | |||||
const CString kClassicalRomantic = "Classical|Romantic"; | |||||
const CString kClassicalSoundtrack = "Classical|Soundtrack"; | |||||
const CString kCountry = "Country"; | |||||
const CString kCountryCountryWestern = "Country|Country/Western"; | |||||
const CString kCountryHonkyTonk = "Country|Honky Tonk"; | |||||
const CString kCountryUrbanCowboy = "Country|Urban Cowboy"; | |||||
const CString kCountryBluegrass = "Country|Bluegrass"; | |||||
const CString kCountryAmericana = "Country|Americana"; | |||||
const CString kCountrySquaredance = "Country|Squaredance"; | |||||
const CString kCountryNorthAmericanFolk = "Country|North American Folk"; | |||||
const CString kElectronicaDance = "Electronica/Dance"; | |||||
const CString kElectronicaDanceMinimal = "Electronica/Dance|Minimal"; | |||||
const CString kElectronicaDanceClassicHouse = "Electronica/Dance|Classic House"; | |||||
const CString kElectronicaDanceElektroHouse = "Electronica/Dance|Elektro House"; | |||||
const CString kElectronicaDanceFunkyHouse = "Electronica/Dance|Funky House"; | |||||
const CString kElectronicaDanceIndustrial = "Electronica/Dance|Industrial"; | |||||
const CString kElectronicaDanceElectronicBodyMusic = "Electronica/Dance|Electronic Body Music"; | |||||
const CString kElectronicaDanceTripHop = "Electronica/Dance|Trip Hop"; | |||||
const CString kElectronicaDanceTechno = "Electronica/Dance|Techno"; | |||||
const CString kElectronicaDanceDrumNBassJungle = "Electronica/Dance|Drum'n'Bass/Jungle"; | |||||
const CString kElectronicaDanceElektro = "Electronica/Dance|Elektro"; | |||||
const CString kElectronicaDanceTrance = "Electronica/Dance|Trance"; | |||||
const CString kElectronicaDanceDub = "Electronica/Dance|Dub"; | |||||
const CString kElectronicaDanceBigBeats = "Electronica/Dance|Big Beats"; | |||||
const CString kExperimental = "Experimental"; | |||||
const CString kExperimentalNewMusic = "Experimental|New Music"; | |||||
const CString kExperimentalFreeImprovisation = "Experimental|Free Improvisation"; | |||||
const CString kExperimentalElectronicArtMusic = "Experimental|Electronic Art Music"; | |||||
const CString kExperimentalNoise = "Experimental|Noise"; | |||||
const CString kJazz = "Jazz"; | |||||
const CString kJazzNewOrleansJazz = "Jazz|New Orleans Jazz"; | |||||
const CString kJazzTraditionalJazz = "Jazz|Traditional Jazz"; | |||||
const CString kJazzOldtimeJazzDixiland = "Jazz|Oldtime Jazz/Dixiland"; | |||||
const CString kJazzFusion = "Jazz|Fusion"; | |||||
const CString kJazzAvantgarde = "Jazz|Avantgarde"; | |||||
const CString kJazzLatinJazz = "Jazz|Latin Jazz"; | |||||
const CString kJazzFreeJazz = "Jazz|Free Jazz"; | |||||
const CString kJazzRagtime = "Jazz|Ragtime"; | |||||
const CString kPop = "Pop"; | |||||
const CString kPopBritpop = "Pop|Britpop"; | |||||
const CString kPopRock = "Pop|Pop/Rock"; | |||||
const CString kPopTeenPop = "Pop|Teen Pop"; | |||||
const CString kPopChartDance = "Pop|Chart Dance"; | |||||
const CString kPop80sPop = "Pop|80's Pop"; | |||||
const CString kPopDancehall = "Pop|Dancehall"; | |||||
const CString kPopDisco = "Pop|Disco"; | |||||
const CString kRockMetal = "Rock/Metal"; | |||||
const CString kRockMetalBluesRock = "Rock/Metal|Blues Rock"; | |||||
const CString kRockMetalClassicRock = "Rock/Metal|Classic Rock"; | |||||
const CString kRockMetalHardRock = "Rock/Metal|Hard Rock"; | |||||
const CString kRockMetalRockRoll = "Rock/Metal|Rock & Roll"; | |||||
const CString kRockMetalSingerSongwriter = "Rock/Metal|Singer/Songwriter"; | |||||
const CString kRockMetalHeavyMetal = "Rock/Metal|Heavy Metal"; | |||||
const CString kRockMetalDeathBlackMetal = "Rock/Metal|Death/Black Metal"; | |||||
const CString kRockMetalNuMetal = "Rock/Metal|NuMetal"; | |||||
const CString kRockMetalReggae = "Rock/Metal|Reggae"; | |||||
const CString kRockMetalBallad = "Rock/Metal|Ballad"; | |||||
const CString kRockMetalAlternativeRock = "Rock/Metal|Alternative Rock"; | |||||
const CString kRockMetalRockabilly = "Rock/Metal|Rockabilly"; | |||||
const CString kRockMetalThrashMetal = "Rock/Metal|Thrash Metal"; | |||||
const CString kRockMetalProgressiveRock = "Rock/Metal|Progressive Rock"; | |||||
const CString kUrbanHipHopRB = "Urban (Hip-Hop / R&B)"; | |||||
const CString kUrbanHipHopRBClassic = "Urban (Hip-Hop / R&B)|Classic R&B"; | |||||
const CString kUrbanHipHopRBModern = "Urban (Hip-Hop / R&B)|Modern R&B"; | |||||
const CString kUrbanHipHopRBPop = "Urban (Hip-Hop / R&B)|R&B Pop"; | |||||
const CString kUrbanHipHopRBWestCoastHipHop = "Urban (Hip-Hop / R&B)|WestCoast Hip-Hop"; | |||||
const CString kUrbanHipHopRBEastCoastHipHop = "Urban (Hip-Hop / R&B)|EastCoast Hip-Hop"; | |||||
const CString kUrbanHipHopRBRapHipHop = "Urban (Hip-Hop / R&B)|Rap/Hip Hop"; | |||||
const CString kUrbanHipHopRBSoul = "Urban (Hip-Hop / R&B)|Soul"; | |||||
const CString kUrbanHipHopRBFunk = "Urban (Hip-Hop / R&B)|Funk"; | |||||
const CString kWorldEthnic = "World/Ethnic"; | |||||
const CString kWorldEthnicAfrica = "World/Ethnic|Africa"; | |||||
const CString kWorldEthnicAsia = "World/Ethnic|Asia"; | |||||
const CString kWorldEthnicCeltic = "World/Ethnic|Celtic"; | |||||
const CString kWorldEthnicEurope = "World/Ethnic|Europe"; | |||||
const CString kWorldEthnicKlezmer = "World/Ethnic|Klezmer"; | |||||
const CString kWorldEthnicScandinavia = "World/Ethnic|Scandinavia"; | |||||
const CString kWorldEthnicEasternEurope = "World/Ethnic|Eastern Europe"; | |||||
const CString kWorldEthnicIndiaOriental = "World/Ethnic|India/Oriental"; | |||||
const CString kWorldEthnicNorthAmerica = "World/Ethnic|North America"; | |||||
const CString kWorldEthnicSouthAmerica = "World/Ethnic|South America"; | |||||
const CString kWorldEthnicAustralia = "World/Ethnic|Australia"; | |||||
/*@}*/ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
/** Predefined Musical Character */ | |||||
//------------------------------------------------------------------------ | |||||
namespace MusicalCharacter | |||||
{ | |||||
/** | |||||
\defgroup musicalCharacter Predefined Musical Character */ | |||||
/*@{*/ | |||||
//----TYPE------------------------------------ | |||||
const CString kMono = "Mono"; | |||||
const CString kPoly = "Poly"; | |||||
const CString kSplit = "Split"; | |||||
const CString kLayer = "Layer"; | |||||
const CString kGlide = "Glide"; | |||||
const CString kGlissando = "Glissando"; | |||||
const CString kMajor = "Major"; | |||||
const CString kMinor = "Minor"; | |||||
const CString kSingle = "Single"; | |||||
const CString kEnsemble = "Ensemble"; | |||||
const CString kAcoustic = "Acoustic"; | |||||
const CString kElectric = "Electric"; | |||||
const CString kAnalog = "Analog"; | |||||
const CString kDigital = "Digital"; | |||||
const CString kVintage = "Vintage"; | |||||
const CString kModern = "Modern"; | |||||
const CString kOld = "Old"; | |||||
const CString kNew = "New"; | |||||
//----TONE------------------------------------ | |||||
const CString kClean = "Clean"; | |||||
const CString kDistorted = "Distorted"; | |||||
const CString kDry = "Dry"; | |||||
const CString kProcessed = "Processed"; | |||||
const CString kHarmonic = "Harmonic"; | |||||
const CString kDissonant = "Dissonant"; | |||||
const CString kClear = "Clear"; | |||||
const CString kNoisy = "Noisy"; | |||||
const CString kThin = "Thin"; | |||||
const CString kRich = "Rich"; | |||||
const CString kDark = "Dark"; | |||||
const CString kBright = "Bright"; | |||||
const CString kCold = "Cold"; | |||||
const CString kWarm = "Warm"; | |||||
const CString kMetallic = "Metallic"; | |||||
const CString kWooden = "Wooden"; | |||||
const CString kGlass = "Glass"; | |||||
const CString kPlastic = "Plastic"; | |||||
//----ENVELOPE------------------------------------ | |||||
const CString kPercussive = "Percussive"; | |||||
const CString kSoft = "Soft"; | |||||
const CString kFast = "Fast"; | |||||
const CString kSlow = "Slow"; | |||||
const CString kShort = "Short"; | |||||
const CString kLong = "Long"; | |||||
const CString kAttack = "Attack"; | |||||
const CString kRelease = "Release"; | |||||
const CString kDecay = "Decay"; | |||||
const CString kSustain = "Sustain"; | |||||
const CString kFastAttack = "Fast Attack"; | |||||
const CString kSlowAttack = "Slow Attack"; | |||||
const CString kShortRelease = "Short Release"; | |||||
const CString kLongRelease = "Long Release"; | |||||
const CString kStatic = "Static"; | |||||
const CString kMoving = "Moving"; | |||||
const CString kLoop = "Loop"; | |||||
const CString kOneShot = "One Shot"; | |||||
/*@}*/ | |||||
}; | |||||
//------------------------------------------------------------------------ | |||||
} // namespace Vst | |||||
} // namespace Steinberg |
@@ -0,0 +1,31 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 |
@@ -0,0 +1,762 @@ | |||||
//------------------------------------------------------------------------ | |||||
// Project : VST SDK | |||||
// Version : 3.6.7 | |||||
// | |||||
// 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 { | |||||
//------------------------------------------------------------------------ | |||||
#ifndef kVstVersionString | |||||
#define kVstVersionString "VST 3.6.7" ///< SDK version for PClassInfo2 | |||||
#endif | |||||
#define kVstVersionMajor 3 | |||||
#define kVstVersionMinor 6 | |||||
#define kVstVersionSub 7 | |||||
// this allows to write things like: #if VST_VERSION >= 0x030500 // note that 3.10.0 is 0x030a00 | |||||
#define VST_VERSION ((kVstVersionMajor << 16) | (kVstVersionMinor << 8) | kVstVersionSub) | |||||
//------------------------------------------------------------------------ | |||||
// struct alignment definitions | |||||
//------------------------------------------------------------------------ | |||||
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) | |||||
#define VST3_STRUCT struct __attribute__((aligned(4))) | |||||
#elif WINDOWS | |||||
#if PLATFORM_64 | |||||
#define VST3_PACKED_SIZE 8 | |||||
#else | |||||
#define VST3_PACKED_SIZE 4 | |||||
#endif | |||||
#define VST3_STRUCT __declspec(align(VST3_PACKED_SIZE)) struct | |||||
#else | |||||
#error "unsupported compiler" | |||||
#endif | |||||
//------------------------------------------------------------------------ | |||||
/** \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 | |||||
typedef int32 UnitID; ///< unit identifier | |||||
typedef double ParamValue; ///< parameter value type | |||||
typedef uint32 ParamID; ///< parameter identifier | |||||
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) | |||||
//------------------------------------------------------------------------ | |||||
// Audio Types | |||||
//------------------------------------------------------------------------ | |||||
typedef float Sample32; ///< 32-bit precision audio sample | |||||
typedef double Sample64; ///< 64-bit precision audio sample | |||||
typedef double SampleRate; ///< sample rate | |||||
/*@}*/ | |||||
//------------------------------------------------------------------------ | |||||
/** \defgroup speakerArrangements Speaker Arrangements | |||||
\image html "vst3_speaker_types.jpg" | |||||
\n | |||||
A SpeakerArrangement is a bitset combination of speakers. For example: | |||||
\code | |||||
const SpeakerArrangement kStereo = kSpeakerL | kSpeakerR; // => hex: 0x03 / binary: 0011. | |||||
\endcode*/ | |||||
//------------------------------------------------------------------------ | |||||
/**@{*/ | |||||
typedef uint64 SpeakerArrangement; ///< Bitset of speakers | |||||
typedef uint64 Speaker; ///< Bit for one speaker | |||||
/**@}*/ | |||||
//------------------------------------------------------------------------ | |||||
/** Speaker Definitions. | |||||
\ingroup speakerArrangements */ | |||||
//------------------------------------------------------------------------ | |||||
/**@{*/ | |||||
const Speaker kSpeakerL = 1 << 0; ///< Left (L) | |||||
const Speaker kSpeakerR = 1 << 1; ///< Right (R) | |||||
const Speaker kSpeakerC = 1 << 2; ///< Center (C) | |||||
const Speaker kSpeakerLfe = 1 << 3; ///< Subbass (Lfe) | |||||
const Speaker kSpeakerLs = 1 << 4; ///< Left Surround (Ls) | |||||
const Speaker kSpeakerRs = 1 << 5; ///< Right Surround (Rs) | |||||
const Speaker kSpeakerLc = 1 << 6; ///< Left of Center (Lc) - Front Left Center | |||||
const Speaker kSpeakerRc = 1 << 7; ///< Right of Center (Rc) - Front Right Center | |||||
const Speaker kSpeakerS = 1 << 8; ///< Surround (S) | |||||
const Speaker kSpeakerCs = kSpeakerS; ///< Center of Surround (Cs) - Back Center - Surround (S) | |||||
const Speaker kSpeakerSl = 1 << 9; ///< Side Left (Sl) | |||||
const Speaker kSpeakerSr = 1 << 10; ///< Side Right (Sr) | |||||
const Speaker kSpeakerTc = 1 << 11; ///< Top Center Over-head, Top Middle (Tc) | |||||
const Speaker kSpeakerTfl = 1 << 12; ///< Top Front Left (Tfl) | |||||
const Speaker kSpeakerTfc = 1 << 13; ///< Top Front Center (Tfc) | |||||
const Speaker kSpeakerTfr = 1 << 14; ///< Top Front Right (Tfr) | |||||
const Speaker kSpeakerTrl = 1 << 15; ///< Top Rear/Back Left (Trl) | |||||
const Speaker kSpeakerTrc = 1 << 16; ///< Top Rear/Back Center (Trc) | |||||
const Speaker kSpeakerTrr = 1 << 17; ///< Top Rear/Back Right (Trr) | |||||
const Speaker kSpeakerLfe2 = 1 << 18; ///< Subbass 2 (Lfe2) | |||||
const Speaker kSpeakerM = 1 << 19; ///< Mono (M) | |||||
const Speaker kSpeakerW = 1 << 20; ///< B-Format W | |||||
const Speaker kSpeakerX = 1 << 21; ///< B-Format X | |||||
const Speaker kSpeakerY = 1 << 22; ///< B-Format Y | |||||
const Speaker kSpeakerZ = 1 << 23; ///< B-Format Z | |||||
const Speaker kSpeakerTsl = 1 << 24; ///< Top Side Left (Tsl) | |||||
const Speaker kSpeakerTsr = 1 << 25; ///< Top Side Right (Tsr) | |||||
const Speaker kSpeakerLcs = 1 << 26; ///< Left of Center Surround (Lcs) - Back Left Center | |||||
const Speaker kSpeakerRcs = 1 << 27; ///< Right of Center Surround (Rcs) - Back Right Center | |||||
const Speaker kSpeakerBfl = 1 << 28; ///< Bottom Front Left (Bfl) | |||||
const Speaker kSpeakerBfc = 1 << 29; ///< Bottom Front Center (Bfc) | |||||
const Speaker kSpeakerBfr = 1 << 30; ///< Bottom Front Right (Bfr) | |||||
const Speaker kSpeakerPl = (Speaker)1 << 31; ///< Proximity Left (Pl) | |||||
const Speaker kSpeakerPr = (Speaker)1 << 32; ///< Proximity Right (Pr) | |||||
//------------------------------------------------------------------------ | |||||
/** @}*/ | |||||
//------------------------------------------------------------------------ | |||||
/** Speaker Arrangement Definitions (SpeakerArrangement)*/ | |||||
//------------------------------------------------------------------------ | |||||
namespace SpeakerArr | |||||
{ | |||||
//------------------------------------------------------------------------ | |||||
/** Speaker Arrangement Definitions. | |||||
\ingroup speakerArrangements */ | |||||
/*@{*/ | |||||
const SpeakerArrangement kEmpty = 0; ///< empty arrangement | |||||
const SpeakerArrangement kMono = kSpeakerM; ///< M | |||||
const SpeakerArrangement kStereo = kSpeakerL | kSpeakerR; ///< L R | |||||
const SpeakerArrangement kStereoSurround = kSpeakerLs | kSpeakerRs; ///< Ls Rs | |||||
const SpeakerArrangement kStereoCenter = kSpeakerLc | kSpeakerRc; ///< Lc Rc | |||||
const SpeakerArrangement kStereoSide = kSpeakerSl | kSpeakerSr; ///< Sl Sr | |||||
const SpeakerArrangement kStereoCLfe = kSpeakerC | kSpeakerLfe; ///< C Lfe | |||||
const SpeakerArrangement kStereoTF = kSpeakerTfl | kSpeakerTfr; ///< Tfl Tfr | |||||
const SpeakerArrangement kStereoTS = kSpeakerTsl | kSpeakerTsr; ///< Tsl Tsr | |||||
const SpeakerArrangement kStereoTR = kSpeakerTrl | kSpeakerTrr; ///< Trl Trr | |||||
const SpeakerArrangement kStereoBF = kSpeakerBfl | kSpeakerBfr; ///< Bfl Bfr | |||||
/** L R C */ | |||||
const SpeakerArrangement k30Cine = kSpeakerL | kSpeakerR | kSpeakerC; | |||||
/** L R S */ | |||||
const SpeakerArrangement k30Music = kSpeakerL | kSpeakerR | kSpeakerS; | |||||
/** L R C Lfe */ | |||||
const SpeakerArrangement k31Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe; | |||||
/** L R Lfe S */ | |||||
const SpeakerArrangement k31Music = kSpeakerL | kSpeakerR | kSpeakerLfe | kSpeakerS; | |||||
/** L R C S (LCRS) */ | |||||
const SpeakerArrangement k40Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerS; | |||||
/** L R Ls Rs (Quadro) */ | |||||
const SpeakerArrangement k40Music = kSpeakerL | kSpeakerR | kSpeakerLs | kSpeakerRs; | |||||
/** L R C Lfe S (LCRS+Lfe) */ | |||||
const SpeakerArrangement k41Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerS; | |||||
/** L R Lfe Ls Rs (Quadro+Lfe) */ | |||||
const SpeakerArrangement k41Music = kSpeakerL | kSpeakerR | kSpeakerLfe | kSpeakerLs | kSpeakerRs; | |||||
/** L R C Ls Rs */ | |||||
const SpeakerArrangement k50 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs; | |||||
/** L R C Lfe Ls Rs */ | |||||
const SpeakerArrangement k51 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs; | |||||
/** L R C Ls Rs Cs */ | |||||
const SpeakerArrangement k60Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerCs; | |||||
/** L R Ls Rs Sl Sr */ | |||||
const SpeakerArrangement k60Music = kSpeakerL | kSpeakerR | kSpeakerLs | kSpeakerRs | kSpeakerSl | kSpeakerSr; | |||||
/** L R C Lfe Ls Rs Cs */ | |||||
const SpeakerArrangement k61Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerCs; | |||||
/** L R Lfe Ls Rs Sl Sr */ | |||||
const SpeakerArrangement k61Music = kSpeakerL | kSpeakerR | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerSl | kSpeakerSr; | |||||
/** L R C Ls Rs Lc Rc */ | |||||
const SpeakerArrangement k70Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerLc | kSpeakerRc; | |||||
/** L R C Ls Rs Sl Sr */ | |||||
const SpeakerArrangement k70Music = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerSl | kSpeakerSr; | |||||
/** L R C Lfe Ls Rs Lc Rc */ | |||||
const SpeakerArrangement k71Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerLc | kSpeakerRc; | |||||
const SpeakerArrangement k71CineFullFront= k71Cine; | |||||
/** L R C Lfe Ls Rs Lcs Rcs */ | |||||
const SpeakerArrangement k71CineFullRear = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerLcs | kSpeakerRcs; | |||||
/** L R C Lfe Ls Rs Sl Sr */ | |||||
const SpeakerArrangement k71Music = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerSl | kSpeakerSr; | |||||
const SpeakerArrangement k71CineSideFill = k71Music; | |||||
/** L R C Lfe Ls Rs Pl Pr */ | |||||
const SpeakerArrangement k71Proximity = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerPl | kSpeakerPr; | |||||
/** L R C Ls Rs Lc Rc Cs */ | |||||
const SpeakerArrangement k80Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerLc | kSpeakerRc | kSpeakerCs; | |||||
/** L R C Ls Rs Cs Sl Sr */ | |||||
const SpeakerArrangement k80Music = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerCs | kSpeakerSl | kSpeakerSr; | |||||
/** L R C Lfe Ls Rs Lc Rc Cs */ | |||||
const SpeakerArrangement k81Cine = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerLc | kSpeakerRc | kSpeakerCs; | |||||
/** L R C Lfe Ls Rs Cs Sl Sr */ | |||||
const SpeakerArrangement k81Music = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerCs | kSpeakerSl | kSpeakerSr; | |||||
/** W X Y Z (First Order) */ | |||||
const SpeakerArrangement kBFormat1stOrder = kSpeakerW | kSpeakerX | kSpeakerY | kSpeakerZ; | |||||
const SpeakerArrangement kBFormat = kBFormat1stOrder; | |||||
/*-----------*/ | |||||
/* 3D formats */ | |||||
/*-----------*/ | |||||
/** L R Ls Rs Tfl Tfr Trl Trr */ | |||||
const SpeakerArrangement k80Cube = kSpeakerL | kSpeakerR | kSpeakerLs | kSpeakerRs | kSpeakerTfl| kSpeakerTfr| kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Cs Tc */ | |||||
const SpeakerArrangement k71CineTopCenter = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerCs | kSpeakerTc; | |||||
/** L R C Lfe Ls Rs Cs Tfc */ | |||||
const SpeakerArrangement k71CineCenterHigh = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerCs | kSpeakerTfc; | |||||
/** L R C Lfe Ls Rs Tfl Tfr */ | |||||
const SpeakerArrangement k71CineFrontHigh = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerTfl | kSpeakerTfr; | |||||
const SpeakerArrangement k71MPEG3D = k71CineFrontHigh; | |||||
/** L R C Lfe Ls Rs Tsl Tsr */ | |||||
const SpeakerArrangement k71CineSideHigh = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerTsl | kSpeakerTsr; | |||||
/** L R Lfe Ls Rs Tfl Tfc Tfr Bfc */ | |||||
const SpeakerArrangement k81MPEG3D = kSpeakerL | kSpeakerR | kSpeakerLfe | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTfl | kSpeakerTfc | kSpeakerTfr | kSpeakerBfc; | |||||
/** L R C Ls Rs Tfl Tfr Trl Trr */ | |||||
const SpeakerArrangement k90 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTfl| kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Tfl Tfr Trl Trr */ | |||||
const SpeakerArrangement k91 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTfl| kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Sl Sr Tsl Tsr */ | |||||
const SpeakerArrangement k71_2 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | | |||||
kSpeakerRs | kSpeakerSl | kSpeakerSr | kSpeakerTsl | kSpeakerTsr; | |||||
const SpeakerArrangement k91Atmos = k71_2; | |||||
/** L R C Ls Rs Tc Tfl Tfr Trl Trr */ | |||||
const SpeakerArrangement k100 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Tc Tfl Tfr Trl Trr */ | |||||
const SpeakerArrangement k101 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
const SpeakerArrangement k101MPEG3D = k101; | |||||
/** L R C Lfe Ls Rs Tfl Tfc Tfr Trl Trr Lfe2 */ | |||||
const SpeakerArrangement k102 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTfl| kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr | kSpeakerLfe2; | |||||
/** L R C Ls Rs Tc Tfl Tfc Tfr Trl Trr */ | |||||
const SpeakerArrangement k110 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Tc Tfl Tfc Tfr Trl Trr */ | |||||
const SpeakerArrangement k111 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Lc Rc Tfl Tfc Tfr Trl Trr Lfe2 */ | |||||
const SpeakerArrangement k122 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerLc | kSpeakerRc | | |||||
kSpeakerTfl| kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr | kSpeakerLfe2; | |||||
/** L R C Ls Rs Cs Tc Tfl Tfc Tfr Trl Trc Trr */ | |||||
const SpeakerArrangement k130 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerSl | kSpeakerSr | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Cs Tc Tfl Tfc Tfr Trl Trc Trr */ | |||||
const SpeakerArrangement k131 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerSl | kSpeakerSr | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; | |||||
/** L R C Lfe Ls Rs Lc Rc Cs Sl Sr Tc Tfl Tfc Tfr Trl Trc Trr Lfe2 Tsl Tsr Bfl Bfc Bfr */ | |||||
const SpeakerArrangement k222 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLfe | kSpeakerLs | kSpeakerRs | kSpeakerLc | kSpeakerRc | kSpeakerCs | kSpeakerSl | kSpeakerSr | | |||||
kSpeakerTc | kSpeakerTfl | kSpeakerTfc | kSpeakerTfr | kSpeakerTrl | kSpeakerTrc | kSpeakerTrr | kSpeakerLfe2 | kSpeakerTsl | kSpeakerTsr | | |||||
kSpeakerBfl| kSpeakerBfc | kSpeakerBfr; | |||||
//------------------------------------------------------------------------ | |||||
/** Speaker Arrangement String Representation. | |||||
\ingroup speakerArrangements */ | |||||
/*@{*/ | |||||
const CString kStringEmpty = ""; | |||||
const CString kStringMono = "Mono"; | |||||
const CString kStringStereo = "Stereo"; | |||||
const CString kStringStereoR = "Stereo (Ls Rs)"; | |||||
const CString kStringStereoC = "Stereo (Lc Rc)"; | |||||
const CString kStringStereoSide = "Stereo (Sl Sr)"; | |||||
const CString kStringStereoCLfe = "Stereo (C LFE)"; | |||||
const CString kStringStereoTF = "Stereo (Tfl Tfr)"; | |||||
const CString kStringStereoTS = "Stereo (Tsl Tsr)"; | |||||
const CString kStringStereoTR = "Stereo (Trl Trr)"; | |||||
const CString kStringStereoBF = "Stereo (Bfl Bfr)"; | |||||
const CString kString30Cine = "LRC"; | |||||
const CString kString30Music = "LRS"; | |||||
const CString kString31Cine = "LRC+LFE"; | |||||
const CString kString31Music = "LRS+LFE"; | |||||
const CString kString40Cine = "LRCS"; | |||||
const CString kString40Music = "Quadro"; | |||||
const CString kString41Cine = "LRCS+LFE"; | |||||
const CString kString41Music = "Quadro+LFE"; | |||||
const CString kString50 = "5.0"; | |||||
const CString kString51 = "5.1"; | |||||
const CString kString60Cine = "6.0 Cine"; | |||||
const CString kString60Music = "6.0 Music"; | |||||
const CString kString61Cine = "6.1 Cine"; | |||||
const CString kString61Music = "6.1 Music"; | |||||
const CString kString70Cine = "7.0 Cine (SDDS)"; | |||||
const CString kString70Music = "7.0 Music (Dolby)"; | |||||
const CString kString71Cine = "7.1 Cine (SDDS)"; | |||||
const CString kString71Music = "7.1 Music (Dolby)"; | |||||
const CString kString71CineTopCenter = "7.1 Cine Top Center"; | |||||
const CString kString71CineCenterHigh = "7.1 Cine Center High"; | |||||
const CString kString71CineFrontHigh = "7.1 Cine Front High"; | |||||
const CString kString71CineSideHigh = "7.1 Cine Side High"; | |||||
const CString kString71CineFullRear = "7.1 Cine Full Rear"; | |||||
const CString kString71Proximity = "7.1 Proximity"; | |||||
const CString kString80Cine = "8.0 Cine"; | |||||
const CString kString80Music = "8.0 Music"; | |||||
const CString kString80Cube = "8.0 Cube"; | |||||
const CString kString81Cine = "8.1 Cine"; | |||||
const CString kString81Music = "8.1 Music"; | |||||
const CString kString102 = "10.2 Experimental"; | |||||
const CString kString122 = "12.2"; | |||||
const CString kString90 = "9.0 Auro-3D"; | |||||
const CString kString91 = "9.1 Auro-3D"; | |||||
const CString kString91Atmos = "9.1 Dolby Atmos"; | |||||
const CString kString100 = "10.0 Auro-3D"; | |||||
const CString kString101 = "10.1 Auro-3D"; | |||||
const CString kString110 = "11.0 Auro-3D"; | |||||
const CString kString111 = "11.1 Auro-3D"; | |||||
const CString kString130 = "13.0 Auro-3D"; | |||||
const CString kString131 = "13.1 Auro-3D"; | |||||
const CString kString81MPEG = "8.1 MPEG"; | |||||
const CString kString222 = "22.2"; | |||||
const CString kStringBFormat1stOrder = "BFormat"; | |||||
/*@}*/ | |||||
//------------------------------------------------------------------------ | |||||
/** Speaker Arrangement String Representation with Speakers Name. | |||||
\ingroup speakerArrangements */ | |||||
/*@{*/ | |||||
const CString kStringMonoS = "M"; | |||||
const CString kStringStereoS = "L R"; | |||||
const CString kStringStereoRS = "Ls Rs"; | |||||
const CString kStringStereoCS = "Lc Rc"; | |||||
const CString kStringStereoSS = "Sl Sr"; | |||||
const CString kStringStereoCLfeS= "C LFE"; | |||||
const CString kStringStereoTFS = "Tfl Tfr"; | |||||
const CString kStringStereoTSS = "Tsl Tsr"; | |||||
const CString kStringStereoTRS = "Trl Trr"; | |||||
const CString kStringStereoBFS = "Bfl Bfr"; | |||||
const CString kString30CineS = "L R C"; | |||||
const CString kString30MusicS = "L R S"; | |||||
const CString kString31CineS = "L R C LFE"; | |||||
const CString kString31MusicS = "L R LFE S"; | |||||
const CString kString40CineS = "L R C S"; | |||||
const CString kString40MusicS = "L R Ls Rs"; | |||||
const CString kString41CineS = "L R C LFE S"; | |||||
const CString kString41MusicS = "L R LFE Ls Rs"; | |||||
const CString kString50S = "L R C Ls Rs"; | |||||
const CString kString51S = "L R C LFE Ls Rs"; | |||||
const CString kString60CineS = "L R C Ls Rs Cs"; | |||||
const CString kString60MusicS = "L R Ls Rs Sl Sr"; | |||||
const CString kString61CineS = "L R C LFE Ls Rs Cs"; | |||||
const CString kString61MusicS = "L R LFE Ls Rs Sl Sr"; | |||||
const CString kString70CineS = "L R C Ls Rs Lc Rc"; | |||||
const CString kString70MusicS = "L R C Ls Rs Sl Sr"; | |||||
const CString kString71CineS = "L R C LFE Ls Rs Lc Rc"; | |||||
const CString kString71MusicS = "L R C LFE Ls Rs Sl Sr"; | |||||
const CString kString80CineS = "L R C Ls Rs Lc Rc Cs"; | |||||
const CString kString80MusicS = "L R C Ls Rs Cs Sl Sr"; | |||||
const CString kString81CineS = "L R C LFE Ls Rs Lc Rc Cs"; | |||||
const CString kString81MusicS = "L R C LFE Ls Rs Cs Sl Sr"; | |||||
const CString kString80CubeS = "L R Ls Rs Tfl Tfr Trl Trr"; | |||||
const CString kStringBFormat1stOrderS = "W X Y Z"; | |||||
const CString kString71CineTopCenterS = "L R C LFE Ls Rs Cs Tc"; | |||||
const CString kString71CineCenterHighS = "L R C LFE Ls Rs Cs Tfc"; | |||||
const CString kString71CineFrontHighS = "L R C LFE Ls Rs Tfl Tfl"; | |||||
const CString kString71CineSideHighS = "L R C LFE Ls Rs Tsl Tsl"; | |||||
const CString kString71CineFullRearS = "L R C LFE Ls Rs Lcs Rcs"; | |||||
const CString kString71ProximityS = "L R C LFE Ls Rs Pl Pr"; | |||||
const CString kString90S = "L R C Ls Rs Tfl Tfr Trl Trr"; | |||||
const CString kString91S = "L R C LFE Ls Rs Tfl Tfr Trl Trr"; | |||||
const CString kString91AtmosS = "L R C LFE Ls Rs Sl Sr Tsl Tsr"; | |||||
const CString kString100S = "L R C Ls Rs Tc Tfl Tfr Trl Trr"; | |||||
const CString kString101S = "L R C LFE Ls Rs Tc Tfl Tfr Trl Trr"; | |||||
const CString kString110S = "L R C Ls Rs Tc Tfl Tfc Tfr Trl Trr"; | |||||
const CString kString111S = "L R C LFE Ls Rs Tc Tfl Tfc Tfr Trl Trr"; | |||||
const CString kString130S = "L R C Ls Rs Sl Sr Tc Tfl Tfc Tfr Trl Trr"; | |||||
const CString kString131S = "L R C LFE Ls Rs Sl Sr Tc Tfl Tfc Tfr Trl Trr"; | |||||
const CString kString102S = "L R C LFE Ls Rs Tfl Tfc Tfr Trl Trr LFE2"; | |||||
const CString kString122S = "L R C LFE Ls Rs Lc Rc Tfl Tfc Tfr Trl Trr LFE2"; | |||||
const CString kString81MPEGS = "L R LFE Ls Rs Tfl Tfc Tfr Bfc"; | |||||
const CString kString222S = "L R C LFE Ls Rs Lc Rc Cs Sl Sr Tc Tfl Tfc Tfr Trl Trc Trr LFE2 Tsl Tsr Bfl Bfc Bfr"; | |||||
/*@}*/ | |||||
//------------------------------------------------------------------------ | |||||
/** Returns number of channels used in speaker arrangement. | |||||
\ingroup speakerArrangements */ | |||||
/*@{*/ | |||||
inline int32 getChannelCount (SpeakerArrangement arr) | |||||
{ | |||||
int32 count = 0; | |||||
while (arr) | |||||
{ | |||||
if (arr & (SpeakerArrangement)1) | |||||
++count; | |||||
arr >>= 1; | |||||
} | |||||
return count; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Returns the index of a given speaker in a speaker arrangement (-1 if speaker is not part of the arrangement). */ | |||||
inline int32 getSpeakerIndex (Speaker speaker, SpeakerArrangement arrangement) | |||||
{ | |||||
// check if speaker is present in arrangement | |||||
if ((arrangement & speaker) == 0) | |||||
return -1; | |||||
int32 result = 0; | |||||
Speaker i = 1; | |||||
while (i < speaker) | |||||
{ | |||||
if (arrangement & i) | |||||
result++; | |||||
i <<= 1; | |||||
} | |||||
return result; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Returns the speaker for a given index in a speaker arrangement (return 0 when out of range). */ | |||||
inline Speaker getSpeaker (const SpeakerArrangement& arr, int32 index) | |||||
{ | |||||
SpeakerArrangement arrTmp = arr; | |||||
int32 index2 = -1; | |||||
int32 pos = -1; | |||||
while (arrTmp) | |||||
{ | |||||
if (arrTmp & 0x1) | |||||
index2++; | |||||
pos++; | |||||
if (index2 == index) | |||||
return (Speaker)1 << pos; | |||||
arrTmp = arrTmp >> 1; | |||||
} | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Returns true if arrSubSet is a subset speaker of arr (means each speaker of arrSubSet is included in arr). */ | |||||
inline bool isSubsetOf (const SpeakerArrangement& arrSubSet, const SpeakerArrangement& arr) | |||||
{ | |||||
return (arrSubSet == (arrSubSet & arr)); | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Returns the speaker arrangement associated to a string representation. | |||||
Returns kEmpty if no associated arrangement is known. | |||||
*/ | |||||
inline SpeakerArrangement getSpeakerArrangementFromString (CString arrStr) | |||||
{ | |||||
if (!strcmp8 (arrStr, kStringMono)) | |||||
return kMono; | |||||
if (!strcmp8 (arrStr, kStringStereo)) | |||||
return kStereo; | |||||
if (!strcmp8 (arrStr, kStringStereoR)) | |||||
return kStereoSurround; | |||||
if (!strcmp8 (arrStr, kStringStereoC)) | |||||
return kStereoCenter; | |||||
if (!strcmp8 (arrStr, kStringStereoSide)) | |||||
return kStereoSide; | |||||
if (!strcmp8 (arrStr, kStringStereoCLfe)) | |||||
return kStereoCLfe; | |||||
if (!strcmp8 (arrStr, kStringStereoTF)) | |||||
return kStereoTF; | |||||
if (!strcmp8 (arrStr, kStringStereoTS)) | |||||
return kStereoTS; | |||||
if (!strcmp8 (arrStr, kStringStereoTR)) | |||||
return kStereoTR; | |||||
if (!strcmp8 (arrStr, kStringStereoBF)) | |||||
return kStereoBF; | |||||
if (!strcmp8 (arrStr, kString30Cine)) | |||||
return k30Cine; | |||||
if (!strcmp8 (arrStr, kString30Music)) | |||||
return k30Music; | |||||
if (!strcmp8 (arrStr, kString31Cine)) | |||||
return k31Cine; | |||||
if (!strcmp8 (arrStr, kString31Music)) | |||||
return k31Music; | |||||
if (!strcmp8 (arrStr, kString40Cine)) | |||||
return k40Cine; | |||||
if (!strcmp8 (arrStr, kString40Music)) | |||||
return k40Music; | |||||
if (!strcmp8 (arrStr, kString41Cine)) | |||||
return k41Cine; | |||||
if (!strcmp8 (arrStr, kString41Music)) | |||||
return k41Music; | |||||
if (!strcmp8 (arrStr, kString50)) | |||||
return k50; | |||||
if (!strcmp8 (arrStr, kString51)) | |||||
return k51; | |||||
if (!strcmp8 (arrStr, kString60Cine)) | |||||
return k60Cine; | |||||
if (!strcmp8 (arrStr, kString60Music)) | |||||
return k60Music; | |||||
if (!strcmp8 (arrStr, kString61Cine)) | |||||
return k61Cine; | |||||
if (!strcmp8 (arrStr, kString61Music)) | |||||
return k61Music; | |||||
if (!strcmp8 (arrStr, kString70Cine)) | |||||
return k70Cine; | |||||
if (!strcmp8 (arrStr, kString70Music)) | |||||
return k70Music; | |||||
if (!strcmp8 (arrStr, kString71Cine)) | |||||
return k71Cine; | |||||
if (!strcmp8 (arrStr, kString71Music)) | |||||
return k71Music; | |||||
if (!strcmp8 (arrStr, kString71Proximity)) | |||||
return k71Proximity; | |||||
if (!strcmp8 (arrStr, kString80Cine)) | |||||
return k80Cine; | |||||
if (!strcmp8 (arrStr, kString80Music)) | |||||
return k80Music; | |||||
if (!strcmp8 (arrStr, kString81Cine)) | |||||
return k81Cine; | |||||
if (!strcmp8 (arrStr, kString81Music)) | |||||
return k81Music; | |||||
if (!strcmp8 (arrStr, kString102)) | |||||
return k102; | |||||
if (!strcmp8 (arrStr, kString122)) | |||||
return k122; | |||||
if (!strcmp8 (arrStr, kString80Cube)) | |||||
return k80Cube; | |||||
if (!strcmp8 (arrStr, kStringBFormat1stOrder)) | |||||
return kBFormat1stOrder; | |||||
if (!strcmp8 (arrStr, kString71CineTopCenter)) | |||||
return k71CineTopCenter; | |||||
if (!strcmp8 (arrStr, kString71CineCenterHigh)) | |||||
return k71CineCenterHigh; | |||||
if (!strcmp8 (arrStr, kString71CineFrontHigh)) | |||||
return k71CineFrontHigh; | |||||
if (!strcmp8 (arrStr, kString71CineSideHigh)) | |||||
return k71CineSideHigh; | |||||
if (!strcmp8 (arrStr, kString71CineFullRear)) | |||||
return k71CineFullRear; | |||||
if (!strcmp8 (arrStr, kString90)) | |||||
return k90; | |||||
if (!strcmp8 (arrStr, kString81MPEG)) | |||||
return k81MPEG3D; | |||||
if (!strcmp8 (arrStr, kString91)) | |||||
return k91; | |||||
if (!strcmp8 (arrStr, kString91Atmos)) | |||||
return k91Atmos; | |||||
if (!strcmp8 (arrStr, kString100)) | |||||
return k100; | |||||
if (!strcmp8 (arrStr, kString101)) | |||||
return k101; | |||||
if (!strcmp8 (arrStr, kString110)) | |||||
return k110; | |||||
if (!strcmp8 (arrStr, kString111)) | |||||
return k111; | |||||
if (!strcmp8 (arrStr, kString130)) | |||||
return k130; | |||||
if (!strcmp8 (arrStr, kString131)) | |||||
return k131; | |||||
if (!strcmp8 (arrStr, kString222)) | |||||
return k222; | |||||
return kEmpty; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Returns the string representation of a given speaker arrangement. | |||||
Returns kStringEmpty if arr is unknown. | |||||
*/ | |||||
inline CString getSpeakerArrangementString (SpeakerArrangement arr, bool withSpeakersName) | |||||
{ | |||||
switch (arr) | |||||
{ | |||||
case kMono: return withSpeakersName ? kStringMonoS : kStringMono; | |||||
case kStereo: return withSpeakersName ? kStringStereoS : kStringStereo; | |||||
case kStereoSurround: return withSpeakersName ? kStringStereoRS : kStringStereoR; | |||||
case kStereoCenter: return withSpeakersName ? kStringStereoCS : kStringStereoC; | |||||
case kStereoSide: return withSpeakersName ? kStringStereoSS : kStringStereoSide; | |||||
case kStereoCLfe: return withSpeakersName ? kStringStereoCLfeS: kStringStereoCLfe; | |||||
case kStereoTF: return withSpeakersName ? kStringStereoTFS : kStringStereoTF; | |||||
case kStereoTS: return withSpeakersName ? kStringStereoTSS : kStringStereoTS; | |||||
case kStereoTR: return withSpeakersName ? kStringStereoTRS : kStringStereoTR; | |||||
case kStereoBF: return withSpeakersName ? kStringStereoBFS : kStringStereoBF; | |||||
case k30Cine: return withSpeakersName ? kString30CineS : kString30Cine; | |||||
case k30Music: return withSpeakersName ? kString30MusicS : kString30Music; | |||||
case k31Cine: return withSpeakersName ? kString31CineS : kString31Cine; | |||||
case k31Music: return withSpeakersName ? kString31MusicS : kString31Music; | |||||
case k40Cine: return withSpeakersName ? kString40CineS : kString40Cine; | |||||
case k40Music: return withSpeakersName ? kString40MusicS : kString40Music; | |||||
case k41Cine: return withSpeakersName ? kString41CineS : kString41Cine; | |||||
case k41Music: return withSpeakersName ? kString41MusicS : kString41Music; | |||||
case k50: return withSpeakersName ? kString50S : kString50; | |||||
case k51: return withSpeakersName ? kString51S : kString51; | |||||
case k60Cine: return withSpeakersName ? kString60CineS : kString60Cine; | |||||
case k60Music: return withSpeakersName ? kString60MusicS : kString60Music; | |||||
case k61Cine: return withSpeakersName ? kString61CineS : kString61Cine; | |||||
case k61Music: return withSpeakersName ? kString61MusicS : kString61Music; | |||||
case k70Cine: return withSpeakersName ? kString70CineS : kString70Cine; | |||||
case k70Music: return withSpeakersName ? kString70MusicS : kString70Music; | |||||
case k71Cine: return withSpeakersName ? kString71CineS : kString71Cine; | |||||
case k71Music: return withSpeakersName ? kString71MusicS : kString71Music; | |||||
case k71Proximity: return withSpeakersName ? kString71ProximityS : kString71Proximity; | |||||
case k80Cine: return withSpeakersName ? kString80CineS : kString80Cine; | |||||
case k80Music: return withSpeakersName ? kString80MusicS : kString80Music; | |||||
case k81Cine: return withSpeakersName ? kString81CineS : kString81Cine; | |||||
case k81Music: return withSpeakersName ? kString81MusicS : kString81Music; | |||||
case k81MPEG3D: return withSpeakersName ? kString81MPEGS : kString81MPEG; | |||||
case k102: return withSpeakersName ? kString102S : kString102; | |||||
case k122: return withSpeakersName ? kString122S : kString122; | |||||
case k80Cube: return withSpeakersName ? kString80CubeS : kString80Cube; | |||||
case kBFormat1stOrder: return withSpeakersName ? kStringBFormat1stOrderS : kStringBFormat1stOrder; | |||||
case k71CineTopCenter: return withSpeakersName ? kString71CineTopCenterS : kString71CineTopCenter; | |||||
case k71CineCenterHigh: return withSpeakersName ? kString71CineCenterHighS : kString71CineCenterHigh; | |||||
case k71CineFrontHigh: return withSpeakersName ? kString71CineFrontHighS : kString71CineFrontHigh; | |||||
case k71CineSideHigh: return withSpeakersName ? kString71CineSideHighS : kString71CineSideHigh; | |||||
case k71CineFullRear: return withSpeakersName ? kString71CineFullRearS : kString71CineFullRear; | |||||
case k90: return withSpeakersName ? kString90S : kString90; | |||||
case k91: return withSpeakersName ? kString91S : kString91; | |||||
case k91Atmos: return withSpeakersName ? kString91AtmosS : kString91Atmos; | |||||
case k100: return withSpeakersName ? kString100S : kString100; | |||||
case k101: return withSpeakersName ? kString101S : kString101; | |||||
case k110: return withSpeakersName ? kString110S : kString110; | |||||
case k111: return withSpeakersName ? kString111S : kString111; | |||||
case k130: return withSpeakersName ? kString130S : kString130; | |||||
case k131: return withSpeakersName ? kString131S : kString131; | |||||
case k222: return withSpeakersName ? kString222S : kString222; | |||||
break; | |||||
} | |||||
return kStringEmpty; | |||||
} | |||||
//------------------------------------------------------------------------ | |||||
/** Returns a CString representation of a given speaker in a given arrangement | |||||
*/ | |||||
inline CString getSpeakerShortName (const SpeakerArrangement& arr, int32 index) | |||||
{ | |||||
SpeakerArrangement arrTmp = arr; | |||||
bool found = false; | |||||
int32 index2 = -1; | |||||
int32 pos = -1; | |||||
while (arrTmp) | |||||
{ | |||||
if (arrTmp & 0x1) | |||||
index2++; | |||||
pos++; | |||||
if (index2 == index) | |||||
{ | |||||
found = true; | |||||
break; | |||||
} | |||||
arrTmp = arrTmp >> 1; | |||||
} | |||||
if (!found) | |||||
return ""; | |||||
switch ((Speaker)1 << pos) | |||||
{ | |||||
case kSpeakerL: | |||||
return "L"; | |||||
case kSpeakerR: | |||||
return "R"; | |||||
case kSpeakerC: | |||||
return "C"; | |||||
case kSpeakerLfe: | |||||
return "LFE"; | |||||
case kSpeakerLs: | |||||
return "Ls"; | |||||
case kSpeakerRs: | |||||
return "Rs"; | |||||
case kSpeakerLc: | |||||
return "Lc"; | |||||
case kSpeakerRc: | |||||
return "Rc"; | |||||
case kSpeakerS: | |||||
return "S"; | |||||
case kSpeakerSl: | |||||
return "Sl"; | |||||
case kSpeakerSr: | |||||
return "Sr"; | |||||
case kSpeakerTc: | |||||
return "Tc"; | |||||
case kSpeakerTfl: | |||||
return "Tfl"; | |||||
case kSpeakerTfc: | |||||
return "Tfc"; | |||||
case kSpeakerTfr: | |||||
return "Tfr"; | |||||
case kSpeakerTrl: | |||||
return "Trl"; | |||||
case kSpeakerTrc: | |||||
return "Trc"; | |||||
case kSpeakerTrr: | |||||
return "Trr"; | |||||
case kSpeakerLfe2: | |||||
return "LFE2"; | |||||
case kSpeakerM: | |||||
return "M"; | |||||
case kSpeakerW: | |||||
return "W"; | |||||
case kSpeakerX: | |||||
return "X"; | |||||
case kSpeakerY: | |||||
return "Y"; | |||||
case kSpeakerZ: | |||||
return "Z"; | |||||
case kSpeakerTsl: | |||||
return "Tsl"; | |||||
case kSpeakerTsr: | |||||
return "Tsr"; | |||||
case kSpeakerLcs: | |||||
return "Lcs"; | |||||
case kSpeakerRcs: | |||||
return "Rcs"; | |||||
case kSpeakerBfl: | |||||
return "Bfl"; | |||||
case kSpeakerBfc: | |||||
return "Bfc"; | |||||
case kSpeakerBfr: | |||||
return "Bfr"; | |||||
case kSpeakerPl: | |||||
return "Pl"; | |||||
case kSpeakerPr: | |||||
return "Pr"; | |||||
} | |||||
return ""; | |||||
} | |||||
/*@}*/ | |||||
//------------------------------------------------------------------------ | |||||
} // namespace SpeakerArr | |||||
} // namespace Vst | |||||
} // namespace Steinberg |