COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :

Go Back   Cockos Incorporated Forums > Other Software Discussion > WDL users forum

Reply
 
Thread Tools Display Modes
Old 07-19-2010, 05:22 AM   #1
AHarker
Human being with feelings
 
Join Date: Jul 2010
Posts: 21
Default Problem with IPlug bypassing in AU version

Hi,

Firstly Iplug seems great and is very straightforward to work with.

I've a plug-in up and running. It all behaves fine when running, but when I bypass the effect in Au Lab, or Sample Manager I don't get passthrough - in AU LAb I get nothing and in Sample Manager I get what sounds like the last output buffer looped...

Is there anything I should be doing here, or is this a bug in IPlug. I don't have an issue in DP 7, but I assume that it is handling the bypass in a different way.

As far as I can see from a glance at IPlugAU.cpp IPlug does nothing if the effect is bypassed. Looking in AUEFfectBase.cpp I see:


if (ShouldBypassEffect())
{
// leave silence bit alone
if(!ProcessesInPlace() )
{
theInput->CopyBufferContentsTo (theOutput->GetBufferList());
}
}

Which suggests that if the effect is bypassed and the inputs and outputs do not alias it is up to the effect to copy its inputs to its outputs.

I can probably recode the IPlugAU file, but if this is the case it'd be better for it to be fixed for everyone...

Thanks

Alex
AHarker is offline   Reply With Quote
Old 11-04-2011, 08:04 AM   #2
olilarkin
Human being with feelings
 
Join Date: Apr 2009
Location: Berlin, Germany
Posts: 1,248
Default

here is a fix for this... it probably could be more efficient (i.e. if you have a single precision host, then this will be copying the buffers to double precision and back again unnecessarily) but it seems OK for now

add these methods to IPlugBase

Code:
void IPlugBase::PassThroughBuffers(double sampleType, int nFrames) 
{
  IPlugBase::ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames);
}

void IPlugBase::PassThroughBuffers(float sampleType, int nFrames) 
{
  IPlugBase::ProcessDoubleReplacing(mInData.Get(), mOutData.Get(), nFrames);
  int i, n = NOutChannels();
  OutChannel** ppOutChannel = mOutChannels.GetList();
  for (i = 0; i < n; ++i, ++ppOutChannel) {
    OutChannel* pOutChannel = *ppOutChannel;
    if (pOutChannel->mConnected) {
      CastCopy(pOutChannel->mFDest, *(pOutChannel->mDest), nFrames);
    }
  }
}
and in IPlugAU::RenderProc() remove the existing if (_this->mBypassed) code and replace the call to ProcessBuffers() with this...

Code:
  if (_this->mBypassed) 
  {
    _this->PassThroughBuffers((AudioSampleType) 0, nFrames);
  }
  else 
  {
    _this->ProcessBuffers((AudioSampleType) 0, nFrames);
  }
__________________
VirtualCZ | Endless Series | iPlug2 | Linkedin | Facebook
olilarkin is offline   Reply With Quote
Old 11-04-2011, 08:10 AM   #3
olilarkin
Human being with feelings
 
Join Date: Apr 2009
Location: Berlin, Germany
Posts: 1,248
Default

one thing i'm not sure about is if the copied buffer should be delayed to match the latency of the plugin (when the plugin has latency of course). In RTAS you are meant to do this
__________________
VirtualCZ | Endless Series | iPlug2 | Linkedin | Facebook
olilarkin is offline   Reply With Quote
Old 11-12-2011, 06:29 AM   #4
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,652
Default

Thanks for this fix.
Tale is offline   Reply With Quote
Old 02-03-2012, 03:56 PM   #5
olilarkin
Human being with feelings
 
Join Date: Apr 2009
Location: Berlin, Germany
Posts: 1,248
Default

an addition to this fix...

if you have more inputs than outputs (for example, you have a sidechain input), then the existing IPlugBase::ProcessDoubleReplacing method would access invalid memory when the plugin was bypassed. Here is a fix:

// Default passthrough.
void IPlugBase::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
// Mutex is already locked.
int i, nIn = mInChannels.GetSize(), nOut = mOutChannels.GetSize();
int j = 0;
for (i = 0; i < nOut; ++i) {
if (i < nIn) {
memcpy(outputs[i], inputs[i], nFrames * sizeof(double));
j++;
}
}
// zero remaining outs
for (/* same j */; j < nOut; ++j) {
memset(outputs[j], 0, nFrames * sizeof(double));
}
}
__________________
VirtualCZ | Endless Series | iPlug2 | Linkedin | Facebook
olilarkin is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 03:48 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.