DiracLE and delphi

Discussion about the DSP Dimension's articles, tutorials and code.

Moderator: neuronaut

DiracLE and delphi

Postby bazxyz » 26.09.2009 09:57

Hello, I'm currently trying to use your DiracLE with Delphi, unforntunately I'm encountering
some problems. I would like to know if it would be possible to get more informations
about some parameters of the function imported from the library.

1/ First, is it legal to traduce the header and to use it, as long as I respect the original licence terms ?

2/ As I only basically knows the syntax of C, are the imports correct in this form ?

Code: Select all
readFromChannelsCallback = Function(var data: PSingle; numFrames: Integer; userData: Pointer): Integer ;cdecl ;
PreadFromChannelsCallback = ^readFromChannelsCallback;

Function    DiracVersion:Byte; cdecl ; external 'DiracLE.dll' ;
Function    DiracCreate(lambda,quality,numChannels: Integer; sampleRate: Single; arfcc: PReadFromChannelsCallback): Pointer; cdecl ; external 'DiracLE.dll' ;
Function    DiracCreateInterlaced(lambda,quality,numChannels: Integer; sampleRate: Single;arfcc: PReadFromChannelsCallback): Pointer; cdecl ; external 'DiracLE.dll' ;
Function    DiracSetProperty(selector:Integer; value:Double; dirac: Pointer): Integer; cdecl ; external 'DiracLE.dll' ;
Function    DiracGetProperty(selector: Integer; dirac:Pointer): Double; cdecl ; external 'DiracLE.dll' ;
Procedure   DiracReset(clear: Boolean; dirac: Pointer); cdecl ; external 'DiracLE.dll' ;
Function    DiracProcess(audioOut: PSingle;numFrames: Integer; userData,dirac: Pointer):Integer; cdecl ; external 'DiracLE.dll' ;
Function   DiracProcessInterlaced(audioOut: PSingle; numFrames: Integer; userData,dirac: Pointer):Integer; cdecl ; external 'DiracLE.dll' ;
Procedure   DiracDestroy(dirac: Pointer); cdecl ; external 'DiracLE.dll' ;
Function    DiracGetInputBufferSizeInFrames(dirac: Pointer): Integer; cdecl ; external 'DiracLE.dll' ;
Function    DiracValidateStretchFactor(factor: Double):Double ; cdecl ; external 'DiracLE.dll' ;


3/ I'm particularly stucking on the callback procedure. As far as I'm understanding how it works,
- the address of 'data' gives me the plugin address where I have to copy my input datas.
( every 4 bytes, starting from 'data' address and for numframes iterations I write a single, is it correct ? )
. in the dll, is 'data' always the first array entry address or does it already include an offset
(should I includes an offset such as the sum of all the numframes: address to write = 'data' address + sizeof(single)*offset ) ?
. is it correct to use a var parameter instead of a copied parameter (otherwise I get some violation access errors) ?

4/ assuming everything is done in the right way in the callback, then I always get empty output buffers, so
in DiracProcess, how should be given the pointer to the out buffer
. simple pointer to buffer @MyOutBuffer ?
. simple pointer to the first buffer entry @MyOutBuffer[0] ?
. pointer to the next data to write @MyOutBuffer[NumBerOfAlreadyWrittenFrames+1] ?
. does DiracLE performing memory operations on the output buffer ( no need to size it from my part ) ?
. does the dll directly write on my output buffer or should I copy something ? ( in a radically different way )
bazxyz
 
Posts: 5
Joined: 26.09.2009 09:05

Re: DiracLE and delphi

Postby neuronaut » 26.09.2009 12:42

bazxyz wrote:Hello, I'm currently trying to use your DiracLE with Delphi


Welcome!

bazxyz wrote:unforntunately I'm encountering some problems. I would like to know if it would be possible to get more informations
about some parameters of the function imported from the library.

1/ First, is it legal to traduce the header and to use it, as long as I respect the original licence terms ?


Yes.

bazxyz wrote:2/ As I only basically knows the syntax of C, are the imports correct in this form ?


I don't know Delphi and its data types at all, so I wouldn't know. We're only using standard C data types so this shouldn't be too difficult to translate, I'm sure there must be a reference on the 'net somewhere that relates ANSI C data types to the Delphi flavors.

bazxyz wrote:3/ I'm particularly stucking on the callback procedure. As far as I'm understanding how it works,
- the address of 'data' gives me the plugin address where I have to copy my input datas.


data is the address of the single precision 32bit float array where you need to copy the data from the file to. In the case of non-interlaced data this is a 2-dimensional array ordered as data[channel][sample value]. For stereo sample frames (channel #0 and #1) this array has two dimensions:

data[0][0...numFrames-1]
data[1][0...numFrames-1]

For interlaced data this array is simply a one-dimensional array holding the channel data as {left, right, left, right...}

bazxyz wrote:( every 4 bytes, starting from 'data' address and for numframes iterations I write a single, is it correct ? )


ANSI C makes no assumption as to how an array is actually laid out in memory during run time so it is considered dangerous to access the samples from an offset starting at data. In practice however this often works, so for single channel data (the only configuration supported by the LE version) your approach should be correct.

bazxyz wrote:. in the dll, is 'data' always the first array entry address or does it already include an offset
(should I includes an offset such as the sum of all the numframes: address to write = 'data' address + sizeof(single)*offset ) ?


I'm not sure if I understand what you're asking... data is the base address for the array and C assumes 0 based indexing, so the first array element should be at that address. Does that answer your question?

bazxyz wrote:. is it correct to use a var parameter instead of a copied parameter (otherwise I get some violation access errors) ?


I don't fully understand the difference between these two since I don't know Delphi, but you will have to modify the array in place, ie. without making a copy.

bazxyz wrote:4/ assuming everything is done in the right way in the callback, then I always get empty output buffers, so
in DiracProcess, how should be given the pointer to the out buffer
. simple pointer to buffer @MyOutBuffer ?
. simple pointer to the first buffer entry @MyOutBuffer[0] ?
. pointer to the next data to write @MyOutBuffer[NumBerOfAlreadyWrittenFrames+1] ?


You need to allocate the buffer before you call DIRAC according to the call that you make (ie. interlaced or non-interlaced). For instance, in case that you're working with interlaced / single channel data you need to allocate a buffer of numFrames single precision floats and pass in the address of that buffer when you call DiracProcessInterlaced(). That call will fill your array with the output values upon return.

What you can do to check that DIRAC is actually doing something is generate some dummy data in your callback. In C, this would look something like this (just a quick hack!):

Non-interlaced case (first channel only)
Code: Select all
long myReadData(float **chdata, long numFrames, void *userData)
{   
   if (!chdata)   return 0;

   static long gCounter = 0;
   for (long v = 0; v < numFrames; v++) chdata[0][v] = sin(1000.*2.*M_PI*gCounter++/44100.);
   
   if (gCounter < 10*44100)
      return numFrames;   
   else
      return 0;
}


Interlaced case
Code: Select all
long myReadDataInterlaced(float *chdata, long numFrames, void *userData)
{   
   if (!chdata)   return 0;

   static long gCounter = 0;
   for (long v = 0; v < numFrames; v++) chdata[v] = sin(1000.*2.*M_PI*gCounter++/44100.);
   
   if (gCounter < 10*44100)
      return numFrames;   
   else
      return 0;
}


This will generate roughly 10 seconds of a 1000 Hz sine wave (@ 44.1kHz sample rate).

bazxyz wrote: . does DiracLE performing memory operations on the output buffer ( no need to size it from my part ) ?


DIRAC expects the buffer to be allocated so it can hold numFrames single precision floats. It does not change the size of the array and copies the processed data to this array.

bazxyz wrote: . does the dll directly write on my output buffer or should I copy something ? ( in a radically different way )


Yes, and no :-)

HTH
+Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany

Re: DiracLE and delphi

Postby bazxyz » 26.09.2009 14:08

Thanks, the example callback code is usefull. It seems that in Delphi the parameter 'chdata' should be 'var chdata: array of single' instead of what I written in the first post( var chdata: PSingle ).
My current approach is to take the address of chdata and then to typecast/write/read in a low level '32 bits address mode'. I'll try to use another type of parameter so that array syntax can be directly used in the callback procedure ( a sin your example ).

Thanks again, I'll hope it'll work with your informations.
bazxyz
 
Posts: 5
Joined: 26.09.2009 09:05

Re: DiracLE and delphi

Postby neuronaut » 26.09.2009 16:33

Ok, I'm glad to hear I'm making sense :-) As I said I'm not familiar with Delphi at all so I don't know what data types you're supposed to be using for this, but I would appreciate getting your feedback if you get it to work (and possibly a link to your project so we can advertise it on our web site if you want). Please post here if you have more questions, I'd be happy to answer them if I can.

Best wishes
+Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany

Re: DiracLE and delphi

Postby bazxyz » 27.09.2009 13:48

Hello, finally it works. I leave the correct delphi imports here:



Code: Select all
readFromChannelsCallback = Function(var data: PSingle; numFrames: Integer; userData: Pointer): Integer ;cdecl ;
PreadFromChannelsCallback = ^readFromChannelsCallback;

Function    DiracVersion:Byte; cdecl ; external 'DiracLE.dll' ;
Function    DiracCreate(lambda,quality,numChannels: Integer; sampleRate: Single; arfcc: PReadFromChannelsCallback): Pointer; cdecl ; external 'DiracLE.dll' ;
Function    DiracCreateInterlaced(lambda,quality,numChannels: Integer; sampleRate: Single;arfcc: PReadFromChannelsCallback): Pointer; cdecl ; external 'DiracLE.dll' ;
Function    DiracSetProperty(selector:Integer; value:Double; dirac: Pointer): Integer; cdecl ; external 'DiracLE.dll' ;
Function    DiracGetProperty(selector: Integer; dirac:Pointer): Double; cdecl ; external 'DiracLE.dll' ;
Procedure DiracReset(clear: Boolean; dirac: Pointer); cdecl ; external 'DiracLE.dll' ;
Function    DiracProcess(var audioOut: PSingle ;numFrames: Integer; userData,dirac: Pointer):Integer; cdecl ; external 'DiracLE.dll' ;
Function   DiracProcessInterlaced(var PaudioOut: Single; numFrames: Integer; userData,dirac: Pointer):Integer; cdecl ; external 'DiracLE.dll' ;
Procedure DiracDestroy(dirac: Pointer); cdecl ; external 'DiracLE.dll' ;
Function    DiracGetInputBufferSizeInFrames(dirac: Pointer): Integer; cdecl ; external 'DiracLE.dll' ;
Function    DiracValidateStretchFactor(factor: Double):Double ; cdecl ; external 'DiracLE.dll' ;


Obviously I have nothing to advertise yet as I've only programmed the typical test which processes a WAV with a custom lenght, pitch and formants.
Thanks again.
bazxyz
 
Posts: 5
Joined: 26.09.2009 09:05

Re: DiracLE and delphi

Postby neuronaut » 27.09.2009 13:52

That's great! Please let us know if you have anything that you want to share...

Have a great Sunday
+Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany

Re: DiracLE and delphi

Postby bazxyz » 28.09.2009 22:51

neuronaut wrote:That's great! Please let us know if you have anything that you want to share...

Yes, :D , thanks, I would like to share the french alphabet to the world:

a,b,c,d,e,f,g,h... :lol:

Hum...no sorry. Anyway I have a proposition for you:
If you would like to put an 'offical'* delphi support to dirac you can contact me by email,
I'll put the header and a delphi example to your disposition in exchange of a pro licence
or something else.

Edit: As I told you the delphi approach is very low level and almost
none delphi coder is able to use my header traduction, because
it recquires a good understanding of adressing, typecasting etc...
So we could work together on this basis.
It's up to you to see


Baz.
bazxyz
 
Posts: 5
Joined: 26.09.2009 09:05

Re: DiracLE and delphi

Postby neuronaut » 29.09.2009 08:07

Hi Baz,

I'm afraid I am not at liberty to do a deal like this, but thanks for the offer!

Best wishes,
+Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany

Re: DiracLE and delphi

Postby bazxyz » 07.10.2009 00:32

Of course I understand. I would have been totally crazy not to try this as you've sayed publicly not mastering delphi. But I'm a bit confused with your reply, you seem to say that you'are not the big master of the dirac component, the confusion is I thought you were this personn but when you talk about 'liberty' that's sounds strange. ( I really was thinking I was talking to the author directly...sorry).
Anyway As I was saying previously my own interest was just into delphi and if you just don't want to open your libratry to all languages, I understand well. :wink:
bazxyz
 
Posts: 5
Joined: 26.09.2009 09:05

Re: DiracLE and delphi

Postby neuronaut » 07.10.2009 08:19

While I am the main author of DIRAC this doesn't mean that I have the authority to decide about the business side of things in our team.

As I understand it, we had no requests for DIRAC and Delphi so far, so there is no incentive for us to offer it for this language. For this reason we don't have much interest in purchasing a Delphi port at this time.

We welcome people to write wrappers for their applications and languages (just as you did) and it doesn't seem to be overly difficult to do with most languages. Like I said, we would be happy to link to your web site with the DIRAC Delphi wrapper, but that's all we can offer at this time.

Best wishes
+Stephan
Free DSP tutorials by Stephan M. Bernsee at http://www.dspdimension.com
"There are 10 types of people in this world: those who understand binary, those who don't"
--Unknown
neuronaut
 
Posts: 1332
Joined: 17.11.2005 09:15
Location: Mainz, Germany


Return to The DSP Dimension

Who is online

Users browsing this forum: No registered users and 0 guests

cron