COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :
Old 01-24-2011, 04:26 AM   #1
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default Implementing Dirac LE in IPlug....

Hi. I got the dspdimension short FFT pitch shift example working, but want to try the better and more efficient Dirac LE instead. I am having a bit of trouble with it though because I can't just replace the data pointers with the in1 and out1 pointers like in the other example.

In the example project, it creates a myReadData function, placed before main().....
Code:
long myReadData(float **chdata, long numFrames, void *userData)
{	
	// This parameter can be used to pass information about the caller (for example, "this") to
	// the callback so it can manage its audio streams. It is not used in this example.
#pragma unused (userData)
	
	static unsigned long readPosition = 0;
	
	long res = mAiffReadData(gName, chdata[0], readPosition, numFrames);
	readPosition += numFrames;
	
	return res;	
}
... and passes it to the DiracCreate function....
Code:
void *dirac = DiracCreate(kDiracLambda3, kDiracQualityPreview, 1, 44100., &myReadData);
....and then does this for the output...
Code:
// Allocate buffer for output
    float *audio = new float[numFrames];

long ret = DiracProcess(audio, numFrames, 0, dirac);
So I am assuming that I can just replace *audio with out1 to get it to write to the output pointer. What I am I totally lost with is how to give it the in1 pointer so that it can process the input.

Does anyone have any ideas of how to do this?

Thanks for any help.
captain caveman is offline   Reply With Quote
Old 01-24-2011, 09:34 AM   #2
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

This unfortunately will be a bit involved to do, because you don't get to decide how much data the Dirac process wants to consume to produce it's output. (The number of audio frames it may want in the callback function can vary from 0 to 1000's of frames.) Yet you are faced with the constraint that IPlug on the other hand tells you explicitly how much input and output to use and produce. You need some way to provide the audio input into the Dirac callback and in a way the callback won't get starved of input audio. WDL's queue classes might come in handy for such purposes. (And yes, this probably will have latency implications.)

I believe Reaper's ReaPitch implements Dirac LE in some manner, so perhaps one of the Cockos guys could chime in how this should really work...

I have myself used the Dirac library in my codes a few times, but it's been different for me because I get to control how the audio streams in/out. (It's been audio editor kind of stuff I've done, not plugins.)
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-24-2011, 02:21 PM   #3
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

Thanks very much for the reply, that has given me some ideas to get this working, namely that I am going to buffer the audio from in1 and in2 into a separate class member array to compensate for the requests for numFrames not being nicely divisible by audio buffer size.

I am down to one compiler error now which is down to me making myReadData a class member which I don't understand though (along with 99% of C++ )....
Code:
error C2276: '&' : illegal operation on bound member function expression
..... relating to passing the address of the function from the end of this line.....
Code:
void *dirac = DiracCreate(kDiracLambdaPreview, kDiracQualityPreview, 1, sampleRate, &myReadData);
.... which if I change to....
Code:
void *dirac = DiracCreate(kDiracLambdaPreview, kDiracQualityPreview, 1, sampleRate, &Transpose::myReadData);
..... gives me new compiler errors.....
Code:
1>.\Transpose.cpp(752) : error C2665: 'DiracCreate' : none of the 2 overloads could convert all the argument types
1>        c:\jof\joftranspose\iplug\transpose\Dirac.h(47): could be 'void *DiracCreate(long,long,long,float,long (__cdecl *)(float **,long,void *))'
1>        c:\jof\joftranspose\iplug\transpose\Dirac.h(48): or       'void *DiracCreate(long,long,long,float,long (__cdecl *)(float *,long,void *))'
1>        while trying to match the argument list '(, , int, float, long (__thiscall Transpose::* )(float **,long,void *))'
Once I get this ironed out I'll be able to start experimenting.

Where is the schoolboy error this time?
captain caveman is offline   Reply With Quote
Old 01-24-2011, 02:35 PM   #4
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Just for the heck of it, I tried putting the Dirac process into a VST plugin myself today after reading and replying into this thread. I did not use a class member for the Dirac callback function, but just a standalone function. Which might not be threadsafe or something...Maybe try the "static" keyword when declaring your callback function in your class :

static long myReadData(float *data, long numFrames, void *userData);

then it should work to do :

void* newDirac1=DiracCreateInterleaved(lambdaVal,qualVal ,1,44100.0,&myReadData);

or similar...That's how I've done it my audio editor app implementation. Though I am not entirely sure if this will be threadsafe either...Hopefully someone with extensive C++ knowledge could tell here...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-24-2011, 03:15 PM   #5
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

You're being a great help, but unfortunately declaring the member function as static is not allowed at file scope (something I only know because I just read it from a new compiler error ).

I'm bamboozled.... again.
captain caveman is offline   Reply With Quote
Old 01-24-2011, 03:18 PM   #6
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by captain caveman View Post
You're being a great help, but unfortunately declaring the member function as static is not allowed at file scope (something I only know because I just read it from a new compiler error ).

I'm bamboozled.... again.
How about just risking it all and having the callback as a global stand alone function? I am not 100% sure but this seems to be working correctly...(Well, you will then of course have to pass around the "this" pointer into the callback etc...)

Code:
long myCallback(float *data, long numFrames, void *userData)
{
	AGain* plugPointer=(AGain*)userData;
	
	if (plugPointer->m_queue1.Available()/sizeof(float)>=numFrames)
	{
		plugPointer->m_queue1.GetToBuf(0,data,numFrames*sizeof(float));
		plugPointer->m_queue1.Advance(sizeof(float)*numFrames);
		
	} else
	{
		// not enough input queued yet, just fill silence to dirac processor...
		for (int i=0;i<numFrames;i++)
			data[i]=0.0;
		sprintf(g_db,"dirac wanted %d frames, %d were available in wdl queue",numFrames,plugPointer->m_queue1.Available()/sizeof(float));
	    OutputDebugStringA(g_db);
	}
	return numFrames;
}
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-24-2011, 03:37 PM   #7
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

Ordinarily I would laugh in the face of danger and do that, but with IPlug global data is shared between instances of plugins and so that would (I am assuming) lead to all kinds of weird stuff going on.

At the moment for example I have created a single global variable for a transposition amount that the plugins can all see and respond to.

I think I'll sleep on it. Not that I'll get any solutions sleeping, but at least I'll get some sleep.
captain caveman is offline   Reply With Quote
Old 01-24-2011, 05:11 PM   #8
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by captain caveman View Post
Ordinarily I would laugh in the face of danger and do that, but with IPlug global data is shared between instances of plugins and so that would (I am assuming) lead to all kinds of weird stuff going on.

At the moment for example I have created a single global variable for a transposition amount that the plugins can all see and respond to.

I think I'll sleep on it. Not that I'll get any solutions sleeping, but at least I'll get some sleep.
I have been assured by a quite well experienced source that this solution using the "global function" should be safe and further testing I've done myself seems to indicate that too. Multiple instances of the plugin, running on multiple CPU cores in Reaper seem to be working just fine. There's of course a difference to global variables which indeed can cause various immediately noticeable havocs with multiple instances of a plugin.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-25-2011, 12:56 AM   #9
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

Okay dokey, I'll give this a try. As usual though I am falling at the first hurdle......

As well as the usual....
Code:
error C2276: '&' : illegal operation on bound member function expression
.... error, I am getting.....
Code:
error C2228: left of '.Available' must have class/struct/union
.... errors too referring to m_queue1, which I have declared as a public member variable of the Transpose class.

Oh, how do I "pass around the 'this' pointer?"

Thanks!

edit: in case you're wondering why I am asking, I was going to do this old skool with a couple of C-style arrays, but those C++ arrays functions look a lot cleaner.

Last edited by captain caveman; 01-25-2011 at 06:04 AM.
captain caveman is offline   Reply With Quote
Old 01-25-2011, 09:04 AM   #10
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by captain caveman View Post
Okay dokey, I'll give this a try. As usual though I am falling at the first hurdle......

As well as the usual....
Code:
error C2276: '&' : illegal operation on bound member function expression
.... error, I am getting.....
Code:
error C2228: left of '.Available' must have class/struct/union
.... errors too referring to m_queue1, which I have declared as a public member variable of the Transpose class.

Oh, how do I "pass around the 'this' pointer?"

Thanks!

edit: in case you're wondering why I am asking, I was going to do this old skool with a couple of C-style arrays, but those C++ arrays functions look a lot cleaner.
In my plugin class header I have :

#include "fastqueue.h"

then as a member variable of the plugin class :

WDL_FastQueue m_queue1;

Note that for this to compile the Cockos WDL headers must be in the include paths...(IPlug comes as part of WDL anyway, so you will most likely have the headers around, it's just about setting up things so the compiler will see them.)

Then in the constructor code of my plugin class I have this to create the Dirac processor instance :

m_dirac1=_DiracCreateInterleaved(kDiracLambdaPrevi ew,kDiracQualityPreview,1,44100.0,myDiracCallback, (void*)this);

Which passes the plugin instance pointer (which is "this" while inside the plugin class code) into the Dirac library.

Note that I haven't done any benchmarking if using a plain C array with some counters etc would be more performant than using the WDL FastQueue class. I simply prefer these days to use the WDL FastQueue whenever I need to negotiate between buffers of varying sizes, because the code is so much simpler to write and understand this way.

May I ask a question in turn, by the way? Have you yet managed to get the Dirac library linked into your plugin and have the plugin actually load in a VST host? I could not do that in any simple manner...I had to resort on Windows to loading the Dirac dll manually and resolving the functions from the dll manually, which turned out to be pretty messy code...It seemed the VST plugin dll simply could not find the Dirac dll automatically from any place I tried on the system...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-25-2011, 12:32 PM   #11
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

I wrote out a big long post in reply, tried to load the plugin (after commenting out the line I'm about to talk about) and got a "could not find dll" message followed by a BSOD.

I am assuming this means that the .lib is linked in someway, but not the right way.

Apart from this I am stuck on one last compiler error....
Code:
error C2661: 'DiracCreate' : no overloaded function takes 6 arguments
Code:
m_dirac1 = DiracCreate(kDiracLambdaPreview,kDiracQualityPreview,1,44100.0, myReadData, (void*)this);
... (I changed the name of the function back to the original). It doesn't work with &myReadData either, and I don't have a DiracCreateInterleaved in the Dirac.h so it won't let me use that.

I actually got an incompatible function overload error when compiling (with VC 2008 Express) the SmbPitchShift example due to it not liking log() getting stuffed with a long. Changing log() to logl() solved that. Surely that would have been changed if it was a problem though.

I dunno. Any ideas regarding the 6 argument error here?

I tried registering with the dspdimension forum, but apparently my email provider is on a blacklist so can't get any info about the .dll thing.
captain caveman is offline   Reply With Quote
Old 01-25-2011, 01:05 PM   #12
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by captain caveman View Post
I wrote out a big long post in reply, tried to load the plugin (after commenting out the line I'm about to talk about) and got a "could not find dll" message followed by a BSOD.

I am assuming this means that the .lib is linked in someway, but not the right way.

Apart from this I am stuck on one last compiler error....
Code:
error C2661: 'DiracCreate' : no overloaded function takes 6 arguments
Code:
m_dirac1 = DiracCreate(kDiracLambdaPreview,kDiracQualityPreview,1,44100.0, myReadData, (void*)this);
... (I changed the name of the function back to the original). It doesn't work with &myReadData either, and I don't have a DiracCreateInterleaved in the Dirac.h so it won't let me use that.

I actually got an incompatible function overload error when compiling (with VC 2008 Express) the SmbPitchShift example due to it not liking log() getting stuffed with a long. Changing log() to logl() solved that. Surely that would have been changed if it was a problem though.

I dunno. Any ideas regarding the 6 argument error here?

I tried registering with the dspdimension forum, but apparently my email provider is on a blacklist so can't get any info about the .dll thing.
About the DiracCreateInterleaved not found in Dirac.h...Perhaps you have an outdated Dirac SDK. It's best to get the latest one that has that function, in case the DiracCreate function in the older one is for split audio arrays. Those will be more messy to handle, and would be wasted effort anyway as you can't do anything but mono processing in the free of charge Dirac library.

http://dirac.dspdimension.com/Dirac3...echnology.html

BSODs are unfortunate occasional consequences when doing code that runs under realtime/low latency audio systems. It's probably your audio interface's driver crapping out when the plugin host program crashes or hangs.

Note also about the Dirac audio callback function that it must not be a member of your class, but a freestanding function like I wrote in the earlier post. You can just write the function into the .cpp file where the implementations of your plugin class are. (Don't declare it in the header file etc...) Then it should work for the compiler when you give the callback function name directly, no & needed.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 01-25-2011 at 01:12 PM.
Xenakios is offline   Reply With Quote
Old 01-25-2011, 01:46 PM   #13
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

Quote:
Originally Posted by Xenakios View Post
About the DiracCreateInterleaved not found in Dirac.h...Perhaps you have an outdated Dirac SDK.
Yes, that was the one. I don't know how that happened, because I only downloaded it a couple of days ago. That's it compiling the m_dirac1 object now, but I am now getting linking errors with all the Dirac functions.
Code:
1>   Creating library Release/test.lib and object Release/test.exp
1>Transpose.obj : error LNK2019: unresolved external symbol _DiracCreateInterleaved referenced in function "public: __thiscall Transpose::Transpose(struct IPlugInstanceInfo)" (??0Transpose@@QAE@UIPlugInstanceInfo@@@Z)
1>Transpose.obj : error LNK2019: unresolved external symbol _DiracDestroy referenced in function "public: virtual void __thiscall Transpose::ProcessDoubleReplacing(double * *,double * *,int)" (?ProcessDoubleReplacing@Transpose@@UAEXPAPAN0H@Z)
1>Transpose.obj : error LNK2019: unresolved external symbol _DiracSetProperty referenced in function "public: virtual void __thiscall Transpose::ProcessDoubleReplacing(double * *,double * *,int)" (?ProcessDoubleReplacing@Transpose@@UAEXPAPAN0H@Z)
1>Release/Transpose.dll : fatal error LNK1120: 3 unresolved externals
I've added DiracLE.lib from the Common Files directory in the Dirac SDK to Project Properties>Config Properties>Linker>Input>Additional Dependencies and then added the directory to Tools>Options>Project and Solutions>VC++ Directories>Library Files.

No joy. Are you getting similar problems when linking?
captain caveman is offline   Reply With Quote
Old 01-25-2011, 01:59 PM   #14
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by captain caveman View Post
Yes, that was the one. I don't know how that happened, because I only downloaded it a couple of days ago. That's it compiling the m_dirac1 object now, but I am now getting linking errors with all the Dirac functions.
Code:
1>   Creating library Release/test.lib and object Release/test.exp
1>Transpose.obj : error LNK2019: unresolved external symbol _DiracCreateInterleaved referenced in function "public: __thiscall Transpose::Transpose(struct IPlugInstanceInfo)" (??0Transpose@@QAE@UIPlugInstanceInfo@@@Z)
1>Transpose.obj : error LNK2019: unresolved external symbol _DiracDestroy referenced in function "public: virtual void __thiscall Transpose::ProcessDoubleReplacing(double * *,double * *,int)" (?ProcessDoubleReplacing@Transpose@@UAEXPAPAN0H@Z)
1>Transpose.obj : error LNK2019: unresolved external symbol _DiracSetProperty referenced in function "public: virtual void __thiscall Transpose::ProcessDoubleReplacing(double * *,double * *,int)" (?ProcessDoubleReplacing@Transpose@@UAEXPAPAN0H@Z)
1>Release/Transpose.dll : fatal error LNK1120: 3 unresolved externals
I've added DiracLE.lib from the Common Files directory in the Dirac SDK to Project Properties>Config Properties>Linker>Input>Additional Dependencies and then added the directory to Tools>Options>Project and Solutions>VC++ Directories>Library Files.

No joy. Are you getting similar problems when linking?
I can get the linker to work using the DiracLE.lib file...But it was of no use, the Dirac dll simply could not be found by the plugin at runtime. And that spawned a whole lot of nasty messy code...I hope you won't be facing this same issue, but if you do, I can show you the code I used for the manual dll loading and function resolving.

Anyway, you should perhaps be adding the .lib file to your Visual Studio project, not in the global library files. Though honestly I don't even know what the latter is meant for...I always just add the .lib files to my project.

This line from the linker by the way reveals you may be trying something unhealthy in your code :

1>Transpose.obj : error LNK2019: unresolved external symbol _DiracDestroy referenced in function "public: virtual void __thiscall Transpose::ProcessDoubleReplacing(double * *,double * *,int)" (?ProcessDoubleReplacing@Transpose@@UAEXPAPAN0H@Z)

You should not really try destroying the Dirac processor object in the audio processing function of your plugin. But if you insist on doing that, do you also recreate the processor before the next processdoublereplacing call?

Also, you haven't edited the Dirac.h file to make the functions have the _ at the front of the names, right? You should not do that...The linker etc rely on the names being in the .h file as they are when you get the SDK from dspdimension...The _ thing in my code snippets is just for my stuff that I had to do to get the Dirac dll working...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 01-25-2011 at 02:08 PM.
Xenakios is offline   Reply With Quote
Old 01-25-2011, 02:45 PM   #15
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

Thanks for going through those errors, it turns out that the issue is with what I am casting m_dirac1 as in the class header file.

I get the linking errors when declaring it as void*. When I don't declare it as void* I get errors complaining that the compiler cannot convert from int to void* and void* to int. This is why I declared it as void*, but now the library linker doesn't like it.

C++..... GRRRRRR!!!
captain caveman is offline   Reply With Quote
Old 01-27-2011, 12:51 AM   #16
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Did you make any progress with your code?

My throw-away plugin project bumped into some sound issues with the Dirac algo itself. I thought I had to be having some bug in how I used it, but nothing I tried for fixing seemed to make any difference. I then tried in Reaper the ReaPitch plugin and the media item pitching with the Dirac LE algorithm. Those have the same issues with the sound.

So don't be surprised if you experience these same issues yourself eventually. It just looks like at least the free-of-charge version of the Dirac library isn't that high quality/robust...It seems unlikely both me and the Cockos Reaper developers would have managed to make the same errors in using the Dirac LE library.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-27-2011, 06:58 AM   #17
captain caveman
Human being with feelings
 
Join Date: Feb 2008
Posts: 1,616
Default

Nope, I didn't get beyond the issue with what to cast m_dirac1 as. As soon as classes and pointers are involved in real-world stuff I tend to get stuck.

Thanks for checking it out though.... an interesting thing which came out of your investigation into Dirac LE in Reaper is that the algorithm (even Preview) is described as slow so I don't know if it'd be any good for realtime anyway.

If only there was a free Elastique LE (with an easy to implement interface for C++ dummies).
captain caveman is offline   Reply With Quote
Old 01-27-2011, 11:41 AM   #18
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by captain caveman View Post
If only there was a free Elastique LE (with an easy to implement interface for C++ dummies).
Yes, I have been dreaming about that too! I don't know, maybe it would be worth the shot to ask z-plane about this...? It could be good public relations for them if developers with low financial resources and/or no business company(*) could use at least some of their stuff. Surely there would then need to be some limitations in the algorithms available, but maybe some satisfactory compromise could be possible...

And yes, Dirac also has the problem of quite high CPU load...Only the lowest quality modes will run sufficiently well in realtime. The lamdba parameter, when increased to higher levels, also starts to eat the CPU very quickly.

(*) The company issue was what prevented me a few years back from even starting to negotiate about prices of the elastique license. Starting a company here in my country isn't a decision to be made too lightly, so I didn't, just to be able to discuss about pricing...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 01-27-2011, 07:55 PM   #19
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by Xenakios View Post
May I ask a question in turn, by the way? Have you yet managed to get the Dirac library linked into your plugin and have the plugin actually load in a VST host? I could not do that in any simple manner...I had to resort on Windows to loading the Dirac dll manually and resolving the functions from the dll manually, which turned out to be pretty messy code...It seemed the VST plugin dll simply could not find the Dirac dll automatically from any place I tried on the system...
I had a short spin with the Dirac LE and while on Linux I was able to create a simple C wrapper providing a much friendlier interface for processing a sequential stream of audio blocks (http://audio.michael-gruhn.com/files...0.1-src.tar.gz should compile fine with any standard compliant compiler) I won't bother any further trying to make a VST, since I wasn't even able to compile the simple test application for Windows. Even though everything compiles fine the resulting binary will instantly crash in the DiracLE.dll. So there is definitively something fishy about the whole thing.

Anyway if anyone is interested the above code can simply be thrown into a VST (call d4d_init() in the constr, d4d_delete() in the destr, d4d_set_prop() in the parameter setting function, and d4d_process() in the process function) ... provided one gets the dll linked correctly into the application. I won't bother even trying.
Mich is offline   Reply With Quote
Old 01-28-2011, 01:54 PM   #20
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Mich View Post
d4d_set_prop() in the parameter setting function, and d4d_process() in the process function) ... provided one gets the dll linked correctly into the application. I won't bother even trying.
Thanks for posting the code. But quickly looking over the code, the pitch property setting won't work like that for the Dirac LE library. It prevents the DiracSetProperty from succeeding once the DiracProcessInterleaved has been called once on a Dirac processor instance. This is simply a documented limitation of the Dirac LE library. (Unless it's been by mistake forgotten in the Linux binaries by the dspdimension guy... )

What I needed to do make the pitch changing work in a VST plugin context is something like this :
Code:
void AGain::setParameter (VstInt32 index, float value)
{
	if (value!=m_pitch)
	{
		m_mutex->Enter();
		_DiracDestroy(m_dirac1);
		_DiracDestroy(m_dirac2);
		m_queue1.Clear();
		m_queue2.Clear();
		m_dirac1=_DiracCreateInterleaved(kDiracLambdaPreview,kDiracQualityPreview,1,44100.0,myFuckingCallback,(void*)this);
		m_dirac2=_DiracCreateInterleaved(kDiracLambdaPreview,kDiracQualityPreview,1,44100.0,myFuckingCallback,(void*)this);
		double p=-12.0+24.0*value;
		double ratio=pow(2.0,p/12.0);
		_DiracSetProperty(kDiracPropertyPitchFactor,ratio,m_dirac1);
		_DiracSetProperty(kDiracPropertyPitchFactor,ratio,m_dirac2);
		m_pitch = value;
		m_mutex->Leave();
	}
}
The mutex needs to then be entered and leaved also at least in the plugin's audio processing method. Obviously this will result in nothing like smooth tweakability of the pitch, but that's just the nature of the Dirac LE lib. It probably would be possible to do some sneaky crossfading etc tricks, but I haven't bothered looking into that at this point.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 01-28-2011 at 02:21 PM.
Xenakios is offline   Reply With Quote
Old 01-28-2011, 04:27 PM   #21
Mich
Human being with feelings
 
Join Date: May 2009
Posts: 1,265
Default

Quote:
Originally Posted by Xenakios View Post
Thanks for posting the code. But quickly looking over the code, the pitch property setting won't work like that for the Dirac LE library. It prevents the DiracSetProperty from succeeding once the DiracProcessInterleaved has been called once on a Dirac processor instance. This is simply a documented limitation of the Dirac LE library.
What a pita ... now it should work http://audio.michael-gruhn.com/files...0.1-src.tar.gz

Has also different resyncing modes for the d4d_set_props(), though the hard resync mode seems to work best (though it can cause some clicks) while the flush mode will cause silence (and clicks) and the stretch mode while not causing any of the before causes annoying time and pitch stretching artifacts. So choose what is least annoying to you and good luck with your VSTs.
Mich is offline   Reply With Quote
Old 11-09-2011, 10:34 PM   #22
do0g
Human being with feelings
 
Join Date: Jan 2009
Posts: 3
Default

Hi Mich, your link seems to be dead - any chance of reposting it somewhere?

Cheers,
Doug
do0g 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 07:27 PM.


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