PDA

View Full Version : IPlug questions (MIDI,timing)


ArdeII
09-09-2010, 11:29 AM
Hi,
Couple of simple questions about IPlug

1. How can I know if the host is playing or stopped?
2. Is ProcessDoubleReplacing called even when host is stopped?
3. How would you implement program which plays 1/16 midi note every quater note in sync with the host?
i.e How can I exactly know which time position every sample presents in ProcessDoubleReplacing in order to trigger a new note?

More to come ;)

Thanks,
- Arto

cerberus
09-09-2010, 04:16 PM
and it's great to see other new faces here...
i'm new, so i can only give you a few tips...
if i give wrong advice, someone please correct me.
but i might as well try to answer some of your q's and learn myself!


1. i think perhaps use the OnIdle() call. (IPlugBase.h)

2. i think so, an exception would be if "run fx when stopped" is unchecked in reaper.

3. try calling GetSamplePos() GetTempo() GetSamplesPerBeat() ... look in IPlugBase.h for these sorts of queries to the host...


e.g : // get sample rate from host
fs = this->GetSampleRate();returns the current host sample rate in hz

schwa
09-09-2010, 07:19 PM
1. Use the host callback audioMasterGetTime, and look for kVstTransportPlaying in the flags field of the returned struct. Or, call iplug's GetSamplePos and compare to the position as of the previous processdoublereplacing.

2. Depends on the host. In REAPER, depends on the user preference "run FX when stopped."

3/4. For fixed time signatures, you can use iplug's GetTempo, GetTimeSig, GetSamplesPerBeat, and some math. For mixed time signatures you will need to use audioMasterGetTime, various fields in the returned struct, and more math.

cc_
09-10-2010, 12:18 AM
3/4. For fixed time signatures, you can use iplug's GetTempo, GetTimeSig, GetSamplesPerBeat, and some math. For mixed time signatures you will need to use audioMasterGetTime, various fields in the returned struct, and more math.

I added this function when I needed to do something like this (it's in my git repo):


virtual void GetTime(double *pSamplePos, double *pTempo,
double *pMusicalPos, double *pLastBar,
int* pNum, int* pDenom,
double *pCycleStart,double *pCycleEnd,
bool *pTransportRunning,bool *pTransportCycle) = 0;


I needed all that stuff to get it to work when looping as well.

ArdeII
09-11-2010, 03:54 AM
How is it possible that samplePos is not an integer? I have debugged samplePos values and getting values like 896.00000000000011.

I don't understand how sample position can be between samples?

- Arto

cc_
09-11-2010, 04:10 AM
That's just what the host is passing back, I don't know why. I think you should just round to the nearest integer.

ArdeII
09-11-2010, 04:47 AM
So the ppqPos is not valid either? I have to round it too? How do I do the rounding?

I don't think this is the right way to calculate the correct ppq at sample level inside ProcessDoubleReplacing method.
I mean what's the point of giving slightly wrong values when host could give the absolutely right values?

Or samplePos is not related to current data buffer in ProcessDoubleReplacing.

Too many questions ;)
Can someone give some tips how to do it?

- Arto

Rome
09-11-2010, 06:05 AM
How is it possible that samplePos is not an integer? I have debugged samplePos values and getting values like 896.00000000000011.

I don't understand how sample position can be between samples?

- Arto

I think doubles are used because of the limited range of 32 bit signed ints. 2 billion samples sound much at first but a 32 bit integer will wrap around already at 93 minutes when recording with 384Khz.

Just ignore the fractional part. This just happens because of the way floats are represented internally.

ArdeII
09-11-2010, 07:45 AM
So what about PPQ position? How to round that value because it is as wrong as sample position. You can't simply remove the fractional part from that value.

I wonder why the host isn't doing the rounding for us?

Schwa you know for sure whats going on here. Can you tell how to treat the values?

ArdeII
09-11-2010, 11:20 AM
OK, I think I got it! The values in samlplePos and PPQPos are values at current playing position. To get sample position in data buffer coming to ProcessDoubleReplacing you just have to round the value to the next one and calculate correct PPQ value!

I hope I'm right about this ;)
- Arto

ArdeII
09-11-2010, 12:33 PM
I tested my program with my assumptions and it works perfectly!

I hope this discussion about samplePos and ppq values helps someone ;)

- Arto

cc_
09-12-2010, 12:53 AM
Good to hear you have it working!

Did you try setting the transport to loop yet? That was the hardest thing to get working right for me.

ArdeII
09-13-2010, 02:12 PM
I have tested my implementation and I'm not sure any more that rounding sample position value up is right way to do it.

I have noticed that in certain situations I'm behind one sample and my MIDI implementation is not working.

Can someone with more experience tell what is the right thing to do to treat the sample position value got from VstTimeInfo.

The situation is when MIDI note ends at sample 192000(tempo 120,before bar 2,96000Hz).
MIDI event occurs with offset 127 which means MIDI note off event should occur at sample position 19200.
Then ProcessDoubleReplacing gets called and sample 192000 gets processed.

After That MIDI event note on occurs with offset 0. This note Should start at bar 2 which is sample position 192000 but when ProcessDoubleReplacing gets called sample position is 192001 which is 1 sample too much.

Is it possible MIDI event calback ProcessMidiMsg is called in wrong place when it should be called right after the MIDI off message.

The playing is started at sample position 144000 when this problem occurs.
When starting playing from sample position 108000 everything works fine. First the note off event occurs then note on event and after that ProcessDoubleReplacing gets called.

Schwa I really need you to help me with this. This smells like a Reaper bug or I have understood something totally wrong.

Thanks,
- Arto

ArdeII
09-13-2010, 10:30 PM
Ok, everything is working excellent right now. I figured out what the problem was.

You actually need to floor the sample position value not to ceil it as I was doing. So Rome was right from the very beginning ;)

I'll continue this journey to he unknown ;)