mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
added support for sysexes to the VST plugin/hosting. Also tweaked URL::isProbablyAWebsiteURL(), and fixed a couple of mac build problems.
This commit is contained in:
parent
693c94978c
commit
ec87ea494c
14 changed files with 866 additions and 524 deletions
|
|
@ -422,7 +422,8 @@ bool juce_launchFile (const String& fileName,
|
|||
String cmdString (fileName);
|
||||
cmdString << " " << parameters;
|
||||
|
||||
if (URL::isProbablyAWebsiteURL (cmdString) || URL::isProbablyAnEmailAddress (cmdString))
|
||||
if (URL::isProbablyAWebsiteURL (fileName)
|
||||
|| URL::isProbablyAnEmailAddress (fileName))
|
||||
{
|
||||
// create a command that tries to launch a bunch of likely browsers
|
||||
const char* const browserNames[] = { "/etc/alternatives/x-www-browser", "firefox", "mozilla", "konqueror", "opera" };
|
||||
|
|
@ -435,6 +436,9 @@ bool juce_launchFile (const String& fileName,
|
|||
cmdString = cmdLines.joinIntoString (T(" || "));
|
||||
}
|
||||
|
||||
if (cmdString.startsWithIgnoreCase (T("file:")))
|
||||
cmdString = cmdString.substring (5);
|
||||
|
||||
char* const argv[4] = { "/bin/sh", "-c", (char*) cmdString.toUTF8(), 0 };
|
||||
|
||||
const int cpid = fork();
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
*/
|
||||
|
||||
#define JUCE_QUICKTIME 0
|
||||
#define JUCE_SUPPORT_CARBON 1
|
||||
|
||||
//#define JUCE_PLUGINHOST_VST 1
|
||||
//#define JUCE_PLUGINHOST_AU 1
|
||||
//#define JUCE_ONLY_BUILD_CORE_LIBRARY 1
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@
|
|||
#endif
|
||||
|
||||
#include "../juce_PluginHeaders.h"
|
||||
#include "../../../../src/juce_appframework/audio/plugins/formats/juce_VSTMidiEventList.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack (pop)
|
||||
|
|
@ -336,8 +338,6 @@ public:
|
|||
filter (filter_)
|
||||
{
|
||||
editorComp = 0;
|
||||
outgoingEvents = 0;
|
||||
outgoingEventSize = 0;
|
||||
chunkMemoryTime = 0;
|
||||
isProcessing = false;
|
||||
hasShutdown = false;
|
||||
|
|
@ -393,15 +393,6 @@ public:
|
|||
delete filter;
|
||||
filter = 0;
|
||||
|
||||
if (outgoingEvents != 0)
|
||||
{
|
||||
for (int i = outgoingEventSize; --i >= 0;)
|
||||
juce_free (outgoingEvents->events[i]);
|
||||
|
||||
juce_free (outgoingEvents);
|
||||
outgoingEvents = 0;
|
||||
}
|
||||
|
||||
jassert (editorComp == 0);
|
||||
|
||||
juce_free (channels);
|
||||
|
|
@ -560,20 +551,7 @@ public:
|
|||
VstInt32 processEvents (VstEvents* events)
|
||||
{
|
||||
#if JucePlugin_WantsMidiInput
|
||||
for (int i = 0; i < events->numEvents; ++i)
|
||||
{
|
||||
const VstEvent* const e = events->events[i];
|
||||
|
||||
if (e != 0 && e->type == kVstMidiType)
|
||||
{
|
||||
const VstMidiEvent* const vme = (const VstMidiEvent*) e;
|
||||
|
||||
midiEvents.addEvent ((const JUCE_NAMESPACE::uint8*) vme->midiData,
|
||||
4,
|
||||
vme->deltaFrames);
|
||||
}
|
||||
}
|
||||
|
||||
VSTMidiEventList::addEventsToMidiBuffer (events, midiEvents);
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
|
|
@ -682,8 +660,8 @@ public:
|
|||
#if JucePlugin_ProducesMidiOutput
|
||||
const int numEvents = midiEvents.getNumEvents();
|
||||
|
||||
ensureOutgoingEventSize (numEvents);
|
||||
outgoingEvents->numEvents = 0;
|
||||
outgoingEvents.ensureSize (numEvents);
|
||||
outgoingEvents.clear();
|
||||
|
||||
const JUCE_NAMESPACE::uint8* midiEventData;
|
||||
int midiEventSize, midiEventPosition;
|
||||
|
|
@ -691,18 +669,12 @@ public:
|
|||
|
||||
while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition))
|
||||
{
|
||||
if (midiEventSize <= 4)
|
||||
{
|
||||
VstMidiEvent* const vme = (VstMidiEvent*) outgoingEvents->events [outgoingEvents->numEvents++];
|
||||
jassert (midiEventPosition >= 0 && midiEventPosition < numSamples);
|
||||
|
||||
memcpy (vme->midiData, midiEventData, midiEventSize);
|
||||
vme->deltaFrames = midiEventPosition;
|
||||
|
||||
jassert (vme->deltaFrames >= 0 && vme->deltaFrames < numSamples);
|
||||
}
|
||||
outgoingEvents.addEvent (midiEventData, midiEventSize, midiEventPosition);
|
||||
}
|
||||
|
||||
sendVstEventsToHost (outgoingEvents);
|
||||
sendVstEventsToHost (outgoingEvents.events);
|
||||
#else
|
||||
/* This assertion is caused when you've added some events to the
|
||||
midiMessages array in your processBlock() method, which usually means
|
||||
|
|
@ -763,7 +735,7 @@ public:
|
|||
AudioEffectX::resume();
|
||||
|
||||
#if JucePlugin_ProducesMidiOutput
|
||||
ensureOutgoingEventSize (64);
|
||||
outgoingEvents.ensureSize (64);
|
||||
#endif
|
||||
|
||||
#if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4
|
||||
|
|
@ -779,7 +751,7 @@ public:
|
|||
AudioEffectX::suspend();
|
||||
|
||||
filter->releaseResources();
|
||||
midiEvents.clear();
|
||||
outgoingEvents.freeEvents();
|
||||
|
||||
isProcessing = false;
|
||||
juce_free (channels);
|
||||
|
|
@ -1355,8 +1327,7 @@ private:
|
|||
EditorCompWrapper* editorComp;
|
||||
ERect editorSize;
|
||||
MidiBuffer midiEvents;
|
||||
VstEvents* outgoingEvents;
|
||||
int outgoingEventSize;
|
||||
VSTMidiEventList outgoingEvents;
|
||||
bool isProcessing;
|
||||
bool hasShutdown;
|
||||
bool firstProcessCallback;
|
||||
|
|
@ -1381,31 +1352,6 @@ private:
|
|||
hasCreatedTempChannels = false;
|
||||
}
|
||||
|
||||
void ensureOutgoingEventSize (int numEvents)
|
||||
{
|
||||
if (outgoingEventSize < numEvents)
|
||||
{
|
||||
numEvents += 32;
|
||||
const int size = 16 + sizeof (VstEvent*) * numEvents;
|
||||
|
||||
if (outgoingEvents == 0)
|
||||
outgoingEvents = (VstEvents*) juce_calloc (size);
|
||||
else
|
||||
outgoingEvents = (VstEvents*) juce_realloc (outgoingEvents, size);
|
||||
|
||||
for (int i = outgoingEventSize; i < numEvents; ++i)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (sizeof (VstMidiEvent));
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = 24;
|
||||
|
||||
outgoingEvents->events[i] = (VstEvent*) e;
|
||||
}
|
||||
|
||||
outgoingEventSize = numEvents;
|
||||
}
|
||||
}
|
||||
|
||||
const String getHostName()
|
||||
{
|
||||
char host[256];
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
*/
|
||||
#include "JucePluginCharacteristics.h"
|
||||
|
||||
#define SUPPORT_CARBON 1
|
||||
|
||||
//==============================================================================
|
||||
// The following stuff is just to cause a compile error if you've forgotten to
|
||||
|
|
|
|||
|
|
@ -615,6 +615,243 @@
|
|||
#pragma warning (disable: 4309 4305)
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC && JUCE_SUPPORT_CARBON
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
/********* Start of inlined file: juce_mac_CarbonViewWrapperComponent.h *********/
|
||||
#ifndef __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
|
||||
#define __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
|
||||
|
||||
/**
|
||||
Creates a floating carbon window that can be used to hold a carbon UI.
|
||||
|
||||
This is a handy class that's designed to be inlined where needed, e.g.
|
||||
in the audio plugin hosting code.
|
||||
*/
|
||||
class CarbonViewWrapperComponent : public Component,
|
||||
public ComponentMovementWatcher,
|
||||
public Timer
|
||||
{
|
||||
public:
|
||||
CarbonViewWrapperComponent()
|
||||
: ComponentMovementWatcher (this),
|
||||
wrapperWindow (0),
|
||||
embeddedView (0),
|
||||
recursiveResize (false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CarbonViewWrapperComponent()
|
||||
{
|
||||
jassert (embeddedView == 0); // must call deleteWindow() in the subclass's destructor!
|
||||
}
|
||||
|
||||
virtual HIViewRef attachView (WindowRef windowRef, HIViewRef rootView) = 0;
|
||||
virtual void removeView (HIViewRef embeddedView) = 0;
|
||||
virtual void mouseDown (int x, int y) {}
|
||||
virtual void paint() {}
|
||||
|
||||
virtual bool getEmbeddedViewSize (int& w, int& h)
|
||||
{
|
||||
if (embeddedView == 0)
|
||||
return false;
|
||||
|
||||
HIRect bounds;
|
||||
HIViewGetBounds (embeddedView, &bounds);
|
||||
w = jmax (1, roundFloatToInt (bounds.size.width));
|
||||
h = jmax (1, roundFloatToInt (bounds.size.height));
|
||||
return true;
|
||||
}
|
||||
|
||||
void createWindow()
|
||||
{
|
||||
if (wrapperWindow == 0)
|
||||
{
|
||||
Rect r;
|
||||
r.left = getScreenX();
|
||||
r.top = getScreenY();
|
||||
r.right = r.left + getWidth();
|
||||
r.bottom = r.top + getHeight();
|
||||
|
||||
CreateNewWindow (kDocumentWindowClass,
|
||||
(WindowAttributes) (kWindowStandardHandlerAttribute | kWindowCompositingAttribute
|
||||
| kWindowNoShadowAttribute | kWindowNoTitleBarAttribute),
|
||||
&r, &wrapperWindow);
|
||||
|
||||
jassert (wrapperWindow != 0);
|
||||
if (wrapperWindow == 0)
|
||||
return;
|
||||
|
||||
NSWindow* carbonWindow = [[NSWindow alloc] initWithWindowRef: wrapperWindow];
|
||||
NSWindow* ownerWindow = [((NSView*) getWindowHandle()) window];
|
||||
|
||||
[ownerWindow addChildWindow: carbonWindow
|
||||
ordered: NSWindowAbove];
|
||||
|
||||
embeddedView = attachView (wrapperWindow, HIViewGetRoot (wrapperWindow));
|
||||
|
||||
EventTypeSpec windowEventTypes[] = { { kEventClassWindow, kEventWindowGetClickActivation },
|
||||
{ kEventClassWindow, kEventWindowHandleDeactivate } };
|
||||
|
||||
EventHandlerUPP upp = NewEventHandlerUPP (carbonEventCallback);
|
||||
InstallWindowEventHandler (wrapperWindow, upp,
|
||||
sizeof (windowEventTypes) / sizeof (EventTypeSpec),
|
||||
windowEventTypes, this, &eventHandlerRef);
|
||||
|
||||
setOurSizeToEmbeddedViewSize();
|
||||
setEmbeddedWindowToOurSize();
|
||||
|
||||
creationTime = Time::getCurrentTime();
|
||||
}
|
||||
}
|
||||
|
||||
void deleteWindow()
|
||||
{
|
||||
removeView (embeddedView);
|
||||
embeddedView = 0;
|
||||
|
||||
if (wrapperWindow != 0)
|
||||
{
|
||||
RemoveEventHandler (eventHandlerRef);
|
||||
DisposeWindow (wrapperWindow);
|
||||
wrapperWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setOurSizeToEmbeddedViewSize()
|
||||
{
|
||||
int w, h;
|
||||
if (getEmbeddedViewSize (w, h))
|
||||
{
|
||||
if (w != getWidth() || h != getHeight())
|
||||
{
|
||||
startTimer (50);
|
||||
|
||||
setSize (w, h);
|
||||
if (getParentComponent() != 0)
|
||||
getParentComponent()->setSize (w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
startTimer (jlimit (50, 500, getTimerInterval() + 20));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void setEmbeddedWindowToOurSize()
|
||||
{
|
||||
if (! recursiveResize)
|
||||
{
|
||||
recursiveResize = true;
|
||||
|
||||
if (embeddedView != 0)
|
||||
{
|
||||
HIRect r;
|
||||
r.origin.x = 0;
|
||||
r.origin.y = 0;
|
||||
r.size.width = (float) getWidth();
|
||||
r.size.height = (float) getHeight();
|
||||
HIViewSetFrame (embeddedView, &r);
|
||||
}
|
||||
|
||||
if (wrapperWindow != 0)
|
||||
{
|
||||
Rect wr;
|
||||
wr.left = getScreenX();
|
||||
wr.top = getScreenY();
|
||||
wr.right = wr.left + getWidth();
|
||||
wr.bottom = wr.top + getHeight();
|
||||
|
||||
SetWindowBounds (wrapperWindow, kWindowContentRgn, &wr);
|
||||
ShowWindow (wrapperWindow);
|
||||
}
|
||||
|
||||
recursiveResize = false;
|
||||
}
|
||||
}
|
||||
|
||||
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
|
||||
{
|
||||
setEmbeddedWindowToOurSize();
|
||||
}
|
||||
|
||||
void componentPeerChanged()
|
||||
{
|
||||
deleteWindow();
|
||||
createWindow();
|
||||
}
|
||||
|
||||
void componentVisibilityChanged (Component&)
|
||||
{
|
||||
if (isShowing())
|
||||
createWindow();
|
||||
else
|
||||
deleteWindow();
|
||||
|
||||
setEmbeddedWindowToOurSize();
|
||||
}
|
||||
|
||||
void timerCallback()
|
||||
{
|
||||
setOurSizeToEmbeddedViewSize();
|
||||
|
||||
// To avoid strange overpainting problems when the UI is first opened, we'll
|
||||
// repaint it a few times during the first second that it's on-screen..
|
||||
if ((Time::getCurrentTime() - creationTime).inMilliseconds() < 1000)
|
||||
HIViewSetNeedsDisplay (embeddedView, true);
|
||||
}
|
||||
|
||||
OSStatus carbonEventHandler (EventHandlerCallRef nextHandlerRef,
|
||||
EventRef event)
|
||||
{
|
||||
switch (GetEventKind (event))
|
||||
{
|
||||
case kEventWindowHandleDeactivate:
|
||||
ActivateWindow (wrapperWindow, TRUE);
|
||||
break;
|
||||
|
||||
case kEventWindowGetClickActivation:
|
||||
{
|
||||
getTopLevelComponent()->toFront (false);
|
||||
|
||||
ClickActivationResult howToHandleClick = kActivateAndHandleClick;
|
||||
|
||||
SetEventParameter (event, kEventParamClickActivation, typeClickActivationResult,
|
||||
sizeof (ClickActivationResult), &howToHandleClick);
|
||||
|
||||
HIViewSetNeedsDisplay (embeddedView, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static pascal OSStatus carbonEventCallback (EventHandlerCallRef nextHandlerRef,
|
||||
EventRef event, void* userData)
|
||||
{
|
||||
return ((CarbonViewWrapperComponent*) userData)->carbonEventHandler (nextHandlerRef, event);
|
||||
}
|
||||
|
||||
protected:
|
||||
WindowRef wrapperWindow;
|
||||
HIViewRef embeddedView;
|
||||
bool recursiveResize;
|
||||
Time creationTime;
|
||||
|
||||
EventHandlerRef eventHandlerRef;
|
||||
};
|
||||
|
||||
#endif // __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
|
||||
/********* End of inlined file: juce_mac_CarbonViewWrapperComponent.h *********/
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/********* Start of inlined file: juce_FileLogger.cpp *********/
|
||||
|
|
@ -7191,17 +7428,27 @@ bool URL::isWellFormed() const
|
|||
|
||||
bool URL::isProbablyAWebsiteURL (const String& possibleURL)
|
||||
{
|
||||
return (possibleURL.containsChar (T('.'))
|
||||
&& (! possibleURL.containsChar (T('@')))
|
||||
&& (! possibleURL.endsWithChar (T('.')))
|
||||
&& (possibleURL.startsWithIgnoreCase (T("www."))
|
||||
|| possibleURL.startsWithIgnoreCase (T("http:"))
|
||||
|| possibleURL.startsWithIgnoreCase (T("ftp:"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".com"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".net"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".org"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".co.uk")))
|
||||
|| possibleURL.startsWithIgnoreCase (T("file:")));
|
||||
if (possibleURL.startsWithIgnoreCase (T("http:"))
|
||||
|| possibleURL.startsWithIgnoreCase (T("ftp:")))
|
||||
return true;
|
||||
|
||||
if (possibleURL.startsWithIgnoreCase (T("file:"))
|
||||
|| possibleURL.containsChar (T('@'))
|
||||
|| possibleURL.endsWithChar (T('.'))
|
||||
|| (! possibleURL.containsChar (T('.'))))
|
||||
return false;
|
||||
|
||||
if (possibleURL.startsWithIgnoreCase (T("www."))
|
||||
&& possibleURL.substring (5).containsChar (T('.')))
|
||||
return true;
|
||||
|
||||
const char* commonTLDs[] = { "com", "net", "org", "uk", "de", "fr", "jp" };
|
||||
|
||||
for (int i = 0; i < numElementsInArray (commonTLDs); ++i)
|
||||
if ((possibleURL + T("/")).containsIgnoreCase (T(".") + String (commonTLDs[i]) + T("/")))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress)
|
||||
|
|
@ -27674,241 +27921,6 @@ BEGIN_JUCE_NAMESPACE
|
|||
#define log(a)
|
||||
#endif
|
||||
|
||||
#if JUCE_SUPPORT_CARBON
|
||||
|
||||
/********* Start of inlined file: juce_mac_CarbonViewWrapperComponent.h *********/
|
||||
#ifndef __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
|
||||
#define __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
|
||||
|
||||
/**
|
||||
Creates a floating carbon window that can be used to hold a carbon UI.
|
||||
|
||||
This is a handy class that's designed to be inlined where needed, e.g.
|
||||
in the audio plugin hosting code.
|
||||
*/
|
||||
class CarbonViewWrapperComponent : public Component,
|
||||
public ComponentMovementWatcher,
|
||||
public Timer
|
||||
{
|
||||
public:
|
||||
CarbonViewWrapperComponent()
|
||||
: ComponentMovementWatcher (this),
|
||||
wrapperWindow (0),
|
||||
embeddedView (0),
|
||||
recursiveResize (false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CarbonViewWrapperComponent()
|
||||
{
|
||||
jassert (embeddedView == 0); // must call deleteWindow() in the subclass's destructor!
|
||||
}
|
||||
|
||||
virtual HIViewRef attachView (WindowRef windowRef, HIViewRef rootView) = 0;
|
||||
virtual void removeView (HIViewRef embeddedView) = 0;
|
||||
virtual void mouseDown (int x, int y) {}
|
||||
virtual void paint() {}
|
||||
|
||||
virtual bool getEmbeddedViewSize (int& w, int& h)
|
||||
{
|
||||
if (embeddedView == 0)
|
||||
return false;
|
||||
|
||||
HIRect bounds;
|
||||
HIViewGetBounds (embeddedView, &bounds);
|
||||
w = jmax (1, roundFloatToInt (bounds.size.width));
|
||||
h = jmax (1, roundFloatToInt (bounds.size.height));
|
||||
return true;
|
||||
}
|
||||
|
||||
void createWindow()
|
||||
{
|
||||
if (wrapperWindow == 0)
|
||||
{
|
||||
Rect r;
|
||||
r.left = getScreenX();
|
||||
r.top = getScreenY();
|
||||
r.right = r.left + getWidth();
|
||||
r.bottom = r.top + getHeight();
|
||||
|
||||
CreateNewWindow (kDocumentWindowClass,
|
||||
(WindowAttributes) (kWindowStandardHandlerAttribute | kWindowCompositingAttribute
|
||||
| kWindowNoShadowAttribute | kWindowNoTitleBarAttribute),
|
||||
&r, &wrapperWindow);
|
||||
|
||||
jassert (wrapperWindow != 0);
|
||||
if (wrapperWindow == 0)
|
||||
return;
|
||||
|
||||
NSWindow* carbonWindow = [[NSWindow alloc] initWithWindowRef: wrapperWindow];
|
||||
NSWindow* ownerWindow = [((NSView*) getWindowHandle()) window];
|
||||
|
||||
[ownerWindow addChildWindow: carbonWindow
|
||||
ordered: NSWindowAbove];
|
||||
|
||||
embeddedView = attachView (wrapperWindow, HIViewGetRoot (wrapperWindow));
|
||||
|
||||
EventTypeSpec windowEventTypes[] = { { kEventClassWindow, kEventWindowGetClickActivation },
|
||||
{ kEventClassWindow, kEventWindowHandleDeactivate } };
|
||||
|
||||
EventHandlerUPP upp = NewEventHandlerUPP (carbonEventCallback);
|
||||
InstallWindowEventHandler (wrapperWindow, upp,
|
||||
sizeof (windowEventTypes) / sizeof (EventTypeSpec),
|
||||
windowEventTypes, this, &eventHandlerRef);
|
||||
|
||||
setOurSizeToEmbeddedViewSize();
|
||||
setEmbeddedWindowToOurSize();
|
||||
|
||||
creationTime = Time::getCurrentTime();
|
||||
}
|
||||
}
|
||||
|
||||
void deleteWindow()
|
||||
{
|
||||
removeView (embeddedView);
|
||||
embeddedView = 0;
|
||||
|
||||
if (wrapperWindow != 0)
|
||||
{
|
||||
RemoveEventHandler (eventHandlerRef);
|
||||
DisposeWindow (wrapperWindow);
|
||||
wrapperWindow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setOurSizeToEmbeddedViewSize()
|
||||
{
|
||||
int w, h;
|
||||
if (getEmbeddedViewSize (w, h))
|
||||
{
|
||||
if (w != getWidth() || h != getHeight())
|
||||
{
|
||||
startTimer (50);
|
||||
|
||||
setSize (w, h);
|
||||
if (getParentComponent() != 0)
|
||||
getParentComponent()->setSize (w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
startTimer (jlimit (50, 500, getTimerInterval() + 20));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void setEmbeddedWindowToOurSize()
|
||||
{
|
||||
if (! recursiveResize)
|
||||
{
|
||||
recursiveResize = true;
|
||||
|
||||
if (embeddedView != 0)
|
||||
{
|
||||
HIRect r;
|
||||
r.origin.x = 0;
|
||||
r.origin.y = 0;
|
||||
r.size.width = (float) getWidth();
|
||||
r.size.height = (float) getHeight();
|
||||
HIViewSetFrame (embeddedView, &r);
|
||||
}
|
||||
|
||||
if (wrapperWindow != 0)
|
||||
{
|
||||
Rect wr;
|
||||
wr.left = getScreenX();
|
||||
wr.top = getScreenY();
|
||||
wr.right = wr.left + getWidth();
|
||||
wr.bottom = wr.top + getHeight();
|
||||
|
||||
SetWindowBounds (wrapperWindow, kWindowContentRgn, &wr);
|
||||
ShowWindow (wrapperWindow);
|
||||
}
|
||||
|
||||
recursiveResize = false;
|
||||
}
|
||||
}
|
||||
|
||||
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
|
||||
{
|
||||
setEmbeddedWindowToOurSize();
|
||||
}
|
||||
|
||||
void componentPeerChanged()
|
||||
{
|
||||
deleteWindow();
|
||||
createWindow();
|
||||
}
|
||||
|
||||
void componentVisibilityChanged (Component&)
|
||||
{
|
||||
if (isShowing())
|
||||
createWindow();
|
||||
else
|
||||
deleteWindow();
|
||||
|
||||
setEmbeddedWindowToOurSize();
|
||||
}
|
||||
|
||||
void timerCallback()
|
||||
{
|
||||
setOurSizeToEmbeddedViewSize();
|
||||
|
||||
// To avoid strange overpainting problems when the UI is first opened, we'll
|
||||
// repaint it a few times during the first second that it's on-screen..
|
||||
if ((Time::getCurrentTime() - creationTime).inMilliseconds() < 1000)
|
||||
HIViewSetNeedsDisplay (embeddedView, true);
|
||||
}
|
||||
|
||||
OSStatus carbonEventHandler (EventHandlerCallRef nextHandlerRef,
|
||||
EventRef event)
|
||||
{
|
||||
switch (GetEventKind (event))
|
||||
{
|
||||
case kEventWindowHandleDeactivate:
|
||||
ActivateWindow (wrapperWindow, TRUE);
|
||||
break;
|
||||
|
||||
case kEventWindowGetClickActivation:
|
||||
{
|
||||
getTopLevelComponent()->toFront (false);
|
||||
|
||||
ClickActivationResult howToHandleClick = kActivateAndHandleClick;
|
||||
|
||||
SetEventParameter (event, kEventParamClickActivation, typeClickActivationResult,
|
||||
sizeof (ClickActivationResult), &howToHandleClick);
|
||||
|
||||
HIViewSetNeedsDisplay (embeddedView, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static pascal OSStatus carbonEventCallback (EventHandlerCallRef nextHandlerRef,
|
||||
EventRef event, void* userData)
|
||||
{
|
||||
return ((CarbonViewWrapperComponent*) userData)->carbonEventHandler (nextHandlerRef, event);
|
||||
}
|
||||
|
||||
protected:
|
||||
WindowRef wrapperWindow;
|
||||
HIViewRef embeddedView;
|
||||
bool recursiveResize;
|
||||
Time creationTime;
|
||||
|
||||
EventHandlerRef eventHandlerRef;
|
||||
};
|
||||
|
||||
#endif // __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
|
||||
/********* End of inlined file: juce_mac_CarbonViewWrapperComponent.h *********/
|
||||
|
||||
#endif
|
||||
|
||||
static int insideCallback = 0;
|
||||
|
||||
static const String osTypeToString (OSType type) throw()
|
||||
|
|
@ -29525,9 +29537,9 @@ END_JUCE_NAMESPACE
|
|||
#endif
|
||||
/********* End of inlined file: juce_Config.h *********/
|
||||
|
||||
#if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WIN32)
|
||||
#if JUCE_PLUGINHOST_VST
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined (_WIN32) || defined (_WIN64))
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x500
|
||||
#undef STRICT
|
||||
|
|
@ -29535,7 +29547,7 @@ END_JUCE_NAMESPACE
|
|||
#include <windows.h>
|
||||
#include <float.h>
|
||||
#pragma warning (disable : 4312 4355)
|
||||
#elif defined (LINUX)
|
||||
#elif defined (LINUX) || defined (__linux__)
|
||||
#include <float.h>
|
||||
#include <sys/time.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
|
@ -29559,10 +29571,6 @@ END_JUCE_NAMESPACE
|
|||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
#if JUCE_MAC
|
||||
|
||||
#endif
|
||||
|
||||
#undef PRAGMA_ALIGN_SUPPORTED
|
||||
#define VST_FORCE_DEPRECATED 0
|
||||
|
||||
|
|
@ -29590,6 +29598,163 @@ BEGIN_JUCE_NAMESPACE
|
|||
#define Time JUCE_NAMESPACE::Time
|
||||
#endif
|
||||
|
||||
/********* Start of inlined file: juce_VSTMidiEventList.h *********/
|
||||
#ifdef __aeffect__
|
||||
|
||||
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#define __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
|
||||
/** Holds a set of VSTMidiEvent objects and makes it easy to add
|
||||
events to the list.
|
||||
|
||||
This is used by both the VST hosting code and the plugin wrapper.
|
||||
*/
|
||||
class VSTMidiEventList
|
||||
{
|
||||
public:
|
||||
|
||||
VSTMidiEventList()
|
||||
: events (0), numEventsUsed (0), numEventsAllocated (0)
|
||||
{
|
||||
}
|
||||
|
||||
~VSTMidiEventList()
|
||||
{
|
||||
freeEvents();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
numEventsUsed = 0;
|
||||
}
|
||||
|
||||
void addEvent (const void* const midiData, const int numBytes, const int frameOffset)
|
||||
{
|
||||
ensureSize (numEventsUsed + 1);
|
||||
|
||||
VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]);
|
||||
events->numEvents = ++numEventsUsed;
|
||||
|
||||
if (numBytes <= 4)
|
||||
{
|
||||
if (e->type == kVstSysExType)
|
||||
{
|
||||
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = sizeof (VstMidiEvent);
|
||||
e->noteLength = 0;
|
||||
e->noteOffset = 0;
|
||||
e->detune = 0;
|
||||
e->noteOffVelocity = 0;
|
||||
}
|
||||
|
||||
e->deltaFrames = frameOffset;
|
||||
memcpy (e->midiData, midiData, numBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e;
|
||||
|
||||
if (se->type == kVstSysExType)
|
||||
se->sysexDump = (char*) juce_realloc (se->sysexDump, numBytes);
|
||||
else
|
||||
se->sysexDump = (char*) juce_malloc (numBytes);
|
||||
|
||||
memcpy (se->sysexDump, midiData, numBytes);
|
||||
|
||||
se->type = kVstSysExType;
|
||||
se->byteSize = sizeof (VstMidiSysexEvent);
|
||||
se->deltaFrames = frameOffset;
|
||||
se->flags = 0;
|
||||
se->dumpBytes = numBytes;
|
||||
se->resvd1 = 0;
|
||||
se->resvd2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Handy method to pull the events out of an event buffer supplied by the host
|
||||
// or plugin.
|
||||
static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest)
|
||||
{
|
||||
for (int i = 0; i < events->numEvents; ++i)
|
||||
{
|
||||
const VstEvent* const e = events->events[i];
|
||||
|
||||
if (e != 0)
|
||||
{
|
||||
if (e->type == kVstMidiType)
|
||||
{
|
||||
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiEvent*) e)->midiData,
|
||||
4, e->deltaFrames);
|
||||
}
|
||||
else if (e->type == kVstSysExType)
|
||||
{
|
||||
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump,
|
||||
(int) ((const VstMidiSysexEvent*) e)->dumpBytes,
|
||||
e->deltaFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ensureSize (int numEventsNeeded)
|
||||
{
|
||||
if (numEventsNeeded > numEventsAllocated)
|
||||
{
|
||||
numEventsNeeded = (numEventsNeeded + 32) & ~31;
|
||||
|
||||
const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
|
||||
|
||||
if (events == 0)
|
||||
events = (VstEvents*) juce_calloc (size);
|
||||
else
|
||||
events = (VstEvents*) juce_realloc (events, size);
|
||||
|
||||
for (int i = numEventsAllocated; i < numEventsNeeded; ++i)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (jmax ((int) sizeof (VstMidiEvent),
|
||||
(int) sizeof (VstMidiSysexEvent)));
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = sizeof (VstMidiEvent);
|
||||
|
||||
events->events[i] = (VstEvent*) e;
|
||||
}
|
||||
|
||||
numEventsAllocated = numEventsNeeded;
|
||||
}
|
||||
}
|
||||
|
||||
void freeEvents()
|
||||
{
|
||||
if (events != 0)
|
||||
{
|
||||
for (int i = numEventsAllocated; --i >= 0;)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) (events->events[i]);
|
||||
|
||||
if (e->type == kVstSysExType)
|
||||
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
||||
|
||||
juce_free (e);
|
||||
}
|
||||
|
||||
juce_free (events);
|
||||
events = 0;
|
||||
numEventsUsed = 0;
|
||||
numEventsAllocated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
VstEvents* events;
|
||||
|
||||
private:
|
||||
int numEventsUsed, numEventsAllocated;
|
||||
};
|
||||
|
||||
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
/********* End of inlined file: juce_VSTMidiEventList.h *********/
|
||||
|
||||
#if ! JUCE_WIN32
|
||||
#define _fpreset()
|
||||
#define _clearfp()
|
||||
|
|
@ -30224,8 +30389,7 @@ private:
|
|||
AudioSampleBuffer tempBuffer;
|
||||
CriticalSection midiInLock;
|
||||
MidiBuffer incomingMidi;
|
||||
void* midiEventsToSend;
|
||||
int numAllocatedMidiEvents;
|
||||
VSTMidiEventList midiEventsToSend;
|
||||
VstTimeInfo vstHostTime;
|
||||
float** channels;
|
||||
|
||||
|
|
@ -30237,8 +30401,6 @@ private:
|
|||
void setParamsInProgramBlock (fxProgram* const prog) throw();
|
||||
void updateStoredProgramNames();
|
||||
void initialise();
|
||||
void ensureMidiEventSize (int numEventsNeeded);
|
||||
void freeMidiEvents();
|
||||
void handleMidiFromPlugin (const VstEvents* const events);
|
||||
void createTempParameterStore (MemoryBlock& dest);
|
||||
void restoreFromTempParameterStore (const MemoryBlock& mb);
|
||||
|
|
@ -30265,8 +30427,6 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHan
|
|||
wantsMidiMessages (false),
|
||||
initialised (false),
|
||||
isPowerOn (false),
|
||||
numAllocatedMidiEvents (0),
|
||||
midiEventsToSend (0),
|
||||
tempBuffer (1, 1),
|
||||
channels (0),
|
||||
module (module_)
|
||||
|
|
@ -30355,8 +30515,6 @@ VSTPluginInstance::~VSTPluginInstance()
|
|||
effect = 0;
|
||||
}
|
||||
|
||||
freeMidiEvents();
|
||||
|
||||
juce_free (channels);
|
||||
channels = 0;
|
||||
}
|
||||
|
|
@ -30441,9 +30599,9 @@ void VSTPluginInstance::prepareToPlay (double sampleRate_,
|
|||
|| (dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0);
|
||||
|
||||
if (wantsMidiMessages)
|
||||
ensureMidiEventSize (256);
|
||||
midiEventsToSend.ensureSize (256);
|
||||
else
|
||||
freeMidiEvents();
|
||||
midiEventsToSend.freeEvents();
|
||||
|
||||
incomingMidi.clear();
|
||||
|
||||
|
|
@ -30478,7 +30636,7 @@ void VSTPluginInstance::releaseResources()
|
|||
tempBuffer.setSize (1, 1);
|
||||
incomingMidi.clear();
|
||||
|
||||
freeMidiEvents();
|
||||
midiEventsToSend.freeEvents();
|
||||
juce_free (channels);
|
||||
channels = 0;
|
||||
}
|
||||
|
|
@ -30524,43 +30682,22 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer,
|
|||
|
||||
if (wantsMidiMessages)
|
||||
{
|
||||
MidiBuffer::Iterator iter (midiMessages);
|
||||
midiEventsToSend.clear();
|
||||
midiEventsToSend.ensureSize (1);
|
||||
|
||||
int eventIndex = 0;
|
||||
MidiBuffer::Iterator iter (midiMessages);
|
||||
const uint8* midiData;
|
||||
int numBytesOfMidiData, samplePosition;
|
||||
|
||||
while (iter.getNextEvent (midiData, numBytesOfMidiData, samplePosition))
|
||||
{
|
||||
if (numBytesOfMidiData < 4)
|
||||
{
|
||||
ensureMidiEventSize (eventIndex + 1);
|
||||
VstMidiEvent* const e
|
||||
= (VstMidiEvent*) ((VstEvents*) midiEventsToSend)->events [eventIndex++];
|
||||
|
||||
// check that some plugin hasn't messed up our objects
|
||||
jassert (e->type == kVstMidiType);
|
||||
jassert (e->byteSize == 24);
|
||||
|
||||
e->deltaFrames = jlimit (0, numSamples - 1, samplePosition);
|
||||
e->noteLength = 0;
|
||||
e->noteOffset = 0;
|
||||
e->midiData[0] = midiData[0];
|
||||
e->midiData[1] = midiData[1];
|
||||
e->midiData[2] = midiData[2];
|
||||
e->detune = 0;
|
||||
e->noteOffVelocity = 0;
|
||||
}
|
||||
midiEventsToSend.addEvent (midiData, numBytesOfMidiData,
|
||||
jlimit (0, numSamples - 1, samplePosition));
|
||||
}
|
||||
|
||||
if (midiEventsToSend == 0)
|
||||
ensureMidiEventSize (1);
|
||||
|
||||
((VstEvents*) midiEventsToSend)->numEvents = eventIndex;
|
||||
|
||||
try
|
||||
{
|
||||
effect->dispatcher (effect, effProcessEvents, 0, 0, midiEventsToSend, 0);
|
||||
effect->dispatcher (effect, effProcessEvents, 0, 0, midiEventsToSend.events, 0);
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
|
|
@ -30624,61 +30761,12 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer,
|
|||
}
|
||||
}
|
||||
|
||||
void VSTPluginInstance::ensureMidiEventSize (int numEventsNeeded)
|
||||
{
|
||||
if (numEventsNeeded > numAllocatedMidiEvents)
|
||||
{
|
||||
numEventsNeeded = (numEventsNeeded + 32) & ~31;
|
||||
|
||||
const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
|
||||
|
||||
if (midiEventsToSend == 0)
|
||||
midiEventsToSend = juce_calloc (size);
|
||||
else
|
||||
midiEventsToSend = juce_realloc (midiEventsToSend, size);
|
||||
|
||||
for (int i = numAllocatedMidiEvents; i < numEventsNeeded; ++i)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (sizeof (VstMidiEvent));
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = 24;
|
||||
|
||||
((VstEvents*) midiEventsToSend)->events[i] = (VstEvent*) e;
|
||||
}
|
||||
|
||||
numAllocatedMidiEvents = numEventsNeeded;
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginInstance::freeMidiEvents()
|
||||
{
|
||||
if (midiEventsToSend != 0)
|
||||
{
|
||||
for (int i = numAllocatedMidiEvents; --i >= 0;)
|
||||
juce_free (((VstEvents*) midiEventsToSend)->events[i]);
|
||||
|
||||
juce_free (midiEventsToSend);
|
||||
midiEventsToSend = 0;
|
||||
numAllocatedMidiEvents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginInstance::handleMidiFromPlugin (const VstEvents* const events)
|
||||
{
|
||||
if (events != 0)
|
||||
{
|
||||
const ScopedLock sl (midiInLock);
|
||||
|
||||
for (int i = 0; i < events->numEvents; ++i)
|
||||
{
|
||||
const VstEvent* const e = events->events[i];
|
||||
|
||||
if (e->type == kVstMidiType)
|
||||
{
|
||||
incomingMidi.addEvent ((const uint8*) ((const VstMidiEvent*) e)->midiData,
|
||||
3, e->deltaFrames);
|
||||
}
|
||||
}
|
||||
VSTMidiEventList::addEventsToMidiBuffer (events, incomingMidi);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31334,6 +31422,11 @@ private:
|
|||
#endif
|
||||
|
||||
#if JUCE_MAC
|
||||
|
||||
#if ! JUCE_SUPPORT_CARBON
|
||||
#error "To build VSTs, you need to enable the JUCE_SUPPORT_CARBON flag in your config!"
|
||||
#endif
|
||||
|
||||
class InnerWrapperComponent : public CarbonViewWrapperComponent
|
||||
{
|
||||
public:
|
||||
|
|
@ -254315,7 +254408,8 @@ bool juce_launchFile (const String& fileName,
|
|||
String cmdString (fileName);
|
||||
cmdString << " " << parameters;
|
||||
|
||||
if (URL::isProbablyAWebsiteURL (cmdString) || URL::isProbablyAnEmailAddress (cmdString))
|
||||
if (URL::isProbablyAWebsiteURL (fileName)
|
||||
|| URL::isProbablyAnEmailAddress (fileName))
|
||||
{
|
||||
// create a command that tries to launch a bunch of likely browsers
|
||||
const char* const browserNames[] = { "/etc/alternatives/x-www-browser", "firefox", "mozilla", "konqueror", "opera" };
|
||||
|
|
@ -254328,6 +254422,9 @@ bool juce_launchFile (const String& fileName,
|
|||
cmdString = cmdLines.joinIntoString (T(" || "));
|
||||
}
|
||||
|
||||
if (cmdString.startsWithIgnoreCase (T("file:")))
|
||||
cmdString = cmdString.substring (5);
|
||||
|
||||
char* const argv[4] = { "/bin/sh", "-c", (char*) cmdString.toUTF8(), 0 };
|
||||
|
||||
const int cpid = fork();
|
||||
|
|
|
|||
|
|
@ -3088,7 +3088,7 @@ public:
|
|||
static int compareElements (const ElementType first,
|
||||
const ElementType second) throw()
|
||||
{
|
||||
return (first > second) - (second < first);
|
||||
return (first < second) ? -1 : ((first == second) ? 0 : 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -3114,7 +3114,7 @@ public:
|
|||
static int compareElements (const ElementType first,
|
||||
const ElementType second) throw()
|
||||
{
|
||||
return (first > second) - (second < first);
|
||||
return (first < second) ? -1 : ((first == second) ? 0 : 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -34902,6 +34902,166 @@ private:
|
|||
#endif // __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
|
||||
/********* End of inlined file: juce_LADSPAPluginFormat.h *********/
|
||||
|
||||
#endif
|
||||
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
|
||||
/********* Start of inlined file: juce_VSTMidiEventList.h *********/
|
||||
#ifdef __aeffect__
|
||||
|
||||
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#define __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
|
||||
/** Holds a set of VSTMidiEvent objects and makes it easy to add
|
||||
events to the list.
|
||||
|
||||
This is used by both the VST hosting code and the plugin wrapper.
|
||||
*/
|
||||
class VSTMidiEventList
|
||||
{
|
||||
public:
|
||||
|
||||
VSTMidiEventList()
|
||||
: events (0), numEventsUsed (0), numEventsAllocated (0)
|
||||
{
|
||||
}
|
||||
|
||||
~VSTMidiEventList()
|
||||
{
|
||||
freeEvents();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
numEventsUsed = 0;
|
||||
}
|
||||
|
||||
void addEvent (const void* const midiData, const int numBytes, const int frameOffset)
|
||||
{
|
||||
ensureSize (numEventsUsed + 1);
|
||||
|
||||
VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]);
|
||||
events->numEvents = ++numEventsUsed;
|
||||
|
||||
if (numBytes <= 4)
|
||||
{
|
||||
if (e->type == kVstSysExType)
|
||||
{
|
||||
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = sizeof (VstMidiEvent);
|
||||
e->noteLength = 0;
|
||||
e->noteOffset = 0;
|
||||
e->detune = 0;
|
||||
e->noteOffVelocity = 0;
|
||||
}
|
||||
|
||||
e->deltaFrames = frameOffset;
|
||||
memcpy (e->midiData, midiData, numBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e;
|
||||
|
||||
if (se->type == kVstSysExType)
|
||||
se->sysexDump = (char*) juce_realloc (se->sysexDump, numBytes);
|
||||
else
|
||||
se->sysexDump = (char*) juce_malloc (numBytes);
|
||||
|
||||
memcpy (se->sysexDump, midiData, numBytes);
|
||||
|
||||
se->type = kVstSysExType;
|
||||
se->byteSize = sizeof (VstMidiSysexEvent);
|
||||
se->deltaFrames = frameOffset;
|
||||
se->flags = 0;
|
||||
se->dumpBytes = numBytes;
|
||||
se->resvd1 = 0;
|
||||
se->resvd2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Handy method to pull the events out of an event buffer supplied by the host
|
||||
// or plugin.
|
||||
static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest)
|
||||
{
|
||||
for (int i = 0; i < events->numEvents; ++i)
|
||||
{
|
||||
const VstEvent* const e = events->events[i];
|
||||
|
||||
if (e != 0)
|
||||
{
|
||||
if (e->type == kVstMidiType)
|
||||
{
|
||||
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiEvent*) e)->midiData,
|
||||
4, e->deltaFrames);
|
||||
}
|
||||
else if (e->type == kVstSysExType)
|
||||
{
|
||||
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump,
|
||||
(int) ((const VstMidiSysexEvent*) e)->dumpBytes,
|
||||
e->deltaFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ensureSize (int numEventsNeeded)
|
||||
{
|
||||
if (numEventsNeeded > numEventsAllocated)
|
||||
{
|
||||
numEventsNeeded = (numEventsNeeded + 32) & ~31;
|
||||
|
||||
const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
|
||||
|
||||
if (events == 0)
|
||||
events = (VstEvents*) juce_calloc (size);
|
||||
else
|
||||
events = (VstEvents*) juce_realloc (events, size);
|
||||
|
||||
for (int i = numEventsAllocated; i < numEventsNeeded; ++i)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (jmax ((int) sizeof (VstMidiEvent),
|
||||
(int) sizeof (VstMidiSysexEvent)));
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = sizeof (VstMidiEvent);
|
||||
|
||||
events->events[i] = (VstEvent*) e;
|
||||
}
|
||||
|
||||
numEventsAllocated = numEventsNeeded;
|
||||
}
|
||||
}
|
||||
|
||||
void freeEvents()
|
||||
{
|
||||
if (events != 0)
|
||||
{
|
||||
for (int i = numEventsAllocated; --i >= 0;)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) (events->events[i]);
|
||||
|
||||
if (e->type == kVstSysExType)
|
||||
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
||||
|
||||
juce_free (e);
|
||||
}
|
||||
|
||||
juce_free (events);
|
||||
events = 0;
|
||||
numEventsUsed = 0;
|
||||
numEventsAllocated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
VstEvents* events;
|
||||
|
||||
private:
|
||||
int numEventsUsed, numEventsAllocated;
|
||||
};
|
||||
|
||||
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
/********* End of inlined file: juce_VSTMidiEventList.h *********/
|
||||
|
||||
#endif
|
||||
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,12 @@
|
|||
#pragma warning (disable: 4309 4305)
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC && JUCE_SUPPORT_CARBON
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
#include "../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
END_JUCE_NAMESPACE
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#include "juce_core/basics/juce_FileLogger.cpp"
|
||||
#include "juce_core/basics/juce_Logger.cpp"
|
||||
|
|
|
|||
|
|
@ -170,6 +170,9 @@
|
|||
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
|
||||
#include "juce_appframework/audio/plugins/formats/juce_LADSPAPluginFormat.h"
|
||||
#endif
|
||||
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#include "juce_appframework/audio/plugins/formats/juce_VSTMidiEventList.h"
|
||||
#endif
|
||||
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
|
||||
#include "juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -75,11 +75,6 @@ BEGIN_JUCE_NAMESPACE
|
|||
#define log(a)
|
||||
#endif
|
||||
|
||||
#if JUCE_SUPPORT_CARBON
|
||||
#include "../../../../../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
#endif
|
||||
|
||||
|
||||
static int insideCallback = 0;
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifdef __aeffect__
|
||||
|
||||
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#define __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Holds a set of VSTMidiEvent objects and makes it easy to add
|
||||
events to the list.
|
||||
|
||||
This is used by both the VST hosting code and the plugin wrapper.
|
||||
*/
|
||||
class VSTMidiEventList
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
VSTMidiEventList()
|
||||
: events (0), numEventsUsed (0), numEventsAllocated (0)
|
||||
{
|
||||
}
|
||||
|
||||
~VSTMidiEventList()
|
||||
{
|
||||
freeEvents();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void clear()
|
||||
{
|
||||
numEventsUsed = 0;
|
||||
}
|
||||
|
||||
void addEvent (const void* const midiData, const int numBytes, const int frameOffset)
|
||||
{
|
||||
ensureSize (numEventsUsed + 1);
|
||||
|
||||
VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]);
|
||||
events->numEvents = ++numEventsUsed;
|
||||
|
||||
if (numBytes <= 4)
|
||||
{
|
||||
if (e->type == kVstSysExType)
|
||||
{
|
||||
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = sizeof (VstMidiEvent);
|
||||
e->noteLength = 0;
|
||||
e->noteOffset = 0;
|
||||
e->detune = 0;
|
||||
e->noteOffVelocity = 0;
|
||||
}
|
||||
|
||||
e->deltaFrames = frameOffset;
|
||||
memcpy (e->midiData, midiData, numBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e;
|
||||
|
||||
if (se->type == kVstSysExType)
|
||||
se->sysexDump = (char*) juce_realloc (se->sysexDump, numBytes);
|
||||
else
|
||||
se->sysexDump = (char*) juce_malloc (numBytes);
|
||||
|
||||
memcpy (se->sysexDump, midiData, numBytes);
|
||||
|
||||
se->type = kVstSysExType;
|
||||
se->byteSize = sizeof (VstMidiSysexEvent);
|
||||
se->deltaFrames = frameOffset;
|
||||
se->flags = 0;
|
||||
se->dumpBytes = numBytes;
|
||||
se->resvd1 = 0;
|
||||
se->resvd2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Handy method to pull the events out of an event buffer supplied by the host
|
||||
// or plugin.
|
||||
static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest)
|
||||
{
|
||||
for (int i = 0; i < events->numEvents; ++i)
|
||||
{
|
||||
const VstEvent* const e = events->events[i];
|
||||
|
||||
if (e != 0)
|
||||
{
|
||||
if (e->type == kVstMidiType)
|
||||
{
|
||||
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiEvent*) e)->midiData,
|
||||
4, e->deltaFrames);
|
||||
}
|
||||
else if (e->type == kVstSysExType)
|
||||
{
|
||||
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump,
|
||||
(int) ((const VstMidiSysexEvent*) e)->dumpBytes,
|
||||
e->deltaFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ensureSize (int numEventsNeeded)
|
||||
{
|
||||
if (numEventsNeeded > numEventsAllocated)
|
||||
{
|
||||
numEventsNeeded = (numEventsNeeded + 32) & ~31;
|
||||
|
||||
const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
|
||||
|
||||
if (events == 0)
|
||||
events = (VstEvents*) juce_calloc (size);
|
||||
else
|
||||
events = (VstEvents*) juce_realloc (events, size);
|
||||
|
||||
for (int i = numEventsAllocated; i < numEventsNeeded; ++i)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (jmax ((int) sizeof (VstMidiEvent),
|
||||
(int) sizeof (VstMidiSysexEvent)));
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = sizeof (VstMidiEvent);
|
||||
|
||||
events->events[i] = (VstEvent*) e;
|
||||
}
|
||||
|
||||
numEventsAllocated = numEventsNeeded;
|
||||
}
|
||||
}
|
||||
|
||||
void freeEvents()
|
||||
{
|
||||
if (events != 0)
|
||||
{
|
||||
for (int i = numEventsAllocated; --i >= 0;)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) (events->events[i]);
|
||||
|
||||
if (e->type == kVstSysExType)
|
||||
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
||||
|
||||
juce_free (e);
|
||||
}
|
||||
|
||||
juce_free (events);
|
||||
events = 0;
|
||||
numEventsUsed = 0;
|
||||
numEventsAllocated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
VstEvents* events;
|
||||
|
||||
private:
|
||||
int numEventsUsed, numEventsAllocated;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
||||
|
|
@ -31,9 +31,9 @@
|
|||
|
||||
#include "../../../../../juce_Config.h"
|
||||
|
||||
#if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WIN32)
|
||||
#if JUCE_PLUGINHOST_VST
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined (_WIN32) || defined (_WIN64))
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x500
|
||||
#undef STRICT
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
#include <windows.h>
|
||||
#include <float.h>
|
||||
#pragma warning (disable : 4312 4355)
|
||||
#elif defined (LINUX)
|
||||
#elif defined (LINUX) || defined (__linux__)
|
||||
#include <float.h>
|
||||
#include <sys/time.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
|
@ -72,6 +72,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../../juce_core/threads/juce_Process.h"
|
||||
#include "../../../../juce_core/threads/juce_ScopedLock.h"
|
||||
#include "../../../../juce_core/basics/juce_Random.h"
|
||||
#include "../../../../juce_core/io/files/juce_DirectoryIterator.h"
|
||||
#include "../../../events/juce_Timer.h"
|
||||
#include "../../../events/juce_AsyncUpdater.h"
|
||||
#include "../../../events/juce_MessageManager.h"
|
||||
|
|
@ -79,10 +80,6 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../application/juce_Application.h"
|
||||
#include "../../../../juce_core/misc/juce_PlatformUtilities.h"
|
||||
|
||||
#if JUCE_MAC
|
||||
#include "../../../../../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
#endif
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#undef PRAGMA_ALIGN_SUPPORTED
|
||||
|
|
@ -114,6 +111,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
#endif
|
||||
|
||||
#include "../juce_PluginDescription.h"
|
||||
#include "juce_VSTMidiEventList.h"
|
||||
|
||||
#if ! JUCE_WIN32
|
||||
#define _fpreset()
|
||||
|
|
@ -771,8 +769,7 @@ private:
|
|||
AudioSampleBuffer tempBuffer;
|
||||
CriticalSection midiInLock;
|
||||
MidiBuffer incomingMidi;
|
||||
void* midiEventsToSend;
|
||||
int numAllocatedMidiEvents;
|
||||
VSTMidiEventList midiEventsToSend;
|
||||
VstTimeInfo vstHostTime;
|
||||
float** channels;
|
||||
|
||||
|
|
@ -785,8 +782,6 @@ private:
|
|||
void setParamsInProgramBlock (fxProgram* const prog) throw();
|
||||
void updateStoredProgramNames();
|
||||
void initialise();
|
||||
void ensureMidiEventSize (int numEventsNeeded);
|
||||
void freeMidiEvents();
|
||||
void handleMidiFromPlugin (const VstEvents* const events);
|
||||
void createTempParameterStore (MemoryBlock& dest);
|
||||
void restoreFromTempParameterStore (const MemoryBlock& mb);
|
||||
|
|
@ -814,8 +809,6 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHan
|
|||
wantsMidiMessages (false),
|
||||
initialised (false),
|
||||
isPowerOn (false),
|
||||
numAllocatedMidiEvents (0),
|
||||
midiEventsToSend (0),
|
||||
tempBuffer (1, 1),
|
||||
channels (0),
|
||||
module (module_)
|
||||
|
|
@ -904,8 +897,6 @@ VSTPluginInstance::~VSTPluginInstance()
|
|||
effect = 0;
|
||||
}
|
||||
|
||||
freeMidiEvents();
|
||||
|
||||
juce_free (channels);
|
||||
channels = 0;
|
||||
}
|
||||
|
|
@ -993,9 +984,9 @@ void VSTPluginInstance::prepareToPlay (double sampleRate_,
|
|||
|| (dispatch (effCanDo, 0, 0, (void*) "receiveVstMidiEvent", 0) > 0);
|
||||
|
||||
if (wantsMidiMessages)
|
||||
ensureMidiEventSize (256);
|
||||
midiEventsToSend.ensureSize (256);
|
||||
else
|
||||
freeMidiEvents();
|
||||
midiEventsToSend.freeEvents();
|
||||
|
||||
incomingMidi.clear();
|
||||
|
||||
|
|
@ -1030,7 +1021,7 @@ void VSTPluginInstance::releaseResources()
|
|||
tempBuffer.setSize (1, 1);
|
||||
incomingMidi.clear();
|
||||
|
||||
freeMidiEvents();
|
||||
midiEventsToSend.freeEvents();
|
||||
juce_free (channels);
|
||||
channels = 0;
|
||||
}
|
||||
|
|
@ -1076,43 +1067,22 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer,
|
|||
|
||||
if (wantsMidiMessages)
|
||||
{
|
||||
MidiBuffer::Iterator iter (midiMessages);
|
||||
midiEventsToSend.clear();
|
||||
midiEventsToSend.ensureSize (1);
|
||||
|
||||
int eventIndex = 0;
|
||||
MidiBuffer::Iterator iter (midiMessages);
|
||||
const uint8* midiData;
|
||||
int numBytesOfMidiData, samplePosition;
|
||||
|
||||
while (iter.getNextEvent (midiData, numBytesOfMidiData, samplePosition))
|
||||
{
|
||||
if (numBytesOfMidiData < 4)
|
||||
{
|
||||
ensureMidiEventSize (eventIndex + 1);
|
||||
VstMidiEvent* const e
|
||||
= (VstMidiEvent*) ((VstEvents*) midiEventsToSend)->events [eventIndex++];
|
||||
|
||||
// check that some plugin hasn't messed up our objects
|
||||
jassert (e->type == kVstMidiType);
|
||||
jassert (e->byteSize == 24);
|
||||
|
||||
e->deltaFrames = jlimit (0, numSamples - 1, samplePosition);
|
||||
e->noteLength = 0;
|
||||
e->noteOffset = 0;
|
||||
e->midiData[0] = midiData[0];
|
||||
e->midiData[1] = midiData[1];
|
||||
e->midiData[2] = midiData[2];
|
||||
e->detune = 0;
|
||||
e->noteOffVelocity = 0;
|
||||
}
|
||||
midiEventsToSend.addEvent (midiData, numBytesOfMidiData,
|
||||
jlimit (0, numSamples - 1, samplePosition));
|
||||
}
|
||||
|
||||
if (midiEventsToSend == 0)
|
||||
ensureMidiEventSize (1);
|
||||
|
||||
((VstEvents*) midiEventsToSend)->numEvents = eventIndex;
|
||||
|
||||
try
|
||||
{
|
||||
effect->dispatcher (effect, effProcessEvents, 0, 0, midiEventsToSend, 0);
|
||||
effect->dispatcher (effect, effProcessEvents, 0, 0, midiEventsToSend.events, 0);
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
|
|
@ -1177,61 +1147,12 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer,
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void VSTPluginInstance::ensureMidiEventSize (int numEventsNeeded)
|
||||
{
|
||||
if (numEventsNeeded > numAllocatedMidiEvents)
|
||||
{
|
||||
numEventsNeeded = (numEventsNeeded + 32) & ~31;
|
||||
|
||||
const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
|
||||
|
||||
if (midiEventsToSend == 0)
|
||||
midiEventsToSend = juce_calloc (size);
|
||||
else
|
||||
midiEventsToSend = juce_realloc (midiEventsToSend, size);
|
||||
|
||||
for (int i = numAllocatedMidiEvents; i < numEventsNeeded; ++i)
|
||||
{
|
||||
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (sizeof (VstMidiEvent));
|
||||
e->type = kVstMidiType;
|
||||
e->byteSize = 24;
|
||||
|
||||
((VstEvents*) midiEventsToSend)->events[i] = (VstEvent*) e;
|
||||
}
|
||||
|
||||
numAllocatedMidiEvents = numEventsNeeded;
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginInstance::freeMidiEvents()
|
||||
{
|
||||
if (midiEventsToSend != 0)
|
||||
{
|
||||
for (int i = numAllocatedMidiEvents; --i >= 0;)
|
||||
juce_free (((VstEvents*) midiEventsToSend)->events[i]);
|
||||
|
||||
juce_free (midiEventsToSend);
|
||||
midiEventsToSend = 0;
|
||||
numAllocatedMidiEvents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginInstance::handleMidiFromPlugin (const VstEvents* const events)
|
||||
{
|
||||
if (events != 0)
|
||||
{
|
||||
const ScopedLock sl (midiInLock);
|
||||
|
||||
for (int i = 0; i < events->numEvents; ++i)
|
||||
{
|
||||
const VstEvent* const e = events->events[i];
|
||||
|
||||
if (e->type == kVstMidiType)
|
||||
{
|
||||
incomingMidi.addEvent ((const uint8*) ((const VstMidiEvent*) e)->midiData,
|
||||
3, e->deltaFrames);
|
||||
}
|
||||
}
|
||||
VSTMidiEventList::addEventsToMidiBuffer (events, incomingMidi);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1899,6 +1820,11 @@ private:
|
|||
#endif
|
||||
|
||||
#if JUCE_MAC
|
||||
|
||||
#if ! JUCE_SUPPORT_CARBON
|
||||
#error "To build VSTs, you need to enable the JUCE_SUPPORT_CARBON flag in your config!"
|
||||
#endif
|
||||
|
||||
class InnerWrapperComponent : public CarbonViewWrapperComponent
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@
|
|||
|
||||
#include "../juce_AudioPluginFormat.h"
|
||||
|
||||
#if JUCE_PLUGINHOST_VST
|
||||
|
||||
#if JUCE_PLUGINHOST_VST
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ public:
|
|||
static int compareElements (const ElementType first,
|
||||
const ElementType second) throw()
|
||||
{
|
||||
return (first > second) - (second < first);
|
||||
return (first < second) ? -1 : ((first == second) ? 0 : 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -312,7 +312,7 @@ public:
|
|||
static int compareElements (const ElementType first,
|
||||
const ElementType second) throw()
|
||||
{
|
||||
return (first > second) - (second < first);
|
||||
return (first < second) ? -1 : ((first == second) ? 0 : 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -136,17 +136,27 @@ bool URL::isWellFormed() const
|
|||
//==============================================================================
|
||||
bool URL::isProbablyAWebsiteURL (const String& possibleURL)
|
||||
{
|
||||
return (possibleURL.containsChar (T('.'))
|
||||
&& (! possibleURL.containsChar (T('@')))
|
||||
&& (! possibleURL.endsWithChar (T('.')))
|
||||
&& (possibleURL.startsWithIgnoreCase (T("www."))
|
||||
|| possibleURL.startsWithIgnoreCase (T("http:"))
|
||||
|| possibleURL.startsWithIgnoreCase (T("ftp:"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".com"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".net"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".org"))
|
||||
|| possibleURL.endsWithIgnoreCase (T(".co.uk")))
|
||||
|| possibleURL.startsWithIgnoreCase (T("file:")));
|
||||
if (possibleURL.startsWithIgnoreCase (T("http:"))
|
||||
|| possibleURL.startsWithIgnoreCase (T("ftp:")))
|
||||
return true;
|
||||
|
||||
if (possibleURL.startsWithIgnoreCase (T("file:"))
|
||||
|| possibleURL.containsChar (T('@'))
|
||||
|| possibleURL.endsWithChar (T('.'))
|
||||
|| (! possibleURL.containsChar (T('.'))))
|
||||
return false;
|
||||
|
||||
if (possibleURL.startsWithIgnoreCase (T("www."))
|
||||
&& possibleURL.substring (5).containsChar (T('.')))
|
||||
return true;
|
||||
|
||||
const char* commonTLDs[] = { "com", "net", "org", "uk", "de", "fr", "jp" };
|
||||
|
||||
for (int i = 0; i < numElementsInArray (commonTLDs); ++i)
|
||||
if ((possibleURL + T("/")).containsIgnoreCase (T(".") + String (commonTLDs[i]) + T("/")))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue