Hey everyone

I have quite succeeded in making the waveform move one on one with mouse.
There are just 3 constraints :P
1. It works best (read 'only') with latency of 42ms.
2. If you shake your mouse like crazy, you might end up a few seconds later
or earlier from where you started!
3. I have not yet configured mouse for pitch other than 0. So if pitch is
changed, you won't  get one-on-one everywhere, but when you return your
mouse pointer from where you started, waveform should come at same point
from where scratching was started

I believe I can handle constraint 1 and 3.
But for constraint 2, its like I am running out of ideas.


Here is my approach (I have tried to present my approach, leaving away the
programming details).
I would appreciate if someone would please point out some shortcomings  or
suggest some thing which would help improve performance, because I have
changed some things in engine and I might not be able to notice
repercussions on different aspects of Mixxx.

ControlObject
   |- static function getCallStatus() returns current state of syncing of CO
[1]

enginebufferscale.h
   |- set MAX_SEEK_SPEED to 500.0f (original value was 4.0f) [2]

enginebufferscalelinear.h
  |- set kiLinearScaleReadAheadLength to 10240000 (yeah I know this is
crazy, I am trying to bring it down) [3]

WGLWaveformViewer
  |-mouseTimerHandler(), the function which actually monitors mouse position
and syncing of COs. Then set new rate. [4]
  |-set a timer in eventFilter() to call [5]

[1] state of syncing of CO is on scale of 0 to 10. Every time
ControlObject::sync() is called this state is updated by adding 1 to
previous state, once the count reaches 10 we restart counting from 0.
Storing the value of last state and tallying value of last state with
current state will tell if engine has *(a) *used the last set value once *
(b)* more than once or *(c)* the last set value has yet not been used at
all. And then you set the current value accordingly.

[2]'rate' as set by scratch2 CO is limited within [-MAX_SEEK_SPEED*baserate,
MAX_SEEK_SPEED*baserate]. This rate decides the PlayPos. Distance traveled
by mouse b/n two calls of RateControl::CalculateRate() can easily exceed
this range. So the only thing I could think of was to increase this limit

[3]'rate * baserate' is used by EngineBufferScaleLinear::scale() (unless we
are using key-lock on, which will trigger
EngineBufferScaleLinearST::scale()) which returns the scaled sample and sets
new playing position. (I am skipping gory details) This needs
kiLinearScaleReadAheadLength. Though not as high as 10240000! I am trying to
bring its value down

[4]This function is called every 50ms (QTimer). This function uses
ControlObject::getCallStatus() to see if last rate set is used more than
once, exactly once or not used at all.
One assumption that I made here is that my ControlObject::sync() call will
never lead by more than count of 4.
I have tested this on core i3, 2GB ram, it works. But situation may change
depending upon what h/w is used.
Here is a snapshot of how I am using ControlObject::getCallStatus()


  //COcallOld stores value of sync() call last time this function was called
  //COcallNew stores current value of sync()
  //m_dist stores the dist traveled by mouse from last call of this
function
  //m_distOld stores last value of m_dist

       *//exact - last set value has been used just once*
       if (COcallNew - COcallOld) = 1 or -10 )*** *
            {
             m_distOld = m_dist;
            }
        *//lag **- last set value has NOT yet been used*
        else if ( COcallOld - COcallNew) = 0 )
            {
             m_dest += m_dstOld;     //since last value has not has not been
used so add it to current value
             m_destOld = m_dest;
            }
        *//lead **- last set value has been used more than once*
        else
            {int engineLead = fabs(COcallNew - COcallOld);

             //Engine can't lead by more than 4 syncs
             if ( engineLead < 6 && engineLead > 4)
                 qDebug()<<"This is not supposed to happen, BLAME IT ON
SHANX!";
             else if ( engineLead == 7 )
                 engineLead = 4;
             else if ( (engineLead == 3) || (engineLead == 8) )
                 engineLead = 3;
             else if ( (engineLead == 2) || (engineLead == 9) )
                 engineLead = 2;

             //engineLead stores number of times value has been re-used,
since we want value to be used atleast once, so we subtract
             //1 from engineLead
             m_dest -= m_destOld * (engineLead-1);
             m_destOld = m_dest;
            }


[5]Set up a QTimer to call mouseTimerHandler(). Timer is supposed to shoot
at every 50ms.


I was thinking, why don't we ship RTLinux with Mixxx?
It will boost the performance and help me resolve timing issues (just
kidding :-D )

On a serious note, looks like I am still missing some #defines somewhere, I
need to poke around more with gdb.
Again, I would really appreciate if someone would please point out some
shortcomings  or suggest some changes.

So this is what I am upto. This might mark start of yet another detour, but
it was fun! :-)

-shanxS
lp:~shanx-shashank/mixxx/mouseScratch
------------------------------------------------------------------------------
Enable your software for Intel(R) Active Management Technology to meet the
growing manageability and security demands of your customers. Businesses
are taking advantage of Intel(R) vPro (TM) technology - will your software 
be a part of the solution? Download the Intel(R) Manageability Checker 
today! http://p.sf.net/sfu/intel-dev2devmar
_______________________________________________
Mixxx-devel mailing list
Mixxx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to