|
|||
Hi To all!
According to Leslie Sanford (http://www.kvraudio.com/forum/viewtopic.php?t=270213), to sync an LFO to the host I only need know the Tempo and the PPQN position. I'm using the ASIO VST Project by Christian Budde, and if I understand correctly I have a record avaiable called TVstTimeInfo, that's probably obtained by using the procedure GetTimeInfo(const Filter: TVstIntPtr): PVstTimeInfo; Is this record provided by the host and I just need to get a pointer to it to read its attributes? But.. What's that Filter parameter? Filter of what? I don't have a clear idea... Thank you in advance. Paolo EDIT: I add that: "filter should contain a mask indicating which fields are requested (see valid masks in aeffectx.h), as some items may require extensive conversions" It don't helps me to understand... |
|||
| ^ | Joined: 24 Jan 2012 Member: #273585 | ||
|
|||
Don't know about Delphi specifically but: the filter is a set of flags specifying what specific information you would like to be included in the time info. In this case you would want to do the equivalent of the C++
VstTimeInfo * vstTime = getTimeInfo(kVstTransportPlaying | kVstTempoValid | kVstPpqPosValid); If you're not familiar with C++, that's just a bitwise OR of the flag contants. You should probably request transport playing too (as done above). This way you can keep your own sample counter to run your LFOs at host tempo when the host playback is stopped (and then sync to PPQN position when host playback resumes). Now, even if you ask for some fields, host isn't required to return those, so check afterwards (in timeinfo's flags field) that you actually got what you wanted before trying to use stuff (uninitialized fields might be anything). Unfortunately no idea how this translates to Delphi but it's probably not too different. Hope this helped at least a bit. |
|||
| ^ | Joined: 11 Feb 2006 Member: #97939 Location: Helsinki, Finland | ||
|
|||
Hi Paoling,
In case you haven't already found a solution, this is what I use. procedure TMyPlugin.ProcessReplacing(inputs, outputs: PPSingle; sampleframes: Integer); var TimeInfo : PVstTimeInfo; Tempo : single; PpqPos : double; begin //Get the TimeInfo pointer. TimeInfo := GetTimeInfo(32767); //Check if the tempo field is valid. if (TimeInfo^.flags and kVstTempoValid) >=1 then Tempo := TimeInfo^.Tempo; //Check if the PPQ value is valid. if (TimeInfo^.Flags and kVstPpqPosValid) >= 1 then PpqPos := TimeInfo^.ppqPos; end; The 32767 is a constant I saw used in an example plugin when I first started programming. If you need them, the flags mystran mentioned are defined in DAEffectX.pas. Hope that helps. |
|||
| ^ | Joined: 14 Dec 2003 Member: #11047 Location: Melbourne, Australia | ||
|
|||
Thank you so much Mystran and Very Angry Mobster; actually I found a solution like yours, Very Angry Mobster(VAM for simplyness).
I'm not very sure about the constant value... In DAEffectX.Pas (DAV_VSTEffect in the VST Framework), the constants range from 0 to 14 if I don't get wrong... But I noticed that changing the parameters doesn't give me different results. I'm trying it in Sonar and I see that I don't get PPQ, so I don't have a kind of way to understand the ticks used per quarter. I know that it is 960 ticks, but I don't have a way to find this info. I think I could live without it... Just for a future reference, let's describe the values and the format of the various entries. This is not very well documented to me in the main VST document from steinberg. I try to explain the things that I know and then if you can you add info for the things I don't know. And correct me if I'm wrong. SamplePos : Double; // current location Current Location in samples. If the Tempo is 120 bpm, a quarter is half a second, then a Bar in 4/4 is 2 seconds long. So the SamplePos of the 2nd bar is 2*SampleRate. If there is a loop, SamplePos can jump backward, and if the sequencer is stopped the SamplePos simply continues to count. Since the GetTimeInfo it is the same during the whole ProcessReplacing method, you can use an internal ISamplePos counter (<than SampleFrames) to keep track of the internal progress of the plugin. SampleRate : Double; The actual samplerate. It should be provided as a parameter in the ProcessReplacing method, so I don't see the point to use it here. But I noticed the type of this parameter (like in SamplePos), why it isn't an integer value? Can fractional values of those parameters exists? It makes no meaning to me. And it could save a Trunc function (i use the magic numbers trick in this case). NanoSeconds : Double; // system time According to the documentation it is: the system time in nanoseconds related to SamplePos (which is related to the first sample in the buffers passed to the process () methods). I don't understand fully this value. What is that: is that just a conversion in time of the SamplePos value, or a measuring of the time passed from the first call to the Process() method? PpqPos : Double; // 1 ppq This seems not valid in Sonar to me; anyway I think that it should be a conversione from SamplePos to the Thick value. If SamplePos is 44100 at a SampleRate of 44100, then the PpqPos should be 960 if the tick value is 960. Is it so? Does exist a valid method to understand the Midi Tick value for the sequencer apart from doing a conversion like this?? This could be useful to set a Midi Resolution value in the plugin Tempo : Double; // in bpm Tempo is obviously the Time value. But what is the purpose of the TempoAt(Value) function? Is it to understand the Tempo at SamplePos+ISamplePos values (The SamplePos + the internal offset < than SampleFrames?); BarStartPos : Double; // last bar start, in 1 ppq I suppose than this is pratically a conversion like: BarStartPos:= PpqPos mod PPQN PPQN is the number of ticks. In case of 960, then it is PpqPos mod 960. Right? CycleStartPos : Double; // 1 ppq CycleEndPos : Double; // 1 ppq Those two values are the PPq position of the loop set in the sequencer? Right? TimeSigNumerator : LongInt; // time signature TimeSigDenominator : LongInt; This is easy and those two values combined can give us the meter of the project. SmpteOffset : LongInt; SmpteFrameRate : LongInt; // 0:24, 1:25, 2:29.97, 3:30, 4:29.97 df, We really care about those two values? They are video related and I can only imagine that they could be useful in a plugin for a video editing software. Am I wrong? Please excuse me for the amount of errors I could have written..! I'm just looking to spread a bit of light in this topic Thank you, Paolo |
|||
| ^ | Joined: 24 Jan 2012 Member: #273585 | ||
|
|||
Quote: I'm not very sure about the constant value... In DAEffectX.Pas (DAV_VSTEffect in the VST Framework), the constants range from 0 to 14 if I don't get wrong... But I noticed that changing the parameters doesn't give me different results.
In DAV_VSTEffect, the values from TVstTimeInfoFlag go from 0 to 15 because they are in a Set. This is a Delphi trick. Their real values (in the memory or in the register, during the run-time) are not 0..15. 0 To 15 is actually the bit order in a TVstTimeInfoFlags. For example in the example of VAM, the value 32767 is actually 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024 + 2048 + 4096 + 8192 + 16384 which is: 2^0 or 2^1 or 2^2 or...or 2^14 (note that he forgets the last value) So when you make your set, lets say Var MyValidityFlags: TVstTimeInfoFlags; Begin MyValidityFlags := []; Include(MyValidityFlags, vtiClockValid); Include(MyValidityFlags, vtiSmpteValid,); // GetTimeInfo(Integer(MyValidityFlags)); End; Myflags won't be equal to 14 + 15 but rather to 2^14 + 2^15 which matches to the constants from the official SDK. Then you can call GetTimeInfo by casting MyFlags as an integer. Quote: SampleRate : Double;
The actual samplerate. It should be provided as a parameter in the ProcessReplacing method, so I don't see the point to use it here. But I noticed the type of this parameter (like in SamplePos), why it isn't an integer value? Can fractional values of those parameters exists? It makes no meaning to me. And it could save a Trunc function (i use the magic numbers trick in this case). The samplerate is not provided in the ProcessReplacing method... You don't need any rounding operation. Just hold it as a single. You will rarely do some integer operations with the samplerate. But it's true that you don't really need to use this member of the structure as in DAV plugins you have an assignable SamplerateChange event. So either the SR is valid from the start of the plugin life-time or you can use the event mentioned previously to update your SR-based audio classes and properties. Quote: PpqPos : Double; // 1 ppq
This seems not valid in Sonar to me; anyway I think that it should be a conversione from SamplePos to the Thick value. If SamplePos is 44100 at a SampleRate of 44100, then the PpqPos should be 960 if the tick value is 960. Is it so? Does exist a valid method to understand the Midi Tick value for the sequencer apart from doing a conversion like this?? This could be useful to set a Midi Resolution value in the plugin No it is not so. ppqPos is independent from the sampling rate. It basically just increases by one every beat. You should use this to compute the midi tick. Usuallly to get a midi clock you just have to multiply this value with the resolution you require. For example: // get the infos with tempovalid and ppqposvalid MyInfos := GetTimeInfos(512 + 1024); // clock with 192 ticks per beat Tick192 := Floor( MyInfos^.ppqPos * 192 ); // clock with 96 ticks per beat Tick96 := Tick192 Shr 1; // clock with 48 ticks per beat Tick48 := Tick96 Shr1; note that actually a clock is a bit more complex, Tick192 should be a property with a setter, as its value can be the same during 2 or more iterations of the audio loop Quote: Since the GetTimeInfo it is the same during the whole ProcessReplacing method
No, you can call GetTimeInfo for each sample in the loop (ppqpos will vary). But to use an internal counter can avoid some calls to the host. |
|||
| ^ | Joined: 22 Oct 2011 Member: #267186 Location: France |
| KVR Forum Index » DSP and Plug-in Development | All times are GMT - 8 Hours |
|
Printable version |
Disclaimer: All communications made available as part of this forum and any opinions, advice, statements, views or other information expressed in this forum are solely provided by, and the responsibility of, the person posting such communication and not of kvraudio.com (unless kvraudio.com is specifically identified as the author of the communication).
Powered by phpBB © phpBB Group













