Quick Sign In:  

Forum: VirtualDJ Plugins

Topic: Plugins creation - What's available? [Please write only tips here] - Page: 2

This topic is old and might contain outdated or incorrect information.

djcelPRO InfinityModeratorMember since 2004
Crossfader Curves - How does it work? Only in VDJ v2.1 and more

You fill a tab of 4096 integers for each level where tab is the level value when crossfader=i and then you give the pointer of this tab to the new function setusercrossfade() for each deck

So with this function you can define all the behaviors (curves) you want. It saves a registry key (binary) "usercrossfade" which is used by Virtual DJ and change the registry key "crossfader" with the value 3 which is the new mode (user,utilisateur). It's not written in the shortcut help as it can only be made by plugin
///////////////////////
int level1[4096];
int level2[4096];
[...]
char cmd[32];
wsprintf(cmd,"setusercrossfade %d",level1)
SendCommand(LEFT_DECK,NOW,cmd);
wsprintf(cmd,"setusercrossfade %d",level2);
SendCommand(RIGHT_DECK,NOW,cmd);
//////////////////////
 

Posted Mon 09 May 05 @ 7:10 pm
claxPRO InfinityMember since 2004
I have a problem with "song_pos":

song_pos -%i ... OK | songpos %i ... go to the beginning of the track !!

Can someone help me ?
 

Posted Wed 18 May 05 @ 12:08 am
djcelPRO InfinityModeratorMember since 2004
Look at the help inside vdj, it's now written.
no-relative = slider
relative = samples
 

Posted Wed 18 May 05 @ 12:32 am
djcelPRO InfinityModeratorMember since 2004
How to work on the sound: (normal)

well first you create a memory space, here called buffer_input, where you set a part of the song, precisely, this part is composed of nb samples and start from the n° sample in the song.
It means you have a memory space with the samples from n° pos to the sample n° (pos+nb-1)
(We verify "0" and nb-1 equals nb samples in memory)

So GetSongSamples() gets a part of the sound from vdj (the song playing) and put it into buffer_input (dynamic memory allocation is automatically done by the function)

See that like a table of nb cases where each case contains a sample
///////////////////////////////////

int *buffer_input;
int pos;
int nb;
HRESULT res=GetSongSamples(pos,nb,(short**)&buffer_input);
if(res) return res;

///////////////////////////////

Well after that the goal is to do whatever with these samples and send them back to VDJ:

/////////////////////////////
HRESULT __stdcall CPlugin::OnComputeNewSamples(int pos,int nb,short *buffer)
{
int *buffer_output;
buffer_output=(int*)buffer;

// then instructions to link buffer_output to buffer_input

}
////////////////////////////

buffer is a memory place use by VDJ to get the sound back
(as buffer is a "short", we need to convert it in "int" so that's the reason why we create buffer_output)

/!\\ You have to know, when you work with sound, VDJ only plays your buffer_output instead of the real song on the deck

For example, if you don't want to modify sound but just get data to work with the beats, you have to write directly:
///////////////
buffer_ouput=buffer_input;
//////////////
 

Posted Sun 12 Jun 05 @ 1:20 am
djcelPRO InfinityModeratorMember since 2004
Type of processing:

- normal:
// Functions and variables for normal samples processing
virtual HRESULT __stdcall OnComputeNewSamples(int pos,int nb,short *buffer) {return 0;}


Your function will need to call GetSongSamples() to get a pointer on samples to process,
and copy the processed samples in the provided buffer.
Even if in most case you will ask for nb samples starting from pos, you're not required to:
You can require how many samples you need from any pos in the song.

HRESULT (__stdcall *GetSongSamples)(int pos,int nb,short **buffer);

- fixed-width:
// Functions and variables for fixed-width samples processing
virtual HRESULT __stdcall OnProcessSamples(int pos,int nb,short *buffer) {return 0;}


Vdj will send you already filled buffer of the required length,
and your function will process it in-place.
This mode is usefull for easy porting of existing code from other platform,
but is a bit slower than the normal mode.

Don't forget to set PluginInit.SampleSize to the length you want to proceed
OnNotify() function will be called with NOTIFY_REFILLBUFFER when VirtualDJ internal buffers
need to be refilled, and thus the same datas are about to be processed again.

// Receive notifications (new song loaded, buffer refilled, etc...)
virtual HRESULT __stdcall OnNotify(ENotify notify,int param1,int param2) {return 0;}


- fft:
// Functions and variables for frequency-domain processing
virtual HRESULT __stdcall OnProcessFFT(int pos,int nb,float *fft) {return 0;}


Vdj will pass to your function a fourrier transformation of the signal.
You can manipulate the frenquency-domain datas as you wish.
Upon return, Vdj will transform it back into PCM signal.
The function will be called with SampleSize complex datas for each channels (which makes 4*SampleSize floats).
Each fft is computer on a window of 2*SampleSize samples, overlapping each others from SampleSize samples.
The buffer provided is in the format:
Re[0].left,Re[1].left,...,Re[nb-1].left,Im[0].left,...,Im[nb-1].left,Re[0].right,Re[1].right,...,Im[nb-1].right
 

Posted Sun 12 Jun 05 @ 4:57 am
djcelPRO InfinityModeratorMember since 2004
In the plugin SDK, you have a function called Release() which returns 2 things
This function enables you to add some instructions when you change of the plugin or you leave VDJ
For example: save data in a file before leaving the plugin, finish a new thread in multi-threading,...

This function is so important as the function OnLoad() to my mind which executes some instructions when you load the plugin => useful to init the values at the beginning The function OnStart() is when you active the plugin in Virtual DJ and the function OnStop() when you disable the plugin If you work on the sound with OnComputeSamples(), the function OnStart() starts this action. I mean the creation of sound buffers
 

Posted Wed 13 Jul 05 @ 10:44 pm
djcelPRO InfinityModeratorMember since 2004
Function loadsamplefile(char*):

char sample[12][MAX_PATH];

sprintf("loadsamplefile %d",sample); where i is between 1 and 12

by Kaleo:
where did you found this function?
loadsamplefile is a parameter, not a function, no?
This allows to... load a file into the sampler (1 to 12 for the sample number)
You must pass the adress of a string containing the sample number and the full path of the file (concatenate them), that's all :)

 

Posted Fri 21 Oct 05 @ 8:38 pm
djbambiPRO InfinityMember since 2003
Hi, maybe one of you can enlighten me on the use of Song[n].Pitch

I'm trying to map the pitch knobs of my mk2, and it's easy if I always assume that the beginning value is 0% (i.e. "2048").

However, when you enable auto-bpm in VDJ, the track you load is automatically set to the same tempo as the active track, so it could be at +3% for example.

looking at Cel's code,

deltapitch[chan]+=delta/8;
if (deltapitch[chan]>4096) deltapitch[chan]=4096;
else if (deltapitch[chan] lessthan 0) deltapitch[chan]=0;
wsprintf(param,"%i",deltapitch[chan]);SendAction("pitch",deck,param,TRUE);

how can I initialize deltapitch[chan] correctly after track load?
anyone know the formula for Song[n].Pitch and how to translate it into a 0-4096 value for use with the pitch action?

(is this the right place to ask this kind of questions?)

I tried to use some tidbits from the DAC mapper code, but couldn't get that to work.

Thanks,

Nicolas

ps: of course, I'll post the code of my plugin when it's finished, although it's highly customized for me, there is some pretty funky code that could probably interest some of you guys.
 

Posted Mon 09 Jan 06 @ 11:35 am
From work on my DAC-3 mapper, when pitch is at 0%, Song[chan].Pitch == 4096

This value increases/decreases appropriately as the pitch slider is moved, but the minimum/maximum values change depending on the pitch range being used (8%, 12%, etc.)

In my mapper, I find the min/max values during intialisation of the DAC-3 by doing the following:

* Set pitch to 0 via pitch action
* Record Song[chan].Pitch minimum value
* Set pitch to 4096 via pitch action
* Record Song[chan].Pitch maxium value
* Set pitch to 2048

The above is done step-by-step in the OnTimer() function, giving VDJ a chance to update the pitch value in between the SendAction() and recording Song[chan].Pitch value.

Now that the min/max values are known, Song[chan].Pitch can be converted to a value between 0-4096 using:

MulDiv((Song[chan].Pitch - pitchmin[chan]),4096, (pitchmax[chan] - pitchmin[chan]))

I use something similar to this to determine whether the pitch in VDJ differs from the current pitch on the DAC-3, and display an appropriate warning on the LCD to allow the user to move the pitch slider to the correct position (Using [CP]+pitch)

NOTE: Downside of above is that if the pitch range is changed in VDJ, the min/max values will be incorrect.
 

Posted Mon 09 Jan 06 @ 4:28 pm
djbambiPRO InfinityMember since 2003
Hey, thanks a lot for this explanation.

A couple of questions about it:

- if you find the values of pitchmin[chan] and pitchmax[chan] manually, then what do Song[chan].PitchMin and Song[chan].PitchMax in the Song struct used for? (in your plugin code, it looks like you use those)

- how do you "Record Song[chan].Pitch minimum value", or more generally any value in the dll at runtime? is it by using watches, breakpoint, building in debug mode, launching vdj.exe from the "start debugging" menu? I'm new to Visual C++ and haven't been succesfull at doing that, I've only been able to use my MK2's LEDs for debugging :P can you point me to a tutorial?

- for a quick fix: do you know pitchmin[chan] and pitchmax[chan] for the +/- 8% range?

much thanks,

Nicolas
 

Posted Mon 09 Jan 06 @ 5:59 pm
>- if you find the values of pitchmin[chan] and pitchmax[chan] manually, then what do Song[chan].PitchMin
>and Song[chan].PitchMax in the Song struct used for? (in your plugin code, it looks like you use those)

Didn't notice those before! They probably contain the minimum and maximum values (So get around the problem of the pitch range being changed.) I'd need to test to see if this is the case.

>- how do you "Record Song[chan].Pitch minimum value", or more generally any value in the dll at runtime?

Generally you would set a breakpoint at a relevant place in the code (Where you want to see the value), or even map an unused button combination that does nothing (So you can set a breakpoint there and trigger it on demand by pressing the button combination.) When the breakpoint is triggered, you can view the contents of various variables in the current scope.

Alternatively, you can use LED combinations to show the value - On the DAC-3 this is easier because of the LCD displays that can display numbers. I.e: I had the main display (Time remaining) showing the DAC-3's pitch value and the small pitch %/BPM digits showing VDJ's Song[chan].Pitch so I could compare the two.

Another possibility is to have a button combination write on demand the values of various variables you're interested in to a file.

The default values I use for pitchmin/max in the DAC-3 mapper are 3606 and 4588 (I think these were at 8% (If not 12%), but the initialisation bit takes care of this anyway.)
 

Posted Mon 09 Jan 06 @ 6:56 pm
djbambiPRO InfinityMember since 2003
This is awesome, THANK YOU so much jpboggis, just tried it and it works like a charm! no problem if you change the pitch range either, it'll adapt.

What I did:

in CDJCMP3Mapper::OnTimer,

if (( Song[chan].PitchMax - Song[chan].PitchMin) != 0 ) Track[chan].currentpitch = MulDiv((Song[chan].Pitch - Song[chan].PitchMin),4096, (Song[chan].PitchMax - Song[chan].PitchMin));


in CDJCMP3Mapper::OnSlider,

// The Pitch knobs
case DJCSLIDER_PITCH:
{
Track[chan].currentpitch += delta/8;
if (Track[chan].currentpitch > 4096) Track[chan].currentpitch = 4096;
else if (0 > Track[chan].currentpitch) Track[chan].currentpitch = 0;
wsprintf(param,"%i",Track[chan].currentpitch);
SendAction("pitch",deck,param,TRUE);
}
break;
 

Posted Mon 09 Jan 06 @ 8:22 pm
djcelPRO InfinityModeratorMember since 2004
How work the FFT:

SampleSize must be power of 2 (for example 8192, 4096, 1024, 512...)

SampleRate is fixed to 44100 samples/second in VirtualDJ

So for a frequency 'frequency', it equals approximately the integer:

i=int(frequency*SampleSize/(float)SampleRate)

that you can read too:
i/(float)SampleSize=frequency/(float)SampleRate

Then select the interval where i is
 

Posted Thu 23 Feb 06 @ 11:50 pm


(Old topics and forums are automatically closed)