1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
jules 2007-10-04 10:56:58 +00:00
parent 05e4c79c7c
commit 697ca8615a
5 changed files with 211 additions and 86 deletions

View file

@ -95,7 +95,7 @@
kVstMaxShortLabelLen = 8, kVstMaxShortLabelLen = 8,
kVstMaxCategLabelLen = 24, kVstMaxCategLabelLen = 24,
kVstMaxFileNameLen = 100 kVstMaxFileNameLen = 100
}; };
#endif #endif
//============================================================================== //==============================================================================
@ -155,8 +155,8 @@ static HWND findMDIParentOf (HWND w)
RECT parentPos; RECT parentPos;
GetWindowRect (parent, &parentPos); GetWindowRect (parent, &parentPos);
int dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left); const int dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left);
int dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top); const int dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top);
if (dw > 100 || dh > 100) if (dw > 100 || dh > 100)
break; break;
@ -328,6 +328,19 @@ public:
filter_->getNumParameters()), filter_->getNumParameters()),
filter (filter_) filter (filter_)
{ {
editorComp = 0;
outgoingEvents = 0;
outgoingEventSize = 0;
chunkMemoryTime = 0;
isProcessing = false;
firstResize = true;
hasShutdown = false;
channels = 0;
#if JUCE_MAC || JUCE_LINUX
hostWindow = 0;
#endif
filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels, filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels,
JucePlugin_MaxNumOutputChannels, JucePlugin_MaxNumOutputChannels,
0, 0); 0, 0);
@ -335,22 +348,10 @@ public:
filter_->setPlayHead (this); filter_->setPlayHead (this);
filter_->addListener (this); filter_->addListener (this);
editorComp = 0;
outgoingEvents = 0;
outgoingEventSize = 0;
chunkMemoryTime = 0;
isProcessing = false;
firstResize = true;
channels = 0;
#if JUCE_MAC || JUCE_LINUX
hostWindow = 0;
#endif
cEffect.flags |= effFlagsHasEditor; cEffect.flags |= effFlagsHasEditor;
cEffect.version = (long) (JucePlugin_VersionCode);
setUniqueID ((int) (JucePlugin_VSTUniqueID)); setUniqueID ((int) (JucePlugin_VSTUniqueID));
getAeffect()->version = (long) (JucePlugin_VersionCode);
#if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4 #if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4
wantEvents(); wantEvents();
@ -379,6 +380,8 @@ public:
stopTimer(); stopTimer();
deleteEditor(); deleteEditor();
hasShutdown = true;
delete filter; delete filter;
filter = 0; filter = 0;
@ -393,12 +396,13 @@ public:
jassert (editorComp == 0); jassert (editorComp == 0);
juce_free (channels);
channels = 0;
deleteTempChannels();
jassert (activePlugins.contains (this)); jassert (activePlugins.contains (this));
activePlugins.removeValue (this); activePlugins.removeValue (this);
juce_free (channels);
#if JUCE_MAC || JUCE_LINUX
if (activePlugins.size() == 0) if (activePlugins.size() == 0)
{ {
#if JUCE_LINUX #if JUCE_LINUX
@ -406,7 +410,6 @@ public:
#endif #endif
shutdownJuce_GUI(); shutdownJuce_GUI();
} }
#endif
} }
void open() void open()
@ -474,11 +477,8 @@ public:
result = -1; result = -1;
#endif #endif
} }
else if (strcmp (text, "receiveVstTimeInfo") == 0) else if (strcmp (text, "receiveVstTimeInfo") == 0
{ || strcmp (text, "conformsToWindowRules") == 0)
result = 1;
}
else if (strcmp (text, "conformsToWindowRules") == 0)
{ {
result = 1; result = 1;
} }
@ -493,6 +493,9 @@ public:
bool getInputProperties (VstInt32 index, VstPinProperties* properties) bool getInputProperties (VstInt32 index, VstPinProperties* properties)
{ {
if (filter == 0 || index >= filter->getNumInputChannels())
return false;
const String name (filter->getInputChannelName ((int) index)); const String name (filter->getInputChannelName ((int) index));
name.copyToBuffer (properties->label, kVstMaxLabelLen - 1); name.copyToBuffer (properties->label, kVstMaxLabelLen - 1);
@ -510,6 +513,9 @@ public:
bool getOutputProperties (VstInt32 index, VstPinProperties* properties) bool getOutputProperties (VstInt32 index, VstPinProperties* properties)
{ {
if (filter == 0 || index >= filter->getNumOutputChannels())
return false;
const String name (filter->getOutputChannelName ((int) index)); const String name (filter->getOutputChannelName ((int) index));
name.copyToBuffer (properties->label, kVstMaxLabelLen - 1); name.copyToBuffer (properties->label, kVstMaxLabelLen - 1);
@ -569,7 +575,6 @@ public:
void processReplacing (float** inputs, float** outputs, VstInt32 numSamples) void processReplacing (float** inputs, float** outputs, VstInt32 numSamples)
{ {
//process (inputs, outputs, numSamples, false);
// if this fails, the host hasn't called resume() before processing // if this fails, the host hasn't called resume() before processing
jassert (isProcessing); jassert (isProcessing);
@ -589,12 +594,11 @@ public:
const int numIn = filter->getNumInputChannels(); const int numIn = filter->getNumInputChannels();
const int numOut = filter->getNumOutputChannels(); const int numOut = filter->getNumOutputChannels();
const int totalChans = jmax (numIn, numOut);
if (filter->isSuspended()) if (filter->isSuspended())
{ {
for (int i = 0; i < numOut; ++i) for (int i = 0; i < numOut; ++i)
zeromem (outputs [i], sizeof (float) * numSamples); zeromem (outputs[i], sizeof (float) * numSamples);
} }
else else
{ {
@ -602,17 +606,25 @@ public:
int i; int i;
for (i = 0; i < numOut; ++i) for (i = 0; i < numOut; ++i)
{ {
channels[i] = outputs [i]; // if some output channels are disabled, the host may pass the same dummy buffer
// pointer for all of these outputs - and that means that we'd be copying all our
// input channels into the same place... so in this case, we use an internal dummy
// buffer which has enough channels for each input.
float* chan = (float*) tempChannels.getUnchecked(i);
if (chan == 0)
chan = outputs[i];
if (i < numIn && inputs != outputs) if (i < numIn && chan != inputs[i])
memcpy (outputs [i], inputs[i], sizeof (float) * numSamples); memcpy (chan, inputs[i], sizeof (float) * numSamples);
channels[i] = chan;
} }
for (; i < numIn; ++i) for (; i < numIn; ++i)
channels [i] = inputs [i]; channels[i] = inputs[i];
} }
AudioSampleBuffer chans (channels, totalChans, numSamples); AudioSampleBuffer chans (channels, jmax (numIn, numOut), numSamples);
filter->processBlock (chans, midiEvents); filter->processBlock (chans, midiEvents);
} }
@ -669,9 +681,12 @@ public:
//============================================================================== //==============================================================================
void resume() void resume()
{ {
if (filter == 0)
return;
isProcessing = true; isProcessing = true;
juce_free (channels); juce_free (channels);
channels = (float**) juce_calloc (sizeof (float*) * jmax (filter->getNumInputChannels(), filter->getNumOutputChannels())); channels = (float**) juce_calloc (sizeof (float*) * (filter->getNumInputChannels() + filter->getNumOutputChannels()));
double rate = getSampleRate(); double rate = getSampleRate();
jassert (rate > 0); jassert (rate > 0);
@ -685,6 +700,14 @@ public:
JucePlugin_MaxNumOutputChannels, JucePlugin_MaxNumOutputChannels,
rate, blockSize); rate, blockSize);
deleteTempChannels();
// any inputs where the output channel is disabled will need our own internal dummy
// buffer, because we can't rely on the host to supply different buffers for each channel
for (int i = 0; i < JucePlugin_MaxNumOutputChannels; ++i)
if (! isOutputConnected (i))
tempChannels.set (i, juce_malloc (sizeof (float) * blockSize * 2));
filter->prepareToPlay (rate, blockSize); filter->prepareToPlay (rate, blockSize);
midiEvents.clear(); midiEvents.clear();
@ -703,6 +726,9 @@ public:
void suspend() void suspend()
{ {
if (filter == 0)
return;
AudioEffectX::suspend(); AudioEffectX::suspend();
filter->releaseResources(); filter->releaseResources();
@ -711,6 +737,8 @@ public:
isProcessing = false; isProcessing = false;
juce_free (channels); juce_free (channels);
channels = 0; channels = 0;
deleteTempChannels();
} }
bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info)
@ -756,10 +784,57 @@ public:
if ((ti->flags & kVstSmpteValid) != 0) if ((ti->flags & kVstSmpteValid) != 0)
{ {
info.frameRate = (AudioPlayHead::FrameRateType) (int) ti->smpteFrameRate; AudioPlayHead::FrameRateType rate = AudioPlayHead::fpsUnknown;
double fps = 1.0;
const double fpsDivisors[] = { 24.0, 25.0, 30.0, 30.0, 30.0, 30.0, 1.0 }; switch (info.frameRate)
info.editOriginTime = (ti->smpteOffset / (80.0 * fpsDivisors [(int) info.frameRate])); {
case kVstSmpte24fps:
rate = AudioPlayHead::fps24;
fps = 24.0;
break;
case kVstSmpte25fps:
rate = AudioPlayHead::fps25;
fps = 25.0;
break;
case kVstSmpte2997fps:
rate = AudioPlayHead::fps2997;
fps = 29.97;
break;
case kVstSmpte30fps:
rate = AudioPlayHead::fps30;
fps = 30.0;
break;
case kVstSmpte2997dfps:
rate = AudioPlayHead::fps2997drop;
fps = 29.97;
break;
case kVstSmpte30dfps:
rate = AudioPlayHead::fps30drop;
fps = 30.0;
break;
case kVstSmpteFilm16mm:
case kVstSmpteFilm35mm:
fps = 24.0;
break;
case kVstSmpte239fps: fps = 23.976; break;
case kVstSmpte249fps: fps = 24.976; break;
case kVstSmpte599fps: fps = 59.94; break;
case kVstSmpte60fps: fps = 60; break;
default:
jassertfalse // unknown frame-rate..
}
info.frameRate = rate;
info.editOriginTime = ti->smpteOffset / (80.0 * fps);
} }
else else
{ {
@ -776,27 +851,30 @@ public:
//============================================================================== //==============================================================================
VstInt32 getProgram() VstInt32 getProgram()
{ {
return filter->getCurrentProgram(); return filter != 0 ? filter->getCurrentProgram() : 0;
} }
void setProgram (VstInt32 program) void setProgram (VstInt32 program)
{ {
filter->setCurrentProgram (program); if (filter != 0)
filter->setCurrentProgram (program);
} }
void setProgramName (char* name) void setProgramName (char* name)
{ {
filter->changeProgramName (filter->getCurrentProgram(), name); if (filter != 0)
filter->changeProgramName (filter->getCurrentProgram(), name);
} }
void getProgramName (char* name) void getProgramName (char* name)
{ {
filter->getProgramName (filter->getCurrentProgram()).copyToBuffer (name, 24); if (filter != 0)
filter->getProgramName (filter->getCurrentProgram()).copyToBuffer (name, 24);
} }
bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text) bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text)
{ {
if (index >= 0 && index < filter->getNumPrograms()) if (index >= 0 && filter != 0 && index < filter->getNumPrograms())
{ {
filter->getProgramName (index).copyToBuffer (text, 24); filter->getProgramName (index).copyToBuffer (text, 24);
return true; return true;
@ -808,26 +886,38 @@ public:
//============================================================================== //==============================================================================
float getParameter (VstInt32 index) float getParameter (VstInt32 index)
{ {
if (filter == 0)
return 0.0f;
jassert (index >= 0 && index < filter->getNumParameters()); jassert (index >= 0 && index < filter->getNumParameters());
return filter->getParameter (index); return filter->getParameter (index);
} }
void setParameter (VstInt32 index, float value) void setParameter (VstInt32 index, float value)
{ {
jassert (index >= 0 && index < filter->getNumParameters()); if (filter != 0)
filter->setParameter (index, value); {
jassert (index >= 0 && index < filter->getNumParameters());
filter->setParameter (index, value);
}
} }
void getParameterDisplay (VstInt32 index, char* text) void getParameterDisplay (VstInt32 index, char* text)
{ {
jassert (index >= 0 && index < filter->getNumParameters()); if (filter != 0)
filter->getParameterText (index).copyToBuffer (text, 24); // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more. {
jassert (index >= 0 && index < filter->getNumParameters());
filter->getParameterText (index).copyToBuffer (text, 24); // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more.
}
} }
void getParameterName (VstInt32 index, char* text) void getParameterName (VstInt32 index, char* text)
{ {
jassert (index >= 0 && index < filter->getNumParameters()); if (filter != 0)
filter->getParameterName (index).copyToBuffer (text, 16); // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more. {
jassert (index >= 0 && index < filter->getNumParameters());
filter->getParameterName (index).copyToBuffer (text, 16); // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more.
}
} }
void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue)
@ -852,12 +942,15 @@ public:
bool canParameterBeAutomated (VstInt32 index) bool canParameterBeAutomated (VstInt32 index)
{ {
return filter->isParameterAutomatable ((int) index); return filter != 0 && filter->isParameterAutomatable ((int) index);
} }
//============================================================================== //==============================================================================
VstInt32 getChunk (void** data, bool onlyStoreCurrentProgramData) VstInt32 getChunk (void** data, bool onlyStoreCurrentProgramData)
{ {
if (filter == 0)
return 0;
chunkMemory.setSize (0); chunkMemory.setSize (0);
if (onlyStoreCurrentProgramData) if (onlyStoreCurrentProgramData)
filter->getCurrentProgramStateInformation (chunkMemory); filter->getCurrentProgramStateInformation (chunkMemory);
@ -875,6 +968,9 @@ public:
VstInt32 setChunk (void* data, VstInt32 byteSize, bool onlyRestoreCurrentProgramData) VstInt32 setChunk (void* data, VstInt32 byteSize, bool onlyRestoreCurrentProgramData)
{ {
if (filter == 0)
return 0;
chunkMemory.setSize (0); chunkMemory.setSize (0);
chunkMemoryTime = 0; chunkMemoryTime = 0;
@ -923,26 +1019,27 @@ public:
void doIdleCallback() void doIdleCallback()
{ {
// (wavelab calls this on a separate thread and causes a deadlock).. // (wavelab calls this on a separate thread and causes a deadlock)..
if (MessageManager::getInstance()->isThisTheMessageThread()) if (MessageManager::getInstance()->isThisTheMessageThread()
&& ! recursionCheck)
{ {
if (! recursionCheck) const MessageManagerLock mml;
{
const MessageManagerLock mml;
recursionCheck = true; recursionCheck = true;
juce_callAnyTimersSynchronously(); juce_callAnyTimersSynchronously();
for (int i = ComponentPeer::getNumPeers(); --i >= 0;) for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
ComponentPeer::getPeer (i)->performAnyPendingRepaintsNow(); ComponentPeer::getPeer (i)->performAnyPendingRepaintsNow();
recursionCheck = false; recursionCheck = false;
}
} }
} }
void createEditorComp() void createEditorComp()
{ {
if (hasShutdown || filter == 0)
return;
if (editorComp == 0) if (editorComp == 0)
{ {
#if JUCE_LINUX #if JUCE_LINUX
@ -996,6 +1093,9 @@ public:
VstIntPtr dispatcher (VstInt32 opCode, VstInt32 index, VstIntPtr value, void* ptr, float opt) VstIntPtr dispatcher (VstInt32 opCode, VstInt32 index, VstIntPtr value, void* ptr, float opt)
{ {
if (hasShutdown)
return 0;
if (opCode == effEditIdle) if (opCode == effEditIdle)
{ {
doIdleCallback(); doIdleCallback();
@ -1218,8 +1318,22 @@ private:
int outgoingEventSize; int outgoingEventSize;
bool isProcessing; bool isProcessing;
bool firstResize; bool firstResize;
bool hasShutdown;
int diffW, diffH; int diffW, diffH;
float** channels; float** channels;
VoidArray tempChannels; // see note in processReplacing()
void deleteTempChannels()
{
int i;
for (i = tempChannels.size(); --i >= 0;)
juce_free (tempChannels.getUnchecked(i));
tempChannels.clear();
if (filter != 0)
tempChannels.insertMultiple (0, 0, filter->getNumInputChannels() + filter->getNumOutputChannels());
}
void ensureOutgoingEventSize (int numEvents) void ensureOutgoingEventSize (int numEvents)
{ {
@ -1294,9 +1408,7 @@ extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
//============================================================================== //==============================================================================
static AEffect* pluginEntryPoint (audioMasterCallback audioMaster) static AEffect* pluginEntryPoint (audioMasterCallback audioMaster)
{ {
#if JUCE_MAC || JUCE_LINUX
initialiseJuce_GUI(); initialiseJuce_GUI();
#endif
MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0); MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
@ -1375,14 +1487,7 @@ extern "C" __declspec (dllexport) void* main (audioMasterCallback audioMaster)
BOOL WINAPI DllMain (HINSTANCE instance, DWORD dwReason, LPVOID) BOOL WINAPI DllMain (HINSTANCE instance, DWORD dwReason, LPVOID)
{ {
if (dwReason == DLL_PROCESS_ATTACH) if (dwReason == DLL_PROCESS_ATTACH)
{
PlatformUtilities::setCurrentModuleInstanceHandle (instance); PlatformUtilities::setCurrentModuleInstanceHandle (instance);
initialiseJuce_GUI();
}
else if (dwReason == DLL_PROCESS_DETACH)
{
shutdownJuce_GUI();
}
return TRUE; return TRUE;
} }

View file

@ -59,22 +59,9 @@ void TextButton::paintButton (Graphics& g,
isMouseOverButton, isMouseOverButton,
isButtonDown); isButtonDown);
const int yIndent = jmin (4, proportionOfHeight (0.3f)); getLookAndFeel().drawButtonText (g, *this,
const int cornerSize = jmin (getHeight(), getWidth()) / 2; isMouseOverButton,
isButtonDown);
g.setFont (getFont());
g.setColour (findColour (textColourId).withMultipliedAlpha (isEnabled() ? 1.0f : 0.5f));
const int fontHeight = roundFloatToInt (g.getCurrentFont().getHeight() * 0.6f);
const int leftIndent = jmin (fontHeight, 2 + cornerSize / (isConnectedOnLeft() ? 4 : 2));
const int rightIndent = jmin (fontHeight, 2 + cornerSize / (isConnectedOnRight() ? 4 : 2));
g.drawFittedText (getButtonText(),
leftIndent,
yIndent,
getWidth() - leftIndent - rightIndent,
getHeight() - yIndent * 2,
Justification::centred, 2);
} }
void TextButton::colourChanged() void TextButton::colourChanged()

View file

@ -308,6 +308,28 @@ void LookAndFeel::drawButtonBackground (Graphics& g,
button.isConnectedOnBottom()); button.isConnectedOnBottom());
} }
void LookAndFeel::drawButtonText (Graphics& g, TextButton& button,
bool /*isMouseOverButton*/, bool /*isButtonDown*/)
{
g.setFont (button.getFont());
g.setColour (button.findColour (TextButton::textColourId)
.withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
const int yIndent = jmin (4, button.proportionOfHeight (0.3f));
const int cornerSize = jmin (button.getHeight(), button.getWidth()) / 2;
const int fontHeight = roundFloatToInt (g.getCurrentFont().getHeight() * 0.6f);
const int leftIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnLeft() ? 4 : 2));
const int rightIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnRight() ? 4 : 2));
g.drawFittedText (button.getButtonText(),
leftIndent,
yIndent,
button.getWidth() - leftIndent - rightIndent,
button.getHeight() - yIndent * 2,
Justification::centred, 2);
}
void LookAndFeel::drawTickBox (Graphics& g, void LookAndFeel::drawTickBox (Graphics& g,
Component& component, Component& component,
int x, int y, int w, int h, int x, int y, int w, int h,

View file

@ -38,6 +38,7 @@
#include "../layout/juce_TabbedComponent.h" #include "../layout/juce_TabbedComponent.h"
class ToggleButton; class ToggleButton;
class TextButton;
class AlertWindow; class AlertWindow;
class TextLayout; class TextLayout;
class ScrollBar; class ScrollBar;
@ -130,6 +131,11 @@ public:
bool isMouseOverButton, bool isMouseOverButton,
bool isButtonDown); bool isButtonDown);
/** Draws the text for a TextButton. */
virtual void drawButtonText (Graphics& g,
TextButton& button,
bool isMouseOverButton,
bool isButtonDown);
/** Draws the contents of a standard ToggleButton. */ /** Draws the contents of a standard ToggleButton. */
virtual void drawToggleButton (Graphics& g, virtual void drawToggleButton (Graphics& g,

View file

@ -137,8 +137,13 @@ void PropertySet::setValue (const String& keyName,
{ {
const ScopedLock sl (lock); const ScopedLock sl (lock);
properties.set (keyName, value); const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
propertyChanged();
if (index < 0 || properties.getAllValues() [index] != value)
{
properties.set (keyName, value);
propertyChanged();
}
} }
} }